import { test, expect } from '@playwright/test'; import { ae_app_local_data_defaults } from './_helpers/ae_defaults'; import { testing_account_id } from './_helpers/env'; // Use canonical demo journal id for deterministic tests const journal_id = 'BVYE-94-46-29'; // Per README test data test.describe('Cold-start: Journal view (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 context (account + journal selection) BEFORE // any navigation so app scripts see the expected `ae_loc` values. await page.addInitScript( ({ defaults, account_id, journal_id }) => { const testData = { ...defaults, account_id: account_id, // Administrator mode for tests: ensures trusted/authenticated fallthrough administrator_access: true, trusted_access: true, authenticated_access: true, manager_access: false, super_access: false, edit_mode: true, // Ensure abstract module prop is present for layout/components mod_abstracts_json: {}, // Provide a test person id so owner-only pages render in tests person_id: 'QWODAPCNLQU', // Per README test data user: { id: 'QWODAPCNLQU' } // Per README test data }; window.localStorage.setItem('ae_loc', JSON.stringify(testData)); // Also set a lightweight selection object used by pages window.localStorage.setItem('ae_slct', JSON.stringify({ journal_id: journal_id })); }, { defaults: ae_app_local_data_defaults, account_id: testing_account_id, journal_id: journal_id } ); // Navigate to the app origin so IndexedDB is available in the page // context, then delete known Dexie DBs to simulate a cold start. await page.goto('/'); await page.evaluate(() => { const dbs = [ 'ae_journals_db', 'ae_events_db', 'ae_posts_db', 'ae_archives_db', 'ae_core_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) { resolve(false); } }) ) ); }); // Seed IndexedDB with the journal record so local liveQuery finds it await page.evaluate(({ journal_id }) => { return new Promise((resolve) => { try { const req = indexedDB.open('ae_journals_db', 1); req.onupgradeneeded = (ev) => { const db = (ev.target as IDBOpenDBRequest).result; if (!db.objectStoreNames.contains('journal')) { db.createObjectStore('journal', { keyPath: 'id' }); } }; req.onsuccess = () => { const db = req.result; const tx = db.transaction('journal', 'readwrite'); const store = tx.objectStore('journal'); // Why are both the id and journal_id fields being set? store.put({ id: journal_id, journal_id: journal_id, name: 'Demo Journal (Cold Start Test)', description: 'Created for cold-start Playwright test', person_id: 'QWODAPCNLQU' }); // Per README test data tx.oncomplete = () => { db.close(); resolve(); }; tx.onerror = () => { db.close(); resolve(); }; }; req.onerror = () => resolve(); } catch (e) { resolve(); } }); }, { journal_id }); // Mock the journal GET endpoint used by the journal page await page.route('**/v3/**', async (route) => { const req = route.request(); const url = req.url(); if (url.includes(`/v3/crud/journal/${journal_id}`) && req.method() === 'GET') { return route.fulfill({ status: 200, contentType: 'application/json', body: JSON.stringify({ data: { id: journal_id, // Why are both the id and journal_id fields being set? journal_id: journal_id, // Why are both the id and journal_id fields being set? name: 'Demo Journal (Cold Start Test)', description: 'Created for cold-start Playwright test' } }) }); } // Default: empty envelope return route.fulfill({ status: 200, contentType: 'application/json', body: JSON.stringify({ data: [] }) }); }); // (already set above) }); test('renders Journal page without prior IndexedDB cache', async ({ page }) => { await page.goto(`/journals/${journal_id}`); // The journal title appears in the journal component header const journal_name = page.locator('h2.journal__name'); await expect(journal_name).toContainText('Demo Journal (Cold Start Test)', { timeout: 10000 }); }); });