typescript - Cypress - Villkorlig test med timeout


Jag försöker göra något mycket liknande det här inlägget: https://stackoverflow.com/questions/56145926/how-to-check-if-element-exists-using-cypress-io

Jag använder TypeScript. Här är min kod:

cy.get("body").then($body => {
            if ($body.find(this.timerLocator).length > 0) {
                return cy.get(this.timerLocator);
            }
            else {
                return cy.contains('No Match Found');
            }
});

Problemet är att "this.timerLocator" kan ta upp till 60 sekunder innan det dyker upp. Dokumentationen för find-kommandon nämner att vi kan ange ett alternativ 'timeout'. Men när jag lägger till en timeout får jag följande felmeddelande:

cy.get("body").then($body => {
            if ($body.find(this.timerLocator, {timeout: 60000}).length > 0) {
                return cy.get(this.timerLocator);
            }
            else {
                return cy.contains('No Match Found');
            }
        });

Expected 1 arguments, but got 2.ts(2554)

Jag försökte också något mycket enklare, som:

try {
    cy.get(this.timerLocator, { timeout: 60000 });            
} catch (error) {
    cy.contains('No Match Found');
}

Men detta fungerar inte. Jag når aldrig catch-satsen.

Kan någon snälla hjälpa mig med det här?

REDIGERA: Jag slutade faktiskt med att använda en multiväljare och det fungerar utmärkt i mitt fall. Här är min kod:

const multiSelector = `${this.timerLocator}, :contains("No Match Found")`;
return cy.get(multiSelector, { timeout: 60000 });

Svar #1

Du kan egentligen inte göra villkorlig $body.find(...) med en timeout.

Eftersom du har antingen/eller och det verkar som att de är ömsesidigt uteslutande, kan du använda flera väljare

// this selector looks for either timerLocator or element with "No Match Found"
const multiSelector = `${this.timerLocator}, :contains("No Match Found")`;

cy.get(multiSelector, {timeout:60000})
  .then($timerOrNoMatch =>
    ...
  })

Svar #2

Jag skulle undvika att definiera timeout och tidsbaserad wait(number) till varje pris. På lång sikt är de inte en lösning, eftersom de kommer att sakta ner dina tester.

t.ex. Oftast behöver du vänta på att ett visst API ska anropas. Och i det fallet bör du definiera en HTTP-interceptor med ett alias.

cy.intercept("GET", "/customers*").as("getCustomers");

och vänta sedan på det aliaset istället.

cy.wait('@getCustomers');

Om du väntar på något annat (vilket är ganska ovanligt), t.ex. något slags annat löfte eller timeout som ska slutföras, hitta då ett sätt att definiera ett alias för den långvariga funktionen. t.ex. skapa en stub och definiera ett alias för den.

const stub = cy.stub(someServiceToWaitFor, 'functionToWaitFor').as('alias')

Du kan dock inte stubba globala funktioner. Du kan bara stubba funktioner som är definierade på ett objekt. Så det kan (eller kanske inte) kräva att du flyttar runt lite kod. (t.ex. organisera din kod i tjänster)

Och för det andra kan det vara utmanande att få tag på det där serviceobjektet i din Cypress-testkod. Men du kan faktiskt skicka variabler genom att definiera dem på window-objektet.

  if (window['Cypress']) {
    window['SomeServiceToWaitFor'] = someServiceToWaitFor;
  }

Du kan sedan få tag på det objektet med cy.window... från ditt test.

Relaterade artiklar