From db4cdeb44463693c20f6a8031309dfb9f242e59b Mon Sep 17 00:00:00 2001 From: Liam DeBeasi Date: Wed, 30 Nov 2022 15:53:25 -0500 Subject: [PATCH] test(utils): migrate utils e2e tests to playwright (#26377) --- .../accordion/test/accordion.e2e.ts | 56 ++++ core/src/components/accordion/test/e2e.ts | 55 ---- core/src/components/label/test/basic/e2e.ts | 10 - .../src/components/loading/test/test.utils.ts | 38 --- core/src/components/slides/test/basic/e2e.ts | 10 - core/src/components/slides/test/image/e2e.ts | 10 - .../slides/test/prevent-default/e2e.ts | 33 --- .../components/slides/test/vertical/e2e.ts | 10 - core/src/components/toast/test/test.utils.ts | 42 --- .../virtual-scroll/test/basic/e2e.ts | 11 - .../virtual-scroll/test/cards/e2e.ts | 11 - core/src/themes/test/css-variables/e2e.ts | 10 - .../test/animationbuilder/animation.e2e.ts | 43 +++ .../animation/test/animationbuilder/e2e.ts | 45 ---- .../animation/test/basic/animation.e2e.ts | 27 ++ core/src/utils/animation/test/basic/e2e.ts | 59 ----- .../src/utils/animation/test/basic/index.html | 2 +- .../animation/test/display/animation.e2e.ts | 37 +++ core/src/utils/animation/test/display/e2e.ts | 42 --- .../utils/animation/test/display/index.html | 6 +- .../animation/test/hooks/animation.e2e.ts | 63 +++++ core/src/utils/animation/test/hooks/e2e.ts | 146 ----------- .../src/utils/animation/test/hooks/index.html | 10 +- .../animation/test/multiple/animation.e2e.ts | 46 ++++ core/src/utils/animation/test/multiple/e2e.ts | 77 ------ .../utils/animation/test/multiple/index.html | 12 +- core/src/utils/gesture/test/e2e.ts | 36 --- core/src/utils/test/framework-delegate/e2e.ts | 34 --- .../framework-delegate.e2e.ts | 40 +++ .../utils/test/framework-delegate/index.html | 1 + core/src/utils/test/modes/e2e.ts | 169 ------------ core/src/utils/test/modes/index.html | 191 -------------- core/src/utils/test/overlays/e2e.ts | 178 ------------- core/src/utils/test/overlays/index.html | 1 + core/src/utils/test/overlays/overlays.e2e.ts | 156 +++++++++++ core/src/utils/test/utils.ts | 248 ------------------ 36 files changed, 485 insertions(+), 1480 deletions(-) create mode 100644 core/src/components/accordion/test/accordion.e2e.ts delete mode 100644 core/src/components/accordion/test/e2e.ts delete mode 100644 core/src/components/label/test/basic/e2e.ts delete mode 100644 core/src/components/loading/test/test.utils.ts delete mode 100644 core/src/components/slides/test/basic/e2e.ts delete mode 100644 core/src/components/slides/test/image/e2e.ts delete mode 100644 core/src/components/slides/test/prevent-default/e2e.ts delete mode 100644 core/src/components/slides/test/vertical/e2e.ts delete mode 100644 core/src/components/toast/test/test.utils.ts delete mode 100644 core/src/components/virtual-scroll/test/basic/e2e.ts delete mode 100644 core/src/components/virtual-scroll/test/cards/e2e.ts delete mode 100644 core/src/themes/test/css-variables/e2e.ts create mode 100644 core/src/utils/animation/test/animationbuilder/animation.e2e.ts delete mode 100644 core/src/utils/animation/test/animationbuilder/e2e.ts create mode 100644 core/src/utils/animation/test/basic/animation.e2e.ts delete mode 100644 core/src/utils/animation/test/basic/e2e.ts create mode 100644 core/src/utils/animation/test/display/animation.e2e.ts delete mode 100644 core/src/utils/animation/test/display/e2e.ts create mode 100644 core/src/utils/animation/test/hooks/animation.e2e.ts delete mode 100644 core/src/utils/animation/test/hooks/e2e.ts create mode 100644 core/src/utils/animation/test/multiple/animation.e2e.ts delete mode 100644 core/src/utils/animation/test/multiple/e2e.ts delete mode 100644 core/src/utils/gesture/test/e2e.ts delete mode 100644 core/src/utils/test/framework-delegate/e2e.ts create mode 100644 core/src/utils/test/framework-delegate/framework-delegate.e2e.ts delete mode 100644 core/src/utils/test/modes/e2e.ts delete mode 100644 core/src/utils/test/modes/index.html delete mode 100644 core/src/utils/test/overlays/e2e.ts delete mode 100644 core/src/utils/test/utils.ts diff --git a/core/src/components/accordion/test/accordion.e2e.ts b/core/src/components/accordion/test/accordion.e2e.ts new file mode 100644 index 0000000000..ab0a48dc28 --- /dev/null +++ b/core/src/components/accordion/test/accordion.e2e.ts @@ -0,0 +1,56 @@ +import { expect } from '@playwright/test'; +import { test } from '@utils/test/playwright'; + +test.describe('accordion: states', () => { + test.beforeEach(({ skip }) => { + skip.rtl(); + skip.mode('ios'); + }); + test('should properly set readonly on child accordions', async ({ page }) => { + await page.setContent(` + + + Label +
Content
+
+
+ `); + + const accordionGroup = page.locator('ion-accordion-group'); + const accordion = page.locator('ion-accordion'); + + expect(accordion).toHaveJSProperty('readonly', false); + + await accordionGroup.evaluate((el: HTMLIonAccordionGroupElement) => { + el.readonly = true; + }); + + await page.waitForChanges(); + + expect(accordion).toHaveJSProperty('readonly', true); + }); + + test('should properly set disabled on child accordions', async ({ page }) => { + await page.setContent(` + + + Label +
Content
+
+
+ `); + + const accordionGroup = page.locator('ion-accordion-group'); + const accordion = page.locator('ion-accordion'); + + expect(accordion).toHaveJSProperty('disabled', false); + + await accordionGroup.evaluate((el: HTMLIonAccordionGroupElement) => { + el.disabled = true; + }); + + await page.waitForChanges(); + + expect(accordion).toHaveJSProperty('disabled', true); + }); +}); diff --git a/core/src/components/accordion/test/e2e.ts b/core/src/components/accordion/test/e2e.ts deleted file mode 100644 index 5642c7ec34..0000000000 --- a/core/src/components/accordion/test/e2e.ts +++ /dev/null @@ -1,55 +0,0 @@ -import { newE2EPage } from '@stencil/core/testing'; - -test('should properly set readonly on child accordions', async () => { - const page = await newE2EPage({ - html: ` - - - Label -
Content
-
-
- `, - }); - - const accordion = await page.find('ion-accordion'); - const value = await accordion.getProperty('readonly'); - - expect(value).toBe(false); - - await page.$eval('ion-accordion-group', (el: HTMLIonAccordionGroupElement) => { - el.readonly = true; - }); - - await page.waitForChanges(); - - const valueAgain = await accordion.getProperty('readonly'); - expect(valueAgain).toBe(true); -}); - -test('should properly set disabled on child accordions', async () => { - const page = await newE2EPage({ - html: ` - - - Label -
Content
-
-
- `, - }); - - const accordion = await page.find('ion-accordion'); - const value = await accordion.getProperty('disabled'); - - expect(value).toBe(false); - - await page.$eval('ion-accordion-group', (el: HTMLIonAccordionGroupElement) => { - el.disabled = true; - }); - - await page.waitForChanges(); - - const valueAgain = await accordion.getProperty('disabled'); - expect(valueAgain).toBe(true); -}); diff --git a/core/src/components/label/test/basic/e2e.ts b/core/src/components/label/test/basic/e2e.ts deleted file mode 100644 index 055e96ba6c..0000000000 --- a/core/src/components/label/test/basic/e2e.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { newE2EPage } from '@stencil/core/testing'; - -test('label: basic', async () => { - const page = await newE2EPage({ - url: '/src/components/label/test/basic?ionic:_testing=true', - }); - - const compare = await page.compareScreenshot(); - expect(compare).toMatchScreenshot(); -}); diff --git a/core/src/components/loading/test/test.utils.ts b/core/src/components/loading/test/test.utils.ts deleted file mode 100644 index f1ab7d3e63..0000000000 --- a/core/src/components/loading/test/test.utils.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { newE2EPage } from '@stencil/core/testing'; -import { generateE2EUrl } from '@utils/test'; - -export const testLoading = async (type: string, selector: string, rtl = false) => { - try { - const pageUrl = generateE2EUrl('loading', type, rtl); - - const page = await newE2EPage({ - url: pageUrl, - }); - - const screenshotCompares = []; - - await page.click(selector); - await page.waitForSelector(selector); - - let loading = await page.find('ion-loading'); - expect(loading).not.toBeNull(); - - await loading.waitForVisible(); - - screenshotCompares.push(await page.compareScreenshot()); - - await loading.callMethod('dismiss'); - await loading.waitForNotVisible(); - - screenshotCompares.push(await page.compareScreenshot('dismiss')); - - loading = await page.find('ion-loading'); - expect(loading).toBeNull(); - - for (const screenshotCompare of screenshotCompares) { - expect(screenshotCompare).toMatchScreenshot(); - } - } catch (err) { - throw err; - } -}; diff --git a/core/src/components/slides/test/basic/e2e.ts b/core/src/components/slides/test/basic/e2e.ts deleted file mode 100644 index 01279aefc8..0000000000 --- a/core/src/components/slides/test/basic/e2e.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { newE2EPage } from '@stencil/core/testing'; - -test('slides: basic', async () => { - const page = await newE2EPage({ - url: '/src/components/slides/test/basic?ionic:_testing=true', - }); - - const compare = await page.compareScreenshot(); - expect(compare).toMatchScreenshot(); -}); diff --git a/core/src/components/slides/test/image/e2e.ts b/core/src/components/slides/test/image/e2e.ts deleted file mode 100644 index 5a12745e69..0000000000 --- a/core/src/components/slides/test/image/e2e.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { newE2EPage } from '@stencil/core/testing'; - -test('slides: image', async () => { - const page = await newE2EPage({ - url: '/src/components/slides/test/image?ionic:_testing=true', - }); - - const compare = await page.compareScreenshot(); - expect(compare).toMatchScreenshot(); -}); diff --git a/core/src/components/slides/test/prevent-default/e2e.ts b/core/src/components/slides/test/prevent-default/e2e.ts deleted file mode 100644 index e92c108342..0000000000 --- a/core/src/components/slides/test/prevent-default/e2e.ts +++ /dev/null @@ -1,33 +0,0 @@ -import { newE2EPage } from '@stencil/core/testing'; - -test('slides: prevent-default', async () => { - // For this specific test, _testing=false to import tap-click in app.tsx - const page = await newE2EPage({ - url: '/src/components/slides/test/prevent-default?ionic:_testing=false', - }); - - const screenshotCompares = []; - - screenshotCompares.push(await page.compareScreenshot()); - - const scroller = await page.find('#scrollDownButton'); - const button = await page.find('#changeBackgroundButton'); - const contentWithBackground = await page.find('#contentWithBackground'); - - await page.waitForTimeout(500); - - await scroller.click(); - await page.waitForTimeout(500); - - screenshotCompares.push(await page.compareScreenshot('scroll down button')); - - await button.click(); - - screenshotCompares.push(await page.compareScreenshot('change background')); - - expect(contentWithBackground).toHaveClasses(['blueBackground']); - - for (const screenshotCompare of screenshotCompares) { - expect(screenshotCompare).toMatchScreenshot(); - } -}); diff --git a/core/src/components/slides/test/vertical/e2e.ts b/core/src/components/slides/test/vertical/e2e.ts deleted file mode 100644 index d3c57a304a..0000000000 --- a/core/src/components/slides/test/vertical/e2e.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { newE2EPage } from '@stencil/core/testing'; - -test('slides: vertical', async () => { - const page = await newE2EPage({ - url: '/src/components/slides/test/vertical?ionic:_testing=true', - }); - - const compare = await page.compareScreenshot(); - expect(compare).toMatchScreenshot(); -}); diff --git a/core/src/components/toast/test/test.utils.ts b/core/src/components/toast/test/test.utils.ts deleted file mode 100644 index 0de7e823f2..0000000000 --- a/core/src/components/toast/test/test.utils.ts +++ /dev/null @@ -1,42 +0,0 @@ -import { newE2EPage } from '@stencil/core/testing'; -import { generateE2EUrl } from '@utils/test'; - -export const testToast = async (type: string, selector: string, rtl = false) => { - try { - const pageUrl = generateE2EUrl('toast', type, rtl); - - const page = await newE2EPage({ - url: pageUrl, - }); - - const screenshotCompares = []; - - const button = await page.find(selector); - await button.waitForVisible(); - await button.click(); - - await page.waitForTimeout(250); - - let toast = await page.find('ion-toast'); - await toast.waitForVisible(); - - expect(toast).not.toBe(null); - await toast.waitForVisible(); - - screenshotCompares.push(await page.compareScreenshot()); - - await toast.callMethod('dismiss'); - await toast.waitForNotVisible(); - - screenshotCompares.push(await page.compareScreenshot('dismiss')); - - toast = await page.find('ion-toast'); - expect(toast).toBe(null); - - for (const screenshotCompare of screenshotCompares) { - expect(screenshotCompare).toMatchScreenshot(); - } - } catch (err) { - throw err; - } -}; diff --git a/core/src/components/virtual-scroll/test/basic/e2e.ts b/core/src/components/virtual-scroll/test/basic/e2e.ts deleted file mode 100644 index 183d21e21d..0000000000 --- a/core/src/components/virtual-scroll/test/basic/e2e.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { newE2EPage } from '@stencil/core/testing'; - -test('virtual-scroll: basic', async () => { - const page = await newE2EPage({ - url: '/src/components/virtual-scroll/test/basic?ionic:_testing=true', - }); - await page.waitForTimeout(300); - - const compare = await page.compareScreenshot(); - expect(compare).toMatchScreenshot(); -}); diff --git a/core/src/components/virtual-scroll/test/cards/e2e.ts b/core/src/components/virtual-scroll/test/cards/e2e.ts deleted file mode 100644 index f9d4db52cb..0000000000 --- a/core/src/components/virtual-scroll/test/cards/e2e.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { newE2EPage } from '@stencil/core/testing'; - -test('virtual-scroll: cards', async () => { - const page = await newE2EPage({ - url: '/src/components/virtual-scroll/test/cards?ionic:_testing=true', - }); - await page.waitForTimeout(300); - - const compare = await page.compareScreenshot(); - expect(compare).toMatchScreenshot(); -}); diff --git a/core/src/themes/test/css-variables/e2e.ts b/core/src/themes/test/css-variables/e2e.ts deleted file mode 100644 index 4656b72a09..0000000000 --- a/core/src/themes/test/css-variables/e2e.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { newE2EPage } from '@stencil/core/testing'; - -test('themes: css-variables', async () => { - const page = await newE2EPage({ - url: '/src/themes/test/css-variables?ionic:_testing=true', - }); - - const compare = await page.compareScreenshot(); - expect(compare).toMatchScreenshot(); -}); diff --git a/core/src/utils/animation/test/animationbuilder/animation.e2e.ts b/core/src/utils/animation/test/animationbuilder/animation.e2e.ts new file mode 100644 index 0000000000..5e556d8c1d --- /dev/null +++ b/core/src/utils/animation/test/animationbuilder/animation.e2e.ts @@ -0,0 +1,43 @@ +import type { E2EPage } from '@utils/test/playwright'; +import { test } from '@utils/test/playwright'; + +test.describe('animation: animationbuilder', async () => { + test.beforeEach(({ skip }) => { + skip.rtl(); + }); + test('backwards-compatibility animation', async ({ page }) => { + await page.goto('/src/utils/animation/test/animationbuilder'); + await testNavigation(page); + }); + + test('ios-transition web', async ({ page, skip }) => { + skip.mode('md'); + + await page.goto('/src/utils/animation/test/animationbuilder'); + await testNavigation(page); + }); + + test('ios-transition css', async ({ page, skip }) => { + skip.mode('md'); + + await page.goto('/src/utils/animation/test/animationbuilder?ionic:_forceCSSAnimations=true'); + await testNavigation(page); + }); +}); + +const testNavigation = async (page: E2EPage) => { + const ionRouteDidChange = await page.spyOnEvent('ionRouteDidChange'); + + await page.click('page-root ion-button.next'); + await ionRouteDidChange.next(); + page.click('page-one ion-button.next'); + await ionRouteDidChange.next(); + page.click('page-two ion-button.next'); + await ionRouteDidChange.next(); + page.click('page-three ion-back-button'); + await ionRouteDidChange.next(); + page.click('page-two ion-back-button'); + await ionRouteDidChange.next(); + page.click('page-one ion-back-button'); + await ionRouteDidChange.next(); +}; diff --git a/core/src/utils/animation/test/animationbuilder/e2e.ts b/core/src/utils/animation/test/animationbuilder/e2e.ts deleted file mode 100644 index d9a5769e7b..0000000000 --- a/core/src/utils/animation/test/animationbuilder/e2e.ts +++ /dev/null @@ -1,45 +0,0 @@ -import type { E2EPage } from '@stencil/core/testing'; -import { newE2EPage } from '@stencil/core/testing'; - -test('animation:backwards-compatibility animation', async () => { - const page = await newE2EPage({ url: '/src/utils/animation/test/animationbuilder' }); - await testNavigation(page); -}); - -test('animation:ios-transition web', async () => { - const page = await newE2EPage({ url: '/src/utils/animation/test/animationbuilder?ionic:mode=ios' }); - await testNavigation(page); -}); - -test('animation:ios-transition css', async () => { - const page = await newE2EPage({ - url: '/src/utils/animation/test/animationbuilder?ionic:mode=ios&ionic:_forceCSSAnimations=true', - }); - await testNavigation(page); -}); - -const testNavigation = async (page: E2EPage) => { - const screenshotCompares = []; - const ionRouteDidChange = await page.spyOnEvent('ionRouteDidChange'); - - screenshotCompares.push(await page.compareScreenshot()); - - await page.click('page-root ion-button.next'); - await ionRouteDidChange.next(); - page.click('page-one ion-button.next'); - await ionRouteDidChange.next(); - page.click('page-two ion-button.next'); - await ionRouteDidChange.next(); - page.click('page-three ion-back-button'); - await ionRouteDidChange.next(); - page.click('page-two ion-back-button'); - await ionRouteDidChange.next(); - page.click('page-one ion-back-button'); - await ionRouteDidChange.next(); - - screenshotCompares.push(await page.compareScreenshot('end navigation')); - - for (const screenshotCompare of screenshotCompares) { - expect(screenshotCompare).toMatchScreenshot(); - } -}; diff --git a/core/src/utils/animation/test/basic/animation.e2e.ts b/core/src/utils/animation/test/basic/animation.e2e.ts new file mode 100644 index 0000000000..41ae95b366 --- /dev/null +++ b/core/src/utils/animation/test/basic/animation.e2e.ts @@ -0,0 +1,27 @@ +import { test } from '@utils/test/playwright'; +import type { E2EPage } from '@utils/test/playwright'; + +test.describe('animation: basic', async () => { + test.beforeEach(({ skip }) => { + skip.rtl(); + skip.mode('ios'); + }); + + test(`should resolve using web animations`, async ({ page }) => { + await page.goto('/src/utils/animation/test/basic'); + await testPage(page); + }); + + test(`should resolve using css animations`, async ({ page }) => { + await page.goto('/src/utils/animation/test/basic?ionic:_forceCSSAnimations=true'); + await testPage(page); + }); +}); + +const testPage = async (page: E2EPage) => { + const ionAnimationFinished = await page.spyOnEvent('ionAnimationFinished'); + + await page.click('.play'); + + await ionAnimationFinished.next(); +}; diff --git a/core/src/utils/animation/test/basic/e2e.ts b/core/src/utils/animation/test/basic/e2e.ts deleted file mode 100644 index 8b86a8ef76..0000000000 --- a/core/src/utils/animation/test/basic/e2e.ts +++ /dev/null @@ -1,59 +0,0 @@ -import { newE2EPage } from '@stencil/core/testing'; - -import { listenForEvent, waitForFunctionTestContext } from '../../../test/utils'; - -test(`animation:web: basic`, async () => { - const page = await newE2EPage({ url: '/src/utils/animation/test/basic' }); - const screenshotCompares = []; - - screenshotCompares.push(await page.compareScreenshot()); - - const ANIMATION_FINISHED = 'onIonAnimationFinished'; - const animationFinishedCount: any = { count: 0 }; - await page.exposeFunction(ANIMATION_FINISHED, () => { - animationFinishedCount.count += 1; - }); - - const square = await page.$('.square-a'); - await listenForEvent(page, 'ionAnimationFinished', square, ANIMATION_FINISHED); - - await page.click('.play'); - await page.waitForSelector('.play'); - - await waitForFunctionTestContext( - (payload: any) => { - return payload.animationFinishedCount.count === 1; - }, - { animationFinishedCount } - ); - - screenshotCompares.push(await page.compareScreenshot('end animation')); -}); - -test(`animation:css: basic`, async () => { - const page = await newE2EPage({ url: '/src/utils/animation/test/basic?ionic:_forceCSSAnimations=true' }); - const screenshotCompares = []; - - screenshotCompares.push(await page.compareScreenshot()); - - const ANIMATION_FINISHED = 'onIonAnimationFinished'; - const animationFinishedCount: any = { count: 0 }; - await page.exposeFunction(ANIMATION_FINISHED, () => { - animationFinishedCount.count += 1; - }); - - const square = await page.$('.square-a'); - await listenForEvent(page, 'ionAnimationFinished', square, ANIMATION_FINISHED); - - await page.click('.play'); - await page.waitForSelector('.play'); - - await waitForFunctionTestContext( - (payload: any) => { - return payload.animationFinishedCount.count === 1; - }, - { animationFinishedCount } - ); - - screenshotCompares.push(await page.compareScreenshot('end animation')); -}); diff --git a/core/src/utils/animation/test/basic/index.html b/core/src/utils/animation/test/basic/index.html index f5c932c770..0d6d193962 100644 --- a/core/src/utils/animation/test/basic/index.html +++ b/core/src/utils/animation/test/basic/index.html @@ -37,7 +37,7 @@ ]) .onFinish(() => { const ev = new CustomEvent('ionAnimationFinished'); - squareA.dispatchEvent(ev); + window.dispatchEvent(ev); }); document.querySelector('.play').addEventListener('click', () => { diff --git a/core/src/utils/animation/test/display/animation.e2e.ts b/core/src/utils/animation/test/display/animation.e2e.ts new file mode 100644 index 0000000000..d5f2b1bd3b --- /dev/null +++ b/core/src/utils/animation/test/display/animation.e2e.ts @@ -0,0 +1,37 @@ +import { expect } from '@playwright/test'; +import { test } from '@utils/test/playwright'; +import type { E2EPage } from '@utils/test/playwright'; + +test.describe('animation: display', async () => { + test.beforeEach(({ skip }) => { + skip.rtl(); + skip.mode('ios'); + }); + + test(`should resolve using web animations`, async ({ page }) => { + await page.goto('/src/utils/animation/test/display'); + await testDisplay(page); + }); + + test(`should resolve using css animations`, async ({ page }) => { + await page.goto('/src/utils/animation/test/display?ionic:_forceCSSAnimations=true'); + await testDisplay(page); + }); +}); + +const testDisplay = async (page: E2EPage) => { + const ionAnimationFinished = await page.spyOnEvent('ionAnimationFinished'); + + await page.click('.play'); + + await ionAnimationFinished.next(); + await expect(ionAnimationFinished).toHaveReceivedEventDetail('AnimationBFinished'); + + await ionAnimationFinished.next(); + await expect(ionAnimationFinished).toHaveReceivedEventDetail('AnimationAFinished'); + + await ionAnimationFinished.next(); + await expect(ionAnimationFinished).toHaveReceivedEventDetail('AnimationRootFinished'); + + await expect(ionAnimationFinished).toHaveReceivedEventTimes(3); +}; diff --git a/core/src/utils/animation/test/display/e2e.ts b/core/src/utils/animation/test/display/e2e.ts deleted file mode 100644 index d09c62b215..0000000000 --- a/core/src/utils/animation/test/display/e2e.ts +++ /dev/null @@ -1,42 +0,0 @@ -import { newE2EPage } from '@stencil/core/testing'; - -import { listenForEvent, waitForFunctionTestContext } from '../../../test/utils'; - -test(`animation:web: display`, async () => { - const page = await newE2EPage({ url: '/src/utils/animation/test/display' }); - await runTest(page); -}); - -test(`animation:css: display`, async () => { - const page = await newE2EPage({ url: '/src/utils/animation/test/display?ionic:_forceCSSAnimations=true' }); - await runTest(page); -}); - -const runTest = async (page: any) => { - const screenshotCompares = []; - - screenshotCompares.push(await page.compareScreenshot()); - - const ANIMATION_FINISHED = 'onIonAnimationFinished'; - const animationStatus = []; - await page.exposeFunction(ANIMATION_FINISHED, (ev: any) => { - animationStatus.push(ev.detail); - }); - - const squareA = await page.$('.square-a'); - await listenForEvent(page, 'ionAnimationFinished', squareA, ANIMATION_FINISHED); - - await page.click('.play'); - await page.waitForSelector('.play'); - - await waitForFunctionTestContext( - (payload: any) => { - return ( - payload.animationStatus.join(', ') === - ['AnimationBFinished', 'AnimationAFinished', 'AnimationRootFinished'].join(', ') - ); - }, - { animationStatus } - ); - screenshotCompares.push(await page.compareScreenshot('end animation')); -}; diff --git a/core/src/utils/animation/test/display/index.html b/core/src/utils/animation/test/display/index.html index 62fe38bc05..68bd0caac4 100644 --- a/core/src/utils/animation/test/display/index.html +++ b/core/src/utils/animation/test/display/index.html @@ -43,7 +43,7 @@ ]) .onFinish(() => { const ev = new CustomEvent('ionAnimationFinished', { detail: 'AnimationAFinished' }); - squareA.dispatchEvent(ev); + window.dispatchEvent(ev); }); animationB @@ -58,12 +58,12 @@ ]) .onFinish(() => { const ev = new CustomEvent('ionAnimationFinished', { detail: 'AnimationBFinished' }); - squareA.dispatchEvent(ev); + window.dispatchEvent(ev); }); rootAnimation.addAnimation([animationA, animationB]).onFinish(() => { const ev = new CustomEvent('ionAnimationFinished', { detail: 'AnimationRootFinished' }); - squareA.dispatchEvent(ev); + window.dispatchEvent(ev); }); document.querySelector('.play').addEventListener('click', () => { diff --git a/core/src/utils/animation/test/hooks/animation.e2e.ts b/core/src/utils/animation/test/hooks/animation.e2e.ts new file mode 100644 index 0000000000..be714b04c0 --- /dev/null +++ b/core/src/utils/animation/test/hooks/animation.e2e.ts @@ -0,0 +1,63 @@ +import { expect } from '@playwright/test'; +import { test } from '@utils/test/playwright'; +import type { E2EPage } from '@utils/test/playwright'; + +test.describe('animation: hooks', async () => { + test.beforeEach(({ skip }) => { + skip.rtl(); + skip.mode('ios'); + }); + + test(`should fire hooks using web animations`, async ({ page }) => { + await page.goto('/src/utils/animation/test/hooks'); + await testHooks(page); + }); + + test(`should fire hooks using css animations`, async ({ page }) => { + await page.goto('/src/utils/animation/test/hooks?ionic:_forceCSSAnimations=true'); + await testHooks(page); + }); +}); + +const testHooks = async (page: E2EPage) => { + const square = page.locator('.square-a'); + const ionAnimationFinished = await page.spyOnEvent('ionAnimationFinished'); + const beforeRead = await page.spyOnEvent('beforeRead'); + const beforeWrite = await page.spyOnEvent('beforeWrite'); + const afterRead = await page.spyOnEvent('afterRead'); + const afterWrite = await page.spyOnEvent('afterWrite'); + + // Test initial classes + await expect(square).toHaveClass(/hello-world/); + await expect(square).not.toHaveClass(/test-class/); + + // Test initial styles + await expect(square).toHaveCSS('padding-bottom', '20px'); + await expect(square).toHaveCSS('color', 'rgb(0, 0, 0)'); + + await page.click('.play'); + + // Test beforeRemoveClass and beforeAddClass + await expect(square).not.toHaveClass(/hello-world/); + await expect(square).toHaveClass(/test-class/); + + // Test beforeStyles and beforeClearStyles + await expect(square).toHaveCSS('padding-bottom', '0px'); + await expect(square).toHaveCSS('color', 'rgb(128, 0, 128)'); + + await beforeRead.next(); + await beforeWrite.next(); + + await ionAnimationFinished.next(); + + await afterRead.next(); + await afterWrite.next(); + + // Test afterRemoveClass and afterAddClass + await expect(square).toHaveClass(/hello-world/); + await expect(square).not.toHaveClass(/test-class/); + + // Test afterStyles and afterClearStyles + await expect(square).toHaveCSS('padding-bottom', '20px'); + await expect(square).toHaveCSS('color', 'rgb(0, 0, 0)'); +}; diff --git a/core/src/utils/animation/test/hooks/e2e.ts b/core/src/utils/animation/test/hooks/e2e.ts deleted file mode 100644 index d060b58f4f..0000000000 --- a/core/src/utils/animation/test/hooks/e2e.ts +++ /dev/null @@ -1,146 +0,0 @@ -import { newE2EPage } from '@stencil/core/testing'; - -import { listenForEvent, waitForFunctionTestContext } from '../../../test/utils'; - -test(`animation:web: hooks`, async () => { - const page = await newE2EPage({ url: '/src/utils/animation/test/hooks' }); - const screenshotCompares = []; - - screenshotCompares.push(await page.compareScreenshot()); - - const square = await page.$('.square-a'); - - const styles = await getStyles(page, '.square-a'); - expect(styles.paddingBottom).toEqual('20px'); - expect(styles.color).toEqual('rgb(0, 0, 0)'); - - const classList = await getClassList(square); - expect(classList.includes('hello-world')).toEqual(true); - expect(classList.includes('test-class')).toEqual(false); - - await waitForEventToBeCalled('afterWrite', page, square, async () => { - await waitForEventToBeCalled('afterRead', page, square, async () => { - await waitForEventToBeCalled('ionAnimationFinished', page, square, async () => { - await waitForEventToBeCalled('beforeWrite', page, square, async () => { - await waitForEventToBeCalled('beforeRead', page, square, async () => { - await page.click('.play'); - await page.waitForSelector('.play'); - - // Test beforeRemoveClass and beforeAddClass - const webClassListAgain = await getClassList(square); - expect(webClassListAgain.includes('hello-world')).toEqual(false); - expect(webClassListAgain.includes('test-class')).toEqual(true); - - // Test beforeStyles and beforeClearStyles - const webStylesAgain = await getStyles(page, '.square-a'); - expect(webStylesAgain.paddingBottom).toEqual('0px'); - expect(webStylesAgain.color).toEqual('rgb(128, 0, 128)'); - }); - }); - }); - }); - }); - - // Test afterRemoveClass and afterAddClass - const classListAgain = await getClassList(square); - expect(classListAgain.includes('hello-world')).toEqual(true); - expect(classListAgain.includes('test-class')).toEqual(false); - - // Test afterStyles and afterClearStyles - const stylesAgain = await getStyles(page, '.square-a'); - expect(stylesAgain.paddingBottom).toEqual('20px'); - expect(stylesAgain.color).toEqual('rgb(0, 0, 0)'); - - screenshotCompares.push(await page.compareScreenshot('end animation')); -}); - -test(`animation:css: hooks`, async () => { - const page = await newE2EPage({ url: '/src/utils/animation/test/hooks?ionic:_forceCSSAnimations=true' }); - const screenshotCompares = []; - - screenshotCompares.push(await page.compareScreenshot()); - - const square = await page.$('.square-a'); - - const styles = await getStyles(page, '.square-a'); - expect(styles.paddingBottom).toEqual('20px'); - expect(styles.color).toEqual('rgb(0, 0, 0)'); - - const classList = await getClassList(square); - expect(classList.includes('hello-world')).toEqual(true); - expect(classList.includes('test-class')).toEqual(false); - - await waitForEventToBeCalled('afterWrite', page, square, async () => { - await waitForEventToBeCalled('afterRead', page, square, async () => { - await waitForEventToBeCalled('ionAnimationFinished', page, square, async () => { - await waitForEventToBeCalled('beforeWrite', page, square, async () => { - await waitForEventToBeCalled('beforeRead', page, square, async () => { - await page.click('.play'); - await page.waitForSelector('.play'); - - // Test beforeRemoveClass and beforeAddClass - const cssClassListAgain = await getClassList(square); - expect(cssClassListAgain.includes('hello-world')).toEqual(false); - expect(cssClassListAgain.includes('test-class')).toEqual(true); - - // Test beforeStyles and beforeClearStyles - const cssStylesAgain = await getStyles(page, '.square-a'); - expect(cssStylesAgain.paddingBottom).toEqual('0px'); - expect(cssStylesAgain.color).toEqual('rgb(128, 0, 128)'); - }); - }); - }); - }); - }); - - // Test afterRemoveClass and afterAddClass - const classListAgain = await getClassList(square); - expect(classListAgain.includes('hello-world')).toEqual(true); - expect(classListAgain.includes('test-class')).toEqual(false); - - // Test afterStyles and afterClearStyles - const stylesAgain = await getStyles(page, '.square-a'); - expect(stylesAgain.paddingBottom).toEqual('20px'); - expect(stylesAgain.color).toEqual('rgb(0, 0, 0)'); - - screenshotCompares.push(await page.compareScreenshot('end animation')); -}); - -const waitForEventToBeCalled = async (eventName: string, page: any, el: HTMLElement, fn: any, num = 1) => { - const EVENT_FIRED = `on${eventName}`; - const eventFiredCount: any = { count: 0 }; - await page.exposeFunction(EVENT_FIRED, () => { - eventFiredCount.count += 1; - }); - - await listenForEvent(page, eventName, el, EVENT_FIRED); - - if (fn) { - await fn(); - } - - await waitForFunctionTestContext( - (payload: any) => { - return payload.eventFiredCount.count === payload.num; - }, - { eventFiredCount, num } - ); -}; - -const getStyles = async (page: any, selector: string) => { - return page.evaluate( - (payload: any) => { - const el = document.querySelector(payload.selector); - - return JSON.parse(JSON.stringify(getComputedStyle(el))); - }, - { selector } - ); -}; - -const getClassList = async (el: HTMLElement) => { - const classListObject = await el.getProperty('classList'); - const jsonValue = await classListObject.jsonValue(); - - return Object.values(jsonValue); -}; diff --git a/core/src/utils/animation/test/hooks/index.html b/core/src/utils/animation/test/hooks/index.html index ec3373fc2c..6d2eb4f887 100644 --- a/core/src/utils/animation/test/hooks/index.html +++ b/core/src/utils/animation/test/hooks/index.html @@ -34,19 +34,19 @@ .beforeClearStyles(['padding-bottom']) .beforeAddRead(() => { const ev = new CustomEvent('beforeRead'); - squareA.dispatchEvent(ev); + window.dispatchEvent(ev); }) .beforeAddWrite(() => { const ev = new CustomEvent('beforeWrite'); - squareA.dispatchEvent(ev); + window.dispatchEvent(ev); }) .afterAddRead(() => { const ev = new CustomEvent('afterRead'); - squareA.dispatchEvent(ev); + window.dispatchEvent(ev); }) .afterAddWrite(() => { const ev = new CustomEvent('afterWrite'); - squareA.dispatchEvent(ev); + window.dispatchEvent(ev); }) .afterAddClass(['hello-world']) .afterRemoveClass(['test-class']) @@ -60,7 +60,7 @@ ]) .onFinish(() => { const ev = new CustomEvent('ionAnimationFinished'); - squareA.dispatchEvent(ev); + window.dispatchEvent(ev); }); document.querySelector('.play').addEventListener('click', () => { diff --git a/core/src/utils/animation/test/multiple/animation.e2e.ts b/core/src/utils/animation/test/multiple/animation.e2e.ts new file mode 100644 index 0000000000..957d0ebc07 --- /dev/null +++ b/core/src/utils/animation/test/multiple/animation.e2e.ts @@ -0,0 +1,46 @@ +import { expect } from '@playwright/test'; +import { test } from '@utils/test/playwright'; +import type { E2EPage } from '@utils/test/playwright'; + +test.describe('animation: multiple', async () => { + test.beforeEach(({ skip }) => { + skip.rtl(); + skip.mode('ios'); + }); + + test(`should resolve grouped animations using web animations`, async ({ page }) => { + await page.goto('/src/utils/animation/test/multiple'); + await testMultiple(page); + }); + + test(`should resolve grouped animations using css animations`, async ({ page }) => { + await page.goto('/src/utils/animation/test/multiple?ionic:_forceCSSAnimations=true'); + await testMultiple(page); + }); +}); + +const testMultiple = async (page: E2EPage) => { + const ionAnimationFinished = await page.spyOnEvent('ionAnimationFinished'); + + await page.click('.play'); + + await ionAnimationFinished.next(); + await expect(ionAnimationFinished).toHaveReceivedEventDetail('AnimationCSubBFinished'); + + await ionAnimationFinished.next(); + await expect(ionAnimationFinished).toHaveReceivedEventDetail('AnimationBFinished'); + + await ionAnimationFinished.next(); + await expect(ionAnimationFinished).toHaveReceivedEventDetail('AnimationCSubAFinished'); + + await ionAnimationFinished.next(); + await expect(ionAnimationFinished).toHaveReceivedEventDetail('AnimationCFinished'); + + await ionAnimationFinished.next(); + await expect(ionAnimationFinished).toHaveReceivedEventDetail('AnimationAFinished'); + + await ionAnimationFinished.next(); + await expect(ionAnimationFinished).toHaveReceivedEventDetail('AnimationRootFinished'); + + await expect(ionAnimationFinished).toHaveReceivedEventTimes(6); +}; diff --git a/core/src/utils/animation/test/multiple/e2e.ts b/core/src/utils/animation/test/multiple/e2e.ts deleted file mode 100644 index 8cc905111f..0000000000 --- a/core/src/utils/animation/test/multiple/e2e.ts +++ /dev/null @@ -1,77 +0,0 @@ -import { newE2EPage } from '@stencil/core/testing'; - -import { listenForEvent, waitForFunctionTestContext } from '../../../test/utils'; - -test(`animation:web: multiple`, async () => { - const page = await newE2EPage({ url: '/src/utils/animation/test/multiple' }); - const screenshotCompares = []; - - screenshotCompares.push(await page.compareScreenshot()); - - const ANIMATION_FINISHED = 'onIonAnimationFinished'; - const animationStatus = []; - await page.exposeFunction(ANIMATION_FINISHED, (ev: any) => { - animationStatus.push(ev.detail); - }); - - const squareA = await page.$('.square-a'); - await listenForEvent(page, 'ionAnimationFinished', squareA, ANIMATION_FINISHED); - - await page.click('.play'); - await page.waitForSelector('.play'); - - await waitForFunctionTestContext( - (payload: any) => { - return ( - payload.animationStatus.join(', ') === - [ - 'AnimationCSubBFinished', - 'AnimationBFinished', - 'AnimationCSubAFinished', - 'AnimationCFinished', - 'AnimationAFinished', - 'AnimationRootFinished', - ].join(', ') - ); - }, - { animationStatus } - ); - screenshotCompares.push(await page.compareScreenshot('end animation')); -}); - -test(`animation:css: multiple`, async () => { - const page = await newE2EPage({ url: '/src/utils/animation/test/multiple?ionic:_forceCSSAnimations=true' }); - const screenshotCompares = []; - - screenshotCompares.push(await page.compareScreenshot()); - - const ANIMATION_FINISHED = 'onIonAnimationFinished'; - const animationStatus = []; - await page.exposeFunction(ANIMATION_FINISHED, (ev: any) => { - animationStatus.push(ev.detail); - }); - - const squareA = await page.$('.square-a'); - await listenForEvent(page, 'ionAnimationFinished', squareA, ANIMATION_FINISHED); - - await page.click('.play'); - await page.waitForSelector('.play'); - - await waitForFunctionTestContext( - (payload: any) => { - return ( - payload.animationStatus.join(', ') === - [ - 'AnimationCSubBFinished', - 'AnimationBFinished', - 'AnimationCSubAFinished', - 'AnimationCFinished', - 'AnimationAFinished', - 'AnimationRootFinished', - ].join(', ') - ); - }, - { animationStatus } - ); - screenshotCompares.push(await page.compareScreenshot('end animation')); -}); diff --git a/core/src/utils/animation/test/multiple/index.html b/core/src/utils/animation/test/multiple/index.html index 497a1dd16b..696e8c3f9a 100644 --- a/core/src/utils/animation/test/multiple/index.html +++ b/core/src/utils/animation/test/multiple/index.html @@ -56,7 +56,7 @@ }) .onFinish(() => { const ev = new CustomEvent('ionAnimationFinished', { detail: 'AnimationAFinished' }); - squareA.dispatchEvent(ev); + window.dispatchEvent(ev); }); animationB @@ -78,7 +78,7 @@ }) .onFinish(() => { const ev = new CustomEvent('ionAnimationFinished', { detail: 'AnimationBFinished' }); - squareA.dispatchEvent(ev); + window.dispatchEvent(ev); }); animationC @@ -100,7 +100,7 @@ }) .onFinish(() => { const ev = new CustomEvent('ionAnimationFinished', { detail: 'AnimationCFinished' }); - squareA.dispatchEvent(ev); + window.dispatchEvent(ev); }); animationCSubA @@ -110,12 +110,12 @@ .fromTo('color', 'red', 'blue') .onFinish(() => { const ev = new CustomEvent('ionAnimationFinished', { detail: 'AnimationCSubAFinished' }); - squareA.dispatchEvent(ev); + window.dispatchEvent(ev); }); animationCSubB.addElement(squareCSubText).onFinish(() => { const ev = new CustomEvent('ionAnimationFinished', { detail: 'AnimationCSubBFinished' }); - squareA.dispatchEvent(ev); + window.dispatchEvent(ev); }); animationC.addAnimation([animationCSubA, animationCSubB]); @@ -125,7 +125,7 @@ .fill('none') .onFinish(() => { const ev = new CustomEvent('ionAnimationFinished', { detail: 'AnimationRootFinished' }); - squareA.dispatchEvent(ev); + window.dispatchEvent(ev); }); document.querySelector('.play').addEventListener('click', () => { diff --git a/core/src/utils/gesture/test/e2e.ts b/core/src/utils/gesture/test/e2e.ts deleted file mode 100644 index 445c1ace37..0000000000 --- a/core/src/utils/gesture/test/e2e.ts +++ /dev/null @@ -1,36 +0,0 @@ -import { newE2EPage } from '@stencil/core/testing'; -import { dragElementBy } from '@utils/test'; - -test('swipe to go back should complete', async () => { - const page = await newE2EPage({ url: '/src/utils/gesture/test?ionic:mode=ios' }); - - const nav = await page.find('ion-nav'); - const ionNavDidChange = await nav.spyOnEvent('ionNavDidChange'); - - await page.click('.next'); - await ionNavDidChange.next(); - - const content = await page.$('.page-two-content'); - - const width = await page.evaluate(() => window.innerWidth); - await dragElementBy(content, page, width, 0, { x: 25, y: 100 }); - - await ionNavDidChange.next(); -}); - -test('swipe to go back should complete in rtl', async () => { - const page = await newE2EPage({ url: '/src/utils/gesture/test?rtl=true&ionic:mode=ios' }); - - const nav = await page.find('ion-nav'); - const ionNavDidChange = await nav.spyOnEvent('ionNavDidChange'); - - await page.click('.next'); - await ionNavDidChange.next(); - - const width = await page.evaluate(() => window.innerWidth); - - const content = await page.$('.page-two-content'); - await dragElementBy(content, page, -width, 0, { x: width - 25, y: 100 }); - - await ionNavDidChange.next(); -}); diff --git a/core/src/utils/test/framework-delegate/e2e.ts b/core/src/utils/test/framework-delegate/e2e.ts deleted file mode 100644 index e7fd72eb8a..0000000000 --- a/core/src/utils/test/framework-delegate/e2e.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { newE2EPage } from '@stencil/core/testing'; - -test('framework-delegate: should present modal already at ion-app root', async () => { - const page = await newE2EPage({ url: '/src/utils/test/framework-delegate?ionic:_testing=true' }); - - const button = await page.find('#button-inline-root'); - await button.click(); - - const modal = await page.find('#inline-root'); - expect(modal).not.toBe(null); - await modal.waitForVisible(); -}); - -test('framework-delegate: should present modal in content', async () => { - const page = await newE2EPage({ url: '/src/utils/test/framework-delegate?ionic:_testing=true' }); - - const button = await page.find('#button-inline-content'); - await button.click(); - - const modal = await page.find('#inline-content'); - expect(modal).not.toBe(null); - await modal.waitForVisible(); -}); - -test('framework-delegate: should present modal via controller', async () => { - const page = await newE2EPage({ url: '/src/utils/test/framework-delegate?ionic:_testing=true' }); - - const button = await page.find('#button-controller'); - await button.click(); - - const modal = await page.find('#controller'); - expect(modal).not.toBe(null); - await modal.waitForVisible(); -}); diff --git a/core/src/utils/test/framework-delegate/framework-delegate.e2e.ts b/core/src/utils/test/framework-delegate/framework-delegate.e2e.ts new file mode 100644 index 0000000000..435f7246d0 --- /dev/null +++ b/core/src/utils/test/framework-delegate/framework-delegate.e2e.ts @@ -0,0 +1,40 @@ +import { expect } from '@playwright/test'; +import { test } from '@utils/test/playwright'; + +test.describe('framework-delegate', () => { + test.beforeEach(async ({ page, skip }) => { + skip.rtl(); + skip.mode('ios'); + + await page.goto('/src/utils/test/framework-delegate'); + }); + test('should present modal already at ion-app root', async ({ page }) => { + const ionModalDidPresent = await page.spyOnEvent('ionModalDidPresent'); + + await page.click('#button-inline-root'); + + const modal = page.locator('#inline-root'); + await ionModalDidPresent.next(); + await expect(modal).toBeVisible(); + }); + + test('should present modal in content', async ({ page }) => { + const ionModalDidPresent = await page.spyOnEvent('ionModalDidPresent'); + + await page.click('#button-inline-content'); + + const modal = page.locator('#inline-content'); + await ionModalDidPresent.next(); + await expect(modal).toBeVisible(); + }); + + test('should present modal via controller', async ({ page }) => { + const ionModalDidPresent = await page.spyOnEvent('ionModalDidPresent'); + + await page.click('#button-controller'); + + const modal = page.locator('#controller'); + await ionModalDidPresent.next(); + await expect(modal).toBeVisible(); + }); +}); diff --git a/core/src/utils/test/framework-delegate/index.html b/core/src/utils/test/framework-delegate/index.html index 4105bd46e9..d893bd1968 100644 --- a/core/src/utils/test/framework-delegate/index.html +++ b/core/src/utils/test/framework-delegate/index.html @@ -9,6 +9,7 @@ /> + - - - - - - - - - -
- - - Components: Modes - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

- -

-

- -

-

- -

-
-
-
-
- - - - diff --git a/core/src/utils/test/overlays/e2e.ts b/core/src/utils/test/overlays/e2e.ts deleted file mode 100644 index 20d62d9b17..0000000000 --- a/core/src/utils/test/overlays/e2e.ts +++ /dev/null @@ -1,178 +0,0 @@ -import { newE2EPage } from '@stencil/core/testing'; - -import { getActiveElementParent } from '../utils'; - -test('overlays: hardware back button: should dismiss a presented overlay', async () => { - const page = await newE2EPage({ url: '/src/utils/test/overlays?ionic:_testing=true' }); - - const createAndPresentButton = await page.find('#create-and-present'); - - const ionModalDidPresent = await page.spyOnEvent('ionModalDidPresent'); - const ionModalDidDismiss = await page.spyOnEvent('ionModalDidDismiss'); - - await createAndPresentButton.click(); - const modal = await page.find('ion-modal'); - expect(modal).not.toBe(null); - - await ionModalDidPresent.next(); - - const simulateButton = await modal.find('#modal-simulate'); - expect(simulateButton).not.toBe(null); - - await simulateButton.click(); - - await ionModalDidDismiss.next(); - - await page.waitForSelector('ion-modal', { hidden: true }); -}); - -test('overlays: hardware back button: should dismiss the presented overlay, even though another hidden modal was added last', async () => { - const page = await newE2EPage({ url: '/src/utils/test/overlays?ionic:_testing=true' }); - - const createAndPresentButton = await page.find('#create-and-present'); - - const ionModalDidPresent = await page.spyOnEvent('ionModalDidPresent'); - - await createAndPresentButton.click(); - const modal = await page.find('ion-modal'); - expect(modal).not.toBe(null); - - await ionModalDidPresent.next(); - - const createButton = await page.find('#modal-create'); - await createButton.click(); - - const modals = await page.$$('ion-modal'); - expect(modals.length).toEqual(2); - - expect(await modals[0].evaluate((node) => node.classList.contains('overlay-hidden'))).toEqual(false); - expect(await modals[1].evaluate((node) => node.classList.contains('overlay-hidden'))).toEqual(true); - - const simulateButton = await modal.find('#modal-simulate'); - expect(simulateButton).not.toBe(null); - - await simulateButton.click(); - - expect(await modals[0].evaluate((node) => node.classList.contains('overlay-hidden'))).toEqual(true); - expect(await modals[1].evaluate((node) => node.classList.contains('overlay-hidden'))).toEqual(true); -}); - -test('overlays: Esc: should dismiss a presented overlay', async () => { - const page = await newE2EPage({ url: '/src/utils/test/overlays?ionic:_testing=true' }); - - const createAndPresentButton = await page.find('#create-and-present'); - - const ionModalDidPresent = await page.spyOnEvent('ionModalDidPresent'); - const ionModalDidDismiss = await page.spyOnEvent('ionModalDidDismiss'); - - await createAndPresentButton.click(); - const modal = await page.find('ion-modal'); - expect(modal).not.toBe(null); - - await ionModalDidPresent.next(); - - await page.keyboard.press('Escape'); - - await ionModalDidDismiss.next(); - - await page.waitForSelector('ion-modal', { hidden: true }); -}); - -test('overlays: Esc: should dismiss the presented overlay, even though another hidden modal was added last', async () => { - const page = await newE2EPage({ url: '/src/utils/test/overlays?ionic:_testing=true' }); - - const createAndPresentButton = await page.find('#create-and-present'); - - const ionModalDidPresent = await page.spyOnEvent('ionModalDidPresent'); - - await createAndPresentButton.click(); - const modal = await page.find('ion-modal'); - expect(modal).not.toBe(null); - - await ionModalDidPresent.next(); - - const createButton = await page.find('#modal-create'); - await createButton.click(); - - const modals = await page.$$('ion-modal'); - expect(modals.length).toEqual(2); - - await page.keyboard.press('Escape'); - - await page.waitForSelector('ion-modal#ion-overlay-1', { hidden: true }); -}); - -test('overlays: Nested: should dismiss the top overlay', async () => { - const page = await newE2EPage({ url: '/src/utils/test/overlays?ionic:_testing=true' }); - - const createNestedButton = await page.find('#create-nested'); - const ionModalDidPresent = await page.spyOnEvent('ionModalDidPresent'); - - await createNestedButton.click(); - - await ionModalDidPresent.next(); - - const modal = await page.find('ion-modal'); - expect(modal).not.toBe(null); - - const dismissNestedOverlayButton = await page.find('#dismiss-modal-nested-overlay'); - const ionModalDidDismiss = await page.spyOnEvent('ionModalDidDismiss'); - - await dismissNestedOverlayButton.click(); - - await ionModalDidDismiss.next(); - - const modals = await page.$$('ion-modal'); - expect(modals.length).toEqual(0); -}); - -test('toast should not cause focus trapping', async () => { - const page = await newE2EPage({ url: '/src/utils/test/overlays?ionic:_testing=true' }); - const ionToastDidPresent = await page.spyOnEvent('ionToastDidPresent'); - - await page.click('#create-and-present-toast'); - await ionToastDidPresent.next(); - - await page.click('#root-input'); - - const parentEl = await getActiveElementParent(page); - expect(parentEl.id).toEqual('root-input'); -}); - -test('toast should not cause focus trapping even when opened from a focus trapping overlay', async () => { - const page = await newE2EPage({ url: '/src/utils/test/overlays?ionic:_testing=true' }); - const ionToastDidPresent = await page.spyOnEvent('ionToastDidPresent'); - const ionModalDidPresent = await page.spyOnEvent('ionModalDidPresent'); - - await page.click('#create-and-present'); - await ionModalDidPresent.next(); - - await page.click('#modal-toast'); - await ionToastDidPresent.next(); - - await page.click('.modal-input'); - - const parentEl = await getActiveElementParent(page); - expect(parentEl.className).toContain('modal-input-0'); -}); - -test('focus trapping should only run on the top-most overlay', async () => { - const page = await newE2EPage({ url: '/src/utils/test/overlays?ionic:_testing=true' }); - const ionModalDidPresent = await page.spyOnEvent('ionModalDidPresent'); - - await page.click('#create-and-present'); - await ionModalDidPresent.next(); - - await page.click('.modal-0 .modal-input'); - - const parentEl = await getActiveElementParent(page); - expect(parentEl.className).toContain('modal-input-0'); - - await page.click('#modal-create-and-present'); - await ionModalDidPresent.next(); - - await page.click('.modal-1 .modal-input'); - - const parentElAgain = await getActiveElementParent(page); - expect(parentElAgain.className).toContain('modal-input-1'); -}); diff --git a/core/src/utils/test/overlays/index.html b/core/src/utils/test/overlays/index.html index 16b0d87642..00885bd555 100644 --- a/core/src/utils/test/overlays/index.html +++ b/core/src/utils/test/overlays/index.html @@ -9,6 +9,7 @@ /> +