Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
642ec36
fix(test): resolve @videojs/cdn imports in the e2e player app
mihar-22 Sep 7, 2026
8379f20
fix(test): hold the stall in the buffering indicator e2e
mihar-22 Sep 7, 2026
22af70b
fix(test): preset the volume before keyboard feedback parity
mihar-22 Sep 7, 2026
69d0c9a
refactor(test): keep skin parity to two-panel comparisons
mihar-22 Sep 7, 2026
b0b7b22
ci(ci): run browser suites on pull requests that touch rendered code
mihar-22 Sep 7, 2026
3c7279a
fix(test): match the play button exactly in the skin override e2e
mihar-22 Sep 7, 2026
bca6c28
fix(skin): size the slotted video inside the HTML skin
mihar-22 Sep 7, 2026
975efd1
test(test): mark the WebKit thumbnail max-height as a known gap
mihar-22 Sep 7, 2026
6fedcba
ci(ci): run pull requests on chromium only and gate skin parity on sk…
mihar-22 Sep 7, 2026
5916d2f
fix(vjsc): emit shadow host rules outside the scope block for WebKit
mihar-22 Sep 7, 2026
12bedad
fix(test): wait for the storyboard before measuring fullscreen previe…
mihar-22 Sep 7, 2026
46545de
ci(ci): build once for the browser suites and retry pull requests once
mihar-22 Sep 7, 2026
49699ae
test(test): compare parity renderings in the page and settle contract…
mihar-22 Sep 7, 2026
e65656f
test(test): snapshot every packaged skin layout in the player suite
mihar-22 Sep 7, 2026
9c945dd
ci(ci): add a manual workflow that records e2e snapshots in the CI co…
mihar-22 Sep 7, 2026
36ff471
ci(ci): record snapshots from a labeled pull request
mihar-22 Sep 7, 2026
0d595b8
fix(test): settle the preview transition before measuring fullscreen …
mihar-22 Sep 7, 2026
f3b144e
test(test): record the skin layout baselines from the CI container
mihar-22 Sep 7, 2026
2651b2f
fix(test): settle fonts before measuring fullscreen gaps
mihar-22 Sep 7, 2026
87b396a
fix(test): measure parity labels once Inter has loaded them
mihar-22 Sep 7, 2026
7398afe
fix(ci): build snapshot recording dependencies
mihar-22 Sep 7, 2026
7169f56
fix(vjsc): preserve shadow host fallback semantics
mihar-22 Sep 7, 2026
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
207 changes: 190 additions & 17 deletions .github/workflows/e2e.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,17 +13,92 @@ concurrency:
cancel-in-progress: true

jobs:
# Pull requests run the browser suites when they touch code the suites render; the `test:e2e` label forces them.
changes:
name: Changed areas
if: github.event_name == 'pull_request'
runs-on: ubuntu-latest
outputs:
player: ${{ steps.filter.outputs.player }}
skins: ${{ steps.filter.outputs.skins }}
steps:
- name: Detect e2e-relevant changes
id: filter
env:
GH_TOKEN: ${{ github.token }}
GH_REPO: ${{ github.repository }}
NUMBER: ${{ github.event.pull_request.number }}
run: |
files=$(gh api "repos/$GH_REPO/pulls/$NUMBER/files" --paginate --jq '.[].filename')
flag() {
if grep -Eq "$2" <<<"$files"; then echo "$1=true" >> "$GITHUB_OUTPUT"; else echo "$1=false" >> "$GITHUB_OUTPUT"; fi
}
# The player suite renders the built packages; skin parity compiles the authored skins in the sandbox.
flag player '^(apps/e2e/|apps/sandbox/|packages/|\.github/workflows/e2e\.yml$|pnpm-lock\.yaml$)'
flag skins '^(apps/e2e/(shared|suites/skin-parity)/|apps/sandbox/|packages/(skins|vjsc|html|react)/|\.github/workflows/e2e\.yml$|pnpm-lock\.yaml$)'

# Every browser job replays this run's Vite Task cache, so the packages, CDN bundles, generated skins, and sandbox
# setup compile once per run instead of once per job.
build:
name: Build for browser suites
needs: changes
if: ${{ !cancelled() && (github.event_name == 'push' || needs.changes.outputs.player == 'true' || needs.changes.outputs.skins == 'true' || contains(github.event.pull_request.labels.*.name, 'test:e2e') || contains(github.event.pull_request.labels.*.name, 'record:snapshots')) }}
runs-on: ubuntu-latest
container:
image: mcr.microsoft.com/playwright:v1.59.1-noble
timeout-minutes: 15

steps:
- name: Checkout code
uses: actions/checkout@v5

- name: Setup pnpm
uses: pnpm/action-setup@v4

- name: Setup Node.js
uses: actions/setup-node@v5
with:
node-version-file: '.nvmrc'
cache: pnpm

- name: Install dependencies
run: pnpm install --frozen-lockfile

- name: Restore Vite Task cache
id: vite-task-cache
uses: actions/cache/restore@v6
with:
path: node_modules/.vite/task-cache
key: vite-task-${{ runner.os }}-${{ runner.arch }}-e2e-${{ github.sha }}-${{ github.run_attempt }}
restore-keys: |
vite-task-${{ runner.os }}-${{ runner.arch }}-e2e-
vite-task-${{ runner.os }}-${{ runner.arch }}-packages-

- name: Build packages and CDN bundles
run: pnpm build:packages && pnpm build:cdn

- name: Prepare the e2e pages, generated skins, and sandbox
run: pnpm exec vp run '@videojs/e2e#prepare:player' && pnpm exec vp run '@videojs/skins#generate' && pnpm exec vp run '@videojs/sandbox#setup'

- name: Save Vite Task cache
uses: actions/cache/save@v6
with:
path: node_modules/.vite/task-cache
key: ${{ steps.vite-task-cache.outputs.cache-primary-key }}

e2e:
name: E2E (${{ matrix.browser }})
if: github.event_name == 'push' || contains(github.event.pull_request.labels.*.name, 'test:e2e')
needs: [changes, build]
if: ${{ !cancelled() && needs.build.result == 'success' && (github.event_name == 'push' || needs.changes.outputs.player == 'true' || contains(github.event.pull_request.labels.*.name, 'test:e2e')) }}
runs-on: ubuntu-latest
container:
image: mcr.microsoft.com/playwright:v1.59.1-noble
timeout-minutes: 15
strategy:
fail-fast: false
matrix:
browser: [chromium, webkit]
# WebKit doubles the wall time, so pull requests run Chromium only and main covers both.
browser: ${{ fromJSON(github.event_name == 'push' && '["chromium", "webkit"]' || '["chromium"]') }}

steps:
- name: Checkout code
Expand All @@ -45,26 +120,17 @@ jobs:
uses: actions/cache/restore@v6
with:
path: node_modules/.vite/task-cache
key: vite-task-${{ runner.os }}-${{ runner.arch }}-restore-only-${{ github.run_id }}-${{ github.run_attempt }}-${{ github.job }}
key: vite-task-${{ runner.os }}-${{ runner.arch }}-e2e-${{ github.sha }}-${{ github.run_attempt }}
restore-keys: |
vite-task-${{ runner.os }}-${{ runner.arch }}-e2e-
vite-task-${{ runner.os }}-${{ runner.arch }}-packages-

- name: Build packages
run: pnpm build:packages

- name: Build CDN bundles
run: pnpm build:cdn

- name: Generate E2E test pages
run: pnpm --dir apps/e2e generate-pages
- name: Replay the build
run: pnpm build:packages && pnpm build:cdn && pnpm exec vp run '@videojs/e2e#prepare:player'

- name: Run E2E tests
run: pnpm --dir apps/e2e exec playwright test --config suites/player/playwright.config.ts --project=vite-${{ matrix.browser }}

- name: Run sandbox E2E tests
if: matrix.browser == 'chromium'
run: pnpm exec vp run '@videojs/e2e#test:sandbox'

- name: Upload test report
if: always()
uses: actions/upload-artifact@v4
Expand All @@ -81,9 +147,63 @@ jobs:
path: apps/e2e/test-results/
retention-days: 7

sandbox:
name: Sandbox
needs: [changes, build]
if: ${{ !cancelled() && needs.build.result == 'success' && (github.event_name == 'push' || needs.changes.outputs.player == 'true' || contains(github.event.pull_request.labels.*.name, 'test:e2e')) }}
runs-on: ubuntu-latest
container:
image: mcr.microsoft.com/playwright:v1.59.1-noble
timeout-minutes: 15

steps:
- name: Checkout code
uses: actions/checkout@v5

- name: Setup pnpm
uses: pnpm/action-setup@v4

- name: Setup Node.js
uses: actions/setup-node@v5
with:
node-version-file: '.nvmrc'
cache: pnpm

- name: Install dependencies
run: pnpm install --frozen-lockfile

- name: Restore Vite Task cache
uses: actions/cache/restore@v6
with:
path: node_modules/.vite/task-cache
key: vite-task-${{ runner.os }}-${{ runner.arch }}-e2e-${{ github.sha }}-${{ github.run_attempt }}
restore-keys: |
vite-task-${{ runner.os }}-${{ runner.arch }}-e2e-
vite-task-${{ runner.os }}-${{ runner.arch }}-packages-

- name: Run sandbox E2E tests
run: pnpm exec vp run '@videojs/e2e#test:sandbox'

- name: Upload test report
if: always()
uses: actions/upload-artifact@v4
with:
name: playwright-report-sandbox
path: apps/e2e/playwright-report/sandbox/
retention-days: 14

- name: Upload test traces
if: failure()
uses: actions/upload-artifact@v4
with:
name: playwright-traces-sandbox
path: apps/e2e/test-results/sandbox/
retention-days: 7

skin-parity:
name: Skin parity (${{ matrix.preset }})
if: github.event_name == 'push' || contains(github.event.pull_request.labels.*.name, 'test:e2e')
needs: [changes, build]
if: ${{ !cancelled() && needs.build.result == 'success' && (github.event_name == 'push' || needs.changes.outputs.skins == 'true' || contains(github.event.pull_request.labels.*.name, 'test:e2e')) }}
runs-on: ubuntu-latest
container:
image: mcr.microsoft.com/playwright:v1.59.1-noble
Expand Down Expand Up @@ -113,8 +233,9 @@ jobs:
uses: actions/cache/restore@v6
with:
path: node_modules/.vite/task-cache
key: vite-task-${{ runner.os }}-${{ runner.arch }}-restore-only-${{ github.run_id }}-${{ github.run_attempt }}-${{ github.job }}
key: vite-task-${{ runner.os }}-${{ runner.arch }}-e2e-${{ github.sha }}-${{ github.run_attempt }}
restore-keys: |
vite-task-${{ runner.os }}-${{ runner.arch }}-e2e-
vite-task-${{ runner.os }}-${{ runner.arch }}-packages-

- name: Run skin parity E2E tests
Expand All @@ -138,6 +259,58 @@ jobs:
path: apps/e2e/test-results/skin-parity/
retention-days: 7

# Baselines only match when recorded in the image the suites run in. Label a pull request `record:snapshots` to
# record the player visual specs here; download the artifact, copy the `*-snapshots` directories into place, and
# commit them.
snapshots:
name: Record snapshots
needs: [changes, build]
if: ${{ !cancelled() && needs.build.result == 'success' && contains(github.event.pull_request.labels.*.name, 'record:snapshots') }}
runs-on: ubuntu-latest
container:
image: mcr.microsoft.com/playwright:v1.59.1-noble
timeout-minutes: 20

steps:
- name: Checkout code
uses: actions/checkout@v5

- name: Setup pnpm
uses: pnpm/action-setup@v4

- name: Setup Node.js
uses: actions/setup-node@v5
with:
node-version-file: '.nvmrc'
cache: pnpm

- name: Install dependencies
run: pnpm install --frozen-lockfile

- name: Restore Vite Task cache
uses: actions/cache/restore@v6
with:
path: node_modules/.vite/task-cache
key: vite-task-${{ runner.os }}-${{ runner.arch }}-e2e-${{ github.sha }}-${{ github.run_attempt }}
restore-keys: |
vite-task-${{ runner.os }}-${{ runner.arch }}-e2e-
vite-task-${{ runner.os }}-${{ runner.arch }}-packages-

- name: Replay the build
run: pnpm build:packages && pnpm build:cdn && pnpm exec vp run '@videojs/e2e#prepare:player'

- name: Record player visual snapshots
working-directory: apps/e2e
run: pnpm exec playwright test --config suites/player/playwright.config.ts visual --update-snapshots --project=vite-chromium --project=vite-webkit

- name: Upload snapshots
if: always()
uses: actions/upload-artifact@v4
with:
name: e2e-snapshots
path: apps/e2e/suites/player/tests/**/*-snapshots/
retention-days: 7

registry:
name: Registry consumers
runs-on: ubuntu-latest
Expand Down
1 change: 1 addition & 0 deletions apps/e2e/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
"@playwright/test": "^1.52.0",
"@types/react": "^19.2.17",
"@types/react-dom": "^19.2.3",
"@videojs/cdn": "workspace:*",
"@videojs/core": "workspace:*",
"@videojs/html": "workspace:*",
"@videojs/icons": "workspace:*",
Expand Down
Loading
Loading