chore(): sync with main

This commit is contained in:
Liam DeBeasi
2022-09-16 15:24:24 -04:00
759 changed files with 13280 additions and 7837 deletions

View File

@@ -2,9 +2,10 @@ import { expect } from '@playwright/test';
import { test } from '@utils/test/playwright';
test.describe('overlays: focus', () => {
test('should not focus the overlay container if element inside of overlay is focused', async ({ page, skip }) => {
test.beforeEach(({ skip }) => {
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">
@@ -26,4 +27,93 @@ test.describe('overlays: focus', () => {
await expect(page.locator('ion-input input')).toBeFocused();
});
test('should not select a hidden focusable element', async ({ page, browserName }) => {
await page.setContent(`
<style>
[hidden] {
display: none;
}
</style>
<ion-button id="open-modal">Show Modal</ion-button>
<ion-modal trigger="open-modal">
<ion-content>
<ion-button hidden id="hidden">Hidden Button</ion-button>
<ion-button id="visible">Visible Button</ion-button>
</ion-content>
</ion-modal>
`);
const ionModalDidPresent = await page.spyOnEvent('ionModalDidPresent');
const presentButton = page.locator('ion-button#open-modal');
const visibleButton = page.locator('ion-button#visible');
const tabKey = browserName === 'webkit' ? 'Alt+Tab' : 'Tab';
await presentButton.click();
await ionModalDidPresent.next();
await page.keyboard.press(tabKey);
await expect(visibleButton).toBeFocused();
await page.keyboard.press(tabKey);
await expect(visibleButton).toBeFocused();
});
test('should not select a disabled focusable element', async ({ page, browserName }) => {
await page.setContent(`
<ion-button id="open-modal">Show Modal</ion-button>
<ion-modal trigger="open-modal">
<ion-content>
<ion-button disabled="true" id="disabled">Button</ion-button>
<ion-button id="active">Active Button</ion-button>
</ion-content>
</ion-modal>
`);
const ionModalDidPresent = await page.spyOnEvent('ionModalDidPresent');
const presentButton = page.locator('ion-button#open-modal');
const activeButton = page.locator('ion-button#active');
const tabKey = browserName === 'webkit' ? 'Alt+Tab' : 'Tab';
await presentButton.click();
await ionModalDidPresent.next();
await page.keyboard.press(tabKey);
await expect(activeButton).toBeFocused();
await page.keyboard.press(tabKey);
await expect(activeButton).toBeFocused();
});
test('should select a focusable element with disabled="false"', async ({ page, browserName }) => {
await page.setContent(`
<ion-button id="open-modal">Show Modal</ion-button>
<ion-modal trigger="open-modal">
<ion-content>
<ion-button disabled="false" id="disabled-false">Button</ion-button>
<ion-button id="active">Active Button</ion-button>
</ion-content>
</ion-modal>
`);
const ionModalDidPresent = await page.spyOnEvent('ionModalDidPresent');
const presentButton = page.locator('ion-button#open-modal');
const disabledFalseButton = page.locator('ion-button#disabled-false');
const activeButton = page.locator('ion-button#active');
const tabKey = browserName === 'webkit' ? 'Alt+Tab' : 'Tab';
await presentButton.click();
await ionModalDidPresent.next();
await page.keyboard.press(tabKey);
await expect(disabledFalseButton).toBeFocused();
await page.keyboard.press(tabKey);
await expect(activeButton).toBeFocused();
// Loop back to beginning of overlay
await page.keyboard.press(tabKey);
await expect(disabledFalseButton).toBeFocused();
});
});

View File

@@ -1,7 +1,9 @@
import { toHaveReceivedEvent } from './toHaveReceivedEvent';
import { toHaveReceivedEventDetail } from './toHaveReceivedEventDetail';
import { toHaveReceivedEventTimes } from './toHaveReceivedEventTimes';
export const matchers = {
toHaveReceivedEvent,
toHaveReceivedEventDetail,
toHaveReceivedEventTimes,
};

View File

@@ -0,0 +1,33 @@
import type { EventSpy } from '../page/event-spy';
export function toHaveReceivedEventTimes(eventSpy: EventSpy, count: number) {
if (!eventSpy) {
return {
message: () => `toHaveReceivedEventTimes event spy is null`,
pass: false,
};
}
if (typeof (eventSpy as any).then === 'function') {
return {
message: () =>
`expected spy to have received event, but it was not resolved (did you forget an await operator?).`,
pass: false,
};
}
if (!eventSpy.eventName) {
return {
message: () => `toHaveReceivedEventTimes did not receive an event spy`,
pass: false,
};
}
const pass = eventSpy.length === count;
return {
message: () =>
`expected event "${eventSpy.eventName}" to have been called ${count} times, but it was called ${eventSpy.events.length} times`,
pass: pass,
};
}

View File

@@ -33,6 +33,12 @@ export const waitForChanges = async (page: Page, timeoutMs = 100) => {
const childElm = children[i];
const childStencilElm = childElm as HostElement;
if (childElm.tagName.includes('-') && typeof childStencilElm.componentOnReady === 'function') {
/**
* We are only using the lazy loaded bundle
* here so we can safely use the
* componentOnReady method.
*/
// eslint-disable-next-line custom-rules/no-component-on-ready-method
promises.push(childStencilElm.componentOnReady());
}
waitComponentOnReady(childElm, promises);

View File

@@ -8,6 +8,11 @@ interface CustomMatchers<R = unknown> {
* @param eventDetail The expected detail of the event.
*/
toHaveReceivedEventDetail(eventDetail: any): R;
/**
* Will check how many times the event has been received.
*/
toHaveReceivedEventTimes(count: number): R;
}
declare namespace PlaywrightTest {