From 8f5bb88abc1b5a72b205cde9a902a0471e3e0623 Mon Sep 17 00:00:00 2001 From: d-oit Date: Fri, 5 Jun 2026 17:18:32 +0200 Subject: [PATCH] =?UTF-8?q?fix:=20resolve=20E2E=20test=20failures=20?= =?UTF-8?q?=E2=80=94=20nested=20transaction=20+=20tiptap=20timing?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - db-worker.ts: defensive COMMIT before BEGIN TRANSACTION to handle SQLite WASM quirk where INSERT...RETURNING leaves autocommit off - library.spec.ts, features.spec.ts: wait for ProseMirror contenteditable=true instead of tiptap-content visibility to ensure useEditor hook has resolved before clicking Save Fixes all 4 previously failing E2E tests. Co-authored-by: d-oit <6849456+d-oit@users.noreply.github.com> --- src/db/db-worker.ts | 10 ++++++++++ tests/e2e/features.spec.ts | 3 ++- tests/e2e/library.spec.ts | 3 ++- 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/src/db/db-worker.ts b/src/db/db-worker.ts index 9c81e24e..127127e4 100644 --- a/src/db/db-worker.ts +++ b/src/db/db-worker.ts @@ -161,6 +161,16 @@ self.onmessage = async (event: MessageEvent) => { const { statements } = payload as TransactionPayload; + // Clear any dangling transaction state from a prior exec() with + // RETURNING — SQLite WASM's oo1.DB.exec can leave autocommit off + // after INSERT…RETURNING with returnValue:'resultRows'. + try { db.exec('COMMIT;'); } catch (err) { + const msg = err instanceof Error ? err.message : String(err); + if (!msg.includes('no transaction is active')) { + throw err; // Unexpected error — rethrow + } + } + db.exec('BEGIN TRANSACTION;'); try { const results = []; diff --git a/tests/e2e/features.spec.ts b/tests/e2e/features.spec.ts index 8f98c74a..077b84a5 100644 --- a/tests/e2e/features.spec.ts +++ b/tests/e2e/features.spec.ts @@ -328,8 +328,9 @@ test.describe('Entity Editor with Source URL', () => { const sourceInput = page.locator('#entity-source-url'); await sourceInput.fill('https://example.com/persisted-article'); - // Wait for tiptap editor to initialize before saving + // Wait for tiptap editor to fully initialize (useEditor hook returns non-null) await expect(page.locator('.tiptap-content')).toBeVisible({ timeout: 5000 }); + await expect(page.locator('.tiptap-content .ProseMirror[contenteditable="true"]')).toBeVisible({ timeout: 5000 }); // Save entity const saveBtn = page.locator('button.primary', { hasText: 'Save to DB' }); diff --git a/tests/e2e/library.spec.ts b/tests/e2e/library.spec.ts index d5a602e1..81e989a6 100644 --- a/tests/e2e/library.spec.ts +++ b/tests/e2e/library.spec.ts @@ -16,8 +16,9 @@ test.describe('Library View', () => { await page.fill('input[placeholder="Entity Name (e.g. TRIZ)"]', 'Library Test Entity'); await page.selectOption('select', 'concept'); - // Wait for tiptap editor to initialize before saving + // Wait for tiptap editor to fully initialize (useEditor hook returns non-null) await expect(page.locator('.tiptap-content')).toBeVisible({ timeout: 5000 }); + await expect(page.locator('.tiptap-content .ProseMirror[contenteditable="true"]')).toBeVisible({ timeout: 5000 }); await page.click('button:has-text("Save to DB")'); await expect(page.locator('[role="alert"]')).toContainText('Saved successfully', { timeout: 10000 }); });