chore(): sync with main
57
.github/CODEOWNERS
vendored
@ -13,3 +13,60 @@
|
|||||||
|
|
||||||
# Global owners
|
# Global owners
|
||||||
* @ionic-team/framework
|
* @ionic-team/framework
|
||||||
|
|
||||||
|
# Frameworks
|
||||||
|
|
||||||
|
## Angular
|
||||||
|
|
||||||
|
/angular/ @sean-perkins
|
||||||
|
/packages/angular-server @sean-perkins
|
||||||
|
/angular/test
|
||||||
|
|
||||||
|
## React
|
||||||
|
|
||||||
|
/packages/react/ @amandaejohnston
|
||||||
|
/packages/react-router @amandaejohnston
|
||||||
|
/packages/react/test-app/
|
||||||
|
/packages/react-router/test-app/
|
||||||
|
|
||||||
|
## Vue
|
||||||
|
|
||||||
|
/packages/vue/ @liamdebeasi
|
||||||
|
/packages/vue-router/ @liamdebeasi
|
||||||
|
/packages/vue/test/
|
||||||
|
/packages/vue-router/__tests__
|
||||||
|
|
||||||
|
# Components
|
||||||
|
|
||||||
|
/core/src/components/accordion/ @liamdebeasi
|
||||||
|
/core/src/components/accordion-group/ @liamdebeasi
|
||||||
|
|
||||||
|
/core/src/components/datetime/ @liamdebeasi @amandaejohnston @sean-perkins
|
||||||
|
/core/src/components/datetime-button/ @liamdebeasi
|
||||||
|
|
||||||
|
/core/src/components/menu/ @amandaejohnston
|
||||||
|
/core/src/components/menu-toggle/ @amandaejohnston
|
||||||
|
|
||||||
|
/core/src/components/nav/ @sean-perkins
|
||||||
|
/core/src/components/nav-link/ @sean-perkins
|
||||||
|
|
||||||
|
/core/src/components/picker-internal/ @liamdebeasi
|
||||||
|
/core/src/components/picker-column-internal/ @liamdebeasi
|
||||||
|
|
||||||
|
/core/src/components/refresher/ @liamdebeasi
|
||||||
|
/core/src/components/refresher-content/ @liamdebeasi
|
||||||
|
|
||||||
|
# Codeowner should own the source, but everyone should own the tests
|
||||||
|
/core/src/components/**/test/ @ionic-team/framework
|
||||||
|
|
||||||
|
# Utilities
|
||||||
|
|
||||||
|
/core/src/utils/animation/ @liamdebeasi
|
||||||
|
/core/src/utils/content/ @sean-perkins
|
||||||
|
/core/src/utils/gesture/ @liamdebeasi
|
||||||
|
/core/src/utils/input-shims/ @liamdebeasi
|
||||||
|
/core/src/utils/keyboard/ @liamdebeasi
|
||||||
|
/core/src/utils/logging/ @amandaejohnston
|
||||||
|
/core/src/utils/sanitization/ @liamdebeasi
|
||||||
|
/core/src/utils/tap-click/ @liamdebeasi
|
||||||
|
/core/src/utils/transition/ @liamdebeasi
|
||||||
|
7
.github/workflows/stencil-eval.yml
vendored
@ -47,13 +47,6 @@ jobs:
|
|||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
- uses: ./.github/workflows/actions/test-core-spec
|
- uses: ./.github/workflows/actions/test-core-spec
|
||||||
|
|
||||||
test-core-e2e:
|
|
||||||
needs: [build-core]
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v3
|
|
||||||
- uses: ./.github/workflows/actions/test-core-e2e
|
|
||||||
|
|
||||||
test-core-screenshot:
|
test-core-screenshot:
|
||||||
strategy:
|
strategy:
|
||||||
# This ensures that all screenshot shard
|
# This ensures that all screenshot shard
|
||||||
|
@ -85,7 +85,10 @@ const config: PlaywrightTestConfig = {
|
|||||||
},
|
},
|
||||||
/* Fail the build on CI if you accidentally left test.only in the source code. */
|
/* Fail the build on CI if you accidentally left test.only in the source code. */
|
||||||
forbidOnly: !!process.env.CI,
|
forbidOnly: !!process.env.CI,
|
||||||
retries: process.env.CI ? 2 : 0,
|
/* Fail fast on CI */
|
||||||
|
maxFailures: process.env.CI ? 1 : 0,
|
||||||
|
/* Flaky test should be either addressed or disabled until we can address them */
|
||||||
|
retries: 0,
|
||||||
/* Opt out of parallel tests on CI. */
|
/* Opt out of parallel tests on CI. */
|
||||||
workers: process.env.CI ? 1 : undefined,
|
workers: process.env.CI ? 1 : undefined,
|
||||||
/* Reporter to use. See https://playwright.dev/docs/test-reporters */
|
/* Reporter to use. See https://playwright.dev/docs/test-reporters */
|
||||||
|
@ -19,7 +19,7 @@ test.describe('accordion: states', () => {
|
|||||||
const accordionGroup = page.locator('ion-accordion-group');
|
const accordionGroup = page.locator('ion-accordion-group');
|
||||||
const accordion = page.locator('ion-accordion');
|
const accordion = page.locator('ion-accordion');
|
||||||
|
|
||||||
expect(accordion).toHaveJSProperty('readonly', false);
|
await expect(accordion).toHaveJSProperty('readonly', false);
|
||||||
|
|
||||||
await accordionGroup.evaluate((el: HTMLIonAccordionGroupElement) => {
|
await accordionGroup.evaluate((el: HTMLIonAccordionGroupElement) => {
|
||||||
el.readonly = true;
|
el.readonly = true;
|
||||||
@ -27,7 +27,7 @@ test.describe('accordion: states', () => {
|
|||||||
|
|
||||||
await page.waitForChanges();
|
await page.waitForChanges();
|
||||||
|
|
||||||
expect(accordion).toHaveJSProperty('readonly', true);
|
await expect(accordion).toHaveJSProperty('readonly', true);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should properly set disabled on child accordions', async ({ page }) => {
|
test('should properly set disabled on child accordions', async ({ page }) => {
|
||||||
@ -43,7 +43,7 @@ test.describe('accordion: states', () => {
|
|||||||
const accordionGroup = page.locator('ion-accordion-group');
|
const accordionGroup = page.locator('ion-accordion-group');
|
||||||
const accordion = page.locator('ion-accordion');
|
const accordion = page.locator('ion-accordion');
|
||||||
|
|
||||||
expect(accordion).toHaveJSProperty('disabled', false);
|
await expect(accordion).toHaveJSProperty('disabled', false);
|
||||||
|
|
||||||
await accordionGroup.evaluate((el: HTMLIonAccordionGroupElement) => {
|
await accordionGroup.evaluate((el: HTMLIonAccordionGroupElement) => {
|
||||||
el.disabled = true;
|
el.disabled = true;
|
||||||
@ -51,6 +51,6 @@ test.describe('accordion: states', () => {
|
|||||||
|
|
||||||
await page.waitForChanges();
|
await page.waitForChanges();
|
||||||
|
|
||||||
expect(accordion).toHaveJSProperty('disabled', true);
|
await expect(accordion).toHaveJSProperty('disabled', true);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -41,7 +41,7 @@ test.describe('action sheet: basic', () => {
|
|||||||
await actionSheetFixture.open('#basic');
|
await actionSheetFixture.open('#basic');
|
||||||
|
|
||||||
const actionSheet = page.locator('ion-action-sheet');
|
const actionSheet = page.locator('ion-action-sheet');
|
||||||
expect(actionSheet).toHaveAttribute('data-testid', 'basic-action-sheet');
|
await expect(actionSheet).toHaveAttribute('data-testid', 'basic-action-sheet');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
test.describe('action sheet: variants', () => {
|
test.describe('action sheet: variants', () => {
|
||||||
@ -78,7 +78,7 @@ test.describe('action sheet: basic', () => {
|
|||||||
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');
|
await expect(backdrop).toHaveCSS('opacity', '1');
|
||||||
});
|
});
|
||||||
test('should open alert from action sheet', async ({ page, skip }) => {
|
test('should open alert from action sheet', async ({ page, skip }) => {
|
||||||
skip.rtl();
|
skip.rtl();
|
||||||
@ -96,7 +96,7 @@ test.describe('action sheet: basic', () => {
|
|||||||
const actionSheet = page.locator('ion-action-sheet');
|
const actionSheet = page.locator('ion-action-sheet');
|
||||||
await actionSheet.locator('ion-backdrop').click();
|
await actionSheet.locator('ion-backdrop').click();
|
||||||
|
|
||||||
expect(actionSheet).toBeVisible();
|
await expect(actionSheet).toBeVisible();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
test.describe('action sheet: focus trap', () => {
|
test.describe('action sheet: focus trap', () => {
|
||||||
@ -133,14 +133,14 @@ class ActionSheetFixture {
|
|||||||
await this.page.locator(selector).click();
|
await this.page.locator(selector).click();
|
||||||
await ionActionSheetDidPresent.next();
|
await ionActionSheetDidPresent.next();
|
||||||
this.actionSheet = this.page.locator('ion-action-sheet');
|
this.actionSheet = this.page.locator('ion-action-sheet');
|
||||||
expect(this.actionSheet).toBeVisible();
|
await expect(this.actionSheet).toBeVisible();
|
||||||
}
|
}
|
||||||
|
|
||||||
async dismiss() {
|
async dismiss() {
|
||||||
const ionActionSheetDidDismiss = await this.page.spyOnEvent('ionActionSheetDidDismiss');
|
const ionActionSheetDidDismiss = await this.page.spyOnEvent('ionActionSheetDidDismiss');
|
||||||
await this.actionSheet.evaluate((el: HTMLIonActionSheetElement) => el.dismiss());
|
await this.actionSheet.evaluate((el: HTMLIonActionSheetElement) => el.dismiss());
|
||||||
await ionActionSheetDidDismiss.next();
|
await ionActionSheetDidDismiss.next();
|
||||||
expect(this.actionSheet).not.toBeVisible();
|
await expect(this.actionSheet).not.toBeVisible();
|
||||||
}
|
}
|
||||||
|
|
||||||
async screenshot(modifier: string) {
|
async screenshot(modifier: string) {
|
||||||
|
@ -51,7 +51,7 @@ test.describe('alert: basic', () => {
|
|||||||
await page.goto(`/src/components/alert/test/basic`);
|
await page.goto(`/src/components/alert/test/basic`);
|
||||||
|
|
||||||
const alert = await openAlert(page, 'basic');
|
const alert = await openAlert(page, 'basic');
|
||||||
expect(alert).toHaveAttribute('data-testid', 'basic-alert');
|
await expect(alert).toHaveAttribute('data-testid', 'basic-alert');
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should dismiss when async handler resolves', async ({ page, skip }) => {
|
test('should dismiss when async handler resolves', async ({ page, skip }) => {
|
||||||
|
@ -14,21 +14,21 @@ test.describe('datetime-button: switching to correct view', () => {
|
|||||||
});
|
});
|
||||||
test('should switch to a date-only view when the date button is clicked', async ({ page }) => {
|
test('should switch to a date-only view when the date button is clicked', async ({ page }) => {
|
||||||
const datetime = page.locator('ion-datetime');
|
const datetime = page.locator('ion-datetime');
|
||||||
expect(datetime).toHaveJSProperty('presentation', 'date-time');
|
await expect(datetime).toHaveJSProperty('presentation', 'date-time');
|
||||||
|
|
||||||
await page.locator('#date-button').click();
|
await page.locator('#date-button').click();
|
||||||
await page.waitForChanges();
|
await page.waitForChanges();
|
||||||
|
|
||||||
expect(datetime).toHaveJSProperty('presentation', 'date');
|
await expect(datetime).toHaveJSProperty('presentation', 'date');
|
||||||
});
|
});
|
||||||
test('should switch to a time-only view when the time button is clicked', async ({ page }) => {
|
test('should switch to a time-only view when the time button is clicked', async ({ page }) => {
|
||||||
const datetime = page.locator('ion-datetime');
|
const datetime = page.locator('ion-datetime');
|
||||||
expect(datetime).toHaveJSProperty('presentation', 'date-time');
|
await expect(datetime).toHaveJSProperty('presentation', 'date-time');
|
||||||
|
|
||||||
await page.locator('#time-button').click();
|
await page.locator('#time-button').click();
|
||||||
await page.waitForChanges();
|
await page.waitForChanges();
|
||||||
|
|
||||||
expect(datetime).toHaveJSProperty('presentation', 'time');
|
await expect(datetime).toHaveJSProperty('presentation', 'time');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -68,38 +68,38 @@ test.describe('datetime-button: popover', () => {
|
|||||||
|
|
||||||
await ionPopoverDidPresent.next();
|
await ionPopoverDidPresent.next();
|
||||||
|
|
||||||
expect(datetime).toBeVisible();
|
await expect(datetime).toBeVisible();
|
||||||
});
|
});
|
||||||
test('should open the time popover', async ({ page }) => {
|
test('should open the time popover', async ({ page }) => {
|
||||||
await page.locator('#time-button').click();
|
await page.locator('#time-button').click();
|
||||||
|
|
||||||
await ionPopoverDidPresent.next();
|
await ionPopoverDidPresent.next();
|
||||||
|
|
||||||
expect(datetime).toBeVisible();
|
await expect(datetime).toBeVisible();
|
||||||
});
|
});
|
||||||
test('should open the date popover then the time popover', async ({ page }) => {
|
test('should open the date popover then the time popover', async ({ page }) => {
|
||||||
await page.locator('#date-button').click();
|
await page.locator('#date-button').click();
|
||||||
await ionPopoverDidPresent.next();
|
await ionPopoverDidPresent.next();
|
||||||
expect(datetime).toBeVisible();
|
await expect(datetime).toBeVisible();
|
||||||
|
|
||||||
await popover.evaluate((el: HTMLIonPopoverElement) => el.dismiss());
|
await popover.evaluate((el: HTMLIonPopoverElement) => el.dismiss());
|
||||||
await ionPopoverDidDismiss.next();
|
await ionPopoverDidDismiss.next();
|
||||||
|
|
||||||
await page.locator('#time-button').click();
|
await page.locator('#time-button').click();
|
||||||
await ionPopoverDidPresent.next();
|
await ionPopoverDidPresent.next();
|
||||||
expect(datetime).toBeVisible();
|
await expect(datetime).toBeVisible();
|
||||||
});
|
});
|
||||||
test('should open the time popover then the date popover', async ({ page }) => {
|
test('should open the time popover then the date popover', async ({ page }) => {
|
||||||
await page.locator('#time-button').click();
|
await page.locator('#time-button').click();
|
||||||
await ionPopoverDidPresent.next();
|
await ionPopoverDidPresent.next();
|
||||||
expect(datetime).toBeVisible();
|
await expect(datetime).toBeVisible();
|
||||||
|
|
||||||
await popover.evaluate((el: HTMLIonPopoverElement) => el.dismiss());
|
await popover.evaluate((el: HTMLIonPopoverElement) => el.dismiss());
|
||||||
await ionPopoverDidDismiss.next();
|
await ionPopoverDidDismiss.next();
|
||||||
|
|
||||||
await page.locator('#date-button').click();
|
await page.locator('#date-button').click();
|
||||||
await ionPopoverDidPresent.next();
|
await ionPopoverDidPresent.next();
|
||||||
expect(datetime).toBeVisible();
|
await expect(datetime).toBeVisible();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -130,37 +130,37 @@ test.describe('datetime-button: modal', () => {
|
|||||||
|
|
||||||
await ionModalDidPresent.next();
|
await ionModalDidPresent.next();
|
||||||
|
|
||||||
expect(datetime).toBeVisible();
|
await expect(datetime).toBeVisible();
|
||||||
});
|
});
|
||||||
test('should open the time modal', async ({ page }) => {
|
test('should open the time modal', async ({ page }) => {
|
||||||
await page.locator('#time-button').click();
|
await page.locator('#time-button').click();
|
||||||
|
|
||||||
await ionModalDidPresent.next();
|
await ionModalDidPresent.next();
|
||||||
|
|
||||||
expect(datetime).toBeVisible();
|
await expect(datetime).toBeVisible();
|
||||||
});
|
});
|
||||||
test('should open the date modal then the time modal', async ({ page }) => {
|
test('should open the date modal then the time modal', async ({ page }) => {
|
||||||
await page.locator('#date-button').click();
|
await page.locator('#date-button').click();
|
||||||
await ionModalDidPresent.next();
|
await ionModalDidPresent.next();
|
||||||
expect(datetime).toBeVisible();
|
await expect(datetime).toBeVisible();
|
||||||
|
|
||||||
await modal.evaluate((el: HTMLIonModalElement) => el.dismiss());
|
await modal.evaluate((el: HTMLIonModalElement) => el.dismiss());
|
||||||
await ionModalDidDismiss.next();
|
await ionModalDidDismiss.next();
|
||||||
|
|
||||||
await page.locator('#time-button').click();
|
await page.locator('#time-button').click();
|
||||||
await ionModalDidPresent.next();
|
await ionModalDidPresent.next();
|
||||||
expect(datetime).toBeVisible();
|
await expect(datetime).toBeVisible();
|
||||||
});
|
});
|
||||||
test('should open the time modal then the date modal', async ({ page }) => {
|
test('should open the time modal then the date modal', async ({ page }) => {
|
||||||
await page.locator('#time-button').click();
|
await page.locator('#time-button').click();
|
||||||
await ionModalDidPresent.next();
|
await ionModalDidPresent.next();
|
||||||
expect(datetime).toBeVisible();
|
await expect(datetime).toBeVisible();
|
||||||
|
|
||||||
await modal.evaluate((el: HTMLIonModalElement) => el.dismiss());
|
await modal.evaluate((el: HTMLIonModalElement) => el.dismiss());
|
||||||
await ionModalDidDismiss.next();
|
await ionModalDidDismiss.next();
|
||||||
|
|
||||||
await page.locator('#date-button').click();
|
await page.locator('#date-button').click();
|
||||||
await ionModalDidPresent.next();
|
await ionModalDidPresent.next();
|
||||||
expect(datetime).toBeVisible();
|
await expect(datetime).toBeVisible();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -300,10 +300,13 @@ test.describe('datetime: visibility', () => {
|
|||||||
|
|
||||||
await datetime.evaluate((el: HTMLIonDatetimeElement) => el.style.setProperty('display', 'none'));
|
await datetime.evaluate((el: HTMLIonDatetimeElement) => el.style.setProperty('display', 'none'));
|
||||||
await expect(datetime).toBeHidden();
|
await expect(datetime).toBeHidden();
|
||||||
|
await expect(datetime).not.toHaveClass(/datetime-ready/);
|
||||||
|
|
||||||
await datetime.evaluate((el: HTMLIonDatetimeElement) => el.style.removeProperty('display'));
|
await datetime.evaluate((el: HTMLIonDatetimeElement) => el.style.removeProperty('display'));
|
||||||
await expect(datetime).toBeVisible();
|
await expect(datetime).toBeVisible();
|
||||||
|
|
||||||
|
await page.waitForSelector('.datetime-ready');
|
||||||
|
|
||||||
// month/year interface should be reset
|
// month/year interface should be reset
|
||||||
await expect(monthYearInterface).toBeHidden();
|
await expect(monthYearInterface).toBeHidden();
|
||||||
});
|
});
|
||||||
|
@ -214,8 +214,8 @@ test.describe('datetime: prefer wheel', () => {
|
|||||||
const monthValues = page.locator('.month-column .picker-item:not(.picker-item-empty)');
|
const monthValues = page.locator('.month-column .picker-item:not(.picker-item-empty)');
|
||||||
const dayValues = page.locator('.day-column .picker-item:not(.picker-item-empty)');
|
const dayValues = page.locator('.day-column .picker-item:not(.picker-item-empty)');
|
||||||
|
|
||||||
expect(monthValues).toHaveText(['1月', '2月', '3月']);
|
await expect(monthValues).toHaveText(['1月', '2月', '3月']);
|
||||||
expect(dayValues).toHaveText(['1日', '2日', '3日']);
|
await expect(dayValues).toHaveText(['1日', '2日', '3日']);
|
||||||
});
|
});
|
||||||
test('should render the columns according to locale - en-US', async ({ page }) => {
|
test('should render the columns according to locale - en-US', async ({ page }) => {
|
||||||
await page.setContent(`
|
await page.setContent(`
|
||||||
@ -334,7 +334,7 @@ test.describe('datetime: prefer wheel', () => {
|
|||||||
|
|
||||||
const dateValues = page.locator('.date-column .picker-item:not(.picker-item-empty)');
|
const dateValues = page.locator('.date-column .picker-item:not(.picker-item-empty)');
|
||||||
|
|
||||||
expect(dateValues).toHaveText(['2月1日(火)', '2月2日(水)', '2月3日(木)']);
|
await expect(dateValues).toHaveText(['2月1日(火)', '2月2日(水)', '2月3日(木)']);
|
||||||
});
|
});
|
||||||
test('should respect min and max bounds even across years', async ({ page }) => {
|
test('should respect min and max bounds even across years', async ({ page }) => {
|
||||||
await page.setContent(`
|
await page.setContent(`
|
||||||
@ -495,7 +495,7 @@ test.describe('datetime: prefer wheel', () => {
|
|||||||
|
|
||||||
const dateValues = page.locator('.date-column .picker-item:not(.picker-item-empty)');
|
const dateValues = page.locator('.date-column .picker-item:not(.picker-item-empty)');
|
||||||
|
|
||||||
expect(dateValues).toHaveText(['2月1日(火)', '2月2日(水)', '2月3日(木)']);
|
await expect(dateValues).toHaveText(['2月1日(火)', '2月2日(水)', '2月3日(木)']);
|
||||||
});
|
});
|
||||||
test('should respect min and max bounds even across years', async ({ page }) => {
|
test('should respect min and max bounds even across years', async ({ page }) => {
|
||||||
await page.setContent(`
|
await page.setContent(`
|
||||||
|
@ -159,9 +159,10 @@ class TimePickerFixture {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async goto() {
|
async goto() {
|
||||||
await this.page.goto(`/src/components/datetime/test/presentation`);
|
await this.page.setContent(`
|
||||||
await this.page.locator('select').selectOption('time');
|
<ion-datetime presentation="time" value="2022-03-10T13:00:00"></ion-datetime>
|
||||||
await this.page.waitForSelector('.datetime-presentation-time');
|
`);
|
||||||
|
await this.page.waitForSelector('.datetime-ready');
|
||||||
this.timePicker = this.page.locator('ion-datetime');
|
this.timePicker = this.page.locator('ion-datetime');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -47,28 +47,28 @@ test.describe('fab: basic (functionality checks)', () => {
|
|||||||
const fab = page.locator('#fab1');
|
const fab = page.locator('#fab1');
|
||||||
const fabList = fab.locator('ion-fab-list');
|
const fabList = fab.locator('ion-fab-list');
|
||||||
|
|
||||||
expect(fabList).not.toHaveClass(/fab-list-active/);
|
await expect(fabList).not.toHaveClass(/fab-list-active/);
|
||||||
|
|
||||||
// open fab
|
// open fab
|
||||||
await fab.click();
|
await fab.click();
|
||||||
await page.waitForChanges();
|
await page.waitForChanges();
|
||||||
expect(fabList).toHaveClass(/fab-list-active/);
|
await expect(fabList).toHaveClass(/fab-list-active/);
|
||||||
|
|
||||||
// close fab
|
// close fab
|
||||||
await fab.click();
|
await fab.click();
|
||||||
await page.waitForChanges();
|
await page.waitForChanges();
|
||||||
expect(fabList).not.toHaveClass(/fab-list-active/);
|
await expect(fabList).not.toHaveClass(/fab-list-active/);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should not open when disabled', async ({ page }) => {
|
test('should not open when disabled', async ({ page }) => {
|
||||||
const fab = page.locator('#fab2');
|
const fab = page.locator('#fab2');
|
||||||
const fabList = fab.locator('ion-fab-list');
|
const fabList = fab.locator('ion-fab-list');
|
||||||
|
|
||||||
expect(fabList).not.toHaveClass(/fab-list-active/);
|
await expect(fabList).not.toHaveClass(/fab-list-active/);
|
||||||
|
|
||||||
// attempt to open fab
|
// attempt to open fab
|
||||||
await fab.click();
|
await fab.click();
|
||||||
await page.waitForChanges();
|
await page.waitForChanges();
|
||||||
expect(fabList).not.toHaveClass(/fab-list-active/);
|
await expect(fabList).not.toHaveClass(/fab-list-active/);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -40,7 +40,8 @@ test.describe('item-sliding: basic', () => {
|
|||||||
expect(await item.screenshot()).toMatchSnapshot(`item-sliding-gesture-${page.getSnapshotSettings()}.png`);
|
expect(await item.screenshot()).toMatchSnapshot(`item-sliding-gesture-${page.getSnapshotSettings()}.png`);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should not scroll when the item-sliding is swiped', async ({ page, skip }) => {
|
// TODO FW-3006
|
||||||
|
test.skip('should not scroll when the item-sliding is swiped', async ({ page, skip }) => {
|
||||||
skip.browser('webkit', 'mouse.wheel is not available in WebKit');
|
skip.browser('webkit', 'mouse.wheel is not available in WebKit');
|
||||||
skip.rtl();
|
skip.rtl();
|
||||||
|
|
||||||
|
@ -2,7 +2,8 @@ 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 ({ page, skip }) => {
|
// TODO FW-3006
|
||||||
|
test.skip('should not scroll when the item-sliding is swiped in custom scroll target', async ({ page, skip }) => {
|
||||||
skip.browser('webkit', 'mouse.wheel is not available in WebKit');
|
skip.browser('webkit', 'mouse.wheel is not available in WebKit');
|
||||||
skip.rtl();
|
skip.rtl();
|
||||||
|
|
||||||
|
@ -2,14 +2,25 @@ import { expect } from '@playwright/test';
|
|||||||
import { test } from '@utils/test/playwright';
|
import { test } from '@utils/test/playwright';
|
||||||
|
|
||||||
test.describe('list: inset', () => {
|
test.describe('list: inset', () => {
|
||||||
test.beforeEach(async ({ page }) => {
|
test.describe('list: rendering', () => {
|
||||||
await page.goto('/src/components/list/test/inset');
|
|
||||||
});
|
|
||||||
test.describe('list: visual regression tests', () => {
|
|
||||||
test('should not have visual regressions', async ({ page }) => {
|
test('should not have visual regressions', async ({ page }) => {
|
||||||
await page.setIonViewport();
|
await page.setContent(`
|
||||||
|
<ion-content color="primary">
|
||||||
|
<div class="wrapper" style="display: flex">
|
||||||
|
<ion-list inset="true" style="width: 100%">
|
||||||
|
<ion-item>Pokémon Yellow</ion-item>
|
||||||
|
<ion-item>Super Metroid</ion-item>
|
||||||
|
<ion-item>Mega Man X</ion-item>
|
||||||
|
<ion-item>The Legend of Zelda</ion-item>
|
||||||
|
<ion-item lines="full">Halo</ion-item>
|
||||||
|
</ion-list>
|
||||||
|
</div>
|
||||||
|
</ion-content>
|
||||||
|
`);
|
||||||
|
|
||||||
expect(await page.screenshot()).toMatchSnapshot(`list-inset-diff-${page.getSnapshotSettings()}.png`);
|
const listWrapper = page.locator('.wrapper');
|
||||||
|
|
||||||
|
expect(await listWrapper.screenshot()).toMatchSnapshot(`list-inset-diff-${page.getSnapshotSettings()}.png`);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
Before Width: | Height: | Size: 90 KiB After Width: | Height: | Size: 32 KiB |
Before Width: | Height: | Size: 32 KiB After Width: | Height: | Size: 12 KiB |
Before Width: | Height: | Size: 84 KiB After Width: | Height: | Size: 30 KiB |
Before Width: | Height: | Size: 90 KiB After Width: | Height: | Size: 31 KiB |
Before Width: | Height: | Size: 33 KiB After Width: | Height: | Size: 12 KiB |
Before Width: | Height: | Size: 84 KiB After Width: | Height: | Size: 30 KiB |
@ -1,6 +1,5 @@
|
|||||||
import { GESTURE } from '@utils/overlays';
|
|
||||||
|
|
||||||
import type { Animation } from '../../../interface';
|
import type { Animation } from '../../../interface';
|
||||||
|
import { GESTURE } from '../../../utils/overlays';
|
||||||
|
|
||||||
export const handleCanDismiss = async (el: HTMLIonModalElement, animation: Animation) => {
|
export const handleCanDismiss = async (el: HTMLIonModalElement, animation: Animation) => {
|
||||||
/**
|
/**
|
||||||
|
@ -60,7 +60,7 @@ test.describe('picker-column-internal: disabled', () => {
|
|||||||
`);
|
`);
|
||||||
|
|
||||||
const disabledItem = page.locator('ion-picker-column-internal .picker-item.picker-item-disabled');
|
const disabledItem = page.locator('ion-picker-column-internal .picker-item.picker-item-disabled');
|
||||||
expect(disabledItem).not.toBeEnabled();
|
await expect(disabledItem).not.toBeEnabled();
|
||||||
});
|
});
|
||||||
test('disabled picker item should not be considered active', async ({ page }) => {
|
test('disabled picker item should not be considered active', async ({ page }) => {
|
||||||
await page.setContent(`
|
await page.setContent(`
|
||||||
@ -79,7 +79,7 @@ test.describe('picker-column-internal: disabled', () => {
|
|||||||
`);
|
`);
|
||||||
|
|
||||||
const disabledItem = page.locator('ion-picker-column-internal .picker-item[data-value="b"]');
|
const disabledItem = page.locator('ion-picker-column-internal .picker-item[data-value="b"]');
|
||||||
expect(disabledItem).not.toHaveClass(/picker-item-active/);
|
await expect(disabledItem).not.toHaveClass(/picker-item-active/);
|
||||||
});
|
});
|
||||||
test('setting the value to a disabled item should not cause that item to be active', async ({ page }) => {
|
test('setting the value to a disabled item should not cause that item to be active', async ({ page }) => {
|
||||||
await page.setContent(`
|
await page.setContent(`
|
||||||
@ -103,8 +103,8 @@ test.describe('picker-column-internal: disabled', () => {
|
|||||||
await page.waitForChanges();
|
await page.waitForChanges();
|
||||||
|
|
||||||
const disabledItem = page.locator('ion-picker-column-internal .picker-item[data-value="b"]');
|
const disabledItem = page.locator('ion-picker-column-internal .picker-item[data-value="b"]');
|
||||||
expect(disabledItem).toHaveClass(/picker-item-disabled/);
|
await expect(disabledItem).toHaveClass(/picker-item-disabled/);
|
||||||
expect(disabledItem).not.toHaveClass(/picker-item-active/);
|
await expect(disabledItem).not.toHaveClass(/picker-item-active/);
|
||||||
});
|
});
|
||||||
test('defaulting the value to a disabled item should not cause that item to be active', async ({ page }) => {
|
test('defaulting the value to a disabled item should not cause that item to be active', async ({ page }) => {
|
||||||
await page.setContent(`
|
await page.setContent(`
|
||||||
@ -124,7 +124,7 @@ test.describe('picker-column-internal: disabled', () => {
|
|||||||
`);
|
`);
|
||||||
|
|
||||||
const disabledItem = page.locator('ion-picker-column-internal .picker-item[data-value="b"]');
|
const disabledItem = page.locator('ion-picker-column-internal .picker-item[data-value="b"]');
|
||||||
expect(disabledItem).toHaveClass(/picker-item-disabled/);
|
await expect(disabledItem).toHaveClass(/picker-item-disabled/);
|
||||||
expect(disabledItem).not.toHaveClass(/picker-item-active/);
|
await expect(disabledItem).not.toHaveClass(/picker-item-active/);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -47,13 +47,13 @@ test.describe('picker-internal', () => {
|
|||||||
|
|
||||||
// Focus first column
|
// Focus first column
|
||||||
await page.keyboard.press('Tab');
|
await page.keyboard.press('Tab');
|
||||||
expect(firstColumn).toBeFocused();
|
await expect(firstColumn).toBeFocused();
|
||||||
|
|
||||||
await page.waitForChanges();
|
await page.waitForChanges();
|
||||||
|
|
||||||
// Focus second column
|
// Focus second column
|
||||||
await page.keyboard.press('Tab');
|
await page.keyboard.press('Tab');
|
||||||
expect(secondColumn).toBeFocused();
|
await expect(secondColumn).toBeFocused();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('tabbing should correctly move focus back', async ({ page }) => {
|
test('tabbing should correctly move focus back', async ({ page }) => {
|
||||||
@ -61,13 +61,13 @@ test.describe('picker-internal', () => {
|
|||||||
const secondColumn = page.locator('ion-picker-column-internal#second');
|
const secondColumn = page.locator('ion-picker-column-internal#second');
|
||||||
|
|
||||||
await secondColumn.focus();
|
await secondColumn.focus();
|
||||||
expect(secondColumn).toBeFocused();
|
await expect(secondColumn).toBeFocused();
|
||||||
|
|
||||||
await page.waitForChanges();
|
await page.waitForChanges();
|
||||||
|
|
||||||
// Focus first column
|
// Focus first column
|
||||||
await page.keyboard.press('Shift+Tab');
|
await page.keyboard.press('Shift+Tab');
|
||||||
expect(firstColumn).toBeFocused();
|
await expect(firstColumn).toBeFocused();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -24,7 +24,7 @@ test.describe('radio-group', () => {
|
|||||||
expect(radio).toBeHidden();
|
expect(radio).toBeHidden();
|
||||||
|
|
||||||
// ensure radio group has the same value
|
// ensure radio group has the same value
|
||||||
expect(radioGroup).toHaveJSProperty('value', 'two');
|
await expect(radioGroup).toHaveJSProperty('value', 'two');
|
||||||
|
|
||||||
// clear the search so the radio appears
|
// clear the search so the radio appears
|
||||||
await page.fill('ion-searchbar input', '');
|
await page.fill('ion-searchbar input', '');
|
||||||
|
@ -12,6 +12,7 @@ test.describe('range: basic', () => {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* The mouse events are flaky on CI
|
* The mouse events are flaky on CI
|
||||||
|
* TODO FW-2873
|
||||||
*/
|
*/
|
||||||
test.fixme('should emit start/end events', async ({ page }, testInfo) => {
|
test.fixme('should emit start/end events', async ({ page }, testInfo) => {
|
||||||
await page.setContent(`<ion-range value="20"></ion-range>`);
|
await page.setContent(`<ion-range value="20"></ion-range>`);
|
||||||
@ -57,7 +58,8 @@ 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, skip }) => {
|
// TODO FW-2873
|
||||||
|
test.skip('should not scroll when the knob is swiped', async ({ page, skip }) => {
|
||||||
skip.browser('webkit', 'mouse.wheel is not available in WebKit');
|
skip.browser('webkit', 'mouse.wheel is not available in WebKit');
|
||||||
skip.rtl();
|
skip.rtl();
|
||||||
|
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
import { expect } from '@playwright/test';
|
import { expect } from '@playwright/test';
|
||||||
import { test } from '@utils/test/playwright';
|
import { test } from '@utils/test/playwright';
|
||||||
|
|
||||||
test.describe('range: scroll-target', () => {
|
// TODO FW-2873
|
||||||
|
test.describe.skip('range: scroll-target', () => {
|
||||||
test('should not scroll when the knob is swiped in custom scroll target', async ({ page, skip }) => {
|
test('should not scroll when the knob is swiped in custom scroll target', async ({ page, skip }) => {
|
||||||
skip.browser('webkit', 'mouse.wheel is not available in WebKit');
|
skip.browser('webkit', 'mouse.wheel is not available in WebKit');
|
||||||
skip.rtl();
|
skip.rtl();
|
||||||
|
@ -1,28 +1,11 @@
|
|||||||
import { expect } from '@playwright/test';
|
import { expect } from '@playwright/test';
|
||||||
import { test } from '@utils/test/playwright';
|
import { test } from '@utils/test/playwright';
|
||||||
|
|
||||||
test.describe('searchbar: basic', () => {
|
test.describe('searchbar: cancel button', () => {
|
||||||
test.beforeEach(async ({ page }) => {
|
test.beforeEach(async ({ page }) => {
|
||||||
await page.goto(`/src/components/searchbar/test/basic`);
|
await page.goto(`/src/components/searchbar/test/basic`);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should not have visual regressions', async ({ page }) => {
|
|
||||||
await page.setIonViewport();
|
|
||||||
/**
|
|
||||||
* The searchbar test template is rendering an ion-searchbar
|
|
||||||
* that is animated. This requires the searchbar to render,
|
|
||||||
* before the cancel button can be positioned correctly.
|
|
||||||
*
|
|
||||||
* We wait for changes to ensure the searchbar has rendered
|
|
||||||
* correctly before capturing the screenshot.
|
|
||||||
*/
|
|
||||||
await page.waitForChanges();
|
|
||||||
|
|
||||||
expect(await page.screenshot({ animations: 'disabled' })).toMatchSnapshot(
|
|
||||||
`searchbar-diff-${page.getSnapshotSettings()}.png`
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
test('should show cancel button on focus if show-cancel-button=focus', async ({ page }) => {
|
test('should show cancel button on focus if show-cancel-button=focus', async ({ page }) => {
|
||||||
const searchbar = page.locator('#basic');
|
const searchbar = page.locator('#basic');
|
||||||
const cancelButton = searchbar.locator('.searchbar-cancel-button');
|
const cancelButton = searchbar.locator('.searchbar-cancel-button');
|
||||||
@ -89,3 +72,76 @@ test.describe('searchbar: clear button', () => {
|
|||||||
await expect(nativeInput).toBeFocused();
|
await expect(nativeInput).toBeFocused();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test.describe('searchbar: rendering', () => {
|
||||||
|
test('should render searchbar', async ({ page }) => {
|
||||||
|
await page.setContent(`
|
||||||
|
<ion-searchbar></ion-searchbar>
|
||||||
|
`);
|
||||||
|
|
||||||
|
const searchbar = page.locator('ion-searchbar');
|
||||||
|
|
||||||
|
expect(await searchbar.screenshot()).toMatchSnapshot(`searchbar-${page.getSnapshotSettings()}.png`);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should render cancel and clear buttons', async ({ page }) => {
|
||||||
|
await page.setContent(`
|
||||||
|
<ion-searchbar show-cancel-button="always" show-clear-button="always"></ion-searchbar>
|
||||||
|
`);
|
||||||
|
|
||||||
|
const searchbar = page.locator('ion-searchbar');
|
||||||
|
|
||||||
|
expect(await searchbar.screenshot()).toMatchSnapshot(`searchbar-buttons-${page.getSnapshotSettings()}.png`);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should render searchbar with color', async ({ page, skip }) => {
|
||||||
|
skip.rtl();
|
||||||
|
|
||||||
|
await page.setContent(`
|
||||||
|
<ion-searchbar color="danger" show-cancel-button="always" show-clear-button="always"></ion-searchbar>
|
||||||
|
`);
|
||||||
|
|
||||||
|
const searchbar = page.locator('ion-searchbar');
|
||||||
|
|
||||||
|
expect(await searchbar.screenshot()).toMatchSnapshot(`searchbar-color-${page.getSnapshotSettings()}.png`);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should render disabled searchbar', async ({ page, skip }) => {
|
||||||
|
skip.rtl();
|
||||||
|
|
||||||
|
await page.setContent(`
|
||||||
|
<ion-searchbar disabled="true"></ion-searchbar>
|
||||||
|
`);
|
||||||
|
|
||||||
|
const searchbar = page.locator('ion-searchbar');
|
||||||
|
|
||||||
|
expect(await searchbar.screenshot()).toMatchSnapshot(`searchbar-disabled-${page.getSnapshotSettings()}.png`);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should render custom search icon', async ({ page, skip }) => {
|
||||||
|
skip.rtl();
|
||||||
|
|
||||||
|
await page.setContent(`
|
||||||
|
<ion-searchbar search-icon="home"></ion-searchbar>
|
||||||
|
`);
|
||||||
|
|
||||||
|
const icon = page.locator('ion-searchbar ion-icon.searchbar-search-icon');
|
||||||
|
|
||||||
|
expect(await icon.screenshot()).toMatchSnapshot(`searchbar-search-icon-${page.getSnapshotSettings()}.png`);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test.describe('searchbar: placeholder', () => {
|
||||||
|
test.beforeEach(({ skip }) => {
|
||||||
|
skip.rtl();
|
||||||
|
skip.mode('ios');
|
||||||
|
});
|
||||||
|
test('should set placeholder', async ({ page }) => {
|
||||||
|
await page.setContent(`
|
||||||
|
<ion-searchbar placeholder="My Placeholder"></ion-searchbar>
|
||||||
|
`);
|
||||||
|
|
||||||
|
const nativeInput = page.locator('ion-searchbar input');
|
||||||
|
await expect(nativeInput).toHaveAttribute('placeholder', 'My Placeholder');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
After Width: | Height: | Size: 11 KiB |
After Width: | Height: | Size: 3.7 KiB |
After Width: | Height: | Size: 11 KiB |
After Width: | Height: | Size: 11 KiB |
After Width: | Height: | Size: 3.6 KiB |
After Width: | Height: | Size: 11 KiB |
After Width: | Height: | Size: 6.8 KiB |
After Width: | Height: | Size: 2.4 KiB |
After Width: | Height: | Size: 6.7 KiB |
After Width: | Height: | Size: 6.8 KiB |
After Width: | Height: | Size: 2.5 KiB |
After Width: | Height: | Size: 6.7 KiB |
After Width: | Height: | Size: 11 KiB |
After Width: | Height: | Size: 3.9 KiB |
After Width: | Height: | Size: 12 KiB |
After Width: | Height: | Size: 6.6 KiB |
After Width: | Height: | Size: 2.7 KiB |
After Width: | Height: | Size: 6.6 KiB |
Before Width: | Height: | Size: 365 KiB |
Before Width: | Height: | Size: 136 KiB |
Before Width: | Height: | Size: 362 KiB |
Before Width: | Height: | Size: 362 KiB |
Before Width: | Height: | Size: 135 KiB |
Before Width: | Height: | Size: 360 KiB |
Before Width: | Height: | Size: 335 KiB |
Before Width: | Height: | Size: 127 KiB |
Before Width: | Height: | Size: 329 KiB |
Before Width: | Height: | Size: 333 KiB |
Before Width: | Height: | Size: 127 KiB |
Before Width: | Height: | Size: 328 KiB |
After Width: | Height: | Size: 6.5 KiB |
After Width: | Height: | Size: 2.2 KiB |
After Width: | Height: | Size: 6.6 KiB |
After Width: | Height: | Size: 6.3 KiB |
After Width: | Height: | Size: 2.3 KiB |
After Width: | Height: | Size: 6.4 KiB |
After Width: | Height: | Size: 7.7 KiB |
After Width: | Height: | Size: 2.5 KiB |
After Width: | Height: | Size: 7.8 KiB |
After Width: | Height: | Size: 7.6 KiB |
After Width: | Height: | Size: 2.5 KiB |
After Width: | Height: | Size: 7.8 KiB |
After Width: | Height: | Size: 7.9 KiB |
After Width: | Height: | Size: 2.7 KiB |
After Width: | Height: | Size: 8.0 KiB |
After Width: | Height: | Size: 7.9 KiB |
After Width: | Height: | Size: 2.7 KiB |
After Width: | Height: | Size: 8.0 KiB |
After Width: | Height: | Size: 1.9 KiB |
After Width: | Height: | Size: 645 B |
After Width: | Height: | Size: 2.2 KiB |
After Width: | Height: | Size: 1.6 KiB |
After Width: | Height: | Size: 553 B |
After Width: | Height: | Size: 1.9 KiB |
@ -11,30 +11,20 @@ test.describe('textarea: autogrow', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('should grow when typing', async ({ page }) => {
|
test('should grow when typing', async ({ page }) => {
|
||||||
await page.setContent(
|
await page.setContent(`
|
||||||
`
|
|
||||||
<ion-app>
|
|
||||||
<ion-content>
|
|
||||||
<ion-list>
|
|
||||||
<ion-item>
|
|
||||||
<ion-textarea auto-grow="true"></ion-textarea>
|
<ion-textarea auto-grow="true"></ion-textarea>
|
||||||
</ion-item>
|
`);
|
||||||
</ion-list>
|
|
||||||
</ion-content>
|
const ionTextarea = page.locator('ion-textarea');
|
||||||
</ion-app>`
|
const nativeTextarea = ionTextarea.locator('textarea');
|
||||||
|
|
||||||
|
await nativeTextarea.type('Now, this is a story all about how');
|
||||||
|
|
||||||
|
expect(await ionTextarea.screenshot({})).toMatchSnapshot(
|
||||||
|
`textarea-autogrow-initial-${page.getSnapshotSettings()}.png`
|
||||||
);
|
);
|
||||||
|
|
||||||
const textarea = await page.waitForSelector('ion-textarea');
|
await nativeTextarea.type(
|
||||||
|
|
||||||
await textarea.click();
|
|
||||||
|
|
||||||
await textarea.type('Now, this is a story all about how');
|
|
||||||
|
|
||||||
await page.setIonViewport();
|
|
||||||
|
|
||||||
expect(await textarea.screenshot()).toMatchSnapshot(`textarea-autogrow-initial-${page.getSnapshotSettings()}.png`);
|
|
||||||
|
|
||||||
await textarea.type(
|
|
||||||
[
|
[
|
||||||
`\nMy life got flipped-turned upside down`,
|
`\nMy life got flipped-turned upside down`,
|
||||||
`And I'd like to take a minute`,
|
`And I'd like to take a minute`,
|
||||||
@ -43,7 +33,7 @@ test.describe('textarea: autogrow', () => {
|
|||||||
].join('\n')
|
].join('\n')
|
||||||
);
|
);
|
||||||
|
|
||||||
expect(await textarea.screenshot()).toMatchSnapshot(`textarea-autogrow-after-${page.getSnapshotSettings()}.png`);
|
expect(await ionTextarea.screenshot()).toMatchSnapshot(`textarea-autogrow-after-${page.getSnapshotSettings()}.png`);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should break long lines without white space', async ({ page }) => {
|
test('should break long lines without white space', async ({ page }) => {
|
||||||
@ -53,17 +43,13 @@ test.describe('textarea: autogrow', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
await page.setContent(
|
await page.setContent(
|
||||||
`<ion-app>
|
`<ion-textarea
|
||||||
<ion-content>
|
|
||||||
<ion-textarea
|
|
||||||
auto-grow="true"
|
auto-grow="true"
|
||||||
value="abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz">
|
value="abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz">
|
||||||
</ion-textarea>
|
</ion-textarea>`
|
||||||
</ion-content>
|
|
||||||
</ion-app>`
|
|
||||||
);
|
);
|
||||||
|
|
||||||
const textarea = await page.locator('ion-textarea');
|
const textarea = page.locator('ion-textarea');
|
||||||
|
|
||||||
expect(await textarea.screenshot()).toMatchSnapshot(
|
expect(await textarea.screenshot()).toMatchSnapshot(
|
||||||
`textarea-autogrow-word-break-${page.getSnapshotSettings()}.png`
|
`textarea-autogrow-word-break-${page.getSnapshotSettings()}.png`
|
||||||
|
Before Width: | Height: | Size: 43 KiB After Width: | Height: | Size: 42 KiB |
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 14 KiB |
Before Width: | Height: | Size: 40 KiB After Width: | Height: | Size: 40 KiB |
Before Width: | Height: | Size: 43 KiB After Width: | Height: | Size: 42 KiB |
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 14 KiB |
Before Width: | Height: | Size: 40 KiB After Width: | Height: | Size: 40 KiB |
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 8.7 KiB |
Before Width: | Height: | Size: 3.8 KiB After Width: | Height: | Size: 3.9 KiB |
Before Width: | Height: | Size: 8.1 KiB After Width: | Height: | Size: 8.2 KiB |
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 8.7 KiB |
Before Width: | Height: | Size: 3.7 KiB After Width: | Height: | Size: 3.8 KiB |
Before Width: | Height: | Size: 8.1 KiB After Width: | Height: | Size: 8.2 KiB |
@ -1,6 +1,12 @@
|
|||||||
|
import { expect } from '@playwright/test';
|
||||||
import { test } from '@utils/test/playwright';
|
import { test } from '@utils/test/playwright';
|
||||||
|
|
||||||
test.describe('tap click utility', () => {
|
// TODO FW-3010
|
||||||
|
test.describe.skip('tap click utility', () => {
|
||||||
|
test.beforeEach(({ skip }) => {
|
||||||
|
skip.rtl();
|
||||||
|
skip.mode('ios');
|
||||||
|
});
|
||||||
test('it should apply activated class when clicking element', async ({ page }) => {
|
test('it should apply activated class when clicking element', async ({ page }) => {
|
||||||
await page.setContent(`
|
await page.setContent(`
|
||||||
<ion-app>
|
<ion-app>
|
||||||
@ -14,8 +20,9 @@ test.describe('tap click utility', () => {
|
|||||||
if (box) {
|
if (box) {
|
||||||
await page.mouse.move(box.x + box.width / 2, box.y + box.height / 2);
|
await page.mouse.move(box.x + box.width / 2, box.y + box.height / 2);
|
||||||
await page.mouse.down();
|
await page.mouse.down();
|
||||||
|
await page.waitForChanges();
|
||||||
}
|
}
|
||||||
|
|
||||||
await page.waitForSelector('button.ion-activated');
|
await expect(button).toHaveClass(/ion-activated/);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -108,29 +108,6 @@ test.describe('overlays: focus', () => {
|
|||||||
test.beforeEach(({ skip }) => {
|
test.beforeEach(({ skip }) => {
|
||||||
skip.rtl();
|
skip.rtl();
|
||||||
});
|
});
|
||||||
test('should not focus the overlay container if element inside of overlay is focused', async ({ page }) => {
|
|
||||||
await page.setContent(`
|
|
||||||
<ion-button id="open-modal">Show Modal</ion-button>
|
|
||||||
<ion-modal trigger="open-modal">
|
|
||||||
<ion-content>
|
|
||||||
<ion-input autofocus="true"></ion-input>
|
|
||||||
</ion-content>
|
|
||||||
</ion-modal>
|
|
||||||
`);
|
|
||||||
|
|
||||||
const ionModalDidPresent = await page.spyOnEvent('ionModalDidPresent');
|
|
||||||
const button = page.locator('ion-button');
|
|
||||||
const input = page.locator('ion-input');
|
|
||||||
|
|
||||||
await button.click();
|
|
||||||
await input.evaluate((el: HTMLIonInputElement) => el.setFocus());
|
|
||||||
|
|
||||||
await ionModalDidPresent.next();
|
|
||||||
await page.waitForChanges();
|
|
||||||
|
|
||||||
await expect(page.locator('ion-input input')).toBeFocused();
|
|
||||||
});
|
|
||||||
|
|
||||||
test('should not select a hidden focusable element', async ({ page, browserName }) => {
|
test('should not select a hidden focusable element', async ({ page, browserName }) => {
|
||||||
await page.setContent(`
|
await page.setContent(`
|
||||||
<style>
|
<style>
|
||||||
|