Merge branch 'main' into chore-update-next-from-main

This commit is contained in:
Brandy Carney
2024-05-02 16:43:54 -04:00
876 changed files with 4034 additions and 2766 deletions

View File

@@ -153,9 +153,6 @@ The focused state should be enabled for elements with actions when tabbed to via
> [!WARNING]
> Do not use `:focus` because that will cause the focus to apply even when an element is tapped (because the element is now focused). Instead, we only want the focus state to be shown when it makes sense which is what the `.ion-focusable` utility mentioned below does.
> [!NOTE]
> The [`:focus-visible`](https://developer.mozilla.org/en-US/docs/Web/CSS/:focus-visible) pseudo-class mostly does the same thing as our JavaScript-driven utility. However, it does not work well with Shadow DOM components as the element that receives focus is typically inside of the Shadow DOM, but we usually want to set the `:focus-visible` state on the host so we can style other parts of the component. Using other combinations such as `:has(:focus-visible)` does not work because `:has` does not pierce the Shadow DOM (as that would leak implementation details about the Shadow DOM contents). `:focus-within` does work with the Shadow DOM, but that has the same problem as `:focus` that was mentioned before. Unfortunately, a [`:focus-visible-within` pseudo-class does not exist yet](https://github.com/WICG/focus-visible/issues/151).
> [!IMPORTANT]
> Make sure the component has the correct [component structure](#component-structure) before continuing.
@@ -216,6 +213,15 @@ ion-button {
}
```
#### When to use `.ion-focusable` versus `:focus-visible`
The [`:focus-visible`](https://developer.mozilla.org/en-US/docs/Web/CSS/:focus-visible) pseudo-class mostly does the same thing as our JavaScript-driven utility. However, it does not work well with Shadow DOM components as the element that receives focus is typically inside of the Shadow DOM, but we usually want to set the `:focus-visible` state on the host so we can style other parts of the component.
Using other combinations such as `:has(:focus-visible)` does not work because `:has` does not pierce the Shadow DOM (as that would leak implementation details about the Shadow DOM contents). `:focus-within` does work with the Shadow DOM, but that has the same problem as `:focus` that was mentioned before. Unfortunately, a [`:focus-visible-within` pseudo-class does not exist yet](https://github.com/WICG/focus-visible/issues/151).
The `.ion-focusable` class should be used when you want to style Element A based on the state of Element B. For example, the Button component styles the host of the component (Element A) when the native `button` inside the Shadow DOM (Element B) has focus.
On the other hand, the `:focus-visible` pseudo-class can be used when you want to style the element based on its own state. For example, we could use `:focus-visible` to style the clear icon on Input when the icon itself is focused.
### Hover

View File

@@ -174,6 +174,19 @@ configs().forEach(({ config, title }) => {
});
```
#### `spyOnEvent` with Locators
Locators have been updated with a `spyOnEvent` method which allows you to listen for an event on the element that the locator matches. Note that Playwright does not support changing the type of an existing fixture, so Locators that use `spyOnEvent` need to be manually cast as `E2ELocator`:
```typescript
import type { E2ELocator } from '@utils/test/playwright';
...
const alert = page.locator('ion-alert') as E2ELocator;
const ionAlertDidPresent = await alert.spyOnEvent('ionAlertDidPresent');
```
### Using `setIonViewport`
`setIonViewport` is only needed when a) you are using `ion-content` and b) you need to take a screenshot of the full page (including content that may overflow offscreen).

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

View File

@@ -19,6 +19,7 @@ This guide details best practices that should be followed when writing E2E tests
- [Start your test with the configuration or layout in place if possible](#practice-test-config)
- [Place your test closest to the fix or feature](#practice-test-close)
- [Account for different locales when writing tests](#practice-locales)
- [Avoid using unrelated components in other component's screenshot tests](#unrelated-components)
<h2 id="practice-test">Use the customized `test` function</h2>
@@ -51,7 +52,7 @@ Some features can be combined together, and so it is acceptable in this instance
<h2 id="practice-file-format">Follow the file format</h2>
E2E test files should follow this format:
E2E test files should follow this format:
```tsx
[component name].e2e.ts
@@ -140,7 +141,7 @@ test.describe('button: disabled state', () => {
test.beforeEach(async ({ page }) => {
await page.goto('/src/components/button/test', config);
});
test(title('should not have any visual regressions'), async ({ page }) => {
...
});
@@ -163,7 +164,7 @@ configs().forEach(({ config, title }) => {
test.beforeEach(async ({ page }) => {
await page.goto('/src/components/button/test', config);
});
/**
* Test title is still unique because of our use of title()
* on the test.describe block.
@@ -174,6 +175,7 @@ configs().forEach(({ config, title }) => {
});
});
```
<h2 id="practice-describe-type">Test rendering and functionality in separate `test.describe` blocks</h2>
Avoid mixing tests that take screenshots with tests that check functionality. These types of tests often have different requirements that can make a single `test.describe` block hard to understand. For example, a screenshot test might check both iOS and MD modes with LTR and RTL text directions, but a functionality test may not need that if the functionality is consistent across modes and directions.
@@ -190,7 +192,7 @@ By default, we run tests on mobile viewports only (think iPhone sized viewports)
For this scenario, developers must write tests that target the tablet viewport. This can be done by using [page.setViewportSize](https://playwright.dev/docs/api/class-page#page-set-viewport-size). The Playwright test utils directory also contains a `Viewports` constant which contains some common viewport presets. Developers should feel free to add new viewports to this as is applicable.
**Example:**
**Example:**
```javascript
import { configs, test, Viewports } from '@utils/test/playwright';
@@ -206,7 +208,7 @@ configs().forEach(({ config, title }) => {
});
});
});
````
```
<h2 id="practice-screenshot-functionality">Avoid using screenshots as a way of verifying functionality</h2>
@@ -221,12 +223,12 @@ configs().forEach(({ config, title }) => {
test.describe(title('modal: rendering') => {
test('it should open a modal', async ({ page }) => {
await page.setContent('<ion-modal is-open="true">...</ion-modal>', config);
await expect(page).toHaveScreenshot(screenshot('modal-open'));
});
});
});
````
```
✅ Correct
@@ -237,13 +239,13 @@ configs().forEach(({ config, title }) => {
test.describe(title('modal: rendering') => {
test('it should open a modal', async ({ page }) => {
await page.setContent('<ion-modal is-open="true">...</ion-modal>', config);
const modal = page.locator('ion-modal');
await expect(modal).toBeVisible();
});
});
});
````
```
<h2 id="practice-test-computed">Avoid tests that compare computed values</h2>
@@ -264,3 +266,11 @@ Tests should be placed closest to where the fix or feature was implemented. This
<h2 id="practice-locales">Account for different locales when writing tests</h2>
Tests ran on CI may not run on the same locale as your local machine. It's always a good idea to apply locale considerations to components that support it, when writing tests (i.e. `ion-datetime` should specify `locale="en-US"`).
<h2 id="unrelated-components">Avoid using unrelated components in other component's screenshot tests</h2>
Tests should be focused only on the component(s) they are testing. When unrelated components are included in a test that captures a screenshot, any changes to the style of those unrelated components will trigger updates in all tests for the component(s) using them. If you need to include a styled button in a test, add a native `<button>` within an `ion-content` or `main` element. It can be modified to take up the full width of its container by adding the `expand` class:
```html
<button class="expand">Full width button</button>
```

View File

@@ -115,7 +115,7 @@ While `npm run test.e2e` can be used to run tests in the same environment that y
This command builds a Docker image before tests run. It will also re-build the Docker image in the event that a Playwright update was merged into the repo.
Note that the Playwright report will not automatically open in your web browser when tests are complete because the tests were run in Docker. Run `npm run test.report` outside of Docker to open the most recent test report.
Note that the Playwright report will not automatically open in your web browser when tests are complete because the tests were run in Docker. Run `npx playwright show-report` outside of Docker to open the most recent test report.
> [!NOTE]
> Additional setup is needed to run Playwright tests with headed mode in Docker. See [Configuring Docker for Headed Tests](#configuring-docker-for-headed-tests-optional) for more information.