From 643e7f42046f83dca576b3ab9ff0ffc1837af0de Mon Sep 17 00:00:00 2001 From: Daniel Date: Wed, 16 Sep 2026 04:05:12 +0200 Subject: [PATCH] test(e2e): the landing specs tie the job to the click, not to a poll count MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The page polls the job list as soon as it opens, so a stub that finished the job on the second poll had already finished it before Generate was pressed — and there was no in-flight to landed transition left to announce, which is the behaviour these two specs exist to pin. The job now stays running until the click is recorded, and the run is green: 34 passed. --- e2e/tests/my-resources.spec.js | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/e2e/tests/my-resources.spec.js b/e2e/tests/my-resources.spec.js index b2cf06c1..dedfea06 100644 --- a/e2e/tests/my-resources.spec.js +++ b/e2e/tests/my-resources.spec.js @@ -211,8 +211,12 @@ test.describe('My Resources', () => { const done = Object.assign({}, running, { status: 'done', resource_id: 9, result: { resource: { id: 9, title: 'Croup in children (new)' }, grounding: { used: true, count: 7 }, searches: [], imageJobs: [], imageFailures: [] } }); - await stub(page, { - jobs: n => [n === 0 ? running : done], + // Running until Generate is pressed, done after it. The page polls the job + // list as soon as it opens, so a job that lands on a poll *count* would + // have landed before the click and there would be no transition to + // announce — which is the behaviour under test, not a detail of the stub. + const sent = await stub(page, { + jobs: () => (sent.length ? [done] : [running]), library: n => n === 0 ? LIBRARY : { success: true, resources: LIBRARY.resources.concat([ { id: 9, title: 'Croup in children (new)', kind: 'presentation', topic: 'croup', grounded_count: 7, created_at: new Date().toISOString() }]) }, @@ -232,7 +236,8 @@ test.describe('My Resources', () => { const running = { id: 9, topic: 'croup', kind: 'presentation', status: 'running', created_at: new Date().toISOString() }; const failed = Object.assign({}, running, { status: 'failed', error: 'The model returned nothing. Try again.' }); - await stub(page, { jobs: n => [n === 0 ? running : failed] }); + // As above: running until the click, so the failure is a transition. + const sent = await stub(page, { jobs: () => (sent.length ? [failed] : [running]) }); await openTab(page); await page.fill('#mr-topic', 'croup'); await page.click('#btn-mr-generate'); @@ -389,7 +394,9 @@ test.describe('My Resources', () => { { tool: 'pubmed_search', query: 'croup', count: 6, reason: null }, { tool: 'web_search', query: 'croup', count: 0, reason: 'no results' }, ], imageJobs: [], imageFailures: [] } }); - await stub(page, { jobs: n => [n === 0 ? running : done] }); + // Running until the click, done after it — searching happens server-side, + // inside the job, so what was searched for arrives with the landing. + const sent = await stub(page, { jobs: () => (sent.length ? [done] : [running]) }); await openTab(page); await page.fill('#mr-topic', 'croup'); await page.click('#btn-mr-generate');