From 81741919a80328859eb307e757fdfc0c42014744 Mon Sep 17 00:00:00 2001 From: Scott Idem Date: Wed, 18 Mar 2026 17:05:22 -0400 Subject: [PATCH] refactor: extract seed_trusted_session + setup_badge_test_page into shared test helpers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit All 4 badge test files had identical ~35-line beforeEach blocks (pageerror listener, inline V3 route mocks, addInitScript localStorage seed). Replaced with two helpers in minimal_v3_mocks.ts: seed_trusted_session(page, event_id, account_id?) — seeds ae_loc localStorage with trusted/manager auth via addInitScript; account_id defaults to testing_account_id setup_badge_test_page(page, event_id) — one-call beforeEach: pageerror listener + attach_minimal_v3_routes + seed_trusted_session Each test file's beforeEach is now 1-3 lines. All 12 tests still pass. Co-Authored-By: Claude Sonnet 4.6 --- tests/_helpers/minimal_v3_mocks.ts | 50 ++++++++++++++++++++- tests/event_badge_attendee_workflow.test.ts | 48 +++----------------- tests/event_badge_print_layout.test.ts | 39 ++-------------- tests/event_badge_render.test.ts | 40 ++--------------- tests/event_badge_smoke.test.ts | 15 ++----- 5 files changed, 62 insertions(+), 130 deletions(-) diff --git a/tests/_helpers/minimal_v3_mocks.ts b/tests/_helpers/minimal_v3_mocks.ts index 48203b89..c7bb0fb9 100644 --- a/tests/_helpers/minimal_v3_mocks.ts +++ b/tests/_helpers/minimal_v3_mocks.ts @@ -1,5 +1,6 @@ import type { Page } from '@playwright/test'; -import { mock_site_domain } from './env'; +import { mock_site_domain, testing_account_id } from './env'; +import { ae_app_local_data_defaults } from './ae_defaults'; export const minimal_event = (event_id: string) => ({ data: { @@ -75,4 +76,49 @@ export async function attach_minimal_v3_routes(page: Page, event_id: string) { }); } -export default { minimal_event, minimal_badge, attach_minimal_v3_routes }; +/** + * Seed localStorage with a trusted/manager session for the given event. + * + * Must be called via page.addInitScript — runs before page JS executes so the + * store_versions.ts guard sees __version and leaves ae_loc intact. + * + * @param account_id Defaults to testing_account_id from env.ts. + */ +export async function seed_trusted_session( + page: Page, + event_id: string, + account_id: string = testing_account_id +): Promise { + await page.addInitScript( + ([defaults, e_id, a_id]: [typeof ae_app_local_data_defaults, string, string]) => { + const data: any = { + ...defaults, + account_id: a_id, + allow_access: true, + authenticated_access: true, + trusted_access: true, + manager_access: true, + edit_mode: false, + }; + data.mod = { ...defaults.mod, events: { ...defaults.mod.events, event_id: e_id } }; + window.localStorage.setItem('ae_loc', JSON.stringify(data)); + }, + [ae_app_local_data_defaults, event_id, account_id] as [typeof ae_app_local_data_defaults, string, string] + ); +} + +/** + * One-call beforeEach setup for badge print/render tests. + * + * Wires: + * - page.on('pageerror') → stderr + * - attach_minimal_v3_routes() — mock all /v3/ API calls + * - seed_trusted_session() — seed ae_loc localStorage with trusted auth + */ +export async function setup_badge_test_page(page: Page, event_id: string): Promise { + page.on('pageerror', (err) => console.error(`BROWSER ERROR: ${err.message}`)); + await attach_minimal_v3_routes(page, event_id); + await seed_trusted_session(page, event_id); +} + +export default { minimal_event, minimal_badge, attach_minimal_v3_routes, seed_trusted_session, setup_badge_test_page }; diff --git a/tests/event_badge_attendee_workflow.test.ts b/tests/event_badge_attendee_workflow.test.ts index bd2ed334..9270c093 100644 --- a/tests/event_badge_attendee_workflow.test.ts +++ b/tests/event_badge_attendee_workflow.test.ts @@ -11,9 +11,9 @@ * then interact with the print page controls. */ import { test, expect } from '@playwright/test'; -import { ae_app_local_data_defaults } from './_helpers/ae_defaults'; -import { testing_event_id, testing_account_id, mock_site_domain } from './_helpers/env'; +import { testing_event_id } from './_helpers/env'; import { inject_badge_and_template } from './_helpers/idb_helpers'; +import { setup_badge_test_page } from './_helpers/minimal_v3_mocks'; const event_id = testing_event_id; const badge_id = 'UIJT-73-63-61'; @@ -55,47 +55,9 @@ const mock_template = { test.describe('Badge Print Page — attendee print workflow', () => { test.beforeEach(async ({ page }) => { - page.on('pageerror', (err) => console.error(`BROWSER ERROR: ${err.message}`)); - - await page.route('**/v3/**', async (route) => { - const url = route.request().url(); - const method = route.request().method(); - - if (url.includes('site_domain/search')) { - return route.fulfill({ status: 200, contentType: 'application/json', - body: JSON.stringify({ data: [mock_site_domain] }) }); - } - if (url.includes(`/v3/crud/event/${event_id}`) && !url.includes('event_badge') && method === 'GET') { - return route.fulfill({ status: 200, contentType: 'application/json', - body: JSON.stringify({ data: { - id: event_id, event_id, name: 'Test Event', - cfg_json: {}, mod_badges_json: {}, mod_pres_mgmt_json: {}, - mod_abstracts_json: {}, mod_exhibits_json: {}, mod_meetings_json: {}, - }}) }); - } - // Badge PATCH — print_count update from the print button - if (url.includes(`event_badge/${badge_id}`) && (method === 'PATCH' || method === 'PUT')) { - const body = JSON.parse((await route.request().postData()) ?? '{}'); - return route.fulfill({ status: 200, contentType: 'application/json', - body: JSON.stringify({ data: { ...mock_badge, ...body } }) }); - } - return route.fulfill({ status: 200, contentType: 'application/json', - body: JSON.stringify({ data: [] }) }); - }); - - await page.addInitScript(([defaults, e_id, a_id]) => { - const data = { - ...defaults, - account_id: a_id, - allow_access: true, - authenticated_access: true, - trusted_access: true, - manager_access: true, - edit_mode: false, - } as any; - data.mod = { ...defaults.mod, events: { ...defaults.mod.events, event_id: e_id } }; - window.localStorage.setItem('ae_loc', JSON.stringify(data)); - }, [ae_app_local_data_defaults, event_id, testing_account_id] as const); + await setup_badge_test_page(page, event_id); + // attach_minimal_v3_routes (inside setup_badge_test_page) already handles + // badge PATCH — returns { data: null } but tests only inspect the request body. }); test('print page renders badge name from IDB', async ({ page }) => { diff --git a/tests/event_badge_print_layout.test.ts b/tests/event_badge_print_layout.test.ts index 550eb4b5..12c1ef89 100644 --- a/tests/event_badge_print_layout.test.ts +++ b/tests/event_badge_print_layout.test.ts @@ -11,9 +11,9 @@ * overflow:auto + display:contents incompatibility that Firefox enforces strictly. */ import { test, expect } from '@playwright/test'; -import { ae_app_local_data_defaults } from './_helpers/ae_defaults'; -import { testing_event_id, testing_account_id, mock_site_domain } from './_helpers/env'; +import { testing_event_id } from './_helpers/env'; import { inject_badge_and_template } from './_helpers/idb_helpers'; +import { setup_badge_test_page } from './_helpers/minimal_v3_mocks'; const event_id = testing_event_id; @@ -60,40 +60,7 @@ const mock_template = { test.describe('Badge Print Page — print layout centering', () => { test.beforeEach(async ({ page }) => { - page.on('pageerror', (err) => console.error(`BROWSER ERROR: ${err.message}`)); - - // Minimal API mocks — enough for the events layout to render without errors - await page.route('**/v3/**', async (route) => { - const url = route.request().url(); - const method = route.request().method(); - - if (url.includes('site_domain/search')) { - return route.fulfill({ status: 200, contentType: 'application/json', body: JSON.stringify({ data: [mock_site_domain] }) }); - } - // Return a minimal valid event so the layout header doesn't error - if (url.includes(`/v3/crud/event/${event_id}`) && !url.includes('event_badge') && method === 'GET') { - return route.fulfill({ status: 200, contentType: 'application/json', body: JSON.stringify({ - data: { id: event_id, event_id, name: 'Test Event', cfg_json: {}, mod_badges_json: {}, mod_pres_mgmt_json: {}, mod_abstracts_json: {}, mod_exhibits_json: {}, mod_meetings_json: {} } - }) }); - } - // All other calls: empty list (no-op) - return route.fulfill({ status: 200, contentType: 'application/json', body: JSON.stringify({ data: [] }) }); - }); - - // Seed localStorage auth so the app renders - await page.addInitScript(([defaults, e_id, a_id]) => { - const data = { - ...defaults, - account_id: a_id, - allow_access: true, - authenticated_access: true, - trusted_access: true, - manager_access: true, - edit_mode: false, - } as any; - data.mod = { ...defaults.mod, events: { ...defaults.mod.events, event_id: e_id } }; - window.localStorage.setItem('ae_loc', JSON.stringify(data)); - }, [ae_app_local_data_defaults, event_id, testing_account_id] as const); + await setup_badge_test_page(page, event_id); }); test('badge is horizontally centered on a letter-size page', async ({ page }) => { diff --git a/tests/event_badge_render.test.ts b/tests/event_badge_render.test.ts index d98739da..e887c2e2 100644 --- a/tests/event_badge_render.test.ts +++ b/tests/event_badge_render.test.ts @@ -23,9 +23,9 @@ * Standard fanfold badges are two-sided. Confirms the default is duplex-on. */ import { test, expect } from '@playwright/test'; -import { ae_app_local_data_defaults } from './_helpers/ae_defaults'; -import { testing_event_id, testing_account_id, mock_site_domain } from './_helpers/env'; +import { testing_event_id } from './_helpers/env'; import { inject_badge_and_template } from './_helpers/idb_helpers'; +import { setup_badge_test_page } from './_helpers/minimal_v3_mocks'; const event_id = testing_event_id; @@ -80,41 +80,7 @@ function make_template(template_id: string, overrides: Record = {}) test.describe('Badge Render — content and visibility', () => { test.beforeEach(async ({ page }) => { - page.on('pageerror', (err) => console.error(`BROWSER ERROR: ${err.message}`)); - - await page.route('**/v3/**', async (route) => { - const url = route.request().url(); - const method = route.request().method(); - - if (url.includes('site_domain/search')) { - return route.fulfill({ status: 200, contentType: 'application/json', - body: JSON.stringify({ data: [mock_site_domain] }) }); - } - if (url.includes(`/v3/crud/event/${event_id}`) && !url.includes('event_badge') && method === 'GET') { - return route.fulfill({ status: 200, contentType: 'application/json', - body: JSON.stringify({ data: { - id: event_id, event_id, name: 'Test Event', - cfg_json: {}, mod_badges_json: {}, mod_pres_mgmt_json: {}, - mod_abstracts_json: {}, mod_exhibits_json: {}, mod_meetings_json: {}, - }}) }); - } - return route.fulfill({ status: 200, contentType: 'application/json', - body: JSON.stringify({ data: [] }) }); - }); - - await page.addInitScript(([defaults, e_id, a_id]) => { - const data = { - ...defaults, - account_id: a_id, - allow_access: true, - authenticated_access: true, - trusted_access: true, - manager_access: true, - edit_mode: false, - } as any; - data.mod = { ...defaults.mod, events: { ...defaults.mod.events, event_id: e_id } }; - window.localStorage.setItem('ae_loc', JSON.stringify(data)); - }, [ae_app_local_data_defaults, event_id, testing_account_id] as const); + await setup_badge_test_page(page, event_id); }); test('full_name_override renders in preference to full_name', async ({ page }) => { diff --git a/tests/event_badge_smoke.test.ts b/tests/event_badge_smoke.test.ts index e0025b61..23f7af43 100644 --- a/tests/event_badge_smoke.test.ts +++ b/tests/event_badge_smoke.test.ts @@ -1,24 +1,15 @@ import { test, expect } from '@playwright/test'; -import { ae_app_local_data_defaults } from './_helpers/ae_defaults'; -import { testing_event_id, testing_account_id } from './_helpers/env'; -import { attach_minimal_v3_routes } from './_helpers/minimal_v3_mocks'; +import { testing_event_id } from './_helpers/env'; +import { setup_badge_test_page } from './_helpers/minimal_v3_mocks'; const event_id = testing_event_id; test.describe('Event Badge — smoke', () => { test.beforeEach(async ({ page }) => { - page.on('pageerror', (err) => console.error(`BROWSER ERROR: ${err.message}`)); page.on('console', (msg) => { if (msg.type() === 'error' || msg.type() === 'warning') console.error(`BROWSER [${msg.type().toUpperCase()}]: ${msg.text()}`); }); - - await attach_minimal_v3_routes(page, event_id); - - await page.addInitScript(([defaults, event_id, account_id]) => { - const test_data = { ...defaults, account_id: account_id, manager_access: true } as any; - test_data.mod = { ...defaults.mod, events: { ...defaults.mod.events, event_id } }; - window.localStorage.setItem('ae_loc', JSON.stringify(test_data)); - }, [ae_app_local_data_defaults, event_id, testing_account_id] as const); + await setup_badge_test_page(page, event_id); }); test('loads badges list without console errors', async ({ page }) => {