-
Notifications
You must be signed in to change notification settings - Fork 2
IBX-11740: Added playwright-browser-tests.yml #100
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
da64571
7e466d1
6ffbfe7
218bc93
cf0f861
7a8103e
8b966d3
46e8126
868c4c3
f441eee
2c48d32
ec6f98d
0996825
0b19049
4f7b7af
65bbc15
1b8f8c7
9fa2907
a141493
7f07adb
1317e8d
ad4806d
20805b5
fdd0779
85fb065
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,370 @@ | ||
| name: Browser tests (Playwright) | ||
|
|
||
| on: | ||
| workflow_call: | ||
| inputs: | ||
| project-edition: | ||
| description: "Project edition to set up: oss, headless, experience, commerce" | ||
| required: true | ||
| type: string | ||
| test-package: | ||
| description: "Run tests of a single package (e.g. admin-ui). Empty = all packages with tests (edition mode)." | ||
| required: false | ||
| type: string | ||
| default: '' | ||
| test-suite: | ||
| description: "Extra Playwright CLI args (e.g. --grep Trash)" | ||
| required: false | ||
| type: string | ||
| default: '' | ||
| project-version: | ||
| description: "Project version (e.g. 6.0.x-dev). If empty, inferred from branch alias." | ||
| required: false | ||
| type: string | ||
| default: '' | ||
| setup: | ||
| description: "Docker Compose files to use" | ||
| required: false | ||
| type: string | ||
| default: "doc/docker/base-dev.yml" | ||
| php-image: | ||
| description: "PHP Docker image to use" | ||
| required: false | ||
| type: string | ||
| default: "ghcr.io/ibexa/docker/php:8.3-node22" | ||
| node-version: | ||
| description: "Node.js version for running Playwright" | ||
| required: false | ||
| type: string | ||
| default: "22" | ||
| ci-scripts-branch: | ||
| description: "Branch from ibexa/ci-scripts to use" | ||
| required: false | ||
| type: string | ||
| default: "main" | ||
| cohesivo-version: | ||
| description: "Composer version constraint for ibexa/cohesivo-playwright. Empty = match the project version (branch alias). Playwright is 5.0+ only — there is no 4.6 branch of the library, so 4.6 projects must not call this workflow." | ||
| required: false | ||
| type: string | ||
| default: "" | ||
| app-url: | ||
| description: "URL under which the app is reachable from the runner host. Empty = derived from setup." | ||
| required: false | ||
| type: string | ||
| default: "" | ||
| artifact-suffix: | ||
| description: "Discriminator when one run calls this workflow several times for the same edition (e.g. 'pgsql18-varnish')" | ||
| required: false | ||
| type: string | ||
| default: '' | ||
| job-count: | ||
| description: "Number of jobs that will run the tests in parallel (Playwright --shard)" | ||
| required: false | ||
| type: number | ||
| default: 1 | ||
| send-success-notification: | ||
| description: "Send a Slack notification when tests pass" | ||
| required: false | ||
| type: boolean | ||
| default: true | ||
| timeout: | ||
| description: "Job timeout in minutes" | ||
| required: false | ||
| type: number | ||
| default: 60 | ||
| secrets: | ||
| SLACK_WEBHOOK_URL: | ||
| required: false | ||
| SATIS_NETWORK_KEY: | ||
| required: false | ||
| SATIS_NETWORK_TOKEN: | ||
| required: false | ||
| AUTOMATION_CLIENT_ID: | ||
| required: false | ||
| AUTOMATION_CLIENT_SECRET: | ||
| required: false | ||
| EZROBOT_33: | ||
| required: false | ||
| ADMIN_LOGIN: | ||
| required: false | ||
| ADMIN_PASSWORD: | ||
| required: false | ||
|
|
||
| env: | ||
| # Symfony env the app boots in — the established platform test env (provided by ibexa/behat), | ||
| # same as the Behat pipeline and expected by the shared project-setup script. It configures | ||
| # the app, not Playwright (the tests just hit it over HTTP). There is no dedicated "playwright" | ||
| # env; dropping this would fall back to "dev", so it stays as-is. | ||
| APP_ENV: behat | ||
| APP_DEBUG: 1 | ||
| APP_SECRET: '2d4218d7b6c69a9f88da7b8986e64717b3c40948a7ba2b1ca309dc292472286d' | ||
| PHP_INI_ENV_memory_limit: 1G | ||
| COMPOSER_CACHE_DIR: ~/.composer/cache | ||
|
|
||
| jobs: | ||
| setup-jobs: | ||
| runs-on: ubuntu-latest | ||
| timeout-minutes: 1 | ||
| outputs: | ||
| matrix: ${{ steps.generate-matrix.outputs.matrix }} | ||
| job-count: ${{ steps.generate-matrix.outputs.job-count }} | ||
| steps: | ||
| - name: Set job count for builds | ||
| run: echo "job_count=${{ inputs.job-count }}" >> $GITHUB_ENV | ||
| - name: Limit job-count to max 3 for PRs | ||
| if: github.event_name == 'pull_request' | ||
| run: | | ||
| if [[ "$job_count" -gt 3 ]] ; then | ||
| job_count=3 | ||
| fi | ||
| echo "job_count=$job_count" >> $GITHUB_ENV | ||
| env: | ||
| job_count: ${{ env.job_count }} | ||
| - name: Generate matrix | ||
| id: generate-matrix | ||
| run: | | ||
| matrix=$(jq -cn --argjson n "$job_count" '{offset: [range(0; $n)]}') | ||
| echo "matrix=$matrix" >> $GITHUB_OUTPUT | ||
| echo "job-count=$job_count" >> $GITHUB_OUTPUT | ||
| - if: always() && github.event_name != 'pull_request' | ||
| name: Create Slack message variables | ||
| run: | | ||
| echo "RESULT_EMOJI=:x:" >> $GITHUB_ENV | ||
| - if: always() && github.event_name != 'pull_request' | ||
| name: Create Slack message | ||
| run: > | ||
| echo "SLACK_PAYLOAD= | ||
| {\"blocks\": [{\"type\": \"section\",\"text\": {\"type\": \"mrkdwn\",\"text\": \" | ||
| $RESULT_EMOJI *$GITHUB_REPOSITORY*:*$GITHUB_REF_NAME* ($GITHUB_ACTOR) | | ||
| <$GITHUB_SERVER_URL/$GITHUB_REPOSITORY/actions/runs/$GITHUB_RUN_ID|Details> | ||
| \"}}]}" >> $GITHUB_ENV | ||
| - if: always() && github.event_name != 'pull_request' && job.status != 'success' && job.status != 'skipped' | ||
| name: Send notification about workflow result | ||
| uses: slackapi/slack-github-action@45a88b9581bfab2566dc881e2cd66d334e621e2c # v3.0.3 | ||
| with: | ||
| webhook: ${{ secrets.SLACK_WEBHOOK_URL }} | ||
| webhook-type: incoming-webhook | ||
| payload: ${{ env.SLACK_PAYLOAD }} | ||
|
|
||
| playwright-tests: | ||
| needs: setup-jobs | ||
| runs-on: ubuntu-latest | ||
| timeout-minutes: ${{ inputs.timeout }} | ||
| strategy: | ||
| fail-fast: false | ||
| matrix: ${{ fromJson(needs.setup-jobs.outputs.matrix) }} | ||
|
|
||
| steps: | ||
| - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 | ||
|
|
||
| - name: Derive app URL from setup | ||
| run: | | ||
| if [ -n "$APP_URL" ]; then | ||
| echo "APP_URL=$APP_URL" >> $GITHUB_ENV | ||
| elif echo "$SETUP" | grep -q varnish; then | ||
| echo "APP_URL=http://localhost:8081" >> $GITHUB_ENV | ||
| else | ||
| echo "APP_URL=http://localhost:8080" >> $GITHUB_ENV | ||
| fi | ||
| env: | ||
| APP_URL: ${{ inputs.app-url }} | ||
| SETUP: ${{ inputs.setup }} | ||
|
|
||
| - name: Set up project version | ||
| id: project-version | ||
| run: | | ||
| if [[ "$version" == "" ]] ; then | ||
| echo "Input project version not set, taking the value from composer.json" | ||
| version=$(cat composer.json | jq -r '.extra | ."branch-alias" | .[]') | ||
| fi | ||
| echo "version=$version" >> $GITHUB_OUTPUT | ||
| env: | ||
| version: ${{ inputs.project-version }} | ||
|
|
||
| - name: Setup PHP Action | ||
| uses: shivammathur/setup-php@f3e473d116dcccaddc5834248c87452386958240 # 2.37.2 | ||
| with: | ||
| php-version: 8.3 | ||
| coverage: none | ||
|
|
||
| - name: Cache dependencies | ||
| uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 | ||
| with: | ||
| path: ${{ env.COMPOSER_CACHE_DIR }} | ||
| key: ${{ inputs.project-edition }}-${{ steps.project-version.outputs.version }}-${{ inputs.php-image }}-${{ github.sha }} | ||
| restore-keys: | | ||
| ${{ inputs.project-edition }}-${{ steps.project-version.outputs.version }}-${{ inputs.php-image }} | ||
|
|
||
| - name: Generate token | ||
| id: generate_token | ||
| if: env.AUTOMATION_CLIENT_ID != '' | ||
| uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # v3.2.0 | ||
| with: | ||
| app-id: ${{ secrets.AUTOMATION_CLIENT_ID }} | ||
| private-key: ${{ secrets.AUTOMATION_CLIENT_SECRET }} | ||
| owner: ibexa | ||
| env: | ||
| AUTOMATION_CLIENT_ID: ${{ secrets.AUTOMATION_CLIENT_ID }} | ||
|
|
||
| - if: env.SATIS_NETWORK_KEY != '' | ||
| name: Add composer keys for private packagist | ||
| run: | | ||
| composer config http-basic.updates.ibexa.co $SATIS_NETWORK_KEY $SATIS_NETWORK_TOKEN | ||
| env: | ||
| SATIS_NETWORK_KEY: ${{ secrets.SATIS_NETWORK_KEY }} | ||
| SATIS_NETWORK_TOKEN: ${{ secrets.SATIS_NETWORK_TOKEN }} | ||
|
|
||
| - name: Add composer key for GitHub App | ||
| if: ${{ steps.generate_token.outputs.token != '' }} | ||
| run: | | ||
| composer config github-oauth.github.com $GITHUB_TOKEN | ||
| env: | ||
| GITHUB_TOKEN: ${{ steps.generate_token.outputs.token }} | ||
|
|
||
| - if: startsWith(steps.project-version.outputs.version, 'v') == false | ||
| name: Set up whole project using the tested dependency (dev version) | ||
| run: | | ||
| curl -L "https://raw.githubusercontent.com/ibexa/ci-scripts/${{ inputs.ci-scripts-branch }}/bin/${{ steps.project-version.outputs.version }}/prepare_project_edition.sh" > prepare_project_edition.sh | ||
|
Check warning on line 227 in .github/workflows/playwright-browser-tests.yml
|
||
| chmod +x prepare_project_edition.sh | ||
| ./prepare_project_edition.sh ${{ inputs.project-edition }} ${{ steps.project-version.outputs.version }} ${{ inputs.setup }} ${{ inputs.php-image }} | ||
|
|
||
| - if: startsWith(steps.project-version.outputs.version, 'v') | ||
| name: Set up whole project using a stable release | ||
| run: | | ||
| curl -L "https://raw.githubusercontent.com/ibexa/ci-scripts/${{ inputs.ci-scripts-branch }}/bin/stable/prepare_project_edition.sh" > prepare_project_edition.sh | ||
|
Check warning on line 234 in .github/workflows/playwright-browser-tests.yml
|
||
| chmod +x prepare_project_edition.sh | ||
| ./prepare_project_edition.sh ${{ inputs.project-edition }} ${{ steps.project-version.outputs.version }} ${{ inputs.setup }} ${{ inputs.php-image }} | ||
|
|
||
| - name: Add ibexa_integrated_help config | ||
| if: inputs.project-edition != 'oss' | ||
| run: | | ||
| cd ${HOME}/build/project | ||
| docker compose --env-file=.env exec -T --user www-data app sh -c "printf 'ibexa_integrated_help:\n enabled: false\n' > config/packages/ibexa_integrated_help.yaml" | ||
|
|
||
| # Data seeding is done per-test through IbexaApiClient (REST) in the packages' | ||
| # beforeAll hooks — no Behat setup phase here, so this workflow has no Behat dependency. | ||
|
|
||
| - name: Install ibexa/cohesivo-playwright | ||
| run: | | ||
| cd ${HOME}/build/project | ||
| # empty cohesivo-version → match the project version (branch alias), so a 5.0/6.0 | ||
| # branch installs the matching library version. (No 4.6 branch of the library exists.) | ||
| if [ -z "$COHESIVO_VERSION" ]; then | ||
| COHESIVO_VERSION="$PROJECT_VERSION" | ||
| fi | ||
| echo "Installing ibexa/cohesivo-playwright:$COHESIVO_VERSION" | ||
| # TODO: drop the vcs repository once ibexa/cohesivo-playwright is published on updates.ibexa.co | ||
|
Check warning on line 256 in .github/workflows/playwright-browser-tests.yml
|
||
| docker compose --env-file=.env exec -T --user www-data -e GITHUB_TOKEN -e COHESIVO_VERSION app sh -c ' | ||
| composer config repositories.cohesivo-playwright vcs https://github.com/ibexa/cohesivo-playwright && | ||
| if [ -n "$GITHUB_TOKEN" ]; then composer config github-oauth.github.com "$GITHUB_TOKEN"; fi && | ||
| composer require --dev "ibexa/cohesivo-playwright:$COHESIVO_VERSION" --no-scripts --no-plugins' | ||
| env: | ||
| GITHUB_TOKEN: ${{ steps.generate_token.outputs.token }} | ||
| COHESIVO_VERSION: ${{ inputs.cohesivo-version }} | ||
| PROJECT_VERSION: ${{ steps.project-version.outputs.version }} | ||
|
|
||
| - name: Setup Node.js | ||
| uses: actions/setup-node@v4 | ||
| with: | ||
| node-version: ${{ inputs.node-version }} | ||
|
|
||
| - name: Configure npm to use HTTPS for GitHub packages | ||
| if: ${{ steps.generate_token.outputs.token != '' }} | ||
| run: | | ||
| git config --global url."https://x-access-token:${GITHUB_TOKEN}@github.com/".insteadOf "git@github.com:" | ||
| git config --global url."https://x-access-token:${GITHUB_TOKEN}@github.com/".insteadOf "ssh://git@github.com/" | ||
| git config --global url."https://x-access-token:${GITHUB_TOKEN}@github.com/".insteadOf "https://github.com/" | ||
| env: | ||
| GITHUB_TOKEN: ${{ steps.generate_token.outputs.token }} | ||
|
|
||
| - name: Fix write permissions on project directory | ||
| run: sudo chmod -R a+rwX ${HOME}/build/project | ||
|
|
||
| - name: Install cohesivo-playwright dependencies and build | ||
| run: | | ||
| cd ${HOME}/build/project/vendor/ibexa/cohesivo-playwright | ||
| npm ci | ||
|
Check warning on line 286 in .github/workflows/playwright-browser-tests.yml
|
||
| npm run build | ||
|
|
||
| - name: Install per-package Playwright test dependencies | ||
| run: | | ||
| for dir in ${HOME}/build/project/vendor/ibexa/*/tests/playwright-tests; do | ||
| if [ -f "$dir/package.json" ]; then | ||
| cd "$dir" | ||
| echo "→ npm ci in $dir" | ||
| npm ci | ||
|
Check warning on line 295 in .github/workflows/playwright-browser-tests.yml
|
||
| fi | ||
| done | ||
|
|
||
| - name: Install Playwright browsers | ||
| run: | | ||
| cd ${HOME}/build/project/vendor/ibexa/cohesivo-playwright | ||
| npx playwright install --with-deps chromium | ||
|
Check warning on line 302 in .github/workflows/playwright-browser-tests.yml
|
||
|
|
||
| - name: Run Playwright tests | ||
| # inputs are passed via env (not interpolated into the script) to avoid shell injection | ||
| run: | | ||
| cd ${HOME}/build/project/vendor/ibexa/cohesivo-playwright | ||
| EXTRA_ARGS="$TEST_SUITE" | ||
| # --pass-with-no-tests only under sharding: an empty shard is expected, an empty | ||
| # unsharded run means the edition grep matched nothing and should fail loudly. | ||
| if [ "$JOB_COUNT" -gt 1 ]; then | ||
| EXTRA_ARGS="$EXTRA_ARGS --shard=$(( SHARD_OFFSET + 1 ))/$JOB_COUNT --pass-with-no-tests" | ||
|
pawlakadrian marked this conversation as resolved.
|
||
| fi | ||
| if [ -n "$TEST_PACKAGE" ]; then | ||
| npm run test:package -- "$TEST_PACKAGE" $EXTRA_ARGS | ||
| else | ||
| npm run test:all -- $EXTRA_ARGS | ||
| fi | ||
| env: | ||
| TEST_SUITE: ${{ inputs.test-suite }} | ||
| TEST_PACKAGE: ${{ inputs.test-package }} | ||
| JOB_COUNT: ${{ needs.setup-jobs.outputs.job-count }} | ||
| SHARD_OFFSET: ${{ matrix.offset }} | ||
| APP_URL: ${{ env.APP_URL }} | ||
| APP_EDITION: ${{ inputs.project-edition }} | ||
| ADMIN_LOGIN: ${{ secrets.ADMIN_LOGIN || 'admin' }} | ||
| ADMIN_PASSWORD: ${{ secrets.ADMIN_PASSWORD || 'publish' }} | ||
| CI: true | ||
|
|
||
| - name: Upload Playwright report | ||
| if: always() | ||
| uses: actions/upload-artifact@v4 | ||
| with: | ||
| name: playwright-report-${{ inputs.project-edition }}-${{ inputs.artifact-suffix || inputs.test-package || 'all' }}-shard${{ matrix.offset }}-${{ github.run_id }}-${{ github.run_attempt }} | ||
| # `**` matches any depth, so one pair of globs covers both the package suites | ||
| # (<pkg>/tests/playwright-tests/) and cohesivo's own tests (cohesivo-playwright/) | ||
| path: | | ||
| /home/runner/build/project/vendor/ibexa/**/playwright-report/ | ||
| /home/runner/build/project/vendor/ibexa/**/test-results/ | ||
| retention-days: 14 | ||
|
|
||
| - if: always() && github.event_name != 'pull_request' | ||
| name: Create Slack message variables | ||
| run: | | ||
| echo "RESULT_EMOJI=:x:" >> $GITHUB_ENV | ||
| JOB_NUMBER=$(expr ${{ matrix.offset }} + 1) | ||
| echo "JOB_NUMBER=$JOB_NUMBER" >> $GITHUB_ENV | ||
|
|
||
| - if: always() && job.status == 'success' && github.event_name != 'pull_request' | ||
| name: Create Slack message success variables | ||
| run: | | ||
| echo "RESULT_EMOJI=:white_check_mark:" >> $GITHUB_ENV | ||
|
|
||
| - if: always() && github.event_name != 'pull_request' | ||
| name: Create Slack message | ||
| run: > | ||
| echo "SLACK_PAYLOAD= | ||
| {\"blocks\": [{\"type\": \"section\",\"text\": {\"type\": \"mrkdwn\",\"text\": \" | ||
| $RESULT_EMOJI *$GITHUB_REPOSITORY*:*$GITHUB_REF_NAME* ($GITHUB_ACTOR) | Playwright | | ||
| <$GITHUB_SERVER_URL/$GITHUB_REPOSITORY/actions/runs/$GITHUB_RUN_ID|Details> | | ||
| $JOB_NUMBER/${{ needs.setup-jobs.outputs.job-count }} | ||
| \"}}]}" >> $GITHUB_ENV | ||
|
|
||
| - if: always() && github.event_name != 'pull_request' && (job.status != 'success' || inputs.send-success-notification) | ||
| name: Send notification about workflow result | ||
| uses: slackapi/slack-github-action@45a88b9581bfab2566dc881e2cd66d334e621e2c # v3.0.3 | ||
| with: | ||
| webhook: ${{ secrets.SLACK_WEBHOOK_URL }} | ||
| webhook-type: incoming-webhook | ||
| payload: ${{ env.SLACK_PAYLOAD }} | ||
Uh oh!
There was an error while loading. Please reload this page.