Make WordPress Core

Changeset 65049


Ignore:
Timestamp:
10/30/2026 04:21:43 PM (2 days ago)
Author:
lancewillett
Message:

Build/Test Tools: Run E2E tests in parallel and serial projects.

Split the Playwright suite into parallel and serial projects, running each in a separate CI job for both SCRIPT_DEBUG settings. Keep the default all project on one worker for local runs, and give each CI job a distinct artifact name.

Remove the redundant media-upload login to avoid concurrent writes to shared authentication state. Document how to classify specs and check their execution order.

Developed in: ​https://github.com/WordPress/wordpress-develop/pull/14897

Props adrianmoldovanwp, lucatume.
See #66392.

Location:
trunk
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/.github/workflows/end-to-end-tests.yml

    r63782 r65049  
    8383      matrix:
    8484        LOCAL_SCRIPT_DEBUG: [ true, false ]
     85        # See the "Projects" section in tests/e2e/README.md.
     86        test-group: [ 'parallel', 'serial' ]
    8587        # A matrix value is needed in the 'name' directive for proper grouping in the GitHub UI.
    8688        label: [ 'E2E Tests' ]
    8789    with:
    8890      LOCAL_SCRIPT_DEBUG: ${{ matrix.LOCAL_SCRIPT_DEBUG }}
     91      test-group: ${{ matrix.test-group }}
    8992
    9093  slack-notifications:
  • trunk/.github/workflows/reusable-end-to-end-tests.yml

    r63898 r65049  
    3333        type: 'boolean'
    3434        default: true
     35      test-group:
     36        description: 'The Playwright project to run. Runs the default projects when empty.'
     37        required: false
     38        type: 'string'
     39        default: ''
    3540
    3641env:
    … …  
    6368  # - Ensures version-controlled files are not modified or deleted.
    6469  e2e-tests:
    65     name: SCRIPT_DEBUG ${{ inputs.LOCAL_SCRIPT_DEBUG && 'enabled' || 'disabled' }}
     70    name: ${{ inputs.test-group && format( '{0}, ', inputs.test-group ) || '' }}SCRIPT_DEBUG ${{ inputs.LOCAL_SCRIPT_DEBUG && 'enabled' || 'disabled' }}
    6671    runs-on: ubuntu-24.04
    6772    permissions:
    … …  
    148153
    149154      - name: Run E2E tests
    150         run: npm run test:e2e
     155        run: |
     156          if [ -n "${TEST_GROUP}" ]; then
     157            npm run test:e2e -- --project="${TEST_GROUP}"
     158          else
     159            npm run test:e2e
     160          fi
    151161        env:
     162          TEST_GROUP: ${{ inputs.test-group }}
    152163          # Chromium is installed above and is the only browser the suite runs. Without this,
    153164          # `wp-scripts test-playwright` also downloads Firefox and WebKit on every run.
    … …  
    158169        if: always()
    159170        with:
    160           name: failures-artifacts${{ inputs.LOCAL_SCRIPT_DEBUG && '-SCRIPT_DEBUG' || '' }}-${{ github.run_id }}
     171          name: failures-artifacts${{ inputs.test-group && format( '-{0}', inputs.test-group ) || '' }}${{ inputs.LOCAL_SCRIPT_DEBUG && '-SCRIPT_DEBUG' || '' }}-${{ github.run_id }}
    161172          path: artifacts
    162173          if-no-files-found: ignore
  • trunk/tests/e2e/README.md

    r56926 r65049  
    4141
    4242
     43## Projects
     44
     45The suite has three Playwright projects, defined in `playwright.config.js`:
     46
     47* `all`: every spec, one at a time on one worker. `npm run test:e2e` runs this project.
     48* `parallel`: specs that can share the site with other tests. Spec files run at the same time on several workers, one for every two CPU cores. Tests inside one file still run in order. Run it with `npm run test:e2e -- --project=parallel`.
     49* `serial`: specs that break the site for other tests. They run one at a time on one worker. Run it with `npm run test:e2e -- --project=serial`.
     50
     51CI runs `parallel` and `serial` in separate jobs.
     52
     53New specs go in `parallel` by default. Add a spec to `SERIAL_SPECS` only if it makes the site unusable for other tests, or if it changes content or settings that other tests use, for example with `requestUtils.deleteAllPosts()`.
     54
     55Before you open a pull request with a new spec, run its project a few times with `--shuffle`. Playwright then runs the spec files in a random order, so a spec that needs another spec to run first, or that breaks a spec that runs after it, fails:
     56
     57```
     58npm run test:e2e -- --project=parallel --shuffle
     59```
     60
     61Playwright prints the seed of each run, for example `shuffle seed 317753389`. To run the same order again, give the seed: `--shuffle 317753389`.
     62
    4363## Documentation
    4464
  • trunk/tests/e2e/playwright.config.js

    r56926 r65049  
    33 */
    44import path from 'node:path';
    5 import { defineConfig } from '@playwright/test';
     5import { defineConfig, devices } from '@playwright/test';
    66
    77/**
    … …  
    1616);
    1717
     18const SERIAL_SPECS = [
     19        'install.test.js',
     20        'maintenance-mode.test.js',
     21        'fatal-error-handler.test.js',
     22        'login-localize-script.test.js',
     23        'gutenberg-plugin.test.js',
     24        'plugins.test.js',
     25        'themes.test.js',
     26        // These delete all posts or media, including other workers' content.
     27        'cache-control-headers-directives.test.js',
     28        'dashboard.test.js',
     29        'edit-posts.test.js',
     30        'empty-trash-restore-trashed-posts.test.js',
     31        'media-library-client-side-upload.test.js',
     32        'media-modal-client-side-upload.test.js',
     33        'media-new-client-side-upload.test.js',
     34];
     35
    1836const config = defineConfig( {
    1937        ...baseConfig,
    2038        globalSetup: require.resolve( './config/global-setup.js' ),
     39        workers: '50%',
    2140        webServer: {
    2241                ...baseConfig.webServer,
    2342                command: 'npm run env:start',
    2443        },
     44        projects: [
     45                {
     46                        name: 'all',
     47                        fullyParallel: false,
     48                        workers: 1,
     49                        use: { ...devices[ 'Desktop Chrome' ] },
     50                },
     51                {
     52                        name: 'parallel',
     53                        default: false,
     54                        testIgnore: SERIAL_SPECS,
     55                        fullyParallel: false,
     56                        use: { ...devices[ 'Desktop Chrome' ] },
     57                },
     58                {
     59                        name: 'serial',
     60                        default: false,
     61                        testMatch: SERIAL_SPECS,
     62                        fullyParallel: false,
     63                        workers: 1,
     64                        use: { ...devices[ 'Desktop Chrome' ] },
     65                },
     66        ],
    2567} );
    2668
  • trunk/tests/e2e/specs/media-upload.test.js

    r64658 r65049  
    1010
    1111test( 'Test dismissing failed upload works correctly', async ({ page, admin, requestUtils }) => {
    12         // Log in before visiting admin page.
    13         await requestUtils.login();
    1412        await admin.visitAdminPage( '/media-new.php' );
    1513
Note: See TracChangeset for help on using the changeset viewer.