I have a selector that changes when running in mobile. For example:
Desktop: div[data-test-id="popup"] div:nth-child(2)
Mobile: div[data-test-id="popup"] div:nth-child(3)
My idea is to check the size of the window and if it's below 375 use the Mobile selector else Desktop.
I have the following working solution but I dont want to have repeated code and rather would like to pass 2 or 3 as a parameter:
cy.get('body').then( (body) => {
if ( body.width() <= 375 ) {
cy.get('div[data-test-id="popup"] div:nth-child(3)')
.children().eq(0)
.should('exist')
.should('have.text', time);
}
else {
cy.get('div[data-test-id="popup"] div:nth-child(2)')
.children().eq(0)
.should('exist')
.should('have.text', time);
}
});
Is there a better way to rewrite it?
Also, the above code, even though it runs and the tests pass, the build fails with a Typescript error due to body.width() --> TS2532: Object is possibly 'undefined'.
CodePudding user response:
I would be testing both desktop and mobile using viewport to explicitly set the width
const widths = [500, 350]
widths.forEach(width => {
// You are looking for a way to parameterize the selector,
// do it using a template literal
const param = width === 350 ? 3 : 2
const selector = `div[data-test-id="popup"] div:nth-child(${param})`
beforeEach(() => {
cy.viewport(width, 800)
})
it(`tests the width of ${width}px`, () => {
cy.get(selector)
.children().eq(0)
.should('exist')
.should('have.text', time)
})
})
It looks like you need to use viewport in a somewhat restricted way, either
- in beforeEach() hook
- before a page cy.visit()
- before a page cy.reload()
The typescript error
body.width() --> TS2532: Object is possibly 'undefined'
can be fixed by using the non-null assertion operator
body!.width() // telling typescript that we know body exists
