MindSift CI & Docker Release / Build, Test in Container & Push (push) Successful in 1m30s
- Turn the collaboration plan into module docs (Doku/modules/collaboration.md) describing the implemented state; remove Doku/plans - Header version comes from the build: git tag via APP_VERSION (CI passes it for tag builds), otherwise "<package version>-dev"; package 0.2.0 - Sample data (setup option and demo mode): six inbox thoughts, two task lists with Kanban states, subtasks and due dates, shopping and packing lists, three notes in folders incl. a long nested outline; demo mode shares the note and two lists with user/user - e2e/screenshots.sh renews the README screenshots from demo data - README: live collaboration, editor sharing, image tags, version badge Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
85 lines
3.5 KiB
JavaScript
85 lines
3.5 KiB
JavaScript
// Takes the README screenshots from a fresh server in demo mode (sample data of admin/admin).
|
|
// Usage: e2e/screenshots.sh (builds the image) or MINDSIFT_URL=… SHOTS_DIR=… node screenshots.mjs
|
|
import { chromium } from 'playwright';
|
|
|
|
const BASE = process.env.MINDSIFT_URL || 'http://localhost:18080';
|
|
const OUT = process.env.SHOTS_DIR || '../screenshots';
|
|
const DESKTOP = { viewport: { width: 1518, height: 886 }, deviceScaleFactor: 2 };
|
|
const MOBILE = { viewport: { width: 390, height: 844 }, deviceScaleFactor: 2, isMobile: true, hasTouch: true };
|
|
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
|
|
|
|
async function login(user) {
|
|
const res = await fetch(`${BASE}/api/v1/auth/login`, {
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify({ login: user, password: user }),
|
|
});
|
|
if (!res.ok) throw new Error(`login ${user}: ${res.status}`);
|
|
return (await res.json()).token;
|
|
}
|
|
|
|
async function open(browser, token, options) {
|
|
const ctx = await browser.newContext({ ...options, colorScheme: 'dark', locale: 'de-DE' });
|
|
await ctx.addInitScript((t) => localStorage.setItem('mindsift_jwt_token', t), token);
|
|
const page = await ctx.newPage();
|
|
page.on('pageerror', (e) => console.log('PAGEERROR', e.message));
|
|
await page.goto(BASE);
|
|
await page.waitForLoadState('networkidle');
|
|
return page;
|
|
}
|
|
|
|
const tab = (page, name) => page.getByRole('button', { name: new RegExp(name) }).first().click();
|
|
|
|
async function shot(page, file) {
|
|
await sleep(800); // animations
|
|
await page.mouse.move(0, 0);
|
|
await page.screenshot({ path: `${OUT}/${file}` });
|
|
console.log(`OK ${file}`);
|
|
}
|
|
|
|
const main = async () => {
|
|
const admin = await login('admin');
|
|
const user = await login('user');
|
|
const browser = await chromium.launch({ args: ['--lang=de-DE'] });
|
|
|
|
const page = await open(browser, admin, DESKTOP);
|
|
await tab(page, 'Triage');
|
|
await shot(page, 'Triage_desktop.png');
|
|
|
|
await tab(page, 'Aufgaben');
|
|
await page.getByText('Homelab', { exact: true }).first().click().catch(() => {});
|
|
await page.getByRole('button', { name: /Kanban|Board/ }).first().click().catch(() => {});
|
|
await shot(page, 'aufgaben_desktop.png');
|
|
|
|
// The demo user edits a bullet of the shared note, so the screenshot shows lock and presence
|
|
const other = await open(browser, user, DESKTOP);
|
|
await tab(other, 'Workspace');
|
|
await other.getByText(/^Homelab 2\.0/).first().click();
|
|
await other.waitForFunction(() => document.querySelectorAll('textarea').length > 5, null, { timeout: 10000 });
|
|
await other.getByText('Endlich Platz für die Dienste', { exact: false }).first().click();
|
|
await other.keyboard.press('End');
|
|
await other.keyboard.type(': Paperless und Immich', { delay: 20 });
|
|
|
|
await tab(page, 'Workspace');
|
|
await page.getByText(/^Homelab 2\.0/).first().click();
|
|
await page.waitForFunction(() => document.querySelectorAll('textarea').length > 5, null, { timeout: 10000 });
|
|
await page.getByText('User', { exact: false }).first().waitFor({ timeout: 15000 }).catch(() => {});
|
|
await sleep(2000);
|
|
await shot(page, 'workspace_desktop.png');
|
|
|
|
await tab(page, 'Listen');
|
|
await page.getByText('Wocheneinkauf', { exact: true }).first().click().catch(() => {});
|
|
await shot(page, 'Listen_desktop.png');
|
|
|
|
const mobile = await open(browser, admin, MOBILE);
|
|
await mobile.getByText('Später im Browser weiter nutzen').click({ timeout: 5000 }).catch(() => {}); // install prompt
|
|
await shot(mobile, 'Mobile_Triage.png');
|
|
|
|
await browser.close();
|
|
};
|
|
|
|
main().catch((e) => {
|
|
console.error(e);
|
|
process.exit(1);
|
|
});
|