Skip to content
Draft
Changes from all commits
Commits
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
361 changes: 361 additions & 0 deletions .github/workflows/playwright-browser-tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,361 @@
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 = same as the project version (branch alias), so 4.6/5.0/6.0 branches get the matching library version."
required: false
type: string
default: ""
app-url:
description: "URL under which the app is reachable from the runner host"
required: false
type: string
default: "http://localhost:8080"
test-setup-phase-1:
description: "Behat suite to run before Playwright tests for data seeding - phase 1"
required: false
type: string
default: ""
test-setup-phase-2:
description: "Behat suite to run before Playwright tests for data seeding - phase 2"
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:
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@v1.23.0
with:
payload: ${{ env.SLACK_PAYLOAD }}
env:
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
SLACK_WEBHOOK_TYPE: INCOMING_WEBHOOK

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@v4

- 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@v2
with:
php-version: 8.3
coverage: none

- name: Cache dependencies
uses: actions/cache@v4
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@v2
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
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
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"

- if: inputs.test-setup-phase-1 != ''
name: Run first phase of tests setup
run: |
cd ${HOME}/build/project
docker compose --env-file=.env exec -T --user www-data app sh -c "vendor/bin/ibexabehat ${{ inputs.test-setup-phase-1 }}"
docker compose --env-file=.env exec -T --user www-data app sh -c "NODE_OPTIONS='--max-old-space-size=3072' composer run post-install-cmd"

- if: inputs.test-setup-phase-2 != ''
name: Run second phase of tests setup
run: |
cd ${HOME}/build/project
docker compose --env-file=.env exec -T --user www-data app sh -c "vendor/bin/ibexabehat ${{ inputs.test-setup-phase-2 }}"
docker compose --env-file=.env exec -T --user www-data app sh -c "NODE_OPTIONS='--max-old-space-size=3072' composer run post-install-cmd"

- name: Install ibexa/cohesivo-playwright
run: |
cd ${HOME}/build/project
export COHESIVO_VERSION="${{ inputs.cohesivo-version }}"
if [ -z "$COHESIVO_VERSION" ]; then
export COHESIVO_VERSION="${{ steps.project-version.outputs.version }}"
fi
echo "Installing ibexa/cohesivo-playwright:$COHESIVO_VERSION"
# TODO: drop the vcs repository once ibexa/cohesivo-playwright is published on updates.ibexa.co
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 }}

- 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
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
fi
done

- name: Install Playwright browsers
run: |
cd ${HOME}/build/project/vendor/ibexa/cohesivo-playwright
npx playwright install --with-deps chromium

- name: Run Playwright tests
run: |
cd ${HOME}/build/project/vendor/ibexa/cohesivo-playwright
EXTRA_ARGS="${{ inputs.test-suite }}"
if [ "${{ needs.setup-jobs.outputs.job-count }}" -gt 1 ]; then
EXTRA_ARGS="$EXTRA_ARGS --shard=$(( ${{ matrix.offset }} + 1 ))/${{ needs.setup-jobs.outputs.job-count }} --pass-with-no-tests"
fi
if [ -n "${{ inputs.test-package }}" ]; then
npm run test:package -- ${{ inputs.test-package }} $EXTRA_ARGS
else
npm run test:all -- $EXTRA_ARGS
fi
env:
APP_URL: ${{ inputs.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 }}-${{ matrix.offset }}
path: |
/home/runner/build/project/vendor/ibexa/**/playwright-tests/playwright-report/
/home/runner/build/project/vendor/ibexa/**/playwright-tests/test-results/
/home/runner/build/project/vendor/ibexa/cohesivo-playwright/playwright-report/
/home/runner/build/project/vendor/ibexa/cohesivo-playwright/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@v1.23.0

Check failure on line 356 in .github/workflows/playwright-browser-tests.yml

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Use full commit SHA hash for this dependency.

See more on https://sonarcloud.io/project/issues?id=ibexa_gh-workflows&issues=AZ9b2-MSKJyKTmB7NrV1&open=AZ9b2-MSKJyKTmB7NrV1&pullRequest=100
with:
payload: ${{ env.SLACK_PAYLOAD }}
env:
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
SLACK_WEBHOOK_TYPE: INCOMING_WEBHOOK