diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4fbcfec97..21d9f9310 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -275,10 +275,10 @@ jobs: if: matrix.name != 'Windows' shell: bash run: | - bash scripts/ci-retry.sh zig build check-web - scripts/test-web-text-input.sh --embed-only + bash scripts/ci-retry.sh zig build web + scripts/test-web-text-input.sh - # `check-web` sets no `-Dapp-layout`, so the web build's layout wiring is a no-op there; this + # The build above sets no `-Dapp-layout`, so its layout wiring is a no-op there; this # builds wasm with an app-owned `.zon` and `.zig` layout, and fails if that wiring is gone. - name: Compile web (wasm) build with a custom layout if: matrix.name != 'Windows' diff --git a/scripts/test-web-text-input.sh b/scripts/test-web-text-input.sh index 61126fad4..3378d9012 100755 --- a/scripts/test-web-text-input.sh +++ b/scripts/test-web-text-input.sh @@ -1,7 +1,8 @@ #!/bin/sh # The hidden input's tests (web/tests/text-input.test.js) against the web.js the web build -# writes: `zig build web` first. Node also runs pointer-input and two-copy embed checks. -# Use --embed-only for the build-independent Node check; hidden-input tests also support jsc. +# writes: `zig build web` first. Node also runs the pointer-input and two-copy embed checks. +# CI builds the web assets and runs both suites. Use --embed-only for the build-independent +# Node check; hidden-input tests also support jsc. set -eu cd "$(dirname "$0")/.." if [ "${1:-}" = --embed-only ]; then diff --git a/web/tests/embed.test.mjs b/web/tests/embed.test.mjs index ee0162376..6de090af0 100644 --- a/web/tests/embed.test.mjs +++ b/web/tests/embed.test.mjs @@ -40,20 +40,21 @@ class Element extends Target { setAttribute() {} focus() {} getBoundingClientRect() { return { left: 0, top: 0, right: 100, bottom: 100, width: 100, height: 100 }; } - requestFullscreen() { document.fullscreenElement = this; this.fullscreen++; document.dispatch("fullscreenchange", {}); return Promise.resolve(); } + requestFullscreen() { fullscreenStack.push(this); document.fullscreenElement = this; this.fullscreen++; document.dispatch("fullscreenchange", {}); return Promise.resolve(); } } class Canvas extends Element { constructor() { super(); this.clientWidth = 100; this.clientHeight = 100; } getContext() { return {}; } setPointerCapture() {} } +const fullscreenStack = []; const document = Object.assign(new Target(), { fullscreenElement: null, baseURI: "http://localhost/", body: new Element(), documentElement: new Element(), createElement: (tag) => (tag === "canvas" ? new Canvas() : new Element()), - exitFullscreen() { document.fullscreenElement = null; document.dispatch("fullscreenchange", {}); return Promise.resolve(); }, + exitFullscreen() { fullscreenStack.pop(); document.fullscreenElement = fullscreenStack.at(-1) ?? null; document.dispatch("fullscreenchange", {}); return Promise.resolve(); }, }); const window = Object.assign(new Target(), { devicePixelRatio: 1, scrollX: 0, scrollY: 0, localStorage: new Map(), parent: null, @@ -134,5 +135,7 @@ assert.equal(document.documentElement.fullscreen, 0); toggles[1](); assert.equal(document.fullscreenElement, parentB, "the other copy takes full screen for itself"); toggles[1](); -assert.equal(document.fullscreenElement, null, "and a second toggle leaves it"); +assert.equal(document.fullscreenElement, parentA, "leaving the second embed reveals the first"); +toggles[0](); +assert.equal(document.fullscreenElement, null, "leaving the first embed exits full screen"); console.log("embed.test: ok");