Skip to content
Open
Show file tree
Hide file tree
Changes from 11 commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 34 additions & 7 deletions .github/workflows/test-playwright.yml
Original file line number Diff line number Diff line change
Expand Up @@ -52,14 +52,25 @@ on:
default: '--with-deps'
required: false
type: string
PLAYWRIGHT_CLI_ARGS:
description: Arguments and flags for `npx playwright test`. When set SCRIPT_NAME will be ignored.
default: ''
required: false
type: string
PRE_SCRIPT:
description: Run custom shell code before executing the test runner.
default: ''
required: false
type: string
SCRIPT_NAME:
description: The name of a custom script to run the tests.
required: true
description: The name of a custom npm script to run the tests. Ignored when PLAYWRIGHT_GREP is set.
default: ''
required: false
type: string
WORK_DIR:
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

question

During the last meeting, we agreed to move all the npm dependencies to the root package.json to avoid this kind of complication, since there is no evidence that your dependencies will cause version clashes. Can you please explain why you are introducing this input? 😄

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've explained this in the first point of "What is the new behavior" section. But maybe I can find a workaround, e.g. by switching the tests: dir in playwright.config 🤔

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is going to be hard to pull off without also assuming control of the playwright.config.js. From my (limited) experience, Playwright is pretty stoic about the way it is configured and bootstraps itself from the config file with extremely limited entrypoints for external configuration/overrides.

We could use npm workspaces to isolate Playwright while also satisfying the centralized node_modules/ requirement, but I am not sure if that really reduces the complexity of the setup. It would allow us to install playwright in the root while executing it in WORK_DIR.

But this still requires the project to be structured to suit the workflow (instead of configuring the workflow to suit the project within a reasonable framework)
It might be a middleground here though.

Another idea:
Playwright supports pointing to a config file with --config - is it then also resolving and picking up tests relative to the config file? Then we would only need a PLAYWRIGHT_CONFIG input

Copy link
Copy Markdown
Author

@mishautkin mishautkin Feb 25, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi, I remember about this unresolved comment. Moving playwright and all it's dependencies from tests/qa/ to root takes some time. I need to go through some PRs on Mollie before I can tackle this.

In case of several PW projects (like on PayPal with legacy UI), my plan is to manage testDir in playwright.config using path stored in env var PLAYWRIGHT_TEST_DIR='tests/qa/tests'.

description: Working directory for npm install, Playwright install, and test execution.
default: '.'
required: false
type: string
secrets:
ENV_FILE_DATA:
Expand Down Expand Up @@ -111,7 +122,8 @@ jobs:

- name: Set up node cache mode
run: |
if [ -f "${GITHUB_WORKSPACE}/package-lock.json" ] || [ -f "${GITHUB_WORKSPACE}/npm-shrinkwrap.json" ]; then
WORK_DIR="${{ inputs.WORK_DIR }}"
if [ -f "${GITHUB_WORKSPACE}/${WORK_DIR}/package-lock.json" ] || [ -f "${GITHUB_WORKSPACE}/${WORK_DIR}/npm-shrinkwrap.json" ]; then
echo "NODE_CACHE_MODE=npm" >> $GITHUB_ENV
else
echo "No lock files found or unknown package manager"
Expand Down Expand Up @@ -143,26 +155,41 @@ jobs:
cache: ${{ env.NODE_CACHE_MODE }}

- name: Install dependencies
working-directory: ${{ inputs.WORK_DIR }}
run: npm ${{ env.NODE_CACHE_MODE == 'npm' && 'ci' || 'install' }}

- name: Install Playwright dependencies
working-directory: ${{ inputs.WORK_DIR }}
run: |
npx playwright install ${{ inputs.PLAYWRIGHT_BROWSER_ARGS }}

- name: Create environment file
working-directory: ${{ inputs.WORK_DIR }}
run: |
touch .env.ci
echo "${{ secrets.ENV_FILE_DATA }}" >> .env.ci

- name: Execute custom code before executing the test script
working-directory: ${{ inputs.WORK_DIR }}
env:
GH_TOKEN: ${{ github.token }}
run: |
set -a && source .env.ci && set +a
${{ inputs.PRE_SCRIPT }}

- name: Run script for test
id: run-script
continue-on-error: true
working-directory: ${{ inputs.WORK_DIR }}
run: |
touch .env.ci
echo "${{ secrets.ENV_FILE_DATA }}" >> .env.ci
# Ensure .env.ci is deleted on exit
trap 'rm -f .env.ci' EXIT

npm run ${{ inputs.SCRIPT_NAME }}
if [ -n "${{ inputs.PLAYWRIGHT_CLI_ARGS }}" ]; then
npx playwright test ${{ inputs.PLAYWRIGHT_CLI_ARGS }}
else
npm run ${{ inputs.SCRIPT_NAME }}
fi

- name: Upload artifact
if: always()
Expand All @@ -179,4 +206,4 @@ jobs:
if: steps.run-script.outcome == 'failure'
run: |
echo "Tests failed! Check the artifacts for details."
exit 1
exit 1
69 changes: 64 additions & 5 deletions docs/test-playwright.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ This workflow executes Playwright-based tests in a controlled and isolated envir
The workflow can:

- execute a building step, both for node and PHP environments (if the PHP version is provided and a `composer.json` file is present)
- create an environment variables file named `.env.ci` dedicated to the test step; load this file using `dotenv-ci` directly in your test script, e.g., `./node_modules/.bin/dotenv -e .env.ci -- npm run e2e`
- execute the tests using Playwright
- create an environment variables file named `.env.ci` dedicated to the test step; load this file using `dotenv-ci` directly in your test script, e.g., `./node_modules/.bin/dotenv -e .env.ci -- npm run e2e`. The file is also sourced before `PRE_SCRIPT`, making all variables available as environment variables.
- execute the tests using Playwright — either via a custom npm script or directly with `--grep`, `--grep-invert`, and `--project` filters
- upload the artifacts

**Simplest possible example:**
Expand Down Expand Up @@ -40,14 +40,20 @@ jobs:
| `NPM_REGISTRY_DOMAIN` | `'https://npm.pkg.github.com/'` | Domain of the private npm registry |
| `PHP_VERSION` | `'8.2'` | PHP version with which the dependencies are installed |
| `PLAYWRIGHT_BROWSER_ARGS` | `'--with-deps'` | Set of arguments passed to `npx playwright install` |
| `PRE_SCRIPT` | `''` | Run custom shell code before executing the test script |
| `SCRIPT_NAME` | | The name of a custom script to run the tests |
| `PLAYWRIGHT_GREP` | `''` | Grep pattern to filter tests. When any Playwright flag is set, `SCRIPT_NAME` is ignored and `npx playwright test` is used directly |
| `PLAYWRIGHT_GREP_INVERT` | `''` | Grep pattern to exclude tests. Passed as `--grep-invert` flag. When any Playwright flag is set, `SCRIPT_NAME` is ignored and `npx playwright test` is used directly |
| `PLAYWRIGHT_PROJECT` | `''` | Playwright project name from `playwright.config`. When any Playwright flag is set, `SCRIPT_NAME` is ignored and `npx playwright test` is used directly |
| `PRE_SCRIPT` | `''` | Run custom shell code before executing the test script. `GH_TOKEN` and all `ENV_FILE_DATA` variables are available |
| `SCRIPT_NAME` | `''` | The name of a custom npm script to run the tests. Ignored when any Playwright flag is set |
| `WORK_DIR` | `'.'` | Working directory for npm install, Playwright install, PRE_SCRIPT, and test execution |

> **Note:** Setting any combination of `PLAYWRIGHT_GREP`, `PLAYWRIGHT_GREP_INVERT`, or `PLAYWRIGHT_PROJECT` will bypass `SCRIPT_NAME` and run `npx playwright test` directly with the specified flags.

### Secrets

| Name | Description |
|-----------------------|------------------------------------------------------------------------------------------|
| `ENV_FILE_DATA` | Additional environment variables for the tests |
| `ENV_FILE_DATA` | Additional environment variables for the tests. Also sourced before `PRE_SCRIPT` |
| `COMPOSER_AUTH_JSON` | Authentication for privately hosted packages and repositories as a JSON formatted object |
| `NPM_REGISTRY_TOKEN` | Authentication for the private npm registry |
| `GITHUB_USER_EMAIL` | Email address for the GitHub user configuration |
Expand Down Expand Up @@ -88,6 +94,59 @@ jobs:
NPM_REGISTRY_TOKEN: ${{ secrets.DEPLOYBOT_PACKAGES_READ_ACCESS_TOKEN}}
```

**Example with subdirectory and grep mode:**

```yml
name: E2E Testing

on:
workflow_dispatch:
inputs:
TEST_SUITE:
description: 'Test suite to run'
required: true
default: 'critical'
type: choice
options:
- smoke
- critical
- all
- grep
TEST_GREP_PATTERN:
description: 'Grep pattern (only used when TEST_SUITE == "grep")'
required: false
type: string
TEST_GREP_INVERT_PATTERN:
description: 'Grep invert pattern (only used when TEST_SUITE == "grep")'
required: false
type: string
TEST_PROJECT:
description: 'Playwright project name (only used when TEST_SUITE == "grep")'
required: false
default: 'all'
type: string

jobs:
e2e-playwright:
uses: inpsyde/reusable-workflows/.github/workflows/test-playwright.yml@main
with:
WORK_DIR: 'tests/qa'
ARTIFACT_PATH: |
tests/qa/artifacts/*
tests/qa/playwright-report/
SCRIPT_NAME: ${{ inputs.TEST_SUITE != 'grep' && format('test:{0}', inputs.TEST_SUITE) || '' }}
PLAYWRIGHT_GREP: ${{ inputs.TEST_SUITE == 'grep' && inputs.TEST_GREP_PATTERN || '' }}
PLAYWRIGHT_GREP_INVERT: ${{ inputs.TEST_SUITE == 'grep' && inputs.TEST_GREP_INVERT_PATTERN || '' }}
PLAYWRIGHT_PROJECT: ${{ inputs.TEST_SUITE == 'grep' && inputs.TEST_PROJECT || '' }}
NODE_VERSION: 22
PLAYWRIGHT_BROWSER_ARGS: 'chromium --with-deps'
PRE_SCRIPT: |
gh run download ${{ github.run_id }} -n my-plugin -D resources/files
npm run setup:env
secrets:
ENV_FILE_DATA: ${{ secrets.ENV_FILE_DATA }}
```

**Example of secrets:**

For `ENV_FILE_DATA`:
Expand Down
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading