From 431291b31ba0edbb0a06fb0e02561b715cd4acc2 Mon Sep 17 00:00:00 2001 From: Jeffrey Smith Date: Thu, 2 Apr 2026 16:04:36 +0000 Subject: [PATCH] Fix Playwright cookie auth in Docker CI environment MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Both test drivers (surface-test-driver.js, e2e-smoke-driver.js) set the arm_token cookie using domain: hostname, which fails in Docker where the hostname is a DNS name like "armature". Playwright's addCookies with a bare domain doesn't reliably match the request origin in this environment. Switch to url-based cookie setting which matches the full origin and works reliably across local and Docker environments. Also wait for .sw-topbar with waitForSelector instead of immediate DOM check to handle Preact SPA boot timing. This fixes the v0.7.2 "Run All button not found" issue — the root cause was auth redirect to /login, not a rendering problem. Co-Authored-By: Claude Opus 4.6 (1M context) --- ci/e2e-smoke-driver.js | 12 ++++++------ ci/surface-test-driver.js | 6 +++--- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/ci/e2e-smoke-driver.js b/ci/e2e-smoke-driver.js index 9f3613c..c8e554b 100644 --- a/ci/e2e-smoke-driver.js +++ b/ci/e2e-smoke-driver.js @@ -97,12 +97,11 @@ async function discoverSurfaces(page) { const browser = await chromium.launch({ headless: true }); const context = await browser.newContext(); - // Set auth cookie + // Set auth cookie — use url instead of domain for reliable matching await context.addCookies([{ name: 'arm_token', value: TOKEN, - domain: new URL(SERVER).hostname, - path: '/', + url: SERVER, }]); const page = await context.newPage(); @@ -145,10 +144,11 @@ async function discoverSurfaces(page) { process.stdout.write(` ${surface.id} (${surface.route}) ... `); await page.goto(url, { waitUntil: 'networkidle', timeout: 30000 }); - // Assert 1: Shell topbar exists - const topbar = await page.$('.sw-topbar'); + // Assert 1: Shell topbar renders (Preact SPA — wait for it to mount) + const topbar = await page.waitForSelector('.sw-topbar', { timeout: 15000 }) + .catch(() => null); if (!topbar) { - throw new Error('Shell topbar (.sw-topbar) not found'); + throw new Error('Shell topbar (.sw-topbar) not found after 15s'); } // Assert 2: Home link exists (favicon link or any link to /) diff --git a/ci/surface-test-driver.js b/ci/surface-test-driver.js index abe6fcd..13e3789 100644 --- a/ci/surface-test-driver.js +++ b/ci/surface-test-driver.js @@ -33,12 +33,12 @@ if (!TOKEN) { const browser = await chromium.launch({ headless: true }); const context = await browser.newContext(); - // Set auth cookie — name must match server's SetCookie ("arm_token") + // Set auth cookie — use url instead of domain for reliable matching + // in Docker/CI where hostname is a Docker DNS name (e.g. "armature") await context.addCookies([{ name: 'arm_token', value: TOKEN, - domain: new URL(SERVER).hostname, - path: '/', + url: SERVER, }]); const page = await context.newPage();