You should read the part of the documentation that handles the async behaviour of cypress: https://docs.cypress.io/guides/core-concepts/introduction-to-cypress.html#Commands-Are-Asynchronous
So you can not assign menu.curPage() to a variable and expect that this variable contains the text.
So this will fail. testVar is still null when the expect line is reached:
it("test", () =>{ let testVar = null; cy.get("body").then(() => { testVar = 5; }) expect(testVar).to.eq(5) })
Instead you can write it this way (depends on what and how you want to test):
it("test", () =>{ let testVar = null; cy.get("body").then(() => { testVar = 5; }) cy.get("body").should(() => { expect(testVar).to.eq(5) }) })
so based on your code, your solution might look similar to this:
describe('check two function should be eq') { const menu = new Menu(); it('Verified "', () => { menu.curPage().then(cPText => { menu.tolPage().then(tPText => { expect(cPText).to.eq(tPText); }) }); });
This nesting of commands can be annoying if you must check more than two text values. To make your life easier, you can do this:
describe("test", () => { beforeEach(() => { cy.visit("https://cypress.io") }) it("test", () => { getCaption(); getSubCaption(); // attention: function() syntax is required to keep `this` context cy.get("body").should(function() { expect(this.caption.indexOf("testing") > -1).to.eq(this.subcaption.indexOf("testing") > -1) }); }) }) function getCaption() { return cy.get(".Hero-TagLine.mt-0").invoke("text").as("caption"); } function getSubCaption() { return cy.get(".Hero-ByLine.mb-0").invoke("text").as("subcaption"); }
I have added an own example so I was able to provide you a runnable and working example. But you can adjust it to fit your code easily. What happens:
cy.get().invoke("text").as("alias") does the same as in your code, except that it stores the textcontent in an alias. Cypress also creates a new instance variable for every alias, so you are able to access it through this.caption. - Using this approach you can easily store 10 and more text elements and then access them in a flat hierarchy
- But be aware of the
function () syntax. You can not use the phat arrow syntax because then your this context is wrong - also you can take advantage of the repeat functionality of the
should command. It will retry your callback until no assert fails or until the timeout is reached - this works in Typescript, too. But of course, Typescript does not know the properties
this.caption and this.subcaption. So you will have to cast this to any before or adjust the type definitions
Btw: I saw that you make this: cy.get().invoke("text").then(t => t.toString()) in order to fix the types in TS. You can avoid this by using a own type definition:
declare global { namespace Cypress { interface Chainable { invoke(fn: "text"): Cypress.Chainable<string>; } } }
This can be removed after https://github.com/cypress-io/cypress/issues/4022 is merged.