From f2fa81e01febbcd8ef2916eaef742040d2ab0cd5 Mon Sep 17 00:00:00 2001 From: Kevin Veen-Birkenbach Date: Thu, 25 Jun 2026 11:56:20 +0200 Subject: [PATCH] test(web-app-nextcloud): capture the Zammad OAuth authorize request, not the post-login redirect The integration_zammad connect control is a button that runs window.location.replace(/oauth/authorize?client_id=...&response_type=code). Zammad's SPA immediately bounces the unauthenticated test browser to its login at the root path, so the settled page URL is no longer the authorize endpoint and the assertion saw the root. Capture the /oauth/authorize request itself (page.waitForRequest) - it is the coupling signal that carries the provisioned client_id to the partner - instead of the URL the browser ends up on after Zammad's redirect. Verified: the spec passes against the live variant-4 coupling (client_id and response_type present, partner host). Co-Authored-By: Claude Opus 4.8 --- .../addons/integration_zammad.spec.js | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/roles/web-app-nextcloud/files/playwright/addons/integration_zammad.spec.js b/roles/web-app-nextcloud/files/playwright/addons/integration_zammad.spec.js index 1453b834b6..cbddabe1f9 100644 --- a/roles/web-app-nextcloud/files/playwright/addons/integration_zammad.spec.js +++ b/roles/web-app-nextcloud/files/playwright/addons/integration_zammad.spec.js @@ -63,15 +63,15 @@ test("integration integration_zammad: per-user OAuth connect reaches the partner let authorizeHref = await connect.getAttribute("href").catch(() => null); if (!authorizeHref || !/\/oauth\/authorize/i.test(authorizeHref)) { - const popupPromise = context.waitForEvent("page", { timeout: 15_000 }).catch(() => null); - await Promise.all([ - page.waitForURL((u) => new URL(u).host === partnerHost, { timeout: 30_000 }).catch(() => {}), - connect.click({ timeout: 10_000 }).catch(() => {}), - ]); - const popup = await popupPromise; - const target = popup || page; - await target.waitForLoadState("domcontentloaded", { timeout: 30_000 }).catch(() => {}); - authorizeHref = target.url(); + // The control is a button doing window.location.replace(/oauth/authorize?...); Zammad's + // SPA then bounces the unauthenticated browser to login at "/", so the settled URL is no longer the + // authorize endpoint. Capture the authorize request itself — it carries the provisioned client_id. + const requestPromise = page + .waitForRequest((req) => /\/oauth\/authorize/i.test(req.url()), { timeout: 30_000 }) + .catch(() => null); + await connect.click({ timeout: 10_000 }).catch(() => {}); + const request = await requestPromise; + authorizeHref = request ? request.url() : page.url(); } const authorize = new URL(authorizeHref, instanceUrl);