Website-Suche

javascript - Wie wartet man darauf, dass der Cypress then()-Befehl beendet ist, bevor ein Wert zurückgegeben wird?


Ich versuche, eine Variable innerhalb eines .then()-Befehls zu setzen, die außerhalb davon deklariert ist, und nachdem der gesamte Block (.then()) abgeschlossen ist, gebe ich diesen Wert zurück.

Das Problem ist, dass die Variable beim Zurückgeben des Wertes undefiniert ist, aber innerhalb des .then()-Blocks geladen wird.

Hier ist der Beispielcode:

public getValueFromElement(): string {
  cy.log("Obtaining the Value");

  let myNumber: string; // Here I'm declaring my variable

  cy.get(this.labelWithText).then(($element) => {

    let originalLabelText: string = $element.text();
    let splittedText: string[];
    splittedText = originalLabelText.split(": ");

    myNumber = splittedText[1]; // Here I'm assigning the value 
    cy.log("Inside the THEN" + myNumber); //This logs the number correctly

  });
        
  return myNumber; // But after I return it using the function, the value is `undefined`!
}

Ich gehe davon aus, dass dies mit dem Async-/Sync-Problem zusammenhängen könnte, da die return-Anweisung sofort ausgeführt wird, wenn die Funktion aufgerufen wird, und das durch das .then() erstellte Versprechen noch läuft, aber ich weiß nicht, wie man das behebt.

Weißt du, wie ich warten kann, bis .then() zuerst fertig ist, bevor ich den Wert zurückgebe?

Danke!!

Antwort #1

Du sagst: "Das Problem ist, wenn ich den Wert zurückgebe, ist die Variable undefiniert."

Das liegt daran, dass die Zeile return myNumber vor dem Abschluss von cy.get(this.labelWithText).then(($element) => { ausgeführt wird, weil der Befehl asynchron läuft.

Sie müssen den Befehl selbst zurückgeben, und auch die abgeleitete myNumber wird von innerhalb des .then() zurückgegeben.

public getValueFromElement(): Chainable<string> {  // cannot return the raw string 
  cy.log("Obtaining the Value");
        
  return cy.get(this.labelWithText).then(($element) => {
    ...
    const myNumber = splittedText[1]; 
    cy.log("Inside the THEN " + myNumber)
    
    return myNumber
  })
}

Verwende es so

getValueFromElement().then(myNumber => {
  cy.log("Outside the function " + myNumber)
})

Antwort #2

Du kannst es so synchron machen

public getValueFromElement(): string {  
  cy.log("Obtaining the Value");
        
  const $element = Cypress.$(this.labelWithText)

  const originalLabelText: string = $element.text()
  const splitText = originalLabelText.split(": ")
  const myNumber = splitText[1]
    
  return myNumber
}

Hier opfern Sie die Wiederholungsoptionen, die in asynchronen Befehlen eingebaut sind.

Cypress sagt, es nur zu verwenden, wenn Sie sicher sind, dass das Element bereits existiert, was vom Kontext Ihres Textes abhängt.

@MikhailBolotov in der Tat. So würdest du das handhaben

cy.get("myOpenElementSelector").click()     // async code
  .then(() => {                             // must wrap sync code in then
    const myNumber = getValueFromElement()  // to ensure correct sequence 
    expect(+myNumber).to.eq(64)
  })

@Mihi hat die idiomatische Art, aber es ist manchmal schwierig, wenn man Seitenobjektmethoden erstellt.

Verwandte Artikel