Skip to content

Commit

Permalink
Merge changes published in the Gutenberg plugin "release/15.0" branch
Browse files Browse the repository at this point in the history
  • Loading branch information
gutenbergplugin committed Jan 11, 2023
1 parent 200bee7 commit 880a619
Show file tree
Hide file tree
Showing 303 changed files with 6,819 additions and 3,299 deletions.
1 change: 1 addition & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ const restrictedImports = [
'partial',
'partialRight',
'pick',
'pickBy',
'random',
'reduce',
'reject',
Expand Down
3 changes: 0 additions & 3 deletions .github/ISSUE_TEMPLATE/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,3 @@ contact_links:
- name: Technical help request
url: https://wordpress.org/support/forum/wp-advanced/
about: For more technical help requests, create a new topic in the Developing with WordPress Forum
- name: Development help request
url: https://wordpress.stackexchange.com/
about: For questions about WordPress development, ask a question in the WordPress Development Stack Exchange
2 changes: 1 addition & 1 deletion .github/workflows/pull-request-automation.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ jobs:
node-version: ${{ matrix.node }}

- name: Cache NPM packages
uses: actions/cache@9b0c1fce7a93df8e3bb8926b0d6e9d89e92f20a7 # v3.0.11
uses: actions/cache@4723a57e26efda3a62cbde1812113b730952852d # v3.2.2
with:
# npm cache files are stored in `~/.npm` on Linux/macOS
path: ~/.npm
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/rnmobile-android-runner.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ jobs:
uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 # v3.1.0

- name: Use desired version of Java
uses: actions/setup-java@de1bb2b0c5634f0fc4438d7aa9944e68f9bf86cc # v3.6.0
uses: actions/setup-java@1df8dbefe2a8cbc99770194893dd902763bee34b # v3.9.0
with:
distribution: 'temurin'
java-version: '11'
Expand All @@ -43,7 +43,7 @@ jobs:
uses: gradle/gradle-build-action@3fbe033aaae657f011f88f29be9e65ed26bd29ef # v2.3.3

- name: AVD cache
uses: actions/cache@9b0c1fce7a93df8e3bb8926b0d6e9d89e92f20a7 # v3.0.11
uses: actions/cache@4723a57e26efda3a62cbde1812113b730952852d # v3.2.2
id: avd-cache
with:
path: |
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/rnmobile-ios-runner.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,15 +37,15 @@ jobs:
run: find package-lock.json packages/react-native-editor/ios packages/react-native-aztec/ios packages/react-native-bridge/ios -type f -print0 | sort -z | xargs -0 shasum | tee ios-checksums.txt

- name: Restore build cache
uses: actions/cache@9b0c1fce7a93df8e3bb8926b0d6e9d89e92f20a7 # v3.0.11
uses: actions/cache@4723a57e26efda3a62cbde1812113b730952852d # v3.2.2
with:
path: |
packages/react-native-editor/ios/build/GutenbergDemo/Build/Products/Release-iphonesimulator/GutenbergDemo.app
packages/react-native-editor/ios/build/WDA
key: ${{ runner.os }}-ios-build-${{ matrix.xcode }}-${{ matrix.device }}-${{ hashFiles('ios-checksums.txt') }}

- name: Restore pods cache
uses: actions/cache@9b0c1fce7a93df8e3bb8926b0d6e9d89e92f20a7 # v3.0.11
uses: actions/cache@4723a57e26efda3a62cbde1812113b730952852d # v3.2.2
with:
path: |
packages/react-native-editor/ios/Pods
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/stale-issue-gardening.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ jobs:

steps:
- name: Update issues
uses: actions/stale@5ebf00ea0e4c1561e9b43a292ed34424fb1d4578 # v6.0.1
uses: actions/stale@6f05e4244c9a0b2ed3401882b05d701dd0a7289b # v7.0.0
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
stale-issue-message: ${{ matrix.message }}
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/storybook-pages.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ jobs:
run: npm run storybook:build

- name: Deploy
uses: peaceiris/actions-gh-pages@de7ea6f8efb354206b205ef54722213d99067935 # v3.9.0
uses: peaceiris/actions-gh-pages@64b46b4226a4a12da2239ba3ea5aa73e3163c75b # v3.9.1
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./storybook/build
Expand Down
2 changes: 1 addition & 1 deletion LICENSE.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
## Gutenberg

Copyright 2016-2022 by the contributors
Copyright 2016-2023 by the contributors

**License for Contributions (on and after April 15, 2021)**

Expand Down
525 changes: 525 additions & 0 deletions changelog.txt

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/contributors/accessibility-testing.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ According to the [WebAIM: Screen Reader User Survey #8 Results](https://webaim.o
| NVDA with Internet Explorer | 14 | 1.2% |
| Other combinations | 126 | 10.4% |

When testing with screen readers, try to use some of the combinations at the top of this list. For example, when testing with VoiceOver, it's preferrable to use Safari.
When testing with screen readers, try to use some of the combinations at the top of this list. For example, when testing with VoiceOver, it's preferable to use Safari.

### NVDA with Firefox

Expand Down
13 changes: 10 additions & 3 deletions test/e2e/MIGRATION.md → docs/contributors/code/e2e/MIGRATION.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# Migration guide

This document outlines a typical flow of migrating a Jest + Puppeteer test to Playwright. Note that the migration process is also a good opportunity to refactor or rewrite parts of the tests. Please read the [best practices](https://github.com/WordPress/gutenberg/tree/HEAD/docs/contributors/code/e2e/README.md#best-practices) guide before starting the migration.

## Migration steps for tests

1. Choose a test suite to migrate in `packages/e2e-tests/specs`, rename `.test.js` into `.spec.js` and put it in the same folder structure inside `test/e2e/specs`.
Expand All @@ -24,12 +26,17 @@
},
} );
```
7. If there's a missing util, go ahead and [migrate it](#migration-steps-for-test-utils).
8. Manually migrate other details in the tests following the proposed [best practices](https://github.com/WordPress/gutenberg/tree/HEAD/test/e2e/README.md#best-practices). Note that even though the differences in the API of Playwright and Puppeteer are similar, some manual changes are still required.
7. If there's a missing util, try to inline the operations directly in the test if there are only a few steps. If you think it deserves to be implemented as a test util, then follow the [guide](#migration-steps-for-test-utils) below.
8. Manually migrate other details in the tests following the proposed [best practices](https://github.com/WordPress/gutenberg/tree/HEAD/docs/contributors/code/e2e/README.md#best-practices). Note that even though the differences in the API of Playwright and Puppeteer are similar, some manual changes are still required.
## Migration steps for test utils
Playwright utilities are organized a little differently to those in the `e2e-test-utils` package. The `e2e-test-utils-playwright` package has the following folders that utils are divided up into:
Before migrating a test utility function, think twice about whether it's necessary. Playwright offers a lot of readable and powerful APIs which make a lot of the utils obsolete. Try implementing the same thing inline directly in the test first. Only follow the below guide if that doesn't work for you. Some examples of utils that deserve to be implemented in the `e2e-test-utils-playwright` package include complex browser APIs (like `pageUtils.dragFiles` and `pageUtils.pressKeyWithModifier`) and APIs that set states (`requestUtils.*`).
> **Note**
> The `e2e-test-utils-playwright` package is not meant to be a drop-in replacement of the Jest + Puppeteer's `e2e-test-utils` package. Some utils are only created to ease the migration process, but they are not necessarily required.

Playwright utilities are organized a little differently from those in the `e2e-test-utils` package. The `e2e-test-utils-playwright` package has the following folders that utils are divided up into:
- `admin` - Utilities related to WordPress admin or WordPress admin's user interface (e.g. `visitAdminPage`).
- `editor` - Utilities for the block editor (e.g. `clickBlockToolbarButton`).
- `pageUtils` - General utilities for interacting with the browser (e.g. `pressKeyWithModifier`).
Expand Down
131 changes: 131 additions & 0 deletions docs/contributors/code/e2e/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
# End-to-End Testing

This living document serves to prescribe instructions and best practices for writing end-to-end (E2E) tests with Playwright in the Gutenberg project.

> **Note**
> See the dedicated guide if you're working with the previous Jest + Puppeteer framework. See the [migration guide](https://github.com/WordPress/gutenberg/tree/HEAD/docs/contributors/code/e2e/MIGRATION.md) if you're migrating tests from Jest + Puppeteer.
## Running tests

```bash
# Run all available tests.
npm run test:e2e:playwright

# Run in headed mode.
npm run test:e2e:playwright -- --headed

# Run tests with specific browsers (`chromium`, `firefox`, or `webkit`).
npm run test:e2e:playwright -- --project=webkit --project=firefox

# Run a single test file.
npm run test:e2e:playwright -- <path_to_test_file> # E.g., npm run test:e2e:playwright -- site-editor/title.spec.js

# Debugging.
npm run test:e2e:playwright -- --debug
```

If you're developing in Linux, it currently requires testing Webkit browsers in headed mode. If you don't want to or can't run it with the GUI (e.g. if you don't have a graphic interface), prepend the command with [`xvfb-run`](https://manpages.ubuntu.com/manpages/xenial/man1/xvfb-run.1.html) to run it in a virtual environment.

```bash
# Run all available tests.
xvfb-run npm run test:e2e:playwright

# Only run webkit tests.
xvfb-run -- npm run test:e2e:playwright -- --project=webkit
```

## Best practices

<details>
<summary><h3>Forbid `$`, use `locator` instead</h3></summary>

In fact, any API that returns `ElementHandle` is [discouraged](https://playwright.dev/docs/api/class-page#page-query-selector). This includes `$`, `$$`, `$eval`, `$$eval`, etc. [`Locator`](https://playwright.dev/docs/api/class-locator) is a much better API and can be used with playwright's [assertions](https://playwright.dev/docs/api/class-locatorassertions). This also works great with Page Object Model since that locator is lazy and doesn't return a promise.
</details>

<details>
<summary><h3>Use accessible selectors</h3></summary>

Use the selector engine [role-selector](https://playwright.dev/docs/selectors#role-selector) to construct the query wherever possible. It enables us to write accessible queries without having to rely on internal implementations. The syntax should be straightforward and looks like this:

```js
// Select a button with the accessible name "Hello World" (case-insensitive).
page.locator( 'role=button[name="Hello World"i]' );

// Using short-form API, the `name` is case-insensitive by default.
page.getByRole( 'button', { name: 'Hello World' } );
```

It's recommended to append `i` to the name attribute to match it case-insensitively wherever it makes sense. It can also be chained with built-in selector engines to perform complex queries:

```js
// Select a button with a name ends with `Back` and is visible on the screen.
page.locator( 'role=button[name=/Back$/] >> visible=true' );
// Select a button with the (exact) name "View options" under `#some-section`.
page.locator( 'css=#some-section >> role=button[name="View options"]' );
```

See the [official documentation](https://playwright.dev/docs/selectors#role-selector) for more info on how to use them.
</details>

<details>
<summary><h3>Selectors are strict by default</h3></summary>

To encourage better practices for querying elements, selectors are [strict](https://playwright.dev/docs/api/class-browser#browser-new-page-option-strict-selectors) by default, meaning that it will throw an error if the query returns more than one element.
</details>

<details>
<summary><h3>Don't overload test-utils, inline simple utils</h3></summary>

`e2e-test-utils` are too bloated with too many utils. Most of them are simple enough to be inlined directly in tests. With the help of accessible selectors, simple utils are easier to write now. For utils that only take place on a certain page, use Page Object Model instead (with an exception of clearing states with `requestUtils` which are better placed in `e2e-test-utils`). Otherwise, only create an util if the action is complex and repetitive enough.
</details>

<details>
<summary><h3>Favor Page Object Model over utils</h3></summary>

As mentioned above, [Page Object Model](https://playwright.dev/docs/test-pom) is the preferred way to create reusable utility functions on a certain page.

The rationale behind using a POM is to group utils under namespaces to be easier to discover and use. In fact, `PageUtils` in the `e2e-test-utils-playwright` package is also a POM, which avoids the need for global variables, and utils can reference each other with `this`.
</details>

<details>
<summary><h3>Restify actions to clear or set states</h3></summary>

It's slow to set states manually before or after tests, especially when they're repeated multiple times between tests. It's recommended to set them via API calls. Use `requestUtils.rest` and `requestUtils.batchRest` instead to call the [REST API](https://developer.wordpress.org/rest-api/reference/) (and add them to `requestUtils` if needed). We should still add a test for manually setting them, but that should only be tested once.
</details>

<details>
<summary><h3>Avoid global variables</h3></summary>

Previously in our Jest + Puppeteer E2E tests, `page` and `browser` are exposed as global variables. This makes it harder to work with when we have multiple pages/tabs in the same test, or if we want to run multiple tests in parallel. `@playwright/test` has the concept of [fixtures](https://playwright.dev/docs/test-fixtures) which allows us to inject `page`, `browser`, and other parameters into the tests.
</details>

<details>
<summary><h3>Make explicit assertions</h3></summary>

We can insert as many assertions in one test as needed. It's better to make explicit assertions whenever possible. For instance, if we want to assert that a button exists before clicking on it, we can do `expect( locator ).toBeVisible()` before performing `locator.click()`. This makes the tests flow better and easier to read.
</details>

## Common pitfalls

### [Overusing snapshots](https://github.com/WordPress/gutenberg/tree/HEAD/docs/contributors/code/e2e/overusing-snapshots.md)


## Cross-browser testing

By default, tests are only run in chromium. You can _tag_ tests to run them in different browsers. Use `@browser` anywhere in the test title to run it in that browser. Tests will always run in chromium by default, append `-chromium` to disable testing in chromium. Available browsers are `chromium`, `firefox`, and `webkit`.

```js
test( 'I will run in @firefox and @webkit (and chromium by default)', async ( { page } ) => {
// ...
} );

test( 'I will only run in @firefox but not -chromium', async ( { page } ) => {
// ...
} );

test.describe( 'Grouping tests (@webkit, -chromium)', () => {
test( 'I will only run in webkit', async ( { page } ) => {
// ...
} );
} );
```
Loading

0 comments on commit 880a619

Please sign in to comment.