diff --git a/apps/presentation/dashboard/src/features/personal-workspace/goal-research-history.tsx b/apps/presentation/dashboard/src/features/personal-workspace/goal-research-history.tsx index 2ecb9d2dbb..2d3b086e76 100644 --- a/apps/presentation/dashboard/src/features/personal-workspace/goal-research-history.tsx +++ b/apps/presentation/dashboard/src/features/personal-workspace/goal-research-history.tsx @@ -544,10 +544,14 @@ export function GoalResearchHistory({goalId, originalGoalId = goalId, preferHist
{!emptySourceHistory ? : null} {!readingSelection && !emptySourceHistory ?
{(["timeline", "graph"] as const).map(item => )}
: null} diff --git a/examples/personal-workspace-browser/research-record-search.mjs b/examples/personal-workspace-browser/research-record-search.mjs index 30a2492b79..dc3c221db7 100644 --- a/examples/personal-workspace-browser/research-record-search.mjs +++ b/examples/personal-workspace-browser/research-record-search.mjs @@ -305,7 +305,21 @@ Path(sys.argv[2]).write_text(json.dumps({'goal_id':other,'display_name':'Other s assert.equal(await phases.count(), 3); assert.equal(await phases.nth(2).getAttribute("aria-pressed"), "true", "Recovery applies the original period bookmark"); await page.goto(url.replace("synthetic-record-search", "synthetic-other-research")); - await history.getByRole("button", {name: "Search research records", exact: true}).click(); + const openOtherSearch = history.getByRole("button", {name: "Search research records", exact: true}); + await openOtherSearch.evaluate(button => { + // Hold the frame from this one search activation until the reader moves focus. + button.addEventListener("click", () => { + const schedule = window.requestAnimationFrame; + const frames = []; + window.__loopxHeldSearchFrames = frames; + window.requestAnimationFrame = callback => { + frames.push(callback); + return -frames.length; + }; + setTimeout(() => {window.requestAnimationFrame = schedule;}, 0); + }, {once: true}); + }); + await openOtherSearch.click(); await results.getByRole("status", {name: "4 matches in 4 loaded records · 3 entries", exact: true}).waitFor(); assert.equal(await search.inputValue(), "", "Another Goal starts with its own search scope"); assert.doesNotMatch(await results.innerText(), /amber|Earlier negative/); @@ -313,7 +327,15 @@ Path(sys.argv[2]).write_text(json.dumps({'goal_id':other,'display_name':'Other s const groupSummary = grouped.locator(":scope > summary"); assert.match(await groupSummary.innerText(), /Refuted.*Resolved.*2 records/); assert.equal(await results.locator(".research-record-entry").count(), 3, "Identical titles and times leave independent attempts and absent links separate"); - await groupSummary.press("Enter"); + await groupSummary.focus(); + await page.evaluate(() => { + const frames = window.__loopxHeldSearchFrames ?? []; + delete window.__loopxHeldSearchFrames; + frames.forEach(callback => callback(performance.now())); + }); + assert(await groupSummary.evaluate(element => element === document.activeElement), + "Delayed search autofocus leaves the already focused record in control"); + await page.keyboard.press("Enter"); const groupHistory = grouped.locator(".research-record-group-history"); await groupHistory.waitFor(); assert.match(await grouped.innerText(), /The alternative missed the target\./);