diff --git a/.github/scripts/test-autoplay.js b/.github/scripts/test-autoplay.js index e980bed..b4fd009 100644 --- a/.github/scripts/test-autoplay.js +++ b/.github/scripts/test-autoplay.js @@ -1,4 +1,4 @@ -const { chromium } = require('playwright'); +const playwright = require('playwright'); const CONFIG = { error: { overlaySelector: '#site-error', clickSelector: '#site-error button', initialTitle: 'Internal Server Error' }, @@ -7,11 +7,16 @@ const CONFIG = { const overlayType = process.argv[2]; if (!CONFIG[overlayType]) { - throw new Error(`usage: node test-autoplay.js <${Object.keys(CONFIG).join('|')}>, got "${overlayType}"`); + throw new Error(`usage: node test-autoplay.js <${Object.keys(CONFIG).join('|')}> [chromium|firefox|webkit], got "${overlayType}"`); } const { overlaySelector, clickSelector, initialTitle } = CONFIG[overlayType]; const cookieSelector = '#cookie-banner'; +const browserType = process.argv[3] || 'chromium'; +if (!playwright[browserType]) { + throw new Error(`unknown browser engine "${browserType}", expected chromium, firefox, or webkit`); +} + async function waitFor(page, predicate, { timeout = 5000, interval = 100 } = {}) { const start = Date.now(); while (Date.now() - start < timeout) { @@ -22,7 +27,7 @@ async function waitFor(page, predicate, { timeout = 5000, interval = 100 } = {}) } (async () => { - const browser = await chromium.launch(); + const browser = await playwright[browserType].launch(); const page = await browser.newPage(); await page.goto('http://localhost:8080/', { waitUntil: 'load' }); @@ -102,7 +107,7 @@ async function waitFor(page, predicate, { timeout = 5000, interval = 100 } = {}) throw new Error('expected the cookie banner to be hidden after clicking, but it is still visible'); } - console.log(`OK: ${overlayType} overlay + cookie banner shown, video autoplays muted, and clicking unmutes + hides both`); + console.log(`OK (${browserType}): ${overlayType} overlay + cookie banner shown, video autoplays muted, and clicking unmutes + hides both`); await browser.close(); })().catch((err) => { console.error(err); diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index e4b5c0a..82a34bb 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -161,7 +161,11 @@ jobs: run: | npm init -y >/dev/null npm install --no-save playwright@1 - npx playwright install --with-deps chromium + # Firefox gets its own engine check alongside Chromium - it's + # historically the most divergent on autoplay/gesture policy + # enforcement of the mainstream browsers, so a bug that's fine + # under one can still be broken under the other. + npx playwright install --with-deps chromium firefox - name: Start container with OVERLAY=error run: docker run -d --name rickroll-error -p 8080:8080 -e OVERLAY=error rickroll:test @@ -175,8 +179,11 @@ jobs: docker logs rickroll-error exit 1 - - name: Verify site-error + cookie banner autoplay muted and unmute on click - run: node .github/scripts/test-autoplay.js error + - name: Verify site-error + cookie banner autoplay muted and unmute on click (Chromium) + run: node .github/scripts/test-autoplay.js error chromium + + - name: Verify site-error + cookie banner autoplay muted and unmute on click (Firefox) + run: node .github/scripts/test-autoplay.js error firefox - name: Stop OVERLAY=error container if: always() @@ -194,8 +201,11 @@ jobs: docker logs rickroll-loading exit 1 - - name: Verify loading-screen + cookie banner autoplay muted and unmute on click - run: node .github/scripts/test-autoplay.js loading + - name: Verify loading-screen + cookie banner autoplay muted and unmute on click (Chromium) + run: node .github/scripts/test-autoplay.js loading chromium + + - name: Verify loading-screen + cookie banner autoplay muted and unmute on click (Firefox) + run: node .github/scripts/test-autoplay.js loading firefox - name: Stop OVERLAY=loading container if: always() diff --git a/scripts/index/80-index.sh b/scripts/index/80-index.sh index 5ef86d3..4987921 100644 --- a/scripts/index/80-index.sh +++ b/scripts/index/80-index.sh @@ -335,7 +335,17 @@ tee /usr/share/nginx/html/index.html << EOF >/dev/null } } - var events = ['click', 'keydown', 'touchstart', 'pointerdown']; + // click fires for both a genuine mouse click and, on + // touch devices, the synthetic click a browser dispatches + // after a completed tap - deliberately not touchstart or + // pointerdown, which fire the instant a finger touches the + // screen, before the browser even knows it's a tap and not + // the start of a scroll/drag. WebKit in particular doesn't + // treat those as a strong enough gesture to permit unmuted + // playback, so play() silently gets rejected and the + // click that follows never gets a retry since the + // listeners here are already torn down. + var events = ['click', 'keydown']; function reveal() { video.muted = false;