134 lines
4.4 KiB
TypeScript
134 lines
4.4 KiB
TypeScript
import assert from "node:assert/strict";
|
|
import { test } from "bun:test";
|
|
|
|
import {
|
|
MDTODO_TASK_TREE_PANE_CONTENT_SELECTOR,
|
|
nodeWebObserveRunnerSamplingSource,
|
|
} from "./hwlab-node-web-observe-runner-sampling-source";
|
|
import { nodeWebObserveAnalyzerProjectSource } from "./hwlab-node-web-observe-analyzer-project-source";
|
|
import { nodeWebObserveRunnerControlSource } from "./hwlab-node-web-observe-runner-control-source";
|
|
|
|
test("MDTODO task tree pane gap treats the pinned facts footer as content", async () => {
|
|
assert.match(
|
|
MDTODO_TASK_TREE_PANE_CONTENT_SELECTOR,
|
|
/\[data-testid="mdtodo-task-tree-facts"\]/u,
|
|
);
|
|
assert.match(
|
|
MDTODO_TASK_TREE_PANE_CONTENT_SELECTOR,
|
|
/\[data-testid="mdtodo-task-page-fact"\]/u,
|
|
);
|
|
|
|
const source = nodeWebObserveRunnerSamplingSource();
|
|
assert.ok(
|
|
source.includes(
|
|
`measurePaneGap("task-tree", '[data-testid="mdtodo-task-tree"]', ${JSON.stringify(MDTODO_TASK_TREE_PANE_CONTENT_SELECTOR)})`,
|
|
),
|
|
);
|
|
assert.match(
|
|
source,
|
|
/semanticTaskCandidates\.length > 0 \? semanticTaskCandidates : fallbackTaskCandidates/u,
|
|
);
|
|
assert.match(
|
|
source,
|
|
/taskCandidates\.filter\(\(candidate\) => !taskRefElement\(candidate\)\)\.length/u,
|
|
);
|
|
assert.doesNotMatch(source, /taskCandidates\.length - taskItems\.length/u);
|
|
assert.match(source, /mdtodo-body-read/u);
|
|
assert.match(source, /mdtodo-launch-workbench/u);
|
|
|
|
const child = Bun.spawn(["node", "--input-type=module", "--check", "-"], {
|
|
stdin: "pipe",
|
|
stdout: "pipe",
|
|
stderr: "pipe",
|
|
});
|
|
child.stdin.write(source);
|
|
child.stdin.end();
|
|
const [stderr, exitCode] = await Promise.all([
|
|
new Response(child.stderr).text(),
|
|
child.exited,
|
|
]);
|
|
assert.equal(exitCode, 0, stderr);
|
|
});
|
|
|
|
test("MDTODO pane gap ignores a naturally short task tree but keeps primary pane regressions", () => {
|
|
const projectManagementPaneGapRows = new Function(
|
|
"maxNumber",
|
|
"projectManagementSampleRef",
|
|
`${nodeWebObserveAnalyzerProjectSource()}; return projectManagementPaneGapRows;`,
|
|
)(
|
|
(values: unknown[]) => Math.max(0, ...values.map((value) => Number(value ?? 0))),
|
|
(sample: Record<string, unknown>) => ({ seq: sample.seq ?? null }),
|
|
) as (samples: unknown[]) => { actionable: unknown[]; ignored: unknown[] };
|
|
|
|
const pane = (name: string, bottomGapPx: number, bottomGapRatio: number) => ({
|
|
name,
|
|
visible: true,
|
|
widthPx: 300,
|
|
heightPx: 600,
|
|
bottomGapPx,
|
|
bottomGapRatio,
|
|
contentNodeCount: 4,
|
|
});
|
|
const sample = (paneGaps: unknown[]) => ({
|
|
seq: 1,
|
|
projectManagement: {
|
|
pageKind: "project-management-mdtodo",
|
|
selectedTaskRef: { hash: "sha256:opaque" },
|
|
paneGaps,
|
|
},
|
|
});
|
|
|
|
assert.deepEqual(
|
|
projectManagementPaneGapRows([sample([pane("task-tree", 391, 0.618)])]),
|
|
{ actionable: [], ignored: [], valuesRedacted: true },
|
|
);
|
|
assert.equal(
|
|
projectManagementPaneGapRows([sample([pane("task-detail", 391, 0.618)])]).actionable.length,
|
|
1,
|
|
);
|
|
assert.equal(
|
|
projectManagementPaneGapRows([sample([
|
|
pane("task-tree", 240, 0.4),
|
|
pane("task-detail", 180, 0.3),
|
|
])]).actionable.length,
|
|
1,
|
|
);
|
|
});
|
|
|
|
test("MDTODO command readiness accepts a selected mobile task when the hidden tree has no visible rows", async () => {
|
|
const source = nodeWebObserveRunnerControlSource();
|
|
const makeReady = (snapshot: Record<string, unknown>) => new Function(
|
|
"projectManagementCommandSnapshot",
|
|
"safeUrlPath",
|
|
"currentPageUrl",
|
|
"page",
|
|
`${source}; return waitForProjectManagementCommandReady;`,
|
|
)(
|
|
async () => snapshot,
|
|
() => String(snapshot.path ?? ""),
|
|
() => `https://hwlab.pikapython.com${String(snapshot.path ?? "")}`,
|
|
{ waitForTimeout: async () => undefined },
|
|
) as (options: { timeoutMs: number }) => Promise<{ ok: boolean; reason: string }>;
|
|
|
|
const selectedMobileTask = {
|
|
path: "/projects/mdtodo/sources/source/files/file/tasks/R1",
|
|
pageKind: "project-management-mdtodo",
|
|
sourceCount: 3,
|
|
fileCount: 18,
|
|
taskCount: 0,
|
|
selectedTaskRef: { hash: "sha256:opaque" },
|
|
taskBodyVisible: true,
|
|
launchButtonVisible: true,
|
|
};
|
|
assert.equal((await makeReady(selectedMobileTask)({ timeoutMs: 1 })).ok, true);
|
|
|
|
const unselectedRoot = {
|
|
path: "/projects/mdtodo",
|
|
pageKind: "project-management-mdtodo",
|
|
sourceCount: 3,
|
|
fileCount: 18,
|
|
taskCount: 0,
|
|
};
|
|
assert.equal((await makeReady(unselectedRoot)({ timeoutMs: 1 })).ok, false);
|
|
});
|