Skip to content
Closed
Show file tree
Hide file tree
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
86 changes: 86 additions & 0 deletions .github/workflows/playwright-reports.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
name: Playwright Snapshot Report

on:
pull_request:
types: [opened, synchronize, reopened]

jobs:
snapshot-report:
runs-on: ubuntu-latest

if: ${{ github.actor != 'dependabot[bot]' }}

permissions:
contents: write
pull-requests: write

steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Ensure snapshot dirs are writable
run: |
mkdir -p e2e/tests/screenshot-test.spec.js-snapshots
sudo chown -R 1000:1000 e2e/tests/screenshot-test.spec.js-snapshots

- name: Create Docker network
run: docker network create sf-website-development || true

- name: Run Playwright tests with snapshot update
run: |
docker compose -f docker-compose.yml -f docker-compose.e2e.yml run --name apostrophe-playwright-test --build \
--entrypoint "sh -c 'until wget -qO- http://apostrophe:3000/ > /dev/null; do echo Waiting for Apostrophe...; sleep 2; done && npm run test:e2e:update -c playwright.config.js'" \
playwright-test
continue-on-error: false

- name: Copy snapshots from Docker volume
run: |
mkdir -p website/e2e/pr-snapshots/screenshot-test.spec.js-snapshots
docker cp $(docker ps -aqf "name=apostrophe-playwright-test"):/e2e/tests/screenshot-test.spec.js-snapshots ./website/e2e/pr-snapshots/screenshot-test.spec.js-snapshots

- name: Upload snapshots as artifact
uses: actions/upload-artifact@v4
with:
name: playwright-snapshots-pr
path: website/e2e/pr-snapshots/screenshot-test.spec.js-snapshots
overwrite: true
retention-days: 20

- name: Generate comment body with links
id: comment
run: |
ARTIFACT_URL="https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}"
COMMENT_BODY="🧪 **Playwright Snapshot Report**

🖼️ Screenshots have been updated and attached as an artifact.

🔗 [View Artifacts & Download Snapshots]($ARTIFACT_URL)

_This comment updates automatically with each commit._"

echo "body<<EOF" >> $GITHUB_OUTPUT
echo "$COMMENT_BODY" >> $GITHUB_OUTPUT
echo "EOF" >> $GITHUB_OUTPUT

- name: Post or update comment on PR
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
PR_NUMBER=${{ github.event.pull_request.number }}
COMMENT_BODY="${{ steps.comment.outputs.body }}"

COMMENT_ID=$(gh pr view $PR_NUMBER --json comments \
--jq '.comments[] | select(.body | contains("🧪 **Playwright Snapshot Report**")) | .id')

if [ -n "$COMMENT_ID" ]; then
echo "Updating existing comment ID: $COMMENT_ID"
gh pr comment $PR_NUMBER --edit "$COMMENT_ID" --body "$COMMENT_BODY"
else
echo "Creating new comment"
gh pr comment $PR_NUMBER --body "$COMMENT_BODY"
fi

- name: Cleanup Docker
run: |
docker compose -f docker-compose.yml -f docker-compose.e2e.yml down --volumes --remove-orphans
docker network rm sf-website-development || true
52 changes: 30 additions & 22 deletions website/e2e/tests/screenshot-test.spec.js
Original file line number Diff line number Diff line change
@@ -1,29 +1,37 @@
import { test, expect } from '@playwright/test';

test('Snapshot for Home Page', async ({ page }) => {
await page.setViewportSize({
width: 1280,
height: 720,
});
const routes = [
{ path: '/', name: 'homepage.png' },
{ path: '/cases', name: 'cases.png' },
{ path: '/about-us', name: 'about-us.png' },
];

await page.goto(process.env.BASE_URL ?? 'http://localhost:3000', {
timeout: 60000,
waitUntil: 'networkidle',
});
for (const { path, name } of routes) {
test(`Snapshot for ${path}`, async ({ page }) => {
await page.setViewportSize({ width: 1280, height: 720 });

await Promise.all([
page.waitForLoadState('domcontentloaded'),
page.waitForLoadState('networkidle'),
]);
await page.evaluate(() => document.fonts.ready);
await page.goto(
`${process.env.BASE_URL ?? 'http://localhost:3000'}${path}`,
{
timeout: 60000,
waitUntil: 'networkidle',
},
);

const snapshot = await page.screenshot({
fullPage: true,
timeout: 30000,
});
await Promise.all([
page.waitForLoadState('domcontentloaded'),
page.waitForLoadState('networkidle'),
]);
await page.evaluate(() => document.fonts.ready);

const snapshot = await page.screenshot({
fullPage: true,
timeout: 30000,
});

expect(snapshot).toMatchSnapshot('homepage.png', {
maxDiffPixels: 300,
threshold: 0.5,
expect(snapshot).toMatchSnapshot(name, {
maxDiffPixels: 300,
threshold: 0.5,
});
});
});
}
Loading