Full document, spreadsheet, slideshow, and diagram tooling
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

at main 114 lines 3.8 kB view raw
1import { test, expect } from '@playwright/test'; 2import { createNewDoc } from './helpers'; 3 4test.describe('Mobile — Docs Editor', () => { 5 test.beforeEach(async ({ page }) => { 6 await createNewDoc(page); 7 }); 8 9 test('editor is visible and fills viewport width', async ({ page }) => { 10 const editor = page.locator('.tiptap'); 11 await expect(editor).toBeVisible(); 12 13 const viewport = page.viewportSize()!; 14 const box = await editor.boundingBox(); 15 // Editor should use most of the viewport width 16 expect(box!.width).toBeGreaterThan(viewport.width * 0.8); 17 }); 18 19 test('toolbar buttons meet minimum touch target size', async ({ page }) => { 20 const viewport = page.viewportSize()!; 21 if (viewport.width > 768) test.skip(); 22 23 const buttons = page.locator('.tb-btn:visible'); 24 const count = await buttons.count(); 25 expect(count).toBeGreaterThan(0); 26 27 for (let i = 0; i < Math.min(count, 5); i++) { 28 const box = await buttons.nth(i).boundingBox(); 29 if (box) { 30 expect(box.width).toBeGreaterThanOrEqual(42); // 44 target, 2px tolerance 31 expect(box.height).toBeGreaterThanOrEqual(42); 32 } 33 } 34 }); 35 36 test('non-essential toolbar items hidden on mobile', async ({ page }) => { 37 const viewport = page.viewportSize()!; 38 if (viewport.width > 768) test.skip(); 39 40 const hiddenItems = page.locator('.toolbar-mobile-hide'); 41 const count = await hiddenItems.count(); 42 for (let i = 0; i < count; i++) { 43 await expect(hiddenItems.nth(i)).not.toBeVisible(); 44 } 45 }); 46 47 test('can type and see text in editor', async ({ page }) => { 48 const editor = page.locator('.tiptap'); 49 await editor.click(); 50 await page.keyboard.type('Mobile typing test'); 51 await expect(editor).toContainText('Mobile typing test'); 52 }); 53 54 test('topbar does not overflow horizontally', async ({ page }) => { 55 const viewport = page.viewportSize()!; 56 const topbar = page.locator('.app-topbar'); 57 const box = await topbar.boundingBox(); 58 if (box) { 59 expect(box.width).toBeLessThanOrEqual(viewport.width + 1); 60 } 61 }); 62 63 test('document title input is accessible', async ({ page }) => { 64 const titleInput = page.locator('.doc-title-input'); 65 await expect(titleInput).toBeVisible(); 66 await titleInput.fill('My Mobile Doc'); 67 await expect(titleInput).toHaveValue('My Mobile Doc'); 68 }); 69 70 test('word count visible in footer', async ({ page }) => { 71 const editor = page.locator('.tiptap'); 72 await editor.click(); 73 await page.keyboard.type('one two three'); 74 75 await expect(page.locator('#word-count')).toContainText('3 words', { timeout: 5000 }); 76 }); 77 78 test('command palette opens and is usable', async ({ page }) => { 79 const viewport = page.viewportSize()!; 80 81 await page.keyboard.press('Meta+k'); 82 const palette = page.locator('.cmd-palette'); 83 await expect(palette).toBeVisible({ timeout: 3000 }); 84 85 // Palette should fit within viewport 86 const box = await palette.boundingBox(); 87 if (box) { 88 expect(box.right).toBeLessThanOrEqual(viewport.width + 5); 89 expect(box.bottom).toBeLessThanOrEqual(viewport.height + 5); 90 } 91 92 // Dismiss 93 await page.keyboard.press('Escape'); 94 await expect(palette).not.toBeVisible(); 95 }); 96 97 test('modals are full-screen on phones', async ({ page }) => { 98 const viewport = page.viewportSize()!; 99 if (viewport.width > 480) test.skip(); 100 101 // Open share dialog as a test modal 102 await page.click('#btn-share'); 103 const dialog = page.locator('#share-dialog'); 104 await expect(dialog).toBeVisible({ timeout: 3000 }); 105 106 const box = await dialog.boundingBox(); 107 if (box) { 108 // Should be approximately full-width on phones 109 expect(box.width).toBeGreaterThan(viewport.width * 0.9); 110 } 111 112 await page.click('#share-dialog-close'); 113 }); 114});