const { test, expect } = require("@playwright/test"); const { resolveTimeout } = require("./timeouts"); const { decodeDotenvQuotedValue, normalizeBaseUrl, runAdminFlow, runBiberFlow, runGuestFlow } = require("./personas"); test.use({ ignoreHTTPSErrors: true }); function contentTypeOf(response) { return response.headers()["content-type"] || ""; } function expectOrigin(url, expectedOrigin, label) { expect(new URL(url).origin, label).toBe(expectedOrigin); } function expectLandingPageText(body) { const normalized = body.toLowerCase(); expect( normalized, "Expected the Simple Icons landing page to expose README or provider content on the Simple Icons domain" ).toMatch(/simple icons|simpleicons\.org|provided by/); } const appBaseUrl = normalizeBaseUrl(process.env.APP_BASE_URL || ""); const knownIconSlug = decodeDotenvQuotedValue(process.env.KNOWN_ICON_SLUG); test("simpleicons serves keycloak assets directly on its own domain", async ({ request }) => { expect(appBaseUrl, "APP_BASE_URL must be set in the Playwright env file").toBeTruthy(); expect(knownIconSlug, "KNOWN_ICON_SLUG must be set in the Playwright env file").toBeTruthy(); const expectedOrigin = new URL(appBaseUrl).origin; const landingResponse = await request.get(appBaseUrl, { maxRedirects: 0, timeout: resolveTimeout(30_000) }); const landingStatus = landingResponse.status(); expect( landingStatus === 200 || (landingStatus >= 301 && landingStatus <= 302), `Expected the Simple Icons landing page to return HTTP 200 or a redirect (301/302), got ${landingStatus}` ).toBe(true); if (landingStatus === 200) { expectOrigin( landingResponse.url(), expectedOrigin, `Expected the Simple Icons landing page to stay on ${expectedOrigin} when no redirect is configured` ); const landingBody = await landingResponse.text(); expect(contentTypeOf(landingResponse)).toMatch(/text\/html|text\/plain/); expectLandingPageText(landingBody); } else { const location = landingResponse.headers()["location"]; expect(location, "Expected the redirect to include a Location header").toBeTruthy(); } const svgResponse = await request.get(`${appBaseUrl}/${knownIconSlug}.svg`, { timeout: resolveTimeout(30_000) }); expect(svgResponse.status(), `Expected ${knownIconSlug}.svg to return HTTP 200`).toBe(200); expectOrigin( svgResponse.url(), expectedOrigin, `Expected ${knownIconSlug}.svg to stay on the Simple Icons domain instead of redirecting elsewhere` ); expect(contentTypeOf(svgResponse)).toContain("image/svg+xml"); const svgBody = await svgResponse.text(); expect(svgBody).toContain(" { await runGuestFlow(page); }); test("biber: app → universal logout", async ({ page }) => { await runBiberFlow(page); }); test("administrator: app → universal logout", async ({ page }) => { await runAdminFlow(page, { adminInteraction: async (interactivePage) => { // web-svc-simpleicons admin-only interaction: open a management surface. const link = interactivePage .getByRole("link", { name: /^(admin|index|status)$/i }) .first(); if (await link.isVisible().catch(() => false)) { await link.click({ timeout: resolveTimeout(30_000) }).catch(() => {}); await interactivePage.waitForLoadState("domcontentloaded", { timeout: resolveTimeout(30_000) }).catch(() => {}); await expect(interactivePage.locator("body")).toContainText( /admin|status|index|simpleicons/i, { timeout: resolveTimeout(30_000) }, ); } }, }); });