diff --git a/cypress/e2e/get-from-supported-selector.spec.ts b/cypress/e2e/get-from-supported-selector.spec.ts index a3cb02b..f94521f 100644 --- a/cypress/e2e/get-from-supported-selector.spec.ts +++ b/cypress/e2e/get-from-supported-selector.spec.ts @@ -96,6 +96,66 @@ describe('Get From Supported Selector', () => { }); }); + describe('filters hidden-page elements BEFORE asserting hydration', () => { + beforeEach(() => { + cy.document().then((doc) => { + doc.body.insertAdjacentHTML( + 'beforeend', + `
+
Not Hydrated Hidden
+
+
+
Visible Hydrated
+
`, + ); + }); + }); + + it('Chainable - does not fail when a hidden element lacks .hydrated', () => { + getFromSupportedSelector(cy.get('.testing-order-bug')) + .should('have.length', 1) + .should('have.text', 'Visible Hydrated'); + }); + + it('JQuery - does not fail when a hidden element lacks .hydrated', () => { + cy.get('.testing-order-bug').then(($els) => { + getFromSupportedSelector($els) + .should('have.length', 1) + .should('have.text', 'Visible Hydrated'); + }); + }); + + it('Chainable - returns empty set without timing out when all matches are hidden', () => { + getFromSupportedSelector( + cy.get('.testing-order-bug').filter(':not(.hydrated)'), + ).should('have.length', 0); + }); + + it('JQuery - returns empty set without timing out when all matches are hidden', () => { + cy.get('.testing-order-bug') + .filter(':not(.hydrated)') + .then(($els) => { + getFromSupportedSelector($els).should('have.length', 0); + }); + }); + + it('css selector - returns empty set without timing out when all matches are hidden and not hydrated', () => { + cy.document().then((doc) => { + doc.body.insertAdjacentHTML( + 'beforeend', + `
+
Hidden Only
+
`, + ); + }); + + getFromSupportedSelector('.testing-order-hidden-only').should( + 'have.length', + 0, + ); + }); + }); + describe('waiting for components hydration', () => { it('css selector', () => { getFromSupportedSelector('.ion-range-to-test-hydration') diff --git a/src/helpers/get-from-supported-selector.ts b/src/helpers/get-from-supported-selector.ts index a31a648..0429ead 100644 --- a/src/helpers/get-from-supported-selector.ts +++ b/src/helpers/get-from-supported-selector.ts @@ -1,4 +1,7 @@ import { CypressIonicReturn, SupportedSelectors } from '../interfaces'; + +const HIDDEN_PAGE_SELECTOR = '.ion-page-hidden, .ion-page-hidden *'; + /** * @internal */ @@ -6,31 +9,26 @@ export function getFromSupportedSelector( selector: SupportedSelectors, ): CypressIonicReturn { if (typeof selector === 'string') { - return filterOutHiddenPage(cy.get(`${selector}.hydrated`)); + return filterThenAssertHydrated(cy.get(selector)); } if (isJQuery(selector)) { - return filterOutHiddenPage( - cy - .wrap(selector) - .should('have.class', 'hydrated') as CypressIonicReturn, - ); + return filterThenAssertHydrated(cy.wrap(selector) as CypressIonicReturn); } - return filterOutHiddenPage( - (selector as unknown as CypressIonicReturn).should( - 'have.class', - 'hydrated', - ), - ); + return filterThenAssertHydrated(selector as unknown as CypressIonicReturn); } -function filterOutHiddenPage( +function filterThenAssertHydrated( subject: CypressIonicReturn, ): CypressIonicReturn { - return subject.not( - '.ion-page-hidden, .ion-page-hidden *', - ) as unknown as CypressIonicReturn; + return subject.then((elements) => { + const $visible = elements.not(HIDDEN_PAGE_SELECTOR) as unknown as JQuery; + if ($visible.length === 0) { + return cy.wrap($visible); + } + return cy.wrap($visible).should('have.class', 'hydrated'); + }) as unknown as CypressIonicReturn; } function isJQuery(