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
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-