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'; const demo_event = testing_event_id; test.describe('Cold-start: Event Settings (IndexedDB empty)', () => { 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()}`); }); // Provide app localStorage before any scripts run await page.addInitScript( ({ defaults, event_id, account_id }) => { const testData = { ...defaults, account_id: account_id, // Administrator implies lower-level access flags are true; // Manager and Super accesses are explicitly set per test requirements. administrator_access: true, trusted_access: true, authenticated_access: true, manager_access: false, super_access: false, edit_mode: true, // Ensure the layout/components that bind this prop don't receive undefined mod_abstracts_json: {}, // Provide a test person id so components that expect an authenticated // user/person render deterministically in tests person_id: 'HMQRNPIXQMK', // Per README test data user: { id: 'HMQRNPIXQMK' }, // Per README test data mod: { ...defaults.mod, events: { ...defaults.mod.events, event_id: event_id } } }; window.localStorage.setItem('ae_loc', JSON.stringify(testData)); }, { defaults: ae_app_local_data_defaults, event_id: demo_event, account_id: testing_account_id } ); // Navigate to the application's origin so the page context is allowed // to access the IndexedDB API, then delete known Dexie DBs to simulate // a cold start. We wrap deleteDatabase in Promises to wait for completion. await page.goto('/'); await page.evaluate(() => { const dbs = [ 'ae_events_db', 'ae_journals_db', 'ae_posts_db', 'ae_archives_db', 'ae_core_db', 'ae_sponsorships_db' ]; return Promise.all( dbs.map((name) => new Promise((resolve) => { try { const req = indexedDB.deleteDatabase(name); req.onsuccess = () => resolve(true); req.onerror = () => resolve(false); req.onblocked = () => resolve(false); } catch (e) { // If deleteDatabase throws, resolve to avoid hanging the test resolve(false); } }) ) ); }); // Seed IndexedDB with the event record so the page's local liveQuery // (which reads from IDB) finds it immediately on mount. await page.evaluate(({ demo_event }) => { return new Promise((resolve) => { try { const req = indexedDB.open('ae_events_db', 1); req.onupgradeneeded = (ev) => { const db = (ev.target as IDBOpenDBRequest).result; if (!db.objectStoreNames.contains('event')) { db.createObjectStore('event', { keyPath: 'id' }); } }; req.onsuccess = () => { const db = req.result; const tx = db.transaction('event', 'readwrite'); const store = tx.objectStore('event'); store.put({ id: demo_event, event_id: demo_event, name: 'Cold Start Test Event', cfg_json: {}, mod_pres_mgmt_json: {}, mod_badges_json: {}, mod_abstracts_json: {} }); tx.oncomplete = () => { db.close(); resolve(); }; tx.onerror = () => { db.close(); resolve(); }; }; req.onerror = () => resolve(); } catch (e) { resolve(); } }); }, { demo_event }); // Minimal network mock for the event GET used by the settings page await page.route('**/v3/**', async (route) => { const req = route.request(); const url = req.url(); if (url.includes(`/v3/crud/event/${demo_event}`) && req.method() === 'GET') { return route.fulfill({ status: 200, contentType: 'application/json', body: JSON.stringify({ data: { id: demo_event, event_id: demo_event, name: 'Cold Start Test Event', cfg_json: {}, mod_pres_mgmt_json: {}, mod_badges_json: {}, mod_abstracts_json: {} } }) }); } // Default: empty envelope so other calls don't error return route.fulfill({ status: 200, contentType: 'application/json', body: JSON.stringify({ data: [] }) }); }); // (already set above) }); test('renders Event Settings without prior IndexedDB cache', async ({ page }) => { await page.goto(`/events/${demo_event}/settings`); const add_btn = page.getByRole('button', { name: 'Add New Badge' }); await expect(add_btn).toBeVisible({ timeout: 10000 }); }); });