mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-08-21 21:15:24 +08:00
test(playwright): add new utilities for skipping tests (#25758)
This commit is contained in:
@ -33,12 +33,14 @@ const projects = [
|
|||||||
{
|
{
|
||||||
name: 'Mobile Chrome',
|
name: 'Mobile Chrome',
|
||||||
use: {
|
use: {
|
||||||
|
browserName: 'chromium',
|
||||||
...devices['Pixel 5']
|
...devices['Pixel 5']
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'Mobile Safari',
|
name: 'Mobile Safari',
|
||||||
use: {
|
use: {
|
||||||
|
browserName: 'webkit',
|
||||||
...devices['iPhone 12']
|
...devices['iPhone 12']
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,9 +2,9 @@ import { expect } from '@playwright/test';
|
|||||||
import { test } from '@utils/test/playwright';
|
import { test } from '@utils/test/playwright';
|
||||||
|
|
||||||
test.describe('accordion: a11y', () => {
|
test.describe('accordion: a11y', () => {
|
||||||
test('accordions should be keyboard navigable', async ({ page, browserName }) => {
|
test('accordions should be keyboard navigable', async ({ page, skip, browserName }) => {
|
||||||
// TODO(FW-1764): remove skip once issue is resolved
|
// TODO(FW-1764): remove skip once issue is resolved
|
||||||
test.skip(browserName === 'firefox', 'https://github.com/ionic-team/ionic-framework/issues/25529');
|
skip.browser('firefox', 'https://github.com/ionic-team/ionic-framework/issues/25529');
|
||||||
|
|
||||||
await page.goto(`/src/components/accordion/test/a11y`);
|
await page.goto(`/src/components/accordion/test/a11y`);
|
||||||
const tabKey = browserName === 'webkit' ? 'Alt+Tab' : 'Tab';
|
const tabKey = browserName === 'webkit' ? 'Alt+Tab' : 'Tab';
|
||||||
|
@ -10,8 +10,8 @@ test.describe('action sheet: basic', () => {
|
|||||||
actionSheetFixture = new ActionSheetFixture(page);
|
actionSheetFixture = new ActionSheetFixture(page);
|
||||||
});
|
});
|
||||||
test.describe('action sheet: data', () => {
|
test.describe('action sheet: data', () => {
|
||||||
test('should return data', async ({ page }, testInfo) => {
|
test('should return data', async ({ page, skip }) => {
|
||||||
test.skip(testInfo.project.metadata.rtl === true, 'This does not test LTR vs. RTL layout.');
|
skip.rtl();
|
||||||
const ionActionSheetDidDismiss = await page.spyOnEvent('ionActionSheetDidDismiss');
|
const ionActionSheetDidDismiss = await page.spyOnEvent('ionActionSheetDidDismiss');
|
||||||
|
|
||||||
await actionSheetFixture.open('#buttonData');
|
await actionSheetFixture.open('#buttonData');
|
||||||
@ -22,8 +22,8 @@ test.describe('action sheet: basic', () => {
|
|||||||
await ionActionSheetDidDismiss.next();
|
await ionActionSheetDidDismiss.next();
|
||||||
expect(ionActionSheetDidDismiss).toHaveReceivedEventDetail({ data: { type: '1' }, role: undefined });
|
expect(ionActionSheetDidDismiss).toHaveReceivedEventDetail({ data: { type: '1' }, role: undefined });
|
||||||
});
|
});
|
||||||
test('should return cancel button data', async ({ page }, testInfo) => {
|
test('should return cancel button data', async ({ page, skip }) => {
|
||||||
test.skip(testInfo.project.metadata.rtl === true, 'This does not test LTR vs. RTL layout.');
|
skip.rtl();
|
||||||
const ionActionSheetDidDismiss = await page.spyOnEvent('ionActionSheetDidDismiss');
|
const ionActionSheetDidDismiss = await page.spyOnEvent('ionActionSheetDidDismiss');
|
||||||
|
|
||||||
await actionSheetFixture.open('#buttonData');
|
await actionSheetFixture.open('#buttonData');
|
||||||
@ -36,8 +36,8 @@ test.describe('action sheet: basic', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
test.describe('action sheet: attributes', () => {
|
test.describe('action sheet: attributes', () => {
|
||||||
test('should set htmlAttributes', async ({ page }, testInfo) => {
|
test('should set htmlAttributes', async ({ page, skip }) => {
|
||||||
test.skip(testInfo.project.metadata.rtl === true, 'This does not test LTR vs. RTL layout.');
|
skip.rtl();
|
||||||
await actionSheetFixture.open('#basic');
|
await actionSheetFixture.open('#basic');
|
||||||
|
|
||||||
const actionSheet = page.locator('ion-action-sheet');
|
const actionSheet = page.locator('ion-action-sheet');
|
||||||
@ -73,15 +73,15 @@ test.describe('action sheet: basic', () => {
|
|||||||
await actionSheetFixture.open('#scrollWithoutCancel');
|
await actionSheetFixture.open('#scrollWithoutCancel');
|
||||||
await actionSheetFixture.screenshot('scroll-without-cancel');
|
await actionSheetFixture.screenshot('scroll-without-cancel');
|
||||||
});
|
});
|
||||||
test('should open custom backdrop action sheet', async ({ page }, testInfo) => {
|
test('should open custom backdrop action sheet', async ({ page, skip }) => {
|
||||||
test.skip(testInfo.project.metadata.rtl === true, 'This does not test LTR vs. RTL layout.');
|
skip.rtl();
|
||||||
await actionSheetFixture.open('#customBackdrop');
|
await actionSheetFixture.open('#customBackdrop');
|
||||||
|
|
||||||
const backdrop = page.locator('ion-action-sheet ion-backdrop');
|
const backdrop = page.locator('ion-action-sheet ion-backdrop');
|
||||||
expect(backdrop).toHaveCSS('opacity', '1');
|
expect(backdrop).toHaveCSS('opacity', '1');
|
||||||
});
|
});
|
||||||
test('should open alert from action sheet', async ({ page }, testInfo) => {
|
test('should open alert from action sheet', async ({ page, skip }) => {
|
||||||
test.skip(testInfo.project.metadata.rtl === true, 'This does not test LTR vs. RTL layout.');
|
skip.rtl();
|
||||||
const ionAlertDidPresent = await page.spyOnEvent('ionAlertDidPresent');
|
const ionAlertDidPresent = await page.spyOnEvent('ionAlertDidPresent');
|
||||||
await actionSheetFixture.open('#alertFromActionSheet');
|
await actionSheetFixture.open('#alertFromActionSheet');
|
||||||
|
|
||||||
@ -89,8 +89,8 @@ test.describe('action sheet: basic', () => {
|
|||||||
|
|
||||||
await ionAlertDidPresent.next();
|
await ionAlertDidPresent.next();
|
||||||
});
|
});
|
||||||
test('should not dismiss action sheet when backdropDismiss: false', async ({ page }, testInfo) => {
|
test('should not dismiss action sheet when backdropDismiss: false', async ({ page, skip }) => {
|
||||||
test.skip(testInfo.project.metadata.rtl === true, 'This does not test LTR vs. RTL layout.');
|
skip.rtl();
|
||||||
await actionSheetFixture.open('#noBackdropDismiss');
|
await actionSheetFixture.open('#noBackdropDismiss');
|
||||||
|
|
||||||
const actionSheet = page.locator('ion-action-sheet');
|
const actionSheet = page.locator('ion-action-sheet');
|
||||||
@ -100,8 +100,8 @@ test.describe('action sheet: basic', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
test.describe('action sheet: focus trap', () => {
|
test.describe('action sheet: focus trap', () => {
|
||||||
test('it should trap focus in action sheet', async ({ page, browserName }, testInfo) => {
|
test('it should trap focus in action sheet', async ({ page, skip, browserName }) => {
|
||||||
test.skip(testInfo.project.metadata.rtl === true, 'This does not test LTR vs. RTL layout.');
|
skip.rtl();
|
||||||
const tabKey = browserName === 'webkit' ? 'Alt+Tab' : 'Tab';
|
const tabKey = browserName === 'webkit' ? 'Alt+Tab' : 'Tab';
|
||||||
|
|
||||||
await actionSheetFixture.open('#basic');
|
await actionSheetFixture.open('#basic');
|
||||||
|
@ -2,12 +2,9 @@ import { expect } from '@playwright/test';
|
|||||||
import { test } from '@utils/test/playwright';
|
import { test } from '@utils/test/playwright';
|
||||||
|
|
||||||
test.describe('action sheet: translucent', () => {
|
test.describe('action sheet: translucent', () => {
|
||||||
test('should not have visual regressions', async ({ page }, testInfo) => {
|
test('should not have visual regressions', async ({ page, skip }) => {
|
||||||
test.skip(testInfo.project.metadata.mode === 'md', 'Translucent effect is only active on iOS mode');
|
skip.mode('md', 'Translucent effect is only active on iOS mode');
|
||||||
test.skip(
|
skip.rtl('This tests how the component is painted, not layout. RTL tests are not needed here');
|
||||||
testInfo.project.metadata.rtl === true,
|
|
||||||
'This tests how the component is painted, not layout. RTL tests are not needed here'
|
|
||||||
);
|
|
||||||
|
|
||||||
await page.goto(`/src/components/action-sheet/test/translucent`);
|
await page.goto(`/src/components/action-sheet/test/translucent`);
|
||||||
|
|
||||||
|
@ -14,11 +14,8 @@ test.describe('app: safe-area', () => {
|
|||||||
|
|
||||||
expect(await page.screenshot()).toMatchSnapshot(`app-${screenshotModifier}-diff-${page.getSnapshotSettings()}.png`);
|
expect(await page.screenshot()).toMatchSnapshot(`app-${screenshotModifier}-diff-${page.getSnapshotSettings()}.png`);
|
||||||
};
|
};
|
||||||
test.beforeEach(async ({ page }, testInfo) => {
|
test.beforeEach(async ({ page, skip }) => {
|
||||||
test.skip(
|
skip.rtl('Safe area tests only check top and bottom edges. RTL checks are not required here.');
|
||||||
testInfo.project.metadata.rtl === true,
|
|
||||||
'Safe area tests only check top and bottom edges. RTL checks are not required here.'
|
|
||||||
);
|
|
||||||
|
|
||||||
await page.goto(`/src/components/app/test/safe-area`);
|
await page.goto(`/src/components/app/test/safe-area`);
|
||||||
});
|
});
|
||||||
|
@ -12,8 +12,8 @@ test.describe('button: basic', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test.describe('button: ripple effect', () => {
|
test.describe('button: ripple effect', () => {
|
||||||
test('should not have visual regressions', async ({ page }, testInfo) => {
|
test('should not have visual regressions', async ({ page, skip }) => {
|
||||||
test.skip(testInfo.project.metadata.mode !== 'md', 'Ripple effect is only available in MD mode.');
|
skip.mode('ios', 'Ripple effect is only available in MD mode.');
|
||||||
|
|
||||||
await page.goto(`/src/components/button/test/basic?ionic:_testing=false`);
|
await page.goto(`/src/components/button/test/basic?ionic:_testing=false`);
|
||||||
|
|
||||||
|
@ -2,9 +2,9 @@ import { expect } from '@playwright/test';
|
|||||||
import { test } from '@utils/test/playwright';
|
import { test } from '@utils/test/playwright';
|
||||||
|
|
||||||
test.describe('datetime-button: switching to correct view', () => {
|
test.describe('datetime-button: switching to correct view', () => {
|
||||||
test.beforeEach(async ({ page }, testInfo) => {
|
test.beforeEach(async ({ page, skip }) => {
|
||||||
test.skip(testInfo.project.metadata.rtl === 'rtl', 'No layout tests');
|
skip.rtl();
|
||||||
test.skip(testInfo.project.metadata.mode === 'ios', 'No mode-specific logic');
|
skip.mode('ios', 'No mode-specific logic');
|
||||||
|
|
||||||
await page.setContent(`
|
await page.setContent(`
|
||||||
<ion-datetime-button datetime="datetime"></ion-datetime-button>
|
<ion-datetime-button datetime="datetime"></ion-datetime-button>
|
||||||
@ -31,10 +31,9 @@ test.describe('datetime-button: switching to correct view', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test.describe('datetime-button: labels', () => {
|
test.describe('datetime-button: labels', () => {
|
||||||
// eslint-disable-next-line no-empty-pattern
|
test.beforeEach(({ skip }) => {
|
||||||
test.beforeEach(({}, testInfo) => {
|
skip.rtl();
|
||||||
test.skip(testInfo.project.metadata.rtl === 'rtl', 'No layout tests');
|
skip.mode('ios', 'No mode-specific logic');
|
||||||
test.skip(testInfo.project.metadata.mode === 'ios', 'No mode-specific logic');
|
|
||||||
});
|
});
|
||||||
test('should set date and time labels in separate buttons', async ({ page }) => {
|
test('should set date and time labels in separate buttons', async ({ page }) => {
|
||||||
await page.setContent(`
|
await page.setContent(`
|
||||||
@ -106,10 +105,9 @@ test.describe('datetime-button: labels', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test.describe('datetime-button: locale', () => {
|
test.describe('datetime-button: locale', () => {
|
||||||
// eslint-disable-next-line no-empty-pattern
|
test.beforeEach(({ skip }) => {
|
||||||
test.beforeEach(({}, testInfo) => {
|
skip.rtl();
|
||||||
test.skip(testInfo.project.metadata.rtl === 'rtl', 'No layout tests');
|
skip.mode('ios', 'No mode-specific logic');
|
||||||
test.skip(testInfo.project.metadata.mode === 'ios', 'No mode-specific logic');
|
|
||||||
});
|
});
|
||||||
test('should use the same locale as datetime', async ({ page }) => {
|
test('should use the same locale as datetime', async ({ page }) => {
|
||||||
await page.setContent(`
|
await page.setContent(`
|
||||||
@ -154,10 +152,9 @@ test.describe('datetime-button: locale', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test.describe('datetime-button: wheel', () => {
|
test.describe('datetime-button: wheel', () => {
|
||||||
// eslint-disable-next-line no-empty-pattern
|
test.beforeEach(({ skip }) => {
|
||||||
test.beforeEach(({}, testInfo) => {
|
skip.rtl();
|
||||||
test.skip(testInfo.project.metadata.rtl === 'rtl', 'No layout tests');
|
skip.mode('ios', 'No mode-specific logic');
|
||||||
test.skip(testInfo.project.metadata.mode === 'ios', 'No mode-specific logic');
|
|
||||||
});
|
});
|
||||||
test('should only show a single date button when presentation="date-time" and prefer-wheel="true"', async ({
|
test('should only show a single date button when presentation="date-time" and prefer-wheel="true"', async ({
|
||||||
page,
|
page,
|
||||||
|
@ -2,9 +2,9 @@ import { expect } from '@playwright/test';
|
|||||||
import { test } from '@utils/test/playwright';
|
import { test } from '@utils/test/playwright';
|
||||||
|
|
||||||
test.describe('datetime-button: disabled buttons', () => {
|
test.describe('datetime-button: disabled buttons', () => {
|
||||||
test('buttons should not be enabled when component is disabled', async ({ page }, testInfo) => {
|
test('buttons should not be enabled when component is disabled', async ({ page, skip }) => {
|
||||||
test.skip(testInfo.project.metadata.rtl === 'rtl', 'No layout tests');
|
skip.rtl();
|
||||||
test.skip(testInfo.project.metadata.mode === 'ios', 'No mode-specific logic');
|
skip.mode('ios', 'No mode-specific logic');
|
||||||
|
|
||||||
await page.setContent(`
|
await page.setContent(`
|
||||||
<ion-datetime-button datetime="datetime" disabled="true"></ion-datetime-button>
|
<ion-datetime-button datetime="datetime" disabled="true"></ion-datetime-button>
|
||||||
|
@ -42,9 +42,9 @@ test.describe('datetime-button: popover', () => {
|
|||||||
let popover: Locator;
|
let popover: Locator;
|
||||||
let ionPopoverDidPresent: EventSpy;
|
let ionPopoverDidPresent: EventSpy;
|
||||||
let ionPopoverDidDismiss: EventSpy;
|
let ionPopoverDidDismiss: EventSpy;
|
||||||
test.beforeEach(async ({ page }, testInfo) => {
|
test.beforeEach(async ({ page, skip }) => {
|
||||||
test.skip(testInfo.project.metadata.rtl === 'rtl', 'No layout tests');
|
skip.rtl();
|
||||||
test.skip(testInfo.project.metadata.mode === 'ios', 'No mode-specific logic');
|
skip.mode('ios', 'No mode-specific logic');
|
||||||
|
|
||||||
await page.setContent(`
|
await page.setContent(`
|
||||||
<ion-datetime-button datetime="datetime"></ion-datetime-button>
|
<ion-datetime-button datetime="datetime"></ion-datetime-button>
|
||||||
@ -104,9 +104,9 @@ test.describe('datetime-button: modal', () => {
|
|||||||
let modal: Locator;
|
let modal: Locator;
|
||||||
let ionModalDidPresent: EventSpy;
|
let ionModalDidPresent: EventSpy;
|
||||||
let ionModalDidDismiss: EventSpy;
|
let ionModalDidDismiss: EventSpy;
|
||||||
test.beforeEach(async ({ page }, testInfo) => {
|
test.beforeEach(async ({ page, skip }) => {
|
||||||
test.skip(testInfo.project.metadata.rtl === 'rtl', 'No layout tests');
|
skip.rtl();
|
||||||
test.skip(testInfo.project.metadata.mode === 'ios', 'No mode-specific logic');
|
skip.mode('ios', 'No mode-specific logic');
|
||||||
|
|
||||||
await page.setContent(`
|
await page.setContent(`
|
||||||
<ion-datetime-button datetime="datetime"></ion-datetime-button>
|
<ion-datetime-button datetime="datetime"></ion-datetime-button>
|
||||||
|
@ -185,10 +185,9 @@ test.describe('datetime: footer', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test.describe('datetime: swiping', () => {
|
test.describe('datetime: swiping', () => {
|
||||||
// eslint-disable-next-line no-empty-pattern
|
test.beforeEach(({ skip }) => {
|
||||||
test.beforeEach(({}, testInfo) => {
|
skip.rtl();
|
||||||
test.skip(testInfo.project.metadata.rtl === true, 'This does not test LTR vs RTL layouts.');
|
skip.mode('ios', 'This does not have mode-specific logic.');
|
||||||
test.skip(testInfo.project.metadata.mode === 'ios', 'This does not have mode-specific logic.');
|
|
||||||
});
|
});
|
||||||
test('should move to prev month by swiping', async ({ page }) => {
|
test('should move to prev month by swiping', async ({ page }) => {
|
||||||
await page.setContent(`
|
await page.setContent(`
|
||||||
@ -224,8 +223,8 @@ test.describe('datetime: swiping', () => {
|
|||||||
|
|
||||||
await expect(calendarHeader).toHaveText(/June 2022/);
|
await expect(calendarHeader).toHaveText(/June 2022/);
|
||||||
});
|
});
|
||||||
test('should not re-render if swipe is in progress', async ({ page, browserName }) => {
|
test('should not re-render if swipe is in progress', async ({ page, skip }) => {
|
||||||
test.skip(browserName === 'webkit', 'Wheel is not available in WebKit');
|
skip.browser('webkit', 'Wheel is not available in WebKit');
|
||||||
|
|
||||||
await page.setContent(`
|
await page.setContent(`
|
||||||
<ion-datetime value="2022-05-03"></ion-datetime>
|
<ion-datetime value="2022-05-03"></ion-datetime>
|
||||||
|
@ -13,13 +13,8 @@ const queryAllWorkingMonthDisabledDays = (page: E2EPage, datetimeSelector = 'ion
|
|||||||
};
|
};
|
||||||
|
|
||||||
test.describe('datetime: disable dates', () => {
|
test.describe('datetime: disable dates', () => {
|
||||||
/**
|
test.beforeEach(({ skip }) => {
|
||||||
* We need to access testInfo, but Playwright
|
skip.rtl();
|
||||||
* requires that we destructure the first parameter.
|
|
||||||
*/
|
|
||||||
// eslint-disable-next-line no-empty-pattern
|
|
||||||
test.beforeEach(({}, testInfo) => {
|
|
||||||
test.skip(testInfo.project.metadata.rtl === true, 'These tests do not check layout rendering functionality.');
|
|
||||||
});
|
});
|
||||||
test.describe('check return values', () => {
|
test.describe('check return values', () => {
|
||||||
test.beforeEach(async ({ page }) => {
|
test.beforeEach(async ({ page }) => {
|
||||||
|
@ -32,9 +32,8 @@ test.describe('datetime: multiple date selection (visual regressions)', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test.describe('datetime: multiple date selection (functionality)', () => {
|
test.describe('datetime: multiple date selection (functionality)', () => {
|
||||||
// eslint-disable-next-line no-empty-pattern
|
test.beforeEach(async ({ skip }) => {
|
||||||
test.beforeEach(async ({}, testInfo) => {
|
skip.rtl();
|
||||||
test.skip(testInfo.project.metadata.rtl === true, 'Does not test LTR vs. RTL layout.');
|
|
||||||
});
|
});
|
||||||
|
|
||||||
test('clicking unselected days should select them', async ({ page }) => {
|
test('clicking unselected days should select them', async ({ page }) => {
|
||||||
|
@ -84,8 +84,8 @@ test.describe('datetime: presentation', () => {
|
|||||||
expect(ionChangeSpy.length).toBe(1);
|
expect(ionChangeSpy.length).toBe(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('switching presentation should close month/year picker', async ({ page }, testInfo) => {
|
test('switching presentation should close month/year picker', async ({ page, skip }) => {
|
||||||
await test.skip(testInfo.project.metadata.rtl === true, 'This feature does not have RTL specific behaviors.');
|
await skip.rtl();
|
||||||
|
|
||||||
await page.setContent(`
|
await page.setContent(`
|
||||||
<ion-datetime presentation="date"></ion-datetime>
|
<ion-datetime presentation="date"></ion-datetime>
|
||||||
|
@ -2,9 +2,9 @@ import { expect } from '@playwright/test';
|
|||||||
import { test } from '@utils/test/playwright';
|
import { test } from '@utils/test/playwright';
|
||||||
|
|
||||||
test.describe('header: condense', () => {
|
test.describe('header: condense', () => {
|
||||||
test('should be hidden from screen readers when collapsed', async ({ page }, testInfo) => {
|
test('should be hidden from screen readers when collapsed', async ({ page, skip }) => {
|
||||||
test.skip(testInfo.project.metadata.mode === 'md', 'Logic only applies to iOS mode');
|
skip.mode('md');
|
||||||
test.skip(testInfo.project.metadata.rtl === true, 'No RTL-specific logic');
|
skip.rtl();
|
||||||
|
|
||||||
await page.goto('/src/components/header/test/condense');
|
await page.goto('/src/components/header/test/condense');
|
||||||
const header = page.locator('#collapsibleHeader');
|
const header = page.locator('#collapsibleHeader');
|
||||||
|
@ -2,10 +2,8 @@ import { expect } from '@playwright/test';
|
|||||||
import { test } from '@utils/test/playwright';
|
import { test } from '@utils/test/playwright';
|
||||||
|
|
||||||
test.describe('input: a11y', () => {
|
test.describe('input: a11y', () => {
|
||||||
test('does not set a default aria-labelledby when there is not a neighboring ion-label', async ({
|
test('does not set a default aria-labelledby when there is not a neighboring ion-label', async ({ page, skip }) => {
|
||||||
page,
|
skip.rtl();
|
||||||
}, testInfo) => {
|
|
||||||
test.skip(testInfo.project.metadata.rtl === true, 'Does not test LTR vs. RTL layout.');
|
|
||||||
|
|
||||||
await page.setContent('<ion-input></ion-input>');
|
await page.setContent('<ion-input></ion-input>');
|
||||||
|
|
||||||
@ -15,8 +13,8 @@ test.describe('input: a11y', () => {
|
|||||||
await expect(ariaLabelledBy).toBe(null);
|
await expect(ariaLabelledBy).toBe(null);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('set a default aria-labelledby when a neighboring ion-label exists', async ({ page }, testInfo) => {
|
test('set a default aria-labelledby when a neighboring ion-label exists', async ({ page, skip }) => {
|
||||||
test.skip(testInfo.project.metadata.rtl === true, 'Does not test LTR vs. RTL layout.');
|
skip.rtl();
|
||||||
|
|
||||||
await page.setContent(
|
await page.setContent(
|
||||||
`
|
`
|
||||||
|
@ -6,8 +6,8 @@ test.describe('input: masking', () => {
|
|||||||
await page.goto('/src/components/input/test/masking');
|
await page.goto('/src/components/input/test/masking');
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should filter out spaces', async ({ page }, testInfo) => {
|
test('should filter out spaces', async ({ page, skip }) => {
|
||||||
test.skip(testInfo.project.metadata.rtl === true, 'Does not test LTR vs. RTL layout.');
|
skip.rtl();
|
||||||
|
|
||||||
const input = page.locator('#inputTrimmed');
|
const input = page.locator('#inputTrimmed');
|
||||||
|
|
||||||
|
@ -2,9 +2,9 @@ import { expect } from '@playwright/test';
|
|||||||
import { test } from '@utils/test/playwright';
|
import { test } from '@utils/test/playwright';
|
||||||
|
|
||||||
test.describe('item-sliding: basic', () => {
|
test.describe('item-sliding: basic', () => {
|
||||||
test('should not scroll when the item-sliding is swiped', async ({ page, browserName }, testInfo) => {
|
test('should not scroll when the item-sliding is swiped', async ({ page, skip }) => {
|
||||||
test.skip(browserName === 'webkit', 'mouse.wheel is not available in WebKit');
|
skip.browser('webkit', 'mouse.wheel is not available in WebKit');
|
||||||
test.skip(testInfo.project.metadata.rtl === true, 'This feature does not have RTL-specific behaviors');
|
skip.rtl();
|
||||||
|
|
||||||
await page.goto(`/src/components/item-sliding/test/basic`);
|
await page.goto(`/src/components/item-sliding/test/basic`);
|
||||||
|
|
||||||
|
@ -2,12 +2,9 @@ import { expect } from '@playwright/test';
|
|||||||
import { test } from '@utils/test/playwright';
|
import { test } from '@utils/test/playwright';
|
||||||
|
|
||||||
test.describe('item-sliding: scroll-target', () => {
|
test.describe('item-sliding: scroll-target', () => {
|
||||||
test('should not scroll when the item-sliding is swiped in custom scroll target', async ({
|
test('should not scroll when the item-sliding is swiped in custom scroll target', async ({ page, skip }) => {
|
||||||
page,
|
skip.browser('webkit', 'mouse.wheel is not available in WebKit');
|
||||||
browserName,
|
skip.rtl();
|
||||||
}, testInfo) => {
|
|
||||||
test.skip(browserName === 'webkit', 'mouse.wheel is not available in WebKit');
|
|
||||||
test.skip(testInfo.project.metadata.rtl === true, 'This feature does not have RTL-specific behaviors');
|
|
||||||
|
|
||||||
await page.goto(`/src/components/item-sliding/test/scroll-target`);
|
await page.goto(`/src/components/item-sliding/test/scroll-target`);
|
||||||
|
|
||||||
|
@ -41,9 +41,8 @@ test.describe('item: inputs', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test.describe('form data', () => {
|
test.describe('form data', () => {
|
||||||
// eslint-disable-next-line no-empty-pattern
|
test.beforeEach(async ({ skip }) => {
|
||||||
test.beforeEach(async ({}, testInfo) => {
|
skip.rtl();
|
||||||
test.skip(testInfo.project.metadata.rtl === true, 'Does not test LTR vs. RTL layout.');
|
|
||||||
});
|
});
|
||||||
|
|
||||||
test('initial form data should be empty', async ({ page }) => {
|
test('initial form data should be empty', async ({ page }) => {
|
||||||
|
@ -3,9 +3,9 @@ import { test, Viewports } from '@utils/test/playwright';
|
|||||||
import type { E2EPage } from '@utils/test/playwright';
|
import type { E2EPage } from '@utils/test/playwright';
|
||||||
|
|
||||||
test.describe('modal: focus trapping', () => {
|
test.describe('modal: focus trapping', () => {
|
||||||
test.beforeEach(async ({ browserName }, testInfo) => {
|
test.beforeEach(async ({ skip }) => {
|
||||||
test.skip(testInfo.project.metadata.rtl === true, 'This does not test LTR vs. RTL layout.');
|
skip.rtl();
|
||||||
test.skip(browserName === 'firefox', 'Firefox incorrectly allows keyboard focus to move to ion-content');
|
skip.browser('firefox', 'Firefox incorrectly allows keyboard focus to move to ion-content');
|
||||||
});
|
});
|
||||||
test('focus should be trapped inside of modal', async ({ page, browserName }) => {
|
test('focus should be trapped inside of modal', async ({ page, browserName }) => {
|
||||||
/**
|
/**
|
||||||
|
@ -134,8 +134,8 @@ test.describe('modal: canDismiss', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test.describe('card modal - iOS swiping', () => {
|
test.describe('card modal - iOS swiping', () => {
|
||||||
test.beforeEach(async ({ page }, testInfo) => {
|
test.beforeEach(async ({ page, skip }) => {
|
||||||
test.skip(testInfo.project.metadata.mode !== 'ios', 'Swipe to close on a modal is only available in iOS mode.');
|
skip.mode('md');
|
||||||
|
|
||||||
await page.click('#radio-card');
|
await page.click('#radio-card');
|
||||||
});
|
});
|
||||||
|
@ -5,13 +5,13 @@ import { CardModalPage } from '../fixtures';
|
|||||||
|
|
||||||
test.describe('card modal - nav', () => {
|
test.describe('card modal - nav', () => {
|
||||||
let cardModalPage: CardModalPage;
|
let cardModalPage: CardModalPage;
|
||||||
test.beforeEach(async ({ page, browserName }, testInfo) => {
|
test.beforeEach(async ({ page, skip }) => {
|
||||||
test.skip(testInfo.project.metadata.mode !== 'ios', 'Card style modal is only available on iOS');
|
skip.mode('md');
|
||||||
test.skip(
|
skip.rtl('This test only verifies that the gesture activates inside of a modal.');
|
||||||
testInfo.project.metadata.rtl === true,
|
skip.browser(
|
||||||
'This test only verifies that the gesture activates inside of a modal.'
|
(browserName: string) => browserName !== 'chromium',
|
||||||
|
'dragElementBy is flaky outside of Chrome browsers.'
|
||||||
);
|
);
|
||||||
test.skip(browserName !== 'chromium', 'dragElementBy is flaky outside of Chrome browsers.');
|
|
||||||
|
|
||||||
cardModalPage = new CardModalPage(page);
|
cardModalPage = new CardModalPage(page);
|
||||||
await cardModalPage.navigate('/src/components/modal/test/card-nav?ionic:_testing=false');
|
await cardModalPage.navigate('/src/components/modal/test/card-nav?ionic:_testing=false');
|
||||||
|
@ -2,8 +2,8 @@ import { expect } from '@playwright/test';
|
|||||||
import { dragElementBy, test } from '@utils/test/playwright';
|
import { dragElementBy, test } from '@utils/test/playwright';
|
||||||
|
|
||||||
test.describe('card modal - with refresher', () => {
|
test.describe('card modal - with refresher', () => {
|
||||||
test.beforeEach(async ({ page }, testInfo) => {
|
test.beforeEach(async ({ page, skip }) => {
|
||||||
test.skip(testInfo.project.metadata.mode !== 'ios', 'Card style modal is only available on iOS');
|
skip.mode('md');
|
||||||
|
|
||||||
await page.goto('/src/components/modal/test/card-refresher');
|
await page.goto('/src/components/modal/test/card-refresher');
|
||||||
});
|
});
|
||||||
|
@ -2,8 +2,8 @@ import { expect } from '@playwright/test';
|
|||||||
import { dragElementBy, test } from '@utils/test/playwright';
|
import { dragElementBy, test } from '@utils/test/playwright';
|
||||||
|
|
||||||
test.describe('card modal - scroll target', () => {
|
test.describe('card modal - scroll target', () => {
|
||||||
test.beforeEach(async ({ page }, testInfo) => {
|
test.beforeEach(async ({ page, skip }) => {
|
||||||
test.skip(testInfo.project.metadata.mode !== 'ios', 'Card style modal is only available on iOS');
|
skip.mode('md');
|
||||||
|
|
||||||
await page.goto('/src/components/modal/test/card-scroll-target');
|
await page.goto('/src/components/modal/test/card-scroll-target');
|
||||||
});
|
});
|
||||||
|
@ -5,8 +5,8 @@ import { CardModalPage } from '../fixtures';
|
|||||||
|
|
||||||
test.describe('card modal', () => {
|
test.describe('card modal', () => {
|
||||||
let cardModalPage: CardModalPage;
|
let cardModalPage: CardModalPage;
|
||||||
test.beforeEach(async ({ page }, testInfo) => {
|
test.beforeEach(async ({ page, skip }) => {
|
||||||
test.skip(testInfo.project.metadata.mode !== 'ios', 'Card style modal is only available on iOS');
|
skip.mode('md');
|
||||||
|
|
||||||
cardModalPage = new CardModalPage(page);
|
cardModalPage = new CardModalPage(page);
|
||||||
await cardModalPage.navigate('/src/components/modal/test/card');
|
await cardModalPage.navigate('/src/components/modal/test/card');
|
||||||
|
@ -2,8 +2,8 @@ import { expect } from '@playwright/test';
|
|||||||
import { test } from '@utils/test/playwright';
|
import { test } from '@utils/test/playwright';
|
||||||
|
|
||||||
test.describe('modal: custom dialog', () => {
|
test.describe('modal: custom dialog', () => {
|
||||||
test('should size custom modal correctly', async ({ page }, testInfo) => {
|
test('should size custom modal correctly', async ({ page, skip }) => {
|
||||||
test.skip(testInfo.project.metadata.rtl === true, 'This does not test LTR vs. RTL layout.');
|
skip.rtl();
|
||||||
test.info().annotations.push({
|
test.info().annotations.push({
|
||||||
type: 'issue',
|
type: 'issue',
|
||||||
description: 'https://github.com/ionic-team/ionic-framework/issues/24080',
|
description: 'https://github.com/ionic-team/ionic-framework/issues/24080',
|
||||||
|
@ -32,8 +32,8 @@ test.describe('picker-column-internal', () => {
|
|||||||
expect(activeColumn).not.toBeNull();
|
expect(activeColumn).not.toBeNull();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('scrolling should change the active item', async ({ page, browserName }) => {
|
test('scrolling should change the active item', async ({ page, skip }) => {
|
||||||
test.skip(browserName === 'firefox', 'https://bugzilla.mozilla.org/show_bug.cgi?id=1766890');
|
skip.browser('firefox', 'https://bugzilla.mozilla.org/show_bug.cgi?id=1766890');
|
||||||
|
|
||||||
await page.locator('#default').evaluate((el: HTMLIonPickerColumnInternalElement) => {
|
await page.locator('#default').evaluate((el: HTMLIonPickerColumnInternalElement) => {
|
||||||
el.scrollTop = 801;
|
el.scrollTop = 801;
|
||||||
@ -45,8 +45,8 @@ test.describe('picker-column-internal', () => {
|
|||||||
expect(await activeColumn?.innerText()).toEqual('23');
|
expect(await activeColumn?.innerText()).toEqual('23');
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should not emit ionChange when the value is modified externally', async ({ page, browserName }) => {
|
test('should not emit ionChange when the value is modified externally', async ({ page, skip }) => {
|
||||||
test.skip(browserName === 'firefox', 'https://bugzilla.mozilla.org/show_bug.cgi?id=1766890');
|
skip.browser('firefox', 'https://bugzilla.mozilla.org/show_bug.cgi?id=1766890');
|
||||||
|
|
||||||
const ionChangeSpy = await page.spyOnEvent('ionChange');
|
const ionChangeSpy = await page.spyOnEvent('ionChange');
|
||||||
|
|
||||||
@ -57,8 +57,8 @@ test.describe('picker-column-internal', () => {
|
|||||||
expect(ionChangeSpy).not.toHaveReceivedEvent();
|
expect(ionChangeSpy).not.toHaveReceivedEvent();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should emit ionChange when the picker is scrolled', async ({ page, browserName }) => {
|
test('should emit ionChange when the picker is scrolled', async ({ page, skip }) => {
|
||||||
test.skip(browserName === 'firefox', 'https://bugzilla.mozilla.org/show_bug.cgi?id=1766890');
|
skip.browser('firefox', 'https://bugzilla.mozilla.org/show_bug.cgi?id=1766890');
|
||||||
|
|
||||||
const ionChangeSpy = await page.spyOnEvent('ionChange');
|
const ionChangeSpy = await page.spyOnEvent('ionChange');
|
||||||
|
|
||||||
|
@ -23,10 +23,10 @@ test.describe('popover: dismissOnSelect', async () => {
|
|||||||
await expect(popover).toBeVisible();
|
await expect(popover).toBeVisible();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should not dismiss a popover when clicking a click trigger', async ({ page, browserName }) => {
|
test('should not dismiss a popover when clicking a click trigger', async ({ page, skip }) => {
|
||||||
// TODO FW-1486
|
// TODO FW-1486
|
||||||
test.skip(
|
skip.browser(
|
||||||
browserName === 'firefox',
|
'firefox',
|
||||||
'Parent popover disappears when click trigger is clicked. Cannot replicate locally. Needs further investigation.'
|
'Parent popover disappears when click trigger is clicked. Cannot replicate locally. Needs further investigation.'
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -16,8 +16,8 @@ test.describe('radio-group: basic', () => {
|
|||||||
test.describe('radio-group: interaction', () => {
|
test.describe('radio-group: interaction', () => {
|
||||||
let radioFixture: RadioFixture;
|
let radioFixture: RadioFixture;
|
||||||
|
|
||||||
test.beforeEach(({ page }, testInfo) => {
|
test.beforeEach(({ page, skip }) => {
|
||||||
test.skip(testInfo.project.metadata.rtl === true, 'This does not test LTR vs RTL logic.');
|
skip.rtl();
|
||||||
radioFixture = new RadioFixture(page);
|
radioFixture = new RadioFixture(page);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -2,8 +2,8 @@ import { expect } from '@playwright/test';
|
|||||||
import { test } from '@utils/test/playwright';
|
import { test } from '@utils/test/playwright';
|
||||||
|
|
||||||
test.describe('radio-group', () => {
|
test.describe('radio-group', () => {
|
||||||
test.beforeEach(async ({ page }, testInfo) => {
|
test.beforeEach(async ({ page, skip }) => {
|
||||||
test.skip(testInfo.project.metadata.rtl === true, 'This does not test LTR vs RTL logic.');
|
skip.rtl();
|
||||||
await page.goto('/src/components/radio-group/test/search');
|
await page.goto('/src/components/radio-group/test/search');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -2,9 +2,8 @@ import { expect } from '@playwright/test';
|
|||||||
import { test } from '@utils/test/playwright';
|
import { test } from '@utils/test/playwright';
|
||||||
|
|
||||||
test.describe('radio: a11y', () => {
|
test.describe('radio: a11y', () => {
|
||||||
// eslint-disable-next-line no-empty-pattern
|
test.beforeEach(({ skip }) => {
|
||||||
test.beforeEach(({}, testInfo) => {
|
skip.rtl();
|
||||||
test.skip(testInfo.project.metadata.rtl === true, 'This does not test LTR vs RTL logic.');
|
|
||||||
});
|
});
|
||||||
test('tabbing should switch between radio groups', async ({ page, browserName }) => {
|
test('tabbing should switch between radio groups', async ({ page, browserName }) => {
|
||||||
const tabKey = browserName === 'webkit' ? 'Alt+Tab' : 'Tab';
|
const tabKey = browserName === 'webkit' ? 'Alt+Tab' : 'Tab';
|
||||||
|
@ -97,9 +97,8 @@ test.describe('radio: rendering', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test.describe('radio: interaction', () => {
|
test.describe('radio: interaction', () => {
|
||||||
// eslint-disable-next-line no-empty-pattern
|
test.beforeEach(({ skip }) => {
|
||||||
test.beforeEach(({}, testInfo) => {
|
skip.rtl();
|
||||||
test.skip(testInfo.project.metadata.rtl === true, 'This does not test LTR vs RTL logic.');
|
|
||||||
});
|
});
|
||||||
test('radio should be checked when activated', async ({ page }) => {
|
test('radio should be checked when activated', async ({ page }) => {
|
||||||
await page.setContent(`
|
await page.setContent(`
|
||||||
|
@ -54,9 +54,9 @@ test.describe('range: basic', () => {
|
|||||||
expect(rangeEnd).toHaveReceivedEventDetail({ value: 21 });
|
expect(rangeEnd).toHaveReceivedEventDetail({ value: 21 });
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should not scroll when the knob is swiped', async ({ page, browserName }, testInfo) => {
|
test('should not scroll when the knob is swiped', async ({ page, skip }) => {
|
||||||
test.skip(browserName === 'webkit', 'mouse.wheel is not available in WebKit');
|
skip.browser('webkit', 'mouse.wheel is not available in WebKit');
|
||||||
test.skip(testInfo.project.metadata.rtl === true, 'This feature does not have RTL-specific behaviors');
|
skip.rtl();
|
||||||
|
|
||||||
await page.goto(`/src/components/range/test/basic`);
|
await page.goto(`/src/components/range/test/basic`);
|
||||||
|
|
||||||
|
@ -2,9 +2,9 @@ import { expect } from '@playwright/test';
|
|||||||
import { test } from '@utils/test/playwright';
|
import { test } from '@utils/test/playwright';
|
||||||
|
|
||||||
test.describe('range: scroll-target', () => {
|
test.describe('range: scroll-target', () => {
|
||||||
test('should not scroll when the knob is swiped in custom scroll target', async ({ page, browserName }, testInfo) => {
|
test('should not scroll when the knob is swiped in custom scroll target', async ({ page, skip }) => {
|
||||||
test.skip(browserName === 'webkit', 'mouse.wheel is not available in WebKit');
|
skip.browser('webkit', 'mouse.wheel is not available in WebKit');
|
||||||
test.skip(testInfo.project.metadata.rtl === true, 'This feature does not have RTL-specific behaviors');
|
skip.rtl();
|
||||||
|
|
||||||
await page.goto(`/src/components/range/test/scroll-target`);
|
await page.goto(`/src/components/range/test/scroll-target`);
|
||||||
|
|
||||||
|
@ -2,8 +2,8 @@ import { expect } from '@playwright/test';
|
|||||||
import { test } from '@utils/test/playwright';
|
import { test } from '@utils/test/playwright';
|
||||||
|
|
||||||
test.describe('select: async', () => {
|
test.describe('select: async', () => {
|
||||||
test('should correctly set the value after a delay', async ({ page }, testInfo) => {
|
test('should correctly set the value after a delay', async ({ page, skip }) => {
|
||||||
test.skip(testInfo.project.metadata.rtl === true, 'This is checking internal logic. RTL tests are not needed');
|
skip.rtl('This is checking internal logic. RTL tests are not needed');
|
||||||
|
|
||||||
await page.goto(`/src/components/select/test/async`);
|
await page.goto(`/src/components/select/test/async`);
|
||||||
const selectValueSet = await page.spyOnEvent('selectValueSet');
|
const selectValueSet = await page.spyOnEvent('selectValueSet');
|
||||||
|
@ -2,8 +2,8 @@ import { expect } from '@playwright/test';
|
|||||||
import { test } from '@utils/test/playwright';
|
import { test } from '@utils/test/playwright';
|
||||||
|
|
||||||
test.describe('select: compare-with', () => {
|
test.describe('select: compare-with', () => {
|
||||||
test('should correctly set value when using compareWith property', async ({ page }, testInfo) => {
|
test('should correctly set value when using compareWith property', async ({ page, skip }) => {
|
||||||
test.skip(testInfo.project.metadata.rtl === true, 'This is checking internal logic. RTL tests are not needed');
|
skip.rtl('This is checking internal logic. RTL tests are not needed');
|
||||||
|
|
||||||
await page.goto('/src/components/select/test/compare-with');
|
await page.goto('/src/components/select/test/compare-with');
|
||||||
|
|
||||||
|
@ -2,8 +2,8 @@ import { expect } from '@playwright/test';
|
|||||||
import { test } from '@utils/test/playwright';
|
import { test } from '@utils/test/playwright';
|
||||||
|
|
||||||
test.describe('overlays: focus', () => {
|
test.describe('overlays: focus', () => {
|
||||||
test('should not focus the overlay container if element inside of overlay is focused', async ({ page }, testInfo) => {
|
test('should not focus the overlay container if element inside of overlay is focused', async ({ page, skip }) => {
|
||||||
test.skip(testInfo.project.metadata.rtl === true, 'RTL tests are not needed as layout is not checked');
|
skip.rtl();
|
||||||
|
|
||||||
await page.setContent(`
|
await page.setContent(`
|
||||||
<ion-button id="open-modal">Show Modal</ion-button>
|
<ion-button id="open-modal">Show Modal</ion-button>
|
||||||
|
69
core/src/utils/test/playwright/README.md
Normal file
69
core/src/utils/test/playwright/README.md
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
# Playwright Test Utils
|
||||||
|
|
||||||
|
This directory contains utilities that can be used to more easily test Stencil projects with Playwright.
|
||||||
|
|
||||||
|
## Test Function
|
||||||
|
|
||||||
|
The default `test` function has been extended to provide two custom options.
|
||||||
|
|
||||||
|
| Fixture | Type | Description |
|
||||||
|
| ------- | ---- | ----------- |
|
||||||
|
| page | [E2EPage](https://github.com/ionic-team/ionic-framework/blob/main/core/src/utils/test/playwright/playwright-declarations.ts) | An extension of the base `page` test fixture within Playwright |
|
||||||
|
| skip | [E2ESkip](https://github.com/ionic-team/ionic-framework/blob/main/core/src/utils/test/playwright/playwright-declarations.ts) | Used to skip tests based on text direction, mode, or browser |
|
||||||
|
|
||||||
|
### Usage
|
||||||
|
|
||||||
|
**`page`**
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
import { test } from '@utils/test/playwright';
|
||||||
|
|
||||||
|
test('my custom test', ({ page }) => {
|
||||||
|
await page.goto('path/to/file');
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
**`skip.mode`**
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
import { test } from '@utils/test/playwright';
|
||||||
|
|
||||||
|
test('my custom test', ({ page, skip }) => {
|
||||||
|
skip.mode('md', 'This test is iOS-specific.');
|
||||||
|
|
||||||
|
await page.goto('path/to/file');
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
**`skip.rtl`**
|
||||||
|
```typescript
|
||||||
|
import { test } from '@utils/test/playwright';
|
||||||
|
|
||||||
|
test('my custom test', ({ page, skip }) => {
|
||||||
|
skip.rtl('This test does not have RTL-specific behaviors.');
|
||||||
|
|
||||||
|
await page.goto('path/to/file');
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
**`skip.browser`**
|
||||||
|
```typescript
|
||||||
|
import { test } from '@utils/test/playwright';
|
||||||
|
|
||||||
|
test('my custom test', ({ page, skip }) => {
|
||||||
|
skip.browser('webkit', 'This test does not work in WebKit yet.');
|
||||||
|
|
||||||
|
await page.goto('path/to/file');
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
**`skip.browser` with callback**
|
||||||
|
```typescript
|
||||||
|
import { test } from '@utils/test/playwright';
|
||||||
|
|
||||||
|
test('my custom test', ({ page, skip }) => {
|
||||||
|
skip.browser((browserName: string) => browserName !== 'webkit', 'This tests a WebKit-specific behavior.');
|
||||||
|
|
||||||
|
await page.goto('path/to/file');
|
||||||
|
});
|
||||||
|
```
|
@ -96,6 +96,14 @@ export interface E2EPage extends Page {
|
|||||||
_e2eEvents: Map<number, any>;
|
_e2eEvents: Map<number, any>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type BrowserNameOrCallback = string | ((browserName: string) => boolean);
|
||||||
|
|
||||||
|
export interface E2ESkip {
|
||||||
|
rtl: (reason?: string) => void;
|
||||||
|
browser: (browserNameOrCallback: BrowserNameOrCallback, reason?: string) => void;
|
||||||
|
mode: (mode: string, reason?: string) => void;
|
||||||
|
}
|
||||||
|
|
||||||
export interface SetIonViewportOptions {
|
export interface SetIonViewportOptions {
|
||||||
/**
|
/**
|
||||||
* `true` if the viewport should be scaled to match the `ion-content`
|
* `true` if the viewport should be scaled to match the `ion-content`
|
||||||
|
@ -18,7 +18,7 @@ import {
|
|||||||
locator,
|
locator,
|
||||||
} from './page/utils';
|
} from './page/utils';
|
||||||
import type { LocatorOptions } from './page/utils';
|
import type { LocatorOptions } from './page/utils';
|
||||||
import type { E2EPage, SetIonViewportOptions } from './playwright-declarations';
|
import type { E2EPage, E2ESkip, BrowserNameOrCallback, SetIonViewportOptions } from './playwright-declarations';
|
||||||
|
|
||||||
type CustomTestArgs = PlaywrightTestArgs &
|
type CustomTestArgs = PlaywrightTestArgs &
|
||||||
PlaywrightTestOptions &
|
PlaywrightTestOptions &
|
||||||
@ -29,6 +29,7 @@ type CustomTestArgs = PlaywrightTestArgs &
|
|||||||
|
|
||||||
type CustomFixtures = {
|
type CustomFixtures = {
|
||||||
page: E2EPage;
|
page: E2EPage;
|
||||||
|
skip: E2ESkip;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -63,4 +64,25 @@ export const test = base.extend<CustomFixtures>({
|
|||||||
page = await extendPageFixture(page, testInfo);
|
page = await extendPageFixture(page, testInfo);
|
||||||
await use(page);
|
await use(page);
|
||||||
},
|
},
|
||||||
|
skip: {
|
||||||
|
rtl: (reason = 'The functionality that is being tested is not applicable to RTL layouts.') => {
|
||||||
|
const testInfo: TestInfo = base.info();
|
||||||
|
base.skip(testInfo.project.metadata.rtl === true, reason);
|
||||||
|
},
|
||||||
|
browser: (
|
||||||
|
browserNameOrFunction: BrowserNameOrCallback,
|
||||||
|
reason = `The functionality that is being tested is not applicable to this browser.`
|
||||||
|
) => {
|
||||||
|
const browserName = base.info().project.use.browserName!;
|
||||||
|
|
||||||
|
if (typeof browserNameOrFunction === 'function') {
|
||||||
|
base.skip(browserNameOrFunction(browserName), reason);
|
||||||
|
} else {
|
||||||
|
base.skip(browserName === browserNameOrFunction, reason);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mode: (mode: string, reason = `The functionality that is being tested is not applicable to ${mode} mode`) => {
|
||||||
|
base.skip(base.info().project.metadata.mode === mode, reason);
|
||||||
|
},
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
Reference in New Issue
Block a user