Files
ObsiGate/tests/e2e/mobile-editor.spec.js
T
bruno 520059d866
CI / lint (push) Successful in 1m13s
CI / security (push) Successful in 47s
CI / test (push) Successful in 2m41s
CI / build (push) Successful in 43s
CI / e2e (push) Successful in 11m14s
feat(mobile): ruban d'edition style Obsidian + correctifs mobile (#83, BUG-017 a BUG-020)
- #83: ruban horizontal defilable ancre au-dessus du clavier, commandes
  etendues (titres, barre, surligne, code bloc, citation, listes, cases,
  wikilinks, tags, pieces jointes, undo/redo, colle, police) et
  personnalisation persistee via l'icone engrenage
- BUG-017: cartes du tableau de bord compressibles (min-width:0)
- BUG-018: en-tete editeur mobile compact, boutons Annuler/Sauvegarder
  accessibles, barre IA plus tactile
- BUG-019: ancrage du ruban via visualViewport (--kb-offset)
- BUG-020: suppression de la double barre de defilement

Tests: mobile-editor 35/35, ai 50/50, 9 suites JSDOM, validate-imports,
pytest 961 passed / 6 skipped, ruff + mypy 0.
2026-09-13 11:49:45 -04:00

74 lines
2.8 KiB
JavaScript

/**
* 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);
});
});