/** * E2E tests for the native mobile editor UX (ROADMAP #69). * * Runs only under the `chromium-mobile` Playwright project (viewport ≤ 768px); * skipped on the desktop project that the CI job executes. * * Prerequisites: * cd tests/e2e && npm install && npx playwright install chromium * * Run: * npx playwright test tests/e2e/mobile-editor.spec.js --project=chromium-mobile */ import { test, expect } from '@playwright/test'; const MOBILE_MAX_WIDTH = 768; async function boot(page) { await page.goto('/'); // Auth may be disabled (test env) or a session may already exist. await page .waitForSelector('#app:not(.hidden)', { timeout: 15000 }) .catch(() => {}); await page.waitForTimeout(500); } test.describe('Mobile editor (#69)', () => { test('reading mode button toggles the distraction-free class', async ({ page, viewport }) => { test.skip((viewport?.width ?? 0) > MOBILE_MAX_WIDTH, 'Mobile viewport required'); await boot(page); const enter = page.locator('#me-reading-btn'); // The floating button only shows once a file is open (and not on the // dashboard), so it cannot cover the assistant's send button. await expect(enter).toBeHidden(); await page.evaluate(() => window.TabManager.open('TestVault', 'note1.md')); await expect(enter).toBeVisible(); await enter.click(); await expect(page.locator('body')).toHaveClass(/reading-mode/); await expect(page.locator('.header')).toBeHidden(); await page.locator('#me-reading-exit').click(); await expect(page.locator('body')).not.toHaveClass(/reading-mode/); }); test('editor modal exposes the Obsidian-style editing ribbon', async ({ page, viewport }) => { test.skip((viewport?.width ?? 0) > MOBILE_MAX_WIDTH, 'Mobile viewport required'); await boot(page); // Force the editor modal open — the ribbon visibility is pure CSS. await page.evaluate(() => document.getElementById('editor-modal').classList.add('active')); const toolbar = page.locator('#me-toolbar'); await expect(toolbar).toBeVisible(); for (const cmd of ['bold', 'italic', 'strike', 'highlight', 'wikilink', 'checkbox', 'undo', 'redo']) { await expect(page.locator('#me-cmd-' + cmd)).toBeVisible(); } await expect(page.locator('#me-ribbon-gear')).toBeVisible(); }); test('font zoom buttons persist the editor font size', async ({ page, viewport }) => { test.skip((viewport?.width ?? 0) > MOBILE_MAX_WIDTH, 'Mobile viewport required'); await boot(page); await page.evaluate(() => document.getElementById('editor-modal').classList.add('active')); await page.locator('#me-cmd-font_larger').click(); await page.locator('#me-cmd-font_larger').click(); const stored = await page.evaluate(() => localStorage.getItem('obsigate-editor-font-size')); expect(Number(stored)).toBeGreaterThan(13.5); }); });