Skip to content

Support Shadow DOM and iframe element grabbing #964

Support Shadow DOM and iframe element grabbing

Support Shadow DOM and iframe element grabbing #964

Workflow file for this run

name: Test Perf
on:
push:
branches: [main]
pull_request:
branches: [main]
permissions:
contents: read
jobs:
test-perf:
runs-on: ubuntu-latest
# PR runs do the bench twice (base ref + HEAD) so the cost roughly
# doubles vs. a push-to-main run.
timeout-minutes: 40
steps:
- name: Checkout
uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Install pnpm
uses: pnpm/action-setup@v6
- name: Setup Node.js
uses: actions/setup-node@v6
with:
node-version: 22
cache: pnpm
- name: Install dependencies
run: pnpm install
- name: Install Playwright browsers
run: pnpm --filter react-grab exec playwright install chromium --with-deps
# ─── Baseline run (PR only) ────────────────────────────────────────
# Swap `packages/react-grab/src/` to the base ref so the same
# bench harness measures the OLD library code. The harness itself
# (`e2e/perf-*.ts`, `scripts/diff-perf-runs.mjs`) and the fixture-app
# stimulus stay at HEAD so the only variable across runs is
# react-grab's source.
- name: Swap react-grab src to base ref
id: swap-base
if: github.event_name == 'pull_request'
run: |
git fetch origin "${{ github.base_ref }}" --depth=1
if git cat-file -e "origin/${{ github.base_ref }}:packages/react-grab/src" 2>/dev/null; then
git checkout "origin/${{ github.base_ref }}" -- packages/react-grab/src
echo "swapped=true" >> "$GITHUB_OUTPUT"
echo "Swapped react-grab/src to origin/${{ github.base_ref }} ($(git rev-parse "origin/${{ github.base_ref }}"))"
else
echo "Base ref lacks packages/react-grab/src; skipping baseline run."
echo "swapped=false" >> "$GITHUB_OUTPUT"
fi
- name: Run perf bench against base ref src
if: github.event_name == 'pull_request' && steps.swap-base.outputs.swapped == 'true'
env:
PERF_LABEL: baseline
# --workers=1 keeps perf measurements off the noise floor that
# the sharded `test-e2e` workflow creates by running 4 workers
# in parallel. Playwright's webServer auto-runs
# `pnpm --filter react-grab build` so the dev server picks up
# whichever src is checked out.
run: pnpm --filter react-grab exec playwright test --grep @perf --workers=1 --reporter=list
- name: Restore react-grab src to HEAD
if: github.event_name == 'pull_request' && steps.swap-base.outputs.swapped == 'true'
run: git checkout HEAD -- packages/react-grab/src
# ─── HEAD run ──────────────────────────────────────────────────────
- name: Run perf bench against HEAD src
env:
PERF_LABEL: current
run: pnpm --filter react-grab exec playwright test --grep @perf --workers=1 --reporter=list
# ─── Diff & surface ────────────────────────────────────────────────
- name: Compute baseline-vs-current diff
if: always() && github.event_name == 'pull_request'
run: |
node packages/react-grab/scripts/diff-perf-runs.mjs packages/react-grab/perf/baseline packages/react-grab/perf/current | tee perf-diff.md >> "$GITHUB_STEP_SUMMARY"
- name: Upload perf diff
if: always() && github.event_name == 'pull_request'
uses: actions/upload-artifact@v4
with:
name: perf-diff
path: perf-diff.md
if-no-files-found: ignore
retention-days: 14
- name: Upload perf reports
if: always()
uses: actions/upload-artifact@v4
with:
name: perf-bench-${{ github.event.pull_request.number || github.sha }}
path: packages/react-grab/perf/
if-no-files-found: warn
retention-days: 14
# Separate job so the write-scoped token never coexists with the bench
# job, which builds and executes the PR's own code. This job runs no
# repo code at all — it only downloads the diff artifact and posts it.
# Sticky comment: created once, updated in place on later pushes.
perf-comment:
needs: test-perf
if: always() && github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository
runs-on: ubuntu-latest
timeout-minutes: 5
permissions:
pull-requests: write
steps:
- name: Download perf diff
uses: actions/download-artifact@v4
continue-on-error: true
with:
name: perf-diff
- name: Post perf diff as PR comment
uses: actions/github-script@v7
with:
script: |
const { readFileSync } = require("node:fs");
const marker = "<!-- perf-diff-comment -->";
let diffBody;
try {
diffBody = readFileSync("perf-diff.md", "utf8").trim();
} catch {
return;
}
if (!diffBody) return;
const body = `${marker}\n${diffBody}\n\n<sub>Commit ${context.payload.pull_request.head.sha.slice(0, 7)} · full reports in the \`perf-bench-${context.payload.pull_request.number}\` artifact.</sub>`;
const { data: comments } = await github.rest.issues.listComments({
...context.repo,
issue_number: context.payload.pull_request.number,
per_page: 100,
});
const existingComment = comments.find((comment) => comment.body?.startsWith(marker));
if (existingComment) {
await github.rest.issues.updateComment({
...context.repo,
comment_id: existingComment.id,
body,
});
} else {
await github.rest.issues.createComment({
...context.repo,
issue_number: context.payload.pull_request.number,
body,
});
}