2026-08-04 09:01:52 +02:00
|
|
|
// Runs once before the e2e suite, after Playwright's webServer is already up
|
|
|
|
|
// (see playwright.config.js) but before any test executes.
|
|
|
|
|
//
|
|
|
|
|
// 1. Resets and migrates a throwaway SQLite DB (data/e2e_test.sqlite3) so
|
|
|
|
|
// tests never touch the real dev database.
|
|
|
|
|
// 2. Creates a fixed test user.
|
|
|
|
|
// 3. Logs that user in through the real login form and saves the resulting
|
|
|
|
|
// storage state, so authenticated specs can start already logged in via
|
|
|
|
|
// `test.use({ storageState: 'e2e/.auth/user.json' })`.
|
|
|
|
|
const fs = require('fs');
|
|
|
|
|
const path = require('path');
|
|
|
|
|
const { execFileSync } = require('child_process');
|
|
|
|
|
const { chromium } = require('@playwright/test');
|
2026-10-14 18:25:06 +02:00
|
|
|
const { BASE_URL, PYTHON, SERVER_ENV, TEST_USER } = require('./env');
|
2026-08-04 09:01:52 +02:00
|
|
|
|
|
|
|
|
const ROOT = path.join(__dirname, '..');
|
|
|
|
|
const DB_PATH = path.join(ROOT, 'data', SERVER_ENV.DIORA_DB_NAME);
|
|
|
|
|
const AUTH_DIR = path.join(__dirname, '.auth');
|
|
|
|
|
const AUTH_FILE = path.join(AUTH_DIR, 'user.json');
|
|
|
|
|
|
|
|
|
|
module.exports = async function globalSetup() {
|
|
|
|
|
// Fresh DB every run.
|
|
|
|
|
fs.rmSync(DB_PATH, { force: true });
|
|
|
|
|
|
2026-10-14 18:25:06 +02:00
|
|
|
execFileSync(PYTHON, ['manage.py', 'migrate', '--noinput'], {
|
2026-08-04 09:01:52 +02:00
|
|
|
cwd: ROOT,
|
|
|
|
|
env: SERVER_ENV,
|
|
|
|
|
stdio: 'inherit',
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
execFileSync(
|
2026-10-14 18:25:06 +02:00
|
|
|
PYTHON,
|
2026-08-04 09:01:52 +02:00
|
|
|
[
|
|
|
|
|
'manage.py',
|
|
|
|
|
'shell',
|
|
|
|
|
'-c',
|
|
|
|
|
`
|
|
|
|
|
from django.contrib.auth import get_user_model
|
|
|
|
|
User = get_user_model()
|
|
|
|
|
User.objects.filter(username=${JSON.stringify(TEST_USER.username)}).delete()
|
|
|
|
|
User.objects.create_user(${JSON.stringify(TEST_USER.username)}, "", ${JSON.stringify(TEST_USER.password)})
|
|
|
|
|
`,
|
|
|
|
|
],
|
|
|
|
|
{ cwd: ROOT, env: SERVER_ENV, stdio: 'inherit' }
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
fs.mkdirSync(AUTH_DIR, { recursive: true });
|
2026-10-19 14:57:03 +02:00
|
|
|
// A big PDF (e2e/make_pdf.py): opening draws only the pages near the view.
|
|
|
|
|
execFileSync(PYTHON, [path.join(__dirname, 'make_pdf.py'), path.join(AUTH_DIR, 'big.pdf'), '400'], { stdio: 'inherit' });
|
2026-10-14 18:25:06 +02:00
|
|
|
// The book the reader tests read (e2e/make_epub.py).
|
|
|
|
|
execFileSync(PYTHON, [path.join(__dirname, 'make_epub.py'), path.join(AUTH_DIR, 'book.epub')], { stdio: 'inherit' });
|
Neue Navigations-Icons (Stil B), mehrere Bücher auf einmal, generiertes Cover pro Buch wählbar
- Icons: eigene SVGs, kräftig und geometrisch (2,4 px, eckige Enden), in
nav.js für alle Leisten (DioraNav.icon, sections()/groups() .svg); der
aktive Bereich gefüllt.
- Hochladen: mehrere Dateien auf einmal (Auswahl oder auf die Bibliothek
ziehen) und aus der Cloud per Häkchen („Alle auswählen“, „n importieren“);
nacheinander mit Fortschritt, ein schon vorhandenes Buch (Titel und Autor)
wird übersprungen.
- Pro Buch: „Generiertes Cover verwenden“ statt des eigenen (im verschlüsselten
Meta, cover: 'generated').
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-16 21:21:10 +02:00
|
|
|
// Two more for uploading several at once (navigation.spec.js).
|
|
|
|
|
for (const n of ['Eins', 'Zwei']) {
|
|
|
|
|
execFileSync(PYTHON, [path.join(__dirname, 'make_epub.py'), path.join(AUTH_DIR, `many-${n}.epub`), `Mehrfach ${n}`], { stdio: 'inherit' });
|
|
|
|
|
}
|
2026-08-04 09:01:52 +02:00
|
|
|
|
|
|
|
|
const browser = await chromium.launch();
|
|
|
|
|
const page = await browser.newPage({ baseURL: BASE_URL });
|
|
|
|
|
await page.goto(`${BASE_URL}/accounts/login/`);
|
|
|
|
|
await page.fill('[name=username]', TEST_USER.username);
|
|
|
|
|
await page.fill('[name=password]', TEST_USER.password);
|
|
|
|
|
await Promise.all([
|
|
|
|
|
page.waitForURL(BASE_URL + '/'),
|
|
|
|
|
page.click('button[type=submit]'),
|
|
|
|
|
]);
|
|
|
|
|
await page.context().storageState({ path: AUTH_FILE });
|
|
|
|
|
await browser.close();
|
|
|
|
|
};
|