From 3c3aa7a8ce825240e0b8c906f62661274eb88ddb Mon Sep 17 00:00:00 2001 From: Michael Seele Date: Mon, 8 Jun 2026 15:06:22 +0000 Subject: [PATCH] feat: add playwright actions with documentation --- .forgejo/workflows/tag-release.yml | 2 + README.md | 2 + playwright-merge/README.md | 39 +++++++++++ playwright-merge/action.yml | 104 +++++++++++++++++++++++++++++ playwright-run/README.md | 33 +++++++++ playwright-run/action.yml | 87 ++++++++++++++++++++++++ 6 files changed, 267 insertions(+) create mode 100644 playwright-merge/README.md create mode 100644 playwright-merge/action.yml create mode 100644 playwright-run/README.md create mode 100644 playwright-run/action.yml diff --git a/.forgejo/workflows/tag-release.yml b/.forgejo/workflows/tag-release.yml index 21f5c87..3bd09b0 100644 --- a/.forgejo/workflows/tag-release.yml +++ b/.forgejo/workflows/tag-release.yml @@ -24,6 +24,8 @@ on: - inject-content - maven-build - pnpm-build + - playwright-merge + - playwright-run - publish-static-contents - rust-build - terraform-apply diff --git a/README.md b/README.md index bfb6f69..cf223c2 100644 --- a/README.md +++ b/README.md @@ -17,6 +17,8 @@ Shared actions for Forgejo CI/CD pipelines. | [inject-content](inject-content) | Inject content into a file by appending or overwriting | | [maven-build](maven-build) | Action for building and validating Maven projects | | [pnpm-build](pnpm-build) | Action for building and validating with PNPM | +| [playwright-merge](playwright-merge) | Merge Playwright shard blob reports and publish consolidated reports | +| [playwright-run](playwright-run) | Run Playwright tests for one shard and upload its blob report | | [publish-static-contents](publish-static-contents) | Syncs frontend assets to S3 and invalidates a CloudFront distribution | | [rust-build](rust-build) | Set up Rust toolchain, run checks, and build via the project's build.sh | | [terraform-apply](terraform-apply) | Apply Terraform configuration files using the official Terraform CLI | diff --git a/playwright-merge/README.md b/playwright-merge/README.md new file mode 100644 index 0000000..fdc9845 --- /dev/null +++ b/playwright-merge/README.md @@ -0,0 +1,39 @@ +# playwright-merge + +Download all Playwright blob reports from shard jobs, merge them into a single HTML + JUnit report, and optionally upload the HTML report to S3. + +## Inputs + +| Input | Required | Default | Description | +|-------|----------|---------|-------------| +| `working-directory` | No | `.` | Directory containing `package.json` and `playwright.config.ts` | +| `node-version` | No | `24` | Node.js version | +| `pnpm-version` | No | `10.33` | pnpm version | +| `jfrog-token` | No | `""` | JFrog npm auth token | +| `role-arn` | Yes | — | IAM role ARN for AWS authentication | +| `aws-access-key-id` | Yes | — | AWS access key ID | +| `aws-secret-access-key` | Yes | — | AWS secret access key | +| `project-name` | Yes | — | Project name used as the folder in the report bucket (e.g. `hs-pricelist`) | +| `publish-test-reports` | No | `true` | Whether to upload the report to S3 and print the URL at `https://test-reports.schmalz.com` | + +## Usage + +```yaml +- uses: https://schmalz-git.git.onstackit.cloud/schmalz/shared-actions/playwright-merge@playwright-merge-v1 + with: + working-directory: frontend + node-version: 22 + jfrog-token: ${{ secrets.JFROG_TOKEN }} + role-arn: arn:aws:iam::953815822701:role/deployment-role + aws-access-key-id: ${{ secrets.DB_STAGE_DEPLOYMENT_ACCESS_KEY }} + aws-secret-access-key: ${{ secrets.DB_STAGE_DEPLOYMENT_SECRET_ACCESS_KEY }} + project-name: hs-pricelist +``` + +## Notes + +- Intended as a follow-up job after all `playwright-run` shard jobs complete. +- Downloads shard artifacts into `all-blob-reports/` and merges them with `playwright merge-reports`. +- Generates HTML report in `playwright-report/` and JUnit XML in `test-results/junit.xml`. +- Uploads report files to `s3://com.schmalz.db.stage.test-reports/reports///` when `publish-test-reports` is `true`. +- Prints the final report URL on `https://test-reports.schmalz.com`. diff --git a/playwright-merge/action.yml b/playwright-merge/action.yml new file mode 100644 index 0000000..f7ae409 --- /dev/null +++ b/playwright-merge/action.yml @@ -0,0 +1,104 @@ +name: Playwright Merge +description: > + Download all blob reports from shard jobs, merge them into a single HTML + JUnit + report, upload the HTML report to S3, and upload the JUnit report as an artifact. + Call this in a follow-up job after all playwright-run shard jobs complete. + +inputs: + working-directory: + description: Directory containing package.json and playwright.config.ts + required: false + default: "." + node-version: + description: Node.js version + required: false + default: "24" + pnpm-version: + description: pnpm version + required: false + default: "10.33" + jfrog-token: + description: JFrog npm auth token + required: false + default: "" + role-arn: + description: IAM role ARN for AWS authentication + required: true + aws-access-key-id: + description: AWS access key ID + required: true + aws-secret-access-key: + description: AWS secret access key + required: true + project-name: + description: Project name used as the folder in the report bucket (e.g. hs-pricelist) + required: true + publish-test-reports: + description: Whether to upload the report to S3 and print the URL at https://test-reports.schmalz.com. Set to false to skip upload entirely. + required: false + default: "true" + +runs: + using: composite + steps: + - name: Install AWS CLI + shell: bash + run: | + if ! command -v aws &>/dev/null; then + curl -fsSL "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o /tmp/awscliv2.zip + unzip -q /tmp/awscliv2.zip -d /tmp + sudo /tmp/aws/install + rm -rf /tmp/awscliv2.zip /tmp/aws + fi + + - name: Configure AWS + uses: https://schmalz-git.git.onstackit.cloud/schmalz/shared-actions/aws-configure@aws-configure-v1 + with: + role-arn: ${{ inputs.role-arn }} + aws-access-key-id: ${{ inputs.aws-access-key-id }} + aws-secret-access-key: ${{ inputs.aws-secret-access-key }} + + - name: Install dependencies + uses: https://schmalz-git.git.onstackit.cloud/schmalz/shared-actions/pnpm-build@pnpm-build-v1 + with: + working-directory: ${{ inputs.working-directory }} + node-version: ${{ inputs.node-version }} + pnpm-version: ${{ inputs.pnpm-version }} + jfrog-token: ${{ inputs.jfrog-token }} + run-scripts: "" + frozen-lockfile: "true" + check-dedupe: "false" + + - name: Download blob reports + uses: https://schmalz-git.git.onstackit.cloud/schmalz/shared-actions/download-artifact@download-artifact-v1 + with: + path: ${{ inputs.working-directory }}/all-blob-reports/ + merge-multiple: "true" + + - name: Merge blob reports + shell: bash + env: + CI: "true" + WORKING_DIR: ${{ inputs.working-directory }} + PLAYWRIGHT_JUNIT_OUTPUT_NAME: test-results/junit.xml + run: | + cd "${WORKING_DIR}" + pnpm exec playwright merge-reports \ + --reporter=html,junit \ + all-blob-reports/ + + - name: Upload report to S3 + if: ${{ inputs.publish-test-reports == 'true' }} + shell: bash + env: + WORKING_DIR: ${{ inputs.working-directory }} + PROJECT_NAME: ${{ inputs.project-name }} + run: | + TIMESTAMP=$(date +%s) + S3_BUCKET=com.schmalz.db.stage.test-reports + S3_PATH="s3://${S3_BUCKET}/reports/${PROJECT_NAME}/${TIMESTAMP}" + aws s3 sync "${WORKING_DIR}/playwright-report/" "${S3_PATH}/" + if [ -f "${WORKING_DIR}/test-results/junit.xml" ]; then + aws s3 cp "${WORKING_DIR}/test-results/junit.xml" "${S3_PATH}/junit.xml" + fi + echo "Report URL: https://test-reports.schmalz.com/reports/${PROJECT_NAME}/${TIMESTAMP}/index.html" diff --git a/playwright-run/README.md b/playwright-run/README.md new file mode 100644 index 0000000..825b354 --- /dev/null +++ b/playwright-run/README.md @@ -0,0 +1,33 @@ +# playwright-run + +Run Playwright E2E tests for one shard and upload the blob report as an artifact. + +## Inputs + +| Input | Required | Default | Description | +|-------|----------|---------|-------------| +| `working-directory` | No | `.` | Directory containing `package.json` and `playwright.config.ts` | +| `node-version` | No | `24` | Node.js version | +| `pnpm-version` | No | `10.33` | pnpm version | +| `jfrog-token` | No | `""` | JFrog npm auth token | +| `shard-index` | No | `1` | Current shard index (1-based). Set to `1` when not sharding. | +| `shard-total` | No | `1` | Total number of shards. Set to `1` to disable sharding. | +| `artifact-retention-days` | No | `3` | Number of days to retain the blob report artifact | + +## Usage + +```yaml +- uses: https://schmalz-git.git.onstackit.cloud/schmalz/shared-actions/playwright-run@playwright-run-v1 + with: + working-directory: frontend + node-version: 22 + jfrog-token: ${{ secrets.JFROG_TOKEN }} + shard-index: ${{ matrix.shard-index }} + shard-total: 5 +``` + +## Notes + +- Intended for matrix shard jobs. +- Uploads one artifact per shard named `blob-report-`. +- Use `playwright-merge` in a follow-up job to merge shard reports. diff --git a/playwright-run/action.yml b/playwright-run/action.yml new file mode 100644 index 0000000..b07b29b --- /dev/null +++ b/playwright-run/action.yml @@ -0,0 +1,87 @@ +name: Playwright Run +description: > + Run Playwright E2E tests for one shard and upload the blob report as an artifact. + Call this from a matrix job. Use the playwright-merge action in a follow-up job + to produce the final HTML + JUnit report. + +inputs: + working-directory: + description: Directory containing package.json and playwright.config.ts + required: false + default: "." + node-version: + description: Node.js version + required: false + default: "24" + pnpm-version: + description: pnpm version + required: false + default: "10.33" + jfrog-token: + description: JFrog npm auth token + required: false + default: "" + shard-index: + description: Current shard index (1-based). Set to 1 when not sharding. + required: false + default: "1" + shard-total: + description: Total number of shards. Set to 1 to disable sharding. + required: false + default: "1" + artifact-retention-days: + description: Number of days to retain the blob report artifact + required: false + default: "3" + +runs: + using: composite + steps: + - name: Install dependencies + uses: https://schmalz-git.git.onstackit.cloud/schmalz/shared-actions/pnpm-build@pnpm-build-v1 + with: + working-directory: ${{ inputs.working-directory }} + node-version: ${{ inputs.node-version }} + pnpm-version: ${{ inputs.pnpm-version }} + jfrog-token: ${{ inputs.jfrog-token }} + run-scripts: "" + frozen-lockfile: "true" + check-dedupe: "false" + + - name: Cache Playwright browsers + id: playwright-cache + uses: https://schmalz-git.git.onstackit.cloud/schmalz/shared-actions/cache@cache-v1 + with: + path: ~/.cache/ms-playwright + key: ${{ runner.os }}-playwright-${{ hashFiles('**/pnpm-lock.yaml') }} + restore-keys: ${{ runner.os }}-playwright- + + - name: Install Playwright browsers + if: ${{ steps.playwright-cache.outputs.cache-hit != 'true' }} + shell: bash + env: + WORKING_DIR: ${{ inputs.working-directory }} + run: pnpm --prefix="${WORKING_DIR}" exec playwright install --with-deps + + - name: Run Playwright tests + shell: bash + env: + CI: "true" + WORKING_DIR: ${{ inputs.working-directory }} + SHARD_INDEX: ${{ inputs.shard-index }} + SHARD_TOTAL: ${{ inputs.shard-total }} + run: | + SHARD_ARG="" + if [ "${SHARD_TOTAL}" != "1" ]; then + SHARD_ARG="--shard=${SHARD_INDEX}/${SHARD_TOTAL}" + fi + pnpm --prefix="${WORKING_DIR}" exec playwright test ${SHARD_ARG} --reporter=blob,dot + + - name: Upload blob report + if: ${{ !cancelled() }} + uses: https://schmalz-git.git.onstackit.cloud/schmalz/shared-actions/upload-artifact@upload-artifact-v1 + with: + name: blob-report-${{ inputs.shard-index }} + path: ${{ inputs.working-directory }}/blob-report/ + retention-days: ${{ inputs.artifact-retention-days }} + if-no-files-found: ignore -- 2.49.1