Skip to content

fix: navigate the frame by replace from the first package, and run the demo's tests in every engine - #23

Merged
alekswebnet merged 1 commit into
mainfrom
test/demo-engines
Oct 14, 2026
Merged

alekswebnet merged 1 commit into
mainfrom
test/demo-engines

Conversation

@alekswebnet

Copy link
Copy Markdown
Contributor

Closes #22.

The demo's tests (the installable app, the embed page and the cmi5 page) now run in Firefox and WebKit as well as Chromium. The first runs found a bug in the player that affects Safari, and this fixes it.

Changes

Player: the frame's first navigation is a replace (packages/player/src/h5p-offline-player.ts)

  • Before: navigateFrame set the frame's src for the first package and used contentWindow.location.replace after that. WebKit adds a history step for that src when the frame's first document has loaded and the page is top-level. So in Safari, the first Back after opening a package emptied the frame and left the page showing an empty player.
  • After: every navigation uses location.replace. A frame out of the document has no window to navigate, so it still gets src, which loads on insertion and adds no step.
  • Effect: opening a file in the demo app in WebKit now adds one history step instead of two (2 → 3, as in Chromium), and Back closes it.
  • playback.test.ts now counts history from before the first package. It doesn't catch the WebKit case: the player's suite runs inside the test runner's frame, where WebKit adds no step. The app's tests, which run in a top-level page, do catch it.
  • AGENTS.md: The frame is navigated in place records the cause.

Demo tests in every engine (apps/demo/tests/)

  • engine.ts picks the browser from H5P_TEST_BROWSER, as the player's config does. All three test files launch through it.
  • The root pnpm test:engine runs the demo's tests after the player's suite. The existing engines job in CI therefore covers them in Firefox and WebKit, with no new job.

What the tests now allow for (each is a real browser behaviour, not an app bug):

  • WebKit and Tab: WebKit, like Safari by default, skips buttons on Tab, so the keyboard tests press Option-Tab there.
  • WebKit's private profile: the profile Playwright gives a page refuses a File in IndexedDB, as a Safari private window does, so the app keeps no copy there. The copy test runs in a profile on disk, where WebKit keeps the copy.
  • Firefox's Back: Firefox's own Back skips a history step the page wrote before anyone interacted with it, which is home when a link opens the app. The link test goes back from script, as the app's Back button does, and that lands home in every engine.
  • Firefox and window.close(): Firefox closes a top-level page Playwright opened when cmi5's Exit asks it to; Chromium ignores the request. That test stands in for close and now asserts that Exit asked to close, in every engine.
  • Chromium-only tests: three app tests are skipped outside Chromium. They cover file handles, and a private profile that keeps a reference to a file rather than its bytes; both are Chromium's.

Docs: AGENTS.md (the commands, the engine notes, the invariant), CONTRIBUTING.md and docs/development.md.

Testing

Locally, on macOS:

Run Result
Demo tests, Chromium 27/27
Demo tests, Firefox 24/24, 3 skipped
Demo tests, WebKit 24/24, 3 skipped
Control: demo app tests in WebKit without the player fix 4 history tests fail
Player browser suite: Chromium (with browser-emulated) / Firefox / WebKit 169 / 165 / 165
Player unit tests 306/306
Typecheck clean
H5P_TEST_BROWSER=webkit pnpm test:engine the player's 165 pass; the demo's link Back/Forward test failed once (see below)
All demo tests in WebKit, 9 further runs 36/36, 3 skipped, every run

Flake: that one failure came right after the player's full suite. The same test passed 3 runs alone and every run of the full demo set afterwards. I didn't catch its error message. If CI shows it, it needs a look rather than a retry.

Not verified

  • Real Safari on macOS and iOS: Playwright's WebKit is neither. The fix uses the same location.replace that every later navigation already used in Safari.
  • Firefox and Chrome's own Back buttons: after a link opens the app, they may skip its home step. That's the browsers' intervention against history manipulation, and the app's Back button is unaffected.

Release

Player patch, 0.9.3, for the Safari fix, when you choose. Nothing else published changes.

🤖 Generated with Claude Code

…e demo's tests in every engine

WebKit adds a history step when a top-level page sets the src of a frame
whose first document has loaded, so in Safari the first Back after
opening a package emptied the frame and left the page showing it. Every
navigation is a location.replace now; only a frame out of the document
still gets src.

Found by running the demo's tests in Firefox and WebKit, which the root
test:engine, and so CI's engines job, now does. The tests allow for four
engine differences: Option-Tab in WebKit, WebKit's private profile
keeping no File in IndexedDB, Firefox's Back passing over an untouched
step, and Firefox closing a page on cmi5's Exit. Three app tests stay
Chromium's.

Refs #22

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@vercel

vercel Bot commented Oct 13, 2026 •

Copy link
Copy Markdown

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

Project Deployment Actions Updated
h5p-offline-player Ready Ready Preview Oct 13, 2026 11:56pm UTC

@alekswebnet
alekswebnet merged commit d82287b into main Oct 14, 2026
10 checks passed
@alekswebnet
alekswebnet deleted the test/demo-engines branch October 15, 2026 17:08

This branch was successfully deployed

1 active deployment
Preview — 0c6323ea Deployed Oct 13, 2026 by vercel[bot]
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.

Safari: the first Back after opening a package empties the player; run the demo's tests in Firefox and WebKit

1 participant