The ideal way (if it works in your scenario) is to shift the last selector inside the .then()
cy.get('[data-slug="add-to-any"] > .plugin-title')
.then(($pluginTitle) => {
const $slug = $pluginTitle.find('strong'); // this finds with jQuery
// which won't fail the test
// if not found
if ($slug.length === 0) { // not found
} else {
cy.get('#deactivate-add-to-any').should('not.exist')
}
})
It's not 100% fool-proof, if $slug is loaded asynchronously (say via fetch) it won't be there immediately and the test might pass when in fact the $slug turns up 100 ms after the test runs.
You need to understand the way the app works to really be sure.
Cypress docs show this pattern, using <body>
as the "stable" element (always present after page load).
cy.get('body').then($body => {
const slug = $body.find('[data-slug="add-to-any"] > .plugin-title > strong')
if ($slug.length) {
...
It's less than ideal because the page might have <body>
but still be fetching elements inside it.
Best practice IMO is to try the immediate parent element of the conditional one. If that is also conditional, move up the element tree until you find an element that is stable/present at that point in you test.
Or add a guard condition that waits for page fetch to complete. A cy.intercept()
is useful for that, or even just this
cy.get('[data-slug="add-to-any"] > .plugin-title')
.should('be.visible') // retries until .plugin-title is showing
.then(($pluginTitle) => {
const $slug = $pluginTitle.find('strong')
if ($slug.length === 0) {
...