help: add relay, context menu, find/replace, assets, super-buckets docs; fix flaky tests

Updates help screen with all undocumented features. Fixes F1 blocked
by input suppression filter (allow function keys). Stabilizes card-join
tests with poll loop instead of fixed sleep.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
thandClaude Opus 4.6 committed 2026-04-12 13:11:52 +02:00
1 parent bbfe968ff1
commit 22a43fdef7
4 files changed
+66 -16

No files matched your search

+17 -9
View File
@@ -20,16 +20,24 @@ function selectIds(ids, { bulk = false } = {}) {
for (const id of ids) state.selectedIds.add(String(id));
}
async function clickJoin(rightClickTargetEl) {
async function clickJoin(rightClickTargetEl, winnerId) {
rightClick(rightClickTargetEl);
await sleep(150);
const joinBtn = $$('#ctx-items [data-action="join"]')[0];
if (!joinBtn) return false;
click(joinBtn);
// joinSelectedCards does: fetch full bodies → PATCH winner → N × DELETE
// losers → _reloadAll. That's 3+ serial API calls and a full board
// re-render, so 400ms was sometimes too tight on slower runs.
await sleep(800);
// losers → _reloadAll. Poll for the winner to have merged body.
for (let i = 0; i < 30; i++) {
await sleep(100);
if (winnerId) {
const c = await getCard(winnerId);
if (c?.body?.includes('## ')) return true;
} else {
await sleep(600);
return true;
}
}
return true;
}
@@ -109,7 +117,7 @@ describe('Card: Join — sequential selection (first wins)', () => {
if (!firstEl) return;
selectIds([first.id, second.id, third.id], { bulk: false });
const ok = await clickJoin(firstEl);
const ok = await clickJoin(firstEl, first.id);
if (!ok) return;
// Winner survives
@@ -132,7 +140,7 @@ describe('Card: Join — sequential selection (first wins)', () => {
if (!aEl) return;
selectIds([a.id, b.id, c.id], { bulk: false });
const ok = await clickJoin(aEl);
const ok = await clickJoin(aEl, a.id);
if (!ok) return;
const survivor = await getCard(a.id);
@@ -159,7 +167,7 @@ describe('Card: Join — sequential selection (first wins)', () => {
if (!aEl) return;
selectIds([a.id, b.id], { bulk: false });
const ok = await clickJoin(aEl);
const ok = await clickJoin(aEl, a.id);
if (!ok) return;
expect(state.selectedIds.size).toBe(0);
@@ -187,7 +195,7 @@ describe('Card: Join — bulk selection (longest title wins)', () => {
// join code uses longest-title strategy.
selectIds([short.id, longer.id, medium.id], { bulk: true });
const ok = await clickJoin(shortEl);
const ok = await clickJoin(shortEl, longer.id);
if (!ok) return;
// The longest-titled card should be the survivor
@@ -220,7 +228,7 @@ describe('Card: Join — undo', () => {
if (!winnerEl) return;
selectIds([winner.id, loser.id], { bulk: false });
const ok = await clickJoin(winnerEl);
const ok = await clickJoin(winnerEl, winner.id);
if (!ok) return;
// Sanity: loser is gone, winner has merged body