diff --git a/web/e2e/bug-3473-write-then-open.spec.ts b/web/e2e/bug-3473-write-then-open.spec.ts index 5ce3e1ed1..5cc02a8b6 100644 --- a/web/e2e/bug-3473-write-then-open.spec.ts +++ b/web/e2e/bug-3473-write-then-open.spec.ts @@ -53,10 +53,11 @@ test.describe('write, then open at once (BUG-3473)', () => { const created = page.waitForResponse( (r) => r.request().method() === 'POST' && /\/collections\/docs\/items$/.test(r.url()) && r.ok(), ); - await dialog.locator('textarea.quick-add-input').press('Enter'); + // Add and open (TASK-3590: plain Enter adds and stays on the list). + await dialog.locator('textarea.quick-add-input').press('ControlOrMeta+Enter'); await created; await expect(dialog).toBeHidden(); - // The quick-add opens the new item's page; go straight back to the list. + // Add and open lands on the new item's page; go straight back to the list. await expect(page).toHaveURL(/\/docs\/[^/?]+$/); await page.goBack(); diff --git a/web/e2e/task-3590-quick-capture-stays.spec.ts b/web/e2e/task-3590-quick-capture-stays.spec.ts new file mode 100644 index 000000000..1ceaa2667 --- /dev/null +++ b/web/e2e/task-3590-quick-capture-stays.spec.ts @@ -0,0 +1,85 @@ +import { test, expect } from './fixtures'; +import { browserLogin } from './lib/collab-helpers'; + +/** + * TASK-3590: quick capture keeps your place. Adding an item used to open it, + * so jotting down an interruption was a context switch. "Add" now saves, + * stays on the current screen ready for the next capture, and confirms with a + * toast whose Open action goes to the item. "Add and open" (Ctrl/Cmd+Enter, + * or the mobile sheet's secondary button) keeps the old behaviour. + */ +test.describe('TASK-3590: quick capture keeps your place', () => { + test('desktop sidebar: Enter adds twice and stays; the toast opens the item; Ctrl/Cmd+Enter opens', async ({ page, fixture }, testInfo) => { + test.skip(testInfo.project.name !== 'desktop-chromium', 'the sidebar quick-add'); + const stamp = `qc${Date.now().toString(36)}`; + await browserLogin(page); + const listUrl = `/${fixture.adminUsername}/${fixture.workspaceSlug}/tasks`; + await page.goto(listUrl); + + const add = page.locator('button.nav-quick-add[title="New Task"]'); + await add.hover({ force: true }); + await add.click({ force: true }); + const dialog = page.locator('.quick-add-modal'); + const input = dialog.locator('textarea.quick-add-input'); + await expect(dialog).toBeVisible(); + + for (const n of [1, 2]) { + await input.fill(`${stamp} stay ${n}`); + const created = page.waitForResponse( + (r) => r.request().method() === 'POST' && /\/collections\/tasks\/items$/.test(new URL(r.url()).pathname) && r.ok(), + ); + await input.press('Enter'); + await created; + await expect(input).toHaveValue(''); + await expect(input).toBeFocused(); + } + await expect(dialog).toBeVisible(); + await expect(page).toHaveURL(new RegExp(`${listUrl}(\\?.*)?$`)); + + const toast = page.locator('.toast', { hasText: /Added TASK-\d+/ }).last(); + await expect(toast).toBeVisible(); + await input.press('Escape'); + await expect(dialog).toBeHidden(); + await toast.getByRole('button', { name: 'Open' }).click(); + await expect(page).toHaveURL(/\/tasks\/TASK-\d+/); + await expect(page.getByText(`${stamp} stay 2`).first()).toBeVisible(); + + // Add and open. + await page.goto(listUrl); + await add.hover({ force: true }); + await add.click({ force: true }); + await input.fill(`${stamp} open`); + await input.press('ControlOrMeta+Enter'); + await expect(dialog).toBeHidden(); + await expect(page).toHaveURL(/\/tasks\/TASK-\d+/); + await expect(page.getByText(`${stamp} open`).first()).toBeVisible(); + }); + + test('mobile sheet: Add stays open for the next capture; Add and open navigates', async ({ page, fixture }, testInfo) => { + test.skip(testInfo.project.name !== 'mobile-chromium', 'the mobile capture sheet'); + const stamp = `qm${Date.now().toString(36)}`; + await browserLogin(page); + const listUrl = `/${fixture.adminUsername}/${fixture.workspaceSlug}/tasks`; + await page.goto(listUrl); + + await page.getByRole('button', { name: 'Quick capture' }).click(); + const sheet = page.getByRole('dialog', { name: 'Quick capture' }); + const title = sheet.getByRole('textbox', { name: 'New item title' }); + await expect(title).toBeVisible(); + await title.fill(`${stamp} stay`); + const created = page.waitForResponse( + (r) => r.request().method() === 'POST' && /\/collections\/tasks\/items$/.test(new URL(r.url()).pathname) && r.ok(), + ); + await sheet.getByRole('button', { name: 'Add', exact: true }).click(); + await created; + await expect(title).toHaveValue(''); + await expect(sheet).toBeVisible(); + await expect(page).toHaveURL(new RegExp(`${listUrl}(\\?.*)?$`)); + await expect(page.locator('.toast', { hasText: /Added TASK-\d+/ }).last()).toBeVisible(); + + await title.fill(`${stamp} open`); + await sheet.getByRole('button', { name: 'Add and open' }).click(); + await expect(page).toHaveURL(/\/tasks\/TASK-\d+/); + await expect(page.getByText(`${stamp} open`).first()).toBeVisible(); + }); +}); diff --git a/web/src/lib/components/layout/QuickCaptureSheet.svelte b/web/src/lib/components/layout/QuickCaptureSheet.svelte index 7b7654a12..00c82e39c 100644 --- a/web/src/lib/components/layout/QuickCaptureSheet.svelte +++ b/web/src/lib/components/layout/QuickCaptureSheet.svelte @@ -1,11 +1,12 @@