Skip to content

fix(test): repair the e2e suites - #2640

Merged
mihar-22 merged 22 commits into
mainfrom
fix/e2e-suite-failures
Sep 7, 2026
Merged

fix(test): repair the e2e suites#2640
mihar-22 merged 22 commits into
mainfrom
fix/e2e-suite-failures

Conversation

@mihar-22

@mihar-22 mihar-22 commented Sep 7, 2026

Copy link
Copy Markdown
Member

Summary

The E2E workflow has been red on every push to main since August 27. Three regressions merged without running the browser suites, and two tests were flaky. This repairs the suites, tightens what the skin-parity suite owns, fixes the regressions the repaired suites then surfaced, and makes the browser suites cheaper to run on pull requests.

Changes

  • The e2e player app declares @videojs/cdn, so the CDN pages resolve again, and its prepare task builds the CDN bundles.
  • The buffering indicator test freezes currentTime at the stall, matching how the store clears waiting since fix(core): stop waiting from latching when readyState never recovers #2574.
  • The sandbox width control test leaves skin parity. It exercised the shell, the sandbox suite already covers it, and it broke when feat(sandbox): fold the skins playground into the sandbox #2586 moved the control into a closed options panel.
  • The consumer-override test moves to the player suite, where the packaged CSS skin is what consumers restyle and WebKit also runs.
  • Each Playwright config states what its suite owns: parity holds two-panel comparisons, player holds single-outcome behavior, sandbox holds the shell.

Unblocking the CDN pages let the rest of the serial visual spec run again for the first time since Sept 3, which surfaced regressions on main:

  • The HTML skin no longer sized the slotted video. refactor(skin): remove legacy skin implementation #2550 removed the legacy ::slotted(video) rule and the base video rule cannot cross the shadow boundary, so the page's video kept its intrinsic size, overflowed the container, and pushed native captions out of view. The container styles now size it for the Shadow DOM variant. The existing captions baseline passes unchanged with this fix.
  • WebKit skips @scope rules on shadow hosts. The slider thumbnail is the only such element in the HTML skin, so its max height and clipping never applied in Safari. VJSC style rules can now declare shadowHost, and the renderer emits those rules outside the scope block with the scope root as an ancestor, the same way it already handles slotted rules. The portrait thumbnail test runs on WebKit again.
  • The sandbox lost its cn helper when shadcn's remote utils registry item changed to export { cn } from "cn". fix(packages): adopt cn for class name merging #2641 on main adopts the cn package, which resolves it; this branch is rebased on top of it.

Suite organization, second pass:

  • Skin parity no longer keeps PNG baselines. It captures the CSS panel in the page as the reference for the Tailwind panel, which is the comparison it exists for. The 94 baselines are gone.
  • The player suite holds every packaged skin to a layout baseline instead: default and minimal, HTML and React, video and audio, at the two widths where each layout changes. The e2e app gained minimal-skin pages for that.
  • The parity contracts wait for the store's volume, for web fonts, and for running transitions before reading, and round centered insets to whole pixels. The dominant cause of the recurring flakes was Inter: the CI container has no local copy, the sandbox loads it one weight at a time on first use, and labels that appear after an interaction, the keyboard indicators and the fullscreen seek preview, were measured in the fallback face. Fonts now settle after those labels appear, and the fullscreen gap pins follow the settled measurement, which reads two pixels smaller than the fallback did.
  • Label a pull request record:snapshots and the E2E workflow records the player visual baselines in its container and uploads them as an artifact, since baselines only match when recorded in that image.

CI cost:

  • A build job compiles the packages, CDN bundles, generated skins, and sandbox setup once per run and saves that run's Vite Task cache. Every browser job restores it instead of rebuilding.
  • Pull requests run the player suite on Chromium only, and skin parity only when they touch the skins, the compiler, the framework packages, the sandbox, or the parity suite. Pushes to main still run both browsers and every suite.
  • The sandbox suite runs in its own job beside the player suite instead of after it.
  • Pull requests retry a failing test once instead of twice.

Testing

Local runs on macOS, with the PNG comparisons left to CI since the baselines are recorded there.

Suite Local result
Player, Chromium and WebKit full suite green apart from platform snapshots; visual specs 21 passed, 1 skipped after the skin and WebKit fixes
Sandbox 90 passed
Skin parity, all four presets 211 passed before the in-page switch; the switched and hardened contracts pass 16 of 16 keyboard and 10 of 10 fullscreen runs
VJSC and skins unit tests, pnpm typecheck, lint on changed files green

The E2E workflow on this PR runs without the test:e2e label, which exercises the path gating. The run on the final pre-rebase commit was green across the build, player, sandbox, skin parity, and registry jobs, with one known flaky parity test passing on retry. Pushes to main will also run WebKit.


Note

Medium Risk
Touches VJSC CSS emission and shipped skin layout (shadow DOM / WebKit), plus CI path gating that could skip suites on PRs if patterns are wrong; test-only and workflow changes otherwise limit runtime risk.

Overview
Repairs long-failing browser E2E and reshapes CI so PRs only run suites when relevant paths change (or test:e2e / record:snapshots labels apply). A shared build job compiles packages, CDN, skins, and sandbox once and saves a Vite task cache that player, sandbox, skin-parity, and snapshot jobs replay; PR player runs Chromium only (WebKit stays on push to main), sandbox is its own job, and PR retries drop from 2 to 1.

Player suite gains minimal-skin generated pages, layout visual baselines for default/minimal × HTML/React × video/audio, and a consumer CSS override test moved from skin-parity. CDN pages work again via @videojs/cdn and prepare:player depending on build:cdn. The buffering indicator test pins currentTime at the stall so waiting stays observable.

Skin-parity drops stored PNG baselines and compares Tailwind to an in-page CSS capture instead; contracts add presetVolume, font/animation settling, and inset rounding to cut Inter-related flakes.

Product/CSS: HTML skins get a shadow-dom container variant so slotted video fills the player; VJSC adds shadowHost so rules on shadow-root hosts (e.g. thumbnail image) emit outside @scope with :where(scope) ancestors—fixing WebKit skipping scoped rules on shadow hosts.

Reviewed by Cursor Bugbot for commit 7169f56. Bugbot is set up for automated code reviews on this repo. Configure here.

@vercel

vercel Bot commented Sep 7, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
v10-sandbox Ready Ready Preview Sep 7, 2026 6:41pm UTC

Request Review

@netlify

netlify Bot commented Sep 7, 2026

Copy link
Copy Markdown

Deploy Preview for vjs10-site ready!

Name Link
🔨 Latest commit 7169f56
🔍 Latest deploy log https://app.netlify.com/projects/vjs10-site/deploys/6a9f05004e420d000895846c
😎 Deploy Preview https://deploy-preview-2640--vjs10-site.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.
🤖 Make changes Run an agent on this branch

To edit notification comments on pull requests, go to your Netlify project configuration.

@netlify

netlify Bot commented Sep 7, 2026

Copy link
Copy Markdown

Deploy Preview for vjs-registry canceled.

Name Link
🔨 Latest commit 7169f56
🔍 Latest deploy log https://app.netlify.com/projects/vjs-registry/deploys/6a9f0500a1487300099a3224

@pkg-pr-new

pkg-pr-new Bot commented Sep 7, 2026

Copy link
Copy Markdown
@videojs/cdn

pnpm add https://pkg.pr.new/videojs/v10/@videojs/cdn@2640

@videojs/core

pnpm add https://pkg.pr.new/videojs/v10/@videojs/core@2640

@videojs/element

pnpm add https://pkg.pr.new/videojs/v10/@videojs/element@2640

@videojs/html

pnpm add https://pkg.pr.new/videojs/v10/@videojs/html@2640

@videojs/media

pnpm add https://pkg.pr.new/videojs/v10/@videojs/media@2640

@videojs/react

pnpm add https://pkg.pr.new/videojs/v10/@videojs/react@2640

@videojs/spf

pnpm add https://pkg.pr.new/videojs/v10/@videojs/spf@2640

@videojs/store

pnpm add https://pkg.pr.new/videojs/v10/@videojs/store@2640

@videojs/utils

pnpm add https://pkg.pr.new/videojs/v10/@videojs/utils@2640

@videojs/cloudflare-video

pnpm add https://pkg.pr.new/videojs/v10/@videojs/cloudflare-video@2640

@videojs/dash-video

pnpm add https://pkg.pr.new/videojs/v10/@videojs/dash-video@2640

@videojs/hlsjs-video

pnpm add https://pkg.pr.new/videojs/v10/@videojs/hlsjs-video@2640

@videojs/mux-audio

pnpm add https://pkg.pr.new/videojs/v10/@videojs/mux-audio@2640

@videojs/mux-video

pnpm add https://pkg.pr.new/videojs/v10/@videojs/mux-video@2640

@videojs/native-hls-video

pnpm add https://pkg.pr.new/videojs/v10/@videojs/native-hls-video@2640

@videojs/shaka-video

pnpm add https://pkg.pr.new/videojs/v10/@videojs/shaka-video@2640

@videojs/spotify-audio

pnpm add https://pkg.pr.new/videojs/v10/@videojs/spotify-audio@2640

@videojs/tiktok-video

pnpm add https://pkg.pr.new/videojs/v10/@videojs/tiktok-video@2640

@videojs/twitch-video

pnpm add https://pkg.pr.new/videojs/v10/@videojs/twitch-video@2640

@videojs/vimeo-video

pnpm add https://pkg.pr.new/videojs/v10/@videojs/vimeo-video@2640

@videojs/wistia-video

pnpm add https://pkg.pr.new/videojs/v10/@videojs/wistia-video@2640

@videojs/youtube-video

pnpm add https://pkg.pr.new/videojs/v10/@videojs/youtube-video@2640

@videojs/google-cast

pnpm add https://pkg.pr.new/videojs/v10/@videojs/google-cast@2640

@videojs/mux-data

pnpm add https://pkg.pr.new/videojs/v10/@videojs/mux-data@2640

commit: 7169f56

@github-actions

github-actions Bot commented Sep 7, 2026

Copy link
Copy Markdown
Contributor

📦 Bundle Size Report

🎨 @videojs/html — 30 small size changes
Path Base initial PR initial Initial diff Lazy diff
/video/minimal-skin.css 7.65 kB 7.68 kB +31 B (+0.4%)
/video/skin.css 7.46 kB 7.50 kB +38 B (+0.5%)
/video/minimal-skin 61.46 kB 61.55 kB +98 B (+0.2%) 0 B
/video/minimal-skin2 8.09 kB 8.15 kB +60 B (+0.7%)
/video/skin 61.34 kB 61.31 kB -27 B (-0.0%) 0 B
/video/skin2 7.95 kB 8.00 kB +54 B (+0.7%)
/audio/minimal-skin.css 5.53 kB 5.55 kB +29 B (+0.5%)
/audio/skin.css 5.34 kB 5.37 kB +27 B (+0.5%)
/audio/minimal-skin 45.77 kB 45.81 kB +40 B (+0.1%) 0 B
/audio/minimal-skin2 5.83 kB 5.88 kB +42 B (+0.7%)
/audio/skin 45.50 kB 45.56 kB +70 B (+0.2%) 0 B
/audio/skin2 5.65 kB 5.69 kB +45 B (+0.8%)
/live-video/minimal-skin.css 6.21 kB 6.23 kB +20 B (+0.3%)
/live-video/skin.css 6.18 kB 6.20 kB +24 B (+0.4%)
/live-video/minimal-skin 49.42 kB 49.39 kB -24 B (-0.0%) 0 B
/live-video/minimal-skin2 6.55 kB 6.58 kB +32 B (+0.5%)
/live-video/skin 49.43 kB 49.40 kB -31 B (-0.1%) 0 B
/live-video/skin2 6.58 kB 6.61 kB +28 B (+0.4%)
/live-audio/minimal-skin.css 4.39 kB 4.42 kB +31 B (+0.7%)
/live-audio/skin.css 4.37 kB 4.39 kB +26 B (+0.6%)
/live-audio/minimal-skin 35.43 kB 35.47 kB +40 B (+0.1%) 0 B
/live-audio/minimal-skin2 4.64 kB 4.68 kB +42 B (+0.9%)
/live-audio/skin 35.36 kB 35.46 kB +107 B (+0.3%) 0 B
/live-audio/skin2 4.63 kB 4.66 kB +37 B (+0.8%)
/video (default) 62.79 kB 62.82 kB +31 B (+0.0%) 0 B
/video (default + hls) 64.52 kB 64.55 kB +28 B (+0.0%) 0 B
/video (minimal) 63.04 kB 62.97 kB -67 B (-0.1%) 0 B
/video (minimal + hls) 64.77 kB 64.91 kB +142 B (+0.2%) 0 B
/audio (default) 46.99 kB 47.03 kB +43 B (+0.1%) 0 B
/audio (minimal) 47.21 kB 47.23 kB +27 B (+0.1%) 0 B
Presets (7)
Entry Initial Lazy
/video (default) 62.82 kB 56.87 kB
/video (default + hls) 64.55 kB 56.87 kB
/video (minimal) 62.97 kB 56.87 kB
/video (minimal + hls) 64.91 kB 56.87 kB
/audio (default) 47.03 kB 56.87 kB
/audio (minimal) 47.23 kB 56.87 kB
/background 11.57 kB 56.87 kB
Media (18)
Entry Initial
/media/mux-video 3.02 kB
/media/mux-audio 2.69 kB
/media/background-video 1.16 kB
/media/cloudflare-video 2.90 kB
/media/dash-video 2.63 kB
/media/hls-audio 22.05 kB
/media/hls-background-video 16.86 kB
/media/hls-video 28.00 kB
/media/hlsjs-video 2.63 kB
/media/mux-background-video 16.86 kB
/media/native-hls-video 7.57 kB
/media/shaka-video 2.63 kB
/media/spotify-audio 3.02 kB
/media/tiktok-video 3.13 kB
/media/twitch-video 2.93 kB
/media/vimeo-video 2.90 kB
/media/wistia-video 607 B
/media/youtube-video 2.90 kB
Players (5)
Entry Initial Lazy
/video/player 9.69 kB 56.87 kB
/audio/player 6.14 kB 56.87 kB
/background/player 4.46 kB 56.87 kB
/live-video/player 9.06 kB 56.87 kB
/live-audio/player 6.15 kB 56.87 kB
Skins (29)
Entry Type Initial Lazy
/video/minimal-skin.css css 7.68 kB
/video/skin.css css 7.50 kB
/video/minimal-skin js 61.55 kB 56.87 kB
/video/minimal-skin2 js 8.15 kB
/video/skin js 61.31 kB 56.87 kB
/video/skin2 js 8.00 kB
/audio/minimal-skin.css css 5.55 kB
/audio/skin.css css 5.37 kB
/audio/minimal-skin js 45.81 kB 56.87 kB
/audio/minimal-skin2 js 5.88 kB
/audio/skin js 45.56 kB 56.87 kB
/audio/skin2 js 5.69 kB
/background/skin.css css 139 B
/background/skin js 9.81 kB 56.87 kB
/background/skin2 js 187 B
/live-video/minimal-skin.css css 6.23 kB
/live-video/skin.css css 6.20 kB
/live-video/minimal-skin js 49.39 kB 56.87 kB
/live-video/minimal-skin2 js 6.58 kB
/live-video/skin js 49.40 kB 56.87 kB
/live-video/skin2 js 6.61 kB
/live-audio/minimal-skin.css css 4.42 kB
/live-audio/skin.css css 4.39 kB
/live-audio/minimal-skin js 35.47 kB 56.87 kB
/live-audio/minimal-skin2 js 4.68 kB
/live-audio/skin js 35.46 kB 56.87 kB
/live-audio/skin2 js 4.66 kB
/global.css css 190 B
/shared.css css 118 B
UI Components (62)
Entry Initial Lazy
/ui/airplay-button 11.26 kB 56.87 kB
/ui/alert-dialog 8.79 kB 56.87 kB
/ui/audio-track-radio-group 11.38 kB 56.87 kB
/ui/buffering-indicator 8.60 kB 56.87 kB
/ui/captions-button 11.51 kB 56.87 kB
/ui/captions-radio-group 11.45 kB 56.87 kB
/ui/cast-button 11.25 kB 56.87 kB
/ui/container 9.47 kB 56.87 kB
/ui/controls 8.77 kB 56.87 kB
/ui/controls-backdrop 1.69 kB 56.87 kB
/ui/controls-content 1.67 kB 56.87 kB
/ui/dialog 8.73 kB 56.87 kB
/ui/dialog-backdrop 1.70 kB 56.87 kB
/ui/dialog-close 2.06 kB 56.87 kB
/ui/dialog-description 1.69 kB 56.87 kB
/ui/dialog-popup 1.90 kB 56.87 kB
/ui/dialog-title 1.70 kB 56.87 kB
/ui/error-dialog 12.38 kB 56.87 kB
/ui/fullscreen-button 11.26 kB 56.87 kB
/ui/gesture 9.57 kB 56.87 kB
/ui/hotkey 9.97 kB 56.87 kB
/ui/live-button 9.74 kB 56.87 kB
/ui/menu 18.45 kB 56.87 kB
/ui/menu-checkbox-item 1.97 kB 56.87 kB
/ui/menu-content 7.52 kB 56.87 kB
/ui/menu-group 2.09 kB 56.87 kB
/ui/menu-group-label 1.64 kB
/ui/menu-item 2.29 kB 56.87 kB
/ui/menu-item-indicator 1.37 kB 56.87 kB
/ui/menu-radio-group 3.01 kB 56.87 kB
/ui/menu-radio-item 2.13 kB 56.87 kB
/ui/menu-separator 1.30 kB 56.87 kB
/ui/mute-button 11.28 kB 56.87 kB
/ui/pip-button 11.22 kB 56.87 kB
/ui/play-button 11.22 kB 56.87 kB
/ui/playback-rate-button 11.32 kB 56.87 kB
/ui/playback-rate-radio-group 11.38 kB 56.87 kB
/ui/popover 8.57 kB 56.87 kB
/ui/poster 8.67 kB 56.87 kB
/ui/quality-radio-group 11.97 kB 56.87 kB
/ui/seek-button 11.27 kB 56.87 kB
/ui/seek-indicator 12.69 kB 56.87 kB
/ui/seek-indicator-value 1.10 kB
/ui/slider 11.65 kB 56.87 kB
/ui/slider-preview 2.01 kB 56.87 kB
/ui/status-announcer 10.60 kB 56.87 kB
/ui/status-indicator 13.01 kB 56.87 kB
/ui/status-indicator-value 1.10 kB
/ui/thumbnail 9.84 kB 56.87 kB
/ui/time 10.80 kB 56.87 kB
/ui/time-slider 12.99 kB 56.87 kB
/ui/time-slider-chapter-title 8.79 kB 56.87 kB
/ui/time-slider-chapters 9.63 kB 56.87 kB
/ui/title 8.17 kB 56.87 kB
/ui/tooltip 9.95 kB 56.87 kB
/ui/tooltip-label 1.21 kB
/ui/tooltip-shortcut 1.18 kB
/ui/volume-indicator 13.02 kB 56.87 kB
/ui/volume-indicator-fill 1.11 kB
/ui/volume-indicator-value 1.10 kB
/ui/volume-popover 14.74 kB 56.87 kB
/ui/volume-slider 12.31 kB 56.87 kB
⚛️ @videojs/react — 2 small size changes
Path Base initial PR initial Initial diff Lazy diff
/video/minimal-skin.css 7.52 kB 7.53 kB +8 B (+0.1%)
/video/skin.css 7.34 kB 7.35 kB +11 B (+0.1%)
Presets (7)
Entry Initial Lazy
/video (default) 50.61 kB 56.87 kB
/video (default + hls) 50.83 kB 56.87 kB
/video (minimal) 50.66 kB 56.87 kB
/video (minimal + hls) 51.06 kB 56.87 kB
/audio (default) 39.50 kB 56.87 kB
/audio (minimal) 39.56 kB 56.87 kB
/background 581 B 56.87 kB
Media (22)
Entry Initial
/media/mux-video/hls-js 958 B
/media/mux-video/spf 961 B
/media/mux-audio/hls-js 699 B
/media/mux-audio/spf 703 B
/media/background-video 402 B
/media/cloudflare-video 911 B
/media/dash-video 693 B
/media/hls-audio 20.36 kB
/media/hls-background-video 16.40 kB
/media/hls-video 26.35 kB
/media/hlsjs-video 695 B
/media/mux-audio 693 B
/media/mux-background-video 16.47 kB
/media/mux-video 950 B
/media/native-hls-video 5.77 kB
/media/shaka-video 704 B
/media/spotify-audio 901 B
/media/tiktok-video 906 B
/media/twitch-video 929 B
/media/vimeo-video 888 B
/media/wistia-video 619 B
/media/youtube-video 897 B
Extensions (2)
Entry Initial
/extensions/google-cast 1.59 kB
/extensions/mux-data 1.64 kB
Players (5)
Entry Initial Lazy
/video/player 7.56 kB 56.87 kB
/audio/player 4.00 kB 56.87 kB
/background/player 2.27 kB 56.87 kB
/live-video/player 6.95 kB 56.87 kB
/live-audio/player 3.99 kB 56.87 kB
Skins (18)
Entry Type Initial Lazy
/video/minimal-skin.css css 7.53 kB
/video/skin.css css 7.35 kB
/video/minimal-skin js 50.63 kB 56.87 kB
/video/skin js 50.50 kB 56.87 kB
/audio/minimal-skin.css css 5.37 kB
/audio/skin.css css 5.18 kB
/audio/minimal-skin js 39.46 kB 56.87 kB
/audio/skin js 39.40 kB 56.87 kB
/background/skin.css css 90 B
/background/skin js 277 B
/live-video/minimal-skin.css css 6.07 kB
/live-video/skin.css css 6.05 kB
/live-video/minimal-skin js 42.57 kB 56.87 kB
/live-video/skin js 42.52 kB 56.87 kB
/live-audio/minimal-skin.css css 4.24 kB
/live-audio/skin.css css 4.21 kB
/live-audio/minimal-skin js 30.35 kB 56.87 kB
/live-audio/skin js 30.36 kB 56.87 kB
UI Components (39)
Entry Initial Lazy
/ui/airplay-button 10.45 kB 56.87 kB
/ui/alert-dialog 4.73 kB 56.87 kB
/ui/audio-track 7.92 kB 56.87 kB
/ui/audio-track-radio-group 9.48 kB 56.87 kB
/ui/buffering-indicator 7.79 kB 56.87 kB
/ui/captions-button 10.43 kB 56.87 kB
/ui/captions-radio-group 9.59 kB 56.87 kB
/ui/cast-button 10.43 kB 56.87 kB
/ui/controls 7.71 kB 56.87 kB
/ui/dialog 4.75 kB 56.87 kB
/ui/error-dialog 11.80 kB 56.87 kB
/ui/fullscreen-button 10.39 kB 56.87 kB
/ui/gesture 7.98 kB 56.87 kB
/ui/hotkey 8.38 kB 56.87 kB
/ui/live-button 8.80 kB 56.87 kB
/ui/menu 19.45 kB 56.87 kB
/ui/mute-button 10.44 kB 56.87 kB
/ui/pip-button 10.39 kB 56.87 kB
/ui/play-button 10.37 kB 56.87 kB
/ui/playback-rate 7.99 kB 56.87 kB
/ui/playback-rate-button 10.37 kB 56.87 kB
/ui/playback-rate-radio-group 9.53 kB 56.87 kB
/ui/popover 8.16 kB 56.87 kB
/ui/poster 7.57 kB 56.87 kB
/ui/quality 8.42 kB 56.87 kB
/ui/quality-radio-group 9.96 kB 56.87 kB
/ui/seek-button 10.41 kB 56.87 kB
/ui/seek-indicator 11.98 kB 56.87 kB
/ui/slider 12.74 kB 56.87 kB
/ui/status-announcer 10.10 kB 56.87 kB
/ui/status-indicator 12.29 kB 56.87 kB
/ui/thumbnail 8.73 kB 56.87 kB
/ui/time 9.77 kB 56.87 kB
/ui/time-slider 14.17 kB 56.87 kB
/ui/title 7.28 kB 56.87 kB
/ui/tooltip 8.93 kB 56.87 kB
/ui/volume-indicator 12.34 kB 56.87 kB
/ui/volume-popover 14.20 kB 56.87 kB
/ui/volume-slider 12.13 kB 56.87 kB
🧩 @videojs/core — no changes
Entries (76)
Entry Initial Lazy
. 13.15 kB
/dom 22.53 kB 56.87 kB
/vjsc 1.82 kB
/i18n 3.23 kB 56.87 kB
/i18n/locales/all 34.97 kB
/i18n/locales/ar 1.22 kB
/i18n/locales/az 1.09 kB
/i18n/locales/bg 1.29 kB
/i18n/locales/bn 1.23 kB
/i18n/locales/bs 1.00 kB
/i18n/locales/ca 1.07 kB
/i18n/locales/cs 1.07 kB
/i18n/locales/cy 1.02 kB
/i18n/locales/da 1006 B
/i18n/locales/de 1.09 kB
/i18n/locales/el 1.49 kB
/i18n/locales/en 785 B
/i18n/locales/es 1018 B
/i18n/locales/et 1.05 kB
/i18n/locales/eu 1.03 kB
/i18n/locales/fa 1.22 kB
/i18n/locales/fi 1.04 kB
/i18n/locales/fr 1.07 kB
/i18n/locales/gd 1.10 kB
/i18n/locales/gl 1022 B
/i18n/locales/he 1.14 kB
/i18n/locales/hi 1.30 kB
/i18n/locales/hr 1.02 kB
/i18n/locales/hu 1.10 kB
/i18n/locales/id 919 B
/i18n/locales/it 1.01 kB
/i18n/locales/ja 1.18 kB
/i18n/locales/ko 1.14 kB
/i18n/locales/lt 1.02 kB
/i18n/locales/lv 1.09 kB
/i18n/locales/mr 1.30 kB
/i18n/locales/nb 987 B
/i18n/locales/ne 1.29 kB
/i18n/locales/nl 1.00 kB
/i18n/locales/nn 987 B
/i18n/locales/oc 1.08 kB
/i18n/locales/pl 1.14 kB
/i18n/locales/pt 1.03 kB
/i18n/locales/pt-BR 1.03 kB
/i18n/locales/pt-PT 1.01 kB
/i18n/locales/ro 1.07 kB
/i18n/locales/ru 1.40 kB
/i18n/locales/sk 1.10 kB
/i18n/locales/sl 1.04 kB
/i18n/locales/sr 1.07 kB
/i18n/locales/sv 1.01 kB
/i18n/locales/te 1.32 kB
/i18n/locales/th 1.29 kB
/i18n/locales/tr 1.08 kB
/i18n/locales/uk 1.41 kB
/i18n/locales/vi 1.11 kB
/i18n/locales/zh 1.02 kB
/i18n/locales/zh-CN 1.02 kB
/i18n/locales/zh-TW 1.02 kB
/i18n/text/airplay 101 B
/i18n/text/buttons 137 B
/i18n/text/captions 93 B
/i18n/text/cast 114 B
/i18n/text/common 90 B
/i18n/text/container 75 B
/i18n/text/errors 285 B
/i18n/text/fullscreen 98 B
/i18n/text/live 126 B
/i18n/text/menu 249 B
/i18n/text/pip 101 B
/i18n/text/playback 80 B
/i18n/text/seek 105 B
/i18n/text/slider 65 B
/i18n/text/status 222 B
/i18n/text/time 280 B
/i18n/text/volume 133 B
🏷️ @videojs/element — no changes
Entries (2)
Entry Initial
. 1.05 kB
/context 943 B
📦 @videojs/store — no changes
Entries (3)
Entry Initial
. 1.72 kB
/html 703 B
/react 365 B
🔧 @videojs/utils — no changes
Entries (13)
Entry Initial
/array 271 B
/dom 5.02 kB
/events 320 B
/function 386 B
/i18n 249 B
/jwt 176 B
/object 535 B
/predicate 297 B
/percent 281 B
/string 239 B
/style 212 B
/time 976 B
/number 199 B
📦 @videojs/cdn — no changes
📦 @videojs/cloudflare-video — no changes
📦 @videojs/dash-video — no changes
📦 @videojs/google-cast — no changes
📦 @videojs/hlsjs-video — no changes
📦 @videojs/media — no changes
Entries (3)
Entry Initial
. 1.14 kB
/dom 4.12 kB
/media-tracks 2.05 kB
📦 @videojs/mux — no changes
📦 @videojs/mux-audio — no changes
Entries (2)
Entry Initial
. 135.58 kB
/spf 20.84 kB
📦 @videojs/mux-data — no changes
📦 @videojs/mux-video — no changes
Entries (2)
Entry Initial
. 135.56 kB
/spf 26.75 kB
📦 @videojs/native-hls-video — no changes
📦 @videojs/shaka-video — no changes
📦 @videojs/spf — no changes
Entries (7)
Entry Initial
. 4.55 kB
/dom 6.60 kB
/hls 22.06 kB
/media-tracks 504 B
/hls-background-video 15.84 kB
/hls-audio 19.84 kB
/hls-video 25.89 kB
📦 @videojs/spotify-audio — no changes
📦 @videojs/tiktok-video — no changes
📦 @videojs/twitch-video — no changes
📦 @videojs/vimeo-video — no changes
📦 @videojs/wistia-video — no changes
Entries (2)
Entry Initial
. 1.91 kB
/helpers 1.77 kB
📦 @videojs/youtube-video — no changes

ℹ️ How to interpret

Each entry is independently bundled, minified, and brotli-compressed. Initial size includes its static import graph; lazy dynamic chunks are reported separately.

Entries are not additive because their dependency graphs overlap. Preset rows represent realistic combined bundles.

Changes of 300 B or less across initial, lazy, and total size are collapsed, not discarded.

Run pnpm size locally to check current initial sizes.

@github-actions

github-actions Bot commented Sep 7, 2026

Copy link
Copy Markdown
Contributor

E2E triage: inconclusive. WebKit has a stale/incorrect portrait-thumbnail assertion; Chromium has a repeatable captions snapshot mismatch that needs a local rendering check before classifying it as intentional or a regression. Tracking: #2642.

@mihar-22 mihar-22 changed the title fix(test): repair the e2e suites and gate them on pull requests fix(test): repair the e2e suites Sep 7, 2026
@github-actions

github-actions Bot commented Sep 7, 2026

Copy link
Copy Markdown
Contributor

E2E triage: real regression. The Chromium sandbox failures consistently hit a Vite overlay because generated registry modules import unresolved bare cn, preventing the media player from rendering. The report-test flake is secondary to that overlay. Tracking issue: #2643.

@github-actions

github-actions Bot commented Sep 7, 2026

Copy link
Copy Markdown
Contributor

E2E triage: expected change. The persistent minimal-video fullscreen failure is a stale absolute thumbnail-to-time gap floor (6–7px measured vs. 8px expected); CSS/Tailwind parity and the CSS visual baseline pass. Two other failures passed on retry. Tracking issue: #2644.

@mihar-22 mihar-22 added the record:snapshots Record the player visual baselines in CI and upload them as an artifact label Sep 7, 2026
@mihar-22 mihar-22 added record:snapshots Record the player visual baselines in CI and upload them as an artifact and removed record:snapshots Record the player visual baselines in CI and upload them as an artifact labels Sep 7, 2026
@github-actions

github-actions Bot commented Sep 7, 2026

Copy link
Copy Markdown
Contributor

E2E triage: expected change. #2644 tracks the 16 newly added visual-layout cases with missing Chromium baselines and the related fullscreen preview-spacing assertion. Assigned to @mihar-22.

@github-actions

github-actions Bot commented Sep 7, 2026

Copy link
Copy Markdown
Contributor

E2E triage: expected change — the 16 new player-layout visual cases lack committed Chromium baselines; this run’s snapshot artifact generated them. Reused and updated #2644 with the run evidence, including the three persistent minimal fullscreen spacing assertions and two retry-passing parity flakes.

@mihar-22 mihar-22 removed the record:snapshots Record the player visual baselines in CI and upload them as an artifact label Sep 7, 2026
@github-actions

github-actions Bot commented Sep 7, 2026

Copy link
Copy Markdown
Contributor

E2E triage: expected change. #2644 now tracks the three retry-persistent minimal fullscreen preview-spacing assertions (6–7px measured vs. 8–10px floors); two other parity failures passed on retry. Assigned to @mihar-22.

The CDN pages import @videojs/cdn since #2598, but the e2e package never declared it, so Vite
could not resolve the imports and every CDN test failed. The player prepare task also builds the
CDN bundles so a local run does not depend on a separate command.
Since #2574 the store clears waiting as soon as currentTime advances past the stall, so a stub on
a playing video lost its waiting state before the indicator delay elapsed. Freeze currentTime at
the stall point alongside paused and readyState.
The volume indicator shakes at a boundary level and prints the level it lands on, so the CSS and
Tailwind panels only agreed when both started at the same volume. Set a mid-range volume in every
panel before the ArrowUp shortcut.
Drop the sandbox width control test from skin parity: it exercised the shell, the sandbox suite
already covers it, and it broke when #2586 moved the control into a closed options panel. Move the
consumer-override test to the player suite, where the packaged CSS skin is what consumers restyle
and WebKit also runs. Document which suite owns what in each Playwright config.
E2E only ran on pushes to main or labeled pull requests, so three regressions merged unnoticed.
Pull requests touching the e2e app, sandbox, any package, the lockfile, or the workflow now run the
player and skin parity suites; the test:e2e label still forces a run.
WebKit exposes the AirPlay button, whose accessible name also contains "Play", so the substring
match resolved to two buttons.
The base `video` rule sizes the media in the React skin, but the HTML skin slots the page's video
through its shadow root, where that rule cannot reach it. #2550 removed the legacy `::slotted(video)`
rule with the legacy skins, so the video kept its intrinsic size and overflowed the container,
which also pushed native captions out of view. Size the slotted video from the container styles
for the Shadow DOM variant.
WebKit does not apply `@scope` rules to an element that hosts a shadow root, and the slider
thumbnail is the one such element in the HTML skin, so its max height never applies there. The
portrait thumbnail e2e records that as a fixme on WebKit instead of failing the run.
…in paths

WebKit doubles the wall time of the player job, so pull requests run Chromium and pushes to main
cover both browsers. Skin parity compiles the authored skins, so it only runs for pull requests
that touch the skins, the compiler, the framework packages, the sandbox, or the parity suite.
WebKit never matches an `@scope` rule whose subject hosts a shadow root, so the slider thumbnail
lost its max height and clipping in Safari. Style rules can now declare `shadowHost`, and the
renderer keeps those rules outside the scope block with the scope root as an ancestor, the same
way it already keeps slotted rules. The thumbnail image rule opts in, and the portrait thumbnail
e2e runs on WebKit again.
…w gaps

The thumbnail keeps a placeholder box until its storyboard image arrives, so on a slow runner the
preview gaps were read against the placeholder and came up short of the pinned minimum.
A build job compiles the packages, CDN bundles, generated skins, and sandbox setup once per run and
saves this run's Vite Task cache; every browser job restores it instead of rebuilding. The sandbox
suite moves to its own job so it runs beside the player suite rather than after it. Pull requests
retry a failing test once, since the second retry mostly re-records the same flake.
…s first

Skin parity captures the CSS panel in the page as the reference for the Tailwind panel instead of
also holding it to a stored PNG; the player suite owns the baselines over time. The contracts wait
for the store's volume, for fonts, and for running transitions before reading, and round centered
insets to whole pixels, since those were the sub-pixel and mid-transition differences behind the
recurring flakes.
The e2e app gains minimal-skin pages for both frameworks and media types, and a visual spec holds
each packaged skin to a baseline at the widths where its layout changes.
…ntainer

Baselines only match when recorded in the same image the E2E workflow runs in, so this records the
requested spec with --update-snapshots there and uploads the snapshot directories as an artifact.
A manually dispatched workflow only exists to the API once it is on the default branch, so the
recording job lives in the E2E workflow instead and runs when a pull request carries the
`record:snapshots` label.
…gaps

The seek preview scales in when hovered, and a rect read mid-transition shifts the gap between the
time label and the thumbnail by a few pixels.
Chromium and WebKit baselines for every packaged skin at its layout widths, recorded by the
labeled snapshot job so they match what the E2E workflow compares against.
The gaps are measured against the time label's box, which follows the fallback font's metrics until
Inter has loaded, so CI read them a pixel or two short. The indicator contract also records the text
each indicator shows, so a width difference names the level behind it.
Inter loads one weight at a time on first use, so labels that appear after an interaction, the
keyboard indicators and the fullscreen seek preview, were measured in the fallback face in CI. The
contracts settle fonts after those labels appear, the contrast contract waits out its color
transition, and the fullscreen gap pins follow the settled measurement, which reads two pixels
smaller than the fallback did.
@mihar-22
mihar-22 force-pushed the fix/e2e-suite-failures branch from 4ecb547 to 87b396a Compare September 7, 2026 09:23
@mihar-22
mihar-22 marked this pull request as ready for review September 7, 2026 09:41
@mihar-22
mihar-22 requested a review from sampotts September 7, 2026 09:41

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 87b396a. Configure here.

Comment thread .github/workflows/e2e.yml Outdated
@mihar-22
mihar-22 merged commit 0a55663 into main Sep 7, 2026
63 checks passed
@mihar-22
mihar-22 deleted the fix/e2e-suite-failures branch September 7, 2026 18:54
@videojs-release videojs-release Bot mentioned this pull request Sep 7, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants