From 7b24cf20caf9636604bb8c8b093dcc7408c93be9 Mon Sep 17 00:00:00 2001 From: eleith Date: Tue, 27 Oct 2026 13:18:14 -0700 Subject: [PATCH] Consolidate redundant end-to-end tests --- apps/web/e2e/bootstrap.e2e.ts | 9 +-- apps/web/e2e/favicon.e2e.ts | 44 ++++++------- apps/web/e2e/signin.e2e.ts | 89 ++++++++++++++------------- apps/web/e2e/site-header-logo.e2e.ts | 61 ------------------ apps/web/src/lib/server/auth/index.ts | 1 - 5 files changed, 66 insertions(+), 138 deletions(-) diff --git a/apps/web/e2e/bootstrap.e2e.ts b/apps/web/e2e/bootstrap.e2e.ts index bfb2698..f27512f 100644 --- a/apps/web/e2e/bootstrap.e2e.ts +++ b/apps/web/e2e/bootstrap.e2e.ts @@ -1,18 +1,11 @@ import { expect, test } from '@playwright/test'; -test('serves the configured directory from the production build', async ({ page }) => { - await page.goto('/'); - await expect(page).toHaveTitle('Directory'); - await expect(page.getByRole('heading', { name: 'Directory' })).toBeVisible(); - await expect(page.getByText("A small directory for your family's homelab.")).toBeVisible(); - await expect(page.getByText('No bookmarks yet.')).toBeVisible(); -}); - test.describe('without JavaScript', () => { test.use({ javaScriptEnabled: false }); test('renders useful initial HTML and serves the bundled icon', async ({ page, request }) => { await page.goto('/'); + await expect(page).toHaveTitle('Directory'); await expect(page.getByRole('heading', { name: 'Directory' })).toBeVisible(); await expect(page.getByText("A small directory for your family's homelab.")).toBeVisible(); await expect(page.getByText('No bookmarks yet.')).toBeVisible(); diff --git a/apps/web/e2e/favicon.e2e.ts b/apps/web/e2e/favicon.e2e.ts index 52d085b..c8eac3b 100644 --- a/apps/web/e2e/favicon.e2e.ts +++ b/apps/web/e2e/favicon.e2e.ts @@ -61,7 +61,6 @@ async function fixtures() { await writeFile(join(publicDir, 'café family.svg'), svg); await writeFile(join(publicDir, 'book.png'), png); await writeFile(join(publicDir, 'private-brand.svg'), svg); - await writeFile(join(publicDir, 'invalid.png'), 'not an image'); return { directory, publicDir }; } catch (error) { await rm(directory, { recursive: true, force: true }); @@ -287,30 +286,27 @@ test('valid reloads keep the alias but change bytes; invalid and auth-changing c } }); -for (const source of ['/public/missing.svg', '/public/invalid.png']) { - test(`configured unavailable source ${source} returns 404 without bundled fallback`, async ({ - browser - }) => { - const fixture = await fixtures(); - const server = await startServer({ - configuration: configuration(source), - publicDir: fixture.publicDir - }); - const context = await browser.newContext({ javaScriptEnabled: false }); - try { - await server.ready(); - await expectNotFound(server); - const page = await context.newPage(); - await page.goto(`${server.url}/signin`); - await expect(page.locator('head link[rel="icon"]')).toHaveCount(1); - await expect(page.locator('head link[rel="icon"]')).toHaveAttribute('href', '/favicon'); - expectNoPrivateData(await page.content(), [source]); - } finally { - await context.close(); - await stop(server, fixture.directory); - } +test('a missing configured favicon returns 404 without bundled fallback', async ({ browser }) => { + const source = '/public/missing.svg'; + const fixture = await fixtures(); + const server = await startServer({ + configuration: configuration(source), + publicDir: fixture.publicDir }); -} + const context = await browser.newContext({ javaScriptEnabled: false }); + try { + await server.ready(); + await expectNotFound(server); + const page = await context.newPage(); + await page.goto(`${server.url}/signin`); + await expect(page.locator('head link[rel="icon"]')).toHaveCount(1); + await expect(page.locator('head link[rel="icon"]')).toHaveAttribute('href', '/favicon'); + expectNoPrivateData(await page.content(), [source]); + } finally { + await context.close(); + await stop(server, fixture.directory); + } +}); test('no-auth mode remains open without changing alias selection', async () => { const fixture = await fixtures(); diff --git a/apps/web/e2e/signin.e2e.ts b/apps/web/e2e/signin.e2e.ts index 02aaa13..007e0c7 100644 --- a/apps/web/e2e/signin.e2e.ts +++ b/apps/web/e2e/signin.e2e.ts @@ -85,7 +85,6 @@ test.beforeEach(async () => { await writeFile(join(publicDir, 'PRIVATE_SELECTED_LOGO.svg'), logo); await writeFile(join(publicDir, 'PRIVATE_OTHER_IMAGE.svg'), favicon); await writeFile(join(publicDir, 'PRIVATE_TAB_ICON.svg'), favicon); - await writeFile(join(publicDir, 'invalid.svg'), 'not an image'); }); test.afterEach(async () => { @@ -342,50 +341,52 @@ test('only selected logo bytes are public, with independent favicon and no arbit } }); -for (const source of [null, '/public/missing.svg', '/public/invalid.svg']) { - for (const javaScriptEnabled of [false, true]) { - test(`${source ?? 'bundled default'} logo with JavaScript ${javaScriptEnabled}`, async ({ - browser - }) => { - const app = await startServer({ - configuration: brandedConfiguration(credentialsAuth, source), - publicDir - }); - const context = await browser.newContext({ - javaScriptEnabled, - viewport: { width: 360, height: 800 } - }); - try { - await app.ready(); - const page = await context.newPage(); - let logoRequests = 0; - page.on('request', (request) => { - if (new URL(request.url()).pathname === '/logo') logoRequests++; - }); - await page.goto(`${app.url}/signin`); - const image = page.locator('header img'); - if (source !== null && !javaScriptEnabled) { - await expect(image).toHaveAttribute('src', '/logo'); - await expect(image).toHaveJSProperty('complete', true); - await expect(image).toHaveJSProperty('naturalWidth', 0); - } else await expectDecoded(image, '/favicon.png'); - expect(logoRequests).toBe(source === null ? 0 : 1); - await expect(page.getByRole('heading')).toHaveText(`Sign in to ${siteTitle}`); - await expect(page.getByRole('button', { name: 'Sign in', exact: true })).toBeEnabled(); - await expect(page.locator('head link[rel="icon"]')).toHaveJSProperty( - 'href', - `${app.url}/favicon` - ); - expect(Buffer.from(await (await app.fetch('/favicon.png')).arrayBuffer())).toEqual( - await readFile(new URL('../static/favicon.png', import.meta.url)) - ); - expect((await app.fetch('/logo')).status).toBe(404); - } finally { - await context.close(); - expect(await app.stop()).toEqual({ code: 0, signal: null }); - } +for (const { source, javaScriptEnabled } of [ + { source: null, javaScriptEnabled: false }, + { source: '/public/missing.svg', javaScriptEnabled: false }, + { source: '/public/missing.svg', javaScriptEnabled: true } +]) { + test(`${source ?? 'bundled default'} logo with JavaScript ${javaScriptEnabled}`, async ({ + browser + }) => { + const app = await startServer({ + configuration: brandedConfiguration(credentialsAuth, source), + publicDir }); - } + const context = await browser.newContext({ + javaScriptEnabled, + viewport: { width: 360, height: 800 } + }); + try { + await app.ready(); + const page = await context.newPage(); + let logoRequests = 0; + page.on('request', (request) => { + if (new URL(request.url()).pathname === '/logo') logoRequests++; + }); + await page.goto(`${app.url}/signin`); + const image = page.locator('header img'); + if (source !== null && !javaScriptEnabled) { + await expect(image).toHaveAttribute('src', '/logo'); + await expect(image).toHaveJSProperty('complete', true); + await expect(image).toHaveJSProperty('naturalWidth', 0); + } else await expectDecoded(image, '/favicon.png'); + expect(logoRequests).toBe(source === null ? 0 : 1); + await expect(page.getByRole('heading')).toHaveText(`Sign in to ${siteTitle}`); + await expect(page.getByRole('button', { name: 'Sign in', exact: true })).toBeEnabled(); + await expect(page.locator('head link[rel="icon"]')).toHaveJSProperty( + 'href', + `${app.url}/favicon` + ); + expect(Buffer.from(await (await app.fetch('/favicon.png')).arrayBuffer())).toEqual( + await readFile(new URL('../static/favicon.png', import.meta.url)) + ); + expect((await app.fetch('/logo')).status).toBe(404); + } finally { + await context.close(); + expect(await app.stop()).toEqual({ code: 0, signal: null }); + } + }); } test('sign-in catches a logo failure before hydration and stops after a failed fallback', async ({ diff --git a/apps/web/e2e/site-header-logo.e2e.ts b/apps/web/e2e/site-header-logo.e2e.ts index 93591b0..a65d786 100644 --- a/apps/web/e2e/site-header-logo.e2e.ts +++ b/apps/web/e2e/site-header-logo.e2e.ts @@ -138,67 +138,6 @@ for (const javaScriptEnabled of [true, false]) { } } -test('a configured image that fails before hydration falls back once in the same SSR image', async ({ - page -}) => { - await writeFile(join(publicDir, 'private-brand-a.svg'), 'not an image'); - const app = await boot(sourceA); - const scripts = Promise.withResolvers(); - let heldScripts = 0; - await page.route('**/_app/immutable/**', async (route) => { - if (route.request().resourceType() === 'script') { - heldScripts++; - await scripts.promise; - } - await route.continue(); - }); - try { - await page.goto(app.url, { waitUntil: 'commit' }); - const image = page.locator('header img'); - await expect(image).toHaveAttribute('src', sourceA); - await expectBroken(image); - await expect.poll(() => heldScripts).toBeGreaterThan(0); - const ssrImage = await image.elementHandle(); - scripts.resolve(); - await expectDecoded(image, '/favicon.png'); - expect(await image.evaluate((node, previous) => node === previous, ssrImage)).toBe(true); - await ssrImage?.dispose(); - } finally { - scripts.resolve(); - await page.unrouteAll({ behavior: 'wait' }); - } -}); - -for (const source of [sourceA, undefined]) { - test(`${source ? 'failed primary and fallback' : 'failed default'} stop after one bundled image request`, async ({ - page - }) => { - await writeFile(join(publicDir, 'private-brand-a.svg'), 'not an image'); - const app = await boot(source); - let requests = 0; - await page.route('**/favicon.png', async (route) => { - requests++; - await route.abort(); - }); - const failed = page.waitForEvent( - 'requestfailed', - (request) => new URL(request.url()).pathname === '/favicon.png' - ); - await page.goto(app.url); - await failed; - const image = page.locator('header img'); - await expect(image).toHaveAttribute('src', '/favicon.png'); - await expectBroken(image); - await page.evaluate( - () => - new Promise((resolve) => - requestAnimationFrame(() => requestAnimationFrame(() => resolve())) - ) - ); - expect(requests).toBe(1); - }); -} - test('without JavaScript a broken configured header leaves title and native navigation usable', async ({ browser }) => { diff --git a/apps/web/src/lib/server/auth/index.ts b/apps/web/src/lib/server/auth/index.ts index d81cef4..91a9ee5 100644 --- a/apps/web/src/lib/server/auth/index.ts +++ b/apps/web/src/lib/server/auth/index.ts @@ -40,7 +40,6 @@ export function createAuthentication(config: DirectoryAuth & { origin: string }) secret, trustHost: true, basePath: '/auth', - // An empty value prevents Auth.js from enabling an environment-inferred redirect proxy. redirectProxyUrl: '', session: { strategy: 'jwt', maxAge: WEEK_SECONDS }, providers: buildProviders(config), -- 2.54.0