import { test, expect } from '@playwright/test'; import { launchApp, resetWorkspace, type LaunchedApp, openNote, scroller, } from './appFixture'; test.describe('per-tab view state', () => { let app: LaunchedApp; let window: LaunchedApp['window']; test.beforeAll(async () => { app = await launchApp(); window = app.window; }); test.afterAll(async () => { await app.close(); }); test.beforeEach(async () => { await resetWorkspace(app); }); test('restores scroll position when returning to a tab', async () => { await openNote(window, 'Target.md'); await scroller(window).evaluate((el) => { el.scrollTop = 600; }); // Let CM record the position before navigating away. await window.waitForTimeout(200); const before = await scroller(window).evaluate((el) => el.scrollTop); expect(before).toBeGreaterThan(0); await openNote(window, 'Other.md'); await openNote(window, 'Target.md'); // Guards: capturing after React detaches the node reads `scrollTop` 0. await expect .poll(() => scroller(window).evaluate((el) => el.scrollTop)) .toBeGreaterThan(before / 2); }); test('restores the cursor position, not just the scroll', async () => { await openNote(window, 'Target.md'); await window.locator('.cm-content').first().click(); for (let i = 0; i < 12; i++) await window.keyboard.press('ArrowDown'); const before = await window.evaluate( () => document.querySelectorAll('.cm-line').length, ); expect(before).toBeGreaterThan(0); const cursorLineBefore = await window.evaluate(() => { const active = document.querySelector('.cm-activeLine'); return active ? active.textContent : null; }); await openNote(window, 'Other.md'); await openNote(window, 'Target.md'); await expect .poll(() => window.evaluate(() => { const active = document.querySelector('.cm-activeLine'); return active ? active.textContent : null; }), ) .toBe(cursorLineBefore); }); });