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 255 lines 9.6 kB view raw
1import { test, expect } from '@playwright/test'; 2import { createNewDoc, createNewSheet, waitForSaved } from './helpers'; 3 4test.describe('Version History', () => { 5 test.describe('Docs', () => { 6 test.beforeEach(async ({ page }) => { 7 await createNewDoc(page); 8 }); 9 10 test('version history panel opens via button click', async ({ page }) => { 11 const editor = page.locator('.tiptap'); 12 await editor.click(); 13 await page.keyboard.type('Version history test content'); 14 await waitForSaved(page); 15 16 await page.click('#btn-history'); 17 18 // The version panel should become visible 19 const panel = page.locator('.version-panel'); 20 await expect(panel).toHaveClass(/open/, { timeout: 5000 }); 21 await expect(panel).toBeVisible(); 22 }); 23 24 test('version history panel opens with Cmd+Shift+H', async ({ page }) => { 25 const editor = page.locator('.tiptap'); 26 await editor.click(); 27 await page.keyboard.type('Keyboard shortcut test'); 28 await waitForSaved(page); 29 30 await page.keyboard.press('Meta+Shift+h'); 31 32 const panel = page.locator('.version-panel'); 33 await expect(panel).toHaveClass(/open/, { timeout: 5000 }); 34 }); 35 36 test('version history panel closes with close button', async ({ page }) => { 37 const editor = page.locator('.tiptap'); 38 await editor.click(); 39 await page.keyboard.type('Close test'); 40 await waitForSaved(page); 41 42 await page.click('#btn-history'); 43 const panel = page.locator('.version-panel'); 44 await expect(panel).toHaveClass(/open/, { timeout: 5000 }); 45 46 // Click the close button inside the panel 47 await page.click('.version-panel-close'); 48 await expect(panel).not.toHaveClass(/open/); 49 }); 50 51 test('version history panel closes with Escape', async ({ page }) => { 52 const editor = page.locator('.tiptap'); 53 await editor.click(); 54 await page.keyboard.type('Escape test'); 55 await waitForSaved(page); 56 57 await page.click('#btn-history'); 58 const panel = page.locator('.version-panel'); 59 await expect(panel).toHaveClass(/open/, { timeout: 5000 }); 60 61 await page.keyboard.press('Escape'); 62 await expect(panel).not.toHaveClass(/open/); 63 }); 64 65 test('version history panel shows version list after content is saved', async ({ page }) => { 66 const editor = page.locator('.tiptap'); 67 await editor.click(); 68 await page.keyboard.type('Content for versioning'); 69 await waitForSaved(page); 70 71 // Wait a moment for the version to be created server-side 72 await page.waitForTimeout(1000); 73 74 await page.click('#btn-history'); 75 const panel = page.locator('.version-panel'); 76 await expect(panel).toHaveClass(/open/, { timeout: 5000 }); 77 78 // The version list should contain items or an empty state 79 const list = panel.locator('.version-panel-list'); 80 await expect(list).toBeVisible(); 81 82 // There should be at least one version item or the "No versions yet" message 83 const items = panel.locator('.version-panel-item'); 84 const emptyMsg = panel.locator('.version-empty'); 85 const hasItems = await items.count() > 0; 86 const hasEmpty = await emptyMsg.count() > 0; 87 expect(hasItems || hasEmpty).toBeTruthy(); 88 }); 89 90 test('version panel shows author and timestamp for each version', async ({ page }) => { 91 const editor = page.locator('.tiptap'); 92 await editor.click(); 93 await page.keyboard.type('Author attribution test'); 94 await waitForSaved(page); 95 await page.waitForTimeout(1000); 96 97 await page.click('#btn-history'); 98 const panel = page.locator('.version-panel'); 99 await expect(panel).toHaveClass(/open/, { timeout: 5000 }); 100 101 const items = panel.locator('.version-panel-item'); 102 if (await items.count() > 0) { 103 // Each version item should have time and author 104 const firstItem = items.first(); 105 await expect(firstItem.locator('.version-panel-time')).toBeVisible(); 106 await expect(firstItem.locator('.version-panel-author')).toBeVisible(); 107 } 108 }); 109 110 test('clicking a version item shows preview', async ({ page }) => { 111 const editor = page.locator('.tiptap'); 112 await editor.click(); 113 await page.keyboard.type('Preview test content'); 114 await waitForSaved(page); 115 await page.waitForTimeout(1000); 116 117 await page.click('#btn-history'); 118 const panel = page.locator('.version-panel'); 119 await expect(panel).toHaveClass(/open/, { timeout: 5000 }); 120 121 const items = panel.locator('.version-panel-item'); 122 if (await items.count() > 0) { 123 await items.first().click(); 124 125 // Preview section should become visible 126 const preview = panel.locator('.version-panel-preview'); 127 await expect(preview).toBeVisible({ timeout: 5000 }); 128 129 // Back button should be visible 130 await expect(panel.locator('.version-panel-back')).toBeVisible(); 131 132 // Restore button should be visible 133 await expect(panel.locator('.version-panel-restore')).toBeVisible(); 134 } 135 }); 136 137 test('back button in preview returns to version list', async ({ page }) => { 138 const editor = page.locator('.tiptap'); 139 await editor.click(); 140 await page.keyboard.type('Back button test'); 141 await waitForSaved(page); 142 await page.waitForTimeout(1000); 143 144 await page.click('#btn-history'); 145 const panel = page.locator('.version-panel'); 146 await expect(panel).toHaveClass(/open/, { timeout: 5000 }); 147 148 const items = panel.locator('.version-panel-item'); 149 if (await items.count() > 0) { 150 await items.first().click(); 151 await expect(panel.locator('.version-panel-preview')).toBeVisible({ timeout: 5000 }); 152 153 // Click back 154 await page.click('.version-panel-back'); 155 await expect(panel.locator('.version-panel-preview')).not.toBeVisible(); 156 } 157 }); 158 159 test('clicking restore button restores the version after confirmation', async ({ page }) => { 160 const editor = page.locator('.tiptap'); 161 await editor.click(); 162 await page.keyboard.type('Original content'); 163 await waitForSaved(page); 164 await page.waitForTimeout(1000); 165 166 // Overwrite with different content 167 await editor.click(); 168 await page.keyboard.press('Meta+a'); 169 await page.keyboard.type('Replaced content'); 170 await waitForSaved(page); 171 await page.waitForTimeout(1000); 172 173 // Open version panel and click the first (oldest) version 174 await page.click('#btn-history'); 175 const panel = page.locator('.version-panel'); 176 await expect(panel).toHaveClass(/open/, { timeout: 5000 }); 177 178 const items = panel.locator('.version-panel-item'); 179 if (await items.count() > 1) { 180 // Click the oldest version (last in the list — newest first) 181 await items.last().click(); 182 await expect(panel.locator('.version-panel-preview')).toBeVisible({ timeout: 5000 }); 183 184 // Accept the confirm() dialog when restore is clicked 185 page.on('dialog', dialog => dialog.accept()); 186 await page.click('.version-panel-restore'); 187 188 // Panel should close after restore 189 await expect(panel).not.toHaveClass(/open/, { timeout: 5000 }); 190 } 191 }); 192 193 test('clicking restore cancel does not restore', async ({ page }) => { 194 const editor = page.locator('.tiptap'); 195 await editor.click(); 196 await page.keyboard.type('Keep this content'); 197 await waitForSaved(page); 198 await page.waitForTimeout(1000); 199 200 await page.click('#btn-history'); 201 const panel = page.locator('.version-panel'); 202 await expect(panel).toHaveClass(/open/, { timeout: 5000 }); 203 204 const items = panel.locator('.version-panel-item'); 205 if (await items.count() > 0) { 206 await items.first().click(); 207 await expect(panel.locator('.version-panel-preview')).toBeVisible({ timeout: 5000 }); 208 209 // Dismiss the confirm() dialog 210 page.on('dialog', dialog => dialog.dismiss()); 211 await page.click('.version-panel-restore'); 212 213 // Panel should remain open (restore was cancelled) 214 await expect(panel).toHaveClass(/open/); 215 await expect(panel.locator('.version-panel-preview')).toBeVisible(); 216 } 217 }); 218 219 test('name version button is present on version items', async ({ page }) => { 220 const editor = page.locator('.tiptap'); 221 await editor.click(); 222 await page.keyboard.type('Name version test'); 223 await waitForSaved(page); 224 await page.waitForTimeout(1000); 225 226 await page.click('#btn-history'); 227 const panel = page.locator('.version-panel'); 228 await expect(panel).toHaveClass(/open/, { timeout: 5000 }); 229 230 const items = panel.locator('.version-panel-item'); 231 if (await items.count() > 0) { 232 // Each item should have a name button 233 await expect(items.first().locator('.version-panel-name-btn')).toBeVisible(); 234 } 235 }); 236 }); 237 238 test.describe('Sheets', () => { 239 test('version history panel opens for sheets via button', async ({ page }) => { 240 await createNewSheet(page); 241 242 // Add some data 243 await page.locator('td[data-id="A1"]').click(); 244 await page.keyboard.type('Sheet data'); 245 await page.keyboard.press('Enter'); 246 await waitForSaved(page); 247 248 await page.click('#btn-history'); 249 250 // Version panel should appear 251 const panel = page.locator('.version-panel'); 252 await expect(panel).toHaveClass(/open/, { timeout: 5000 }); 253 }); 254 }); 255});