FN-8906: scope Stats runtime-status assertions
Scope Task Detail Stats status assertions to their semantic region. - Centralize the shared Stats runtime-status assertion helper. - Update Stats-tab integration assertions to avoid ambiguous status queries. Files changed: ...lModal.inline-editing-and-integrations.test.tsx | 10 ++++++++-- .../__tests__/TaskDetailModal.rendering.test.tsx | 19 ++---------------- .../__tests__/TaskDetailModal.test-helpers.ts | 23 +++++++++++++++++++++- 3 files changed, 32 insertions(+), 20 deletions(-) Fusion-Task-Id: FN-8906 Fusion-Task-Lineage: 980f24a1-0409-46ba-9957-a87329e9831e Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
This commit is contained in:
@@ -17,6 +17,7 @@ import {
|
||||
mockConfirm,
|
||||
mockUsePluginUiSlots,
|
||||
expectBaseRule,
|
||||
expectSingleStatsRuntimeStatus,
|
||||
readDashboardStylesSource,
|
||||
setupTaskDetailModalHooks,
|
||||
} from "./TaskDetailModal.test-helpers";
|
||||
@@ -83,6 +84,11 @@ function getRuleBlockFromSelectorList(css: string, selector: string): string {
|
||||
return ruleEnd === -1 ? "" : css.slice(ruleStart + 1, ruleEnd);
|
||||
}
|
||||
|
||||
/*
|
||||
FNXC:TaskDetailStatsAssertions 2026-08-09-16:50:
|
||||
FN-8906 requires Stats-tab runtime-status assertions to be scoped to the named Stats region because
|
||||
the modal header lifecycle badge intentionally renders the same raw status string.
|
||||
*/
|
||||
describe("TaskDetailModal", () => {
|
||||
describe("source issue metadata", () => {
|
||||
beforeEach(() => {
|
||||
@@ -2440,7 +2446,7 @@ describe("TaskDetailModal", () => {
|
||||
expect(screen.getByText("Execution Details")).toBeInTheDocument();
|
||||
expect(screen.getByText("Loading token statistics…")).toBeDefined();
|
||||
expect(screen.getAllByText("Fast").length).toBeGreaterThan(0);
|
||||
expect(screen.getByText("executing")).toBeInTheDocument();
|
||||
expectSingleStatsRuntimeStatus("executing");
|
||||
});
|
||||
|
||||
it("shows spec content after fetchTaskDetail resolves", async () => {
|
||||
@@ -2529,7 +2535,7 @@ describe("TaskDetailModal", () => {
|
||||
expect(screen.getByText("Execution mode")).toBeInTheDocument();
|
||||
expect(screen.getByText("Runtime status")).toBeInTheDocument();
|
||||
expect(screen.getAllByText("Fast").length).toBeGreaterThan(0);
|
||||
expect(screen.getByText("executing")).toBeInTheDocument();
|
||||
expectSingleStatsRuntimeStatus("executing");
|
||||
expect(screen.getByText((1200).toLocaleString())).toBeInTheDocument();
|
||||
expect(screen.getByText((450).toLocaleString())).toBeInTheDocument();
|
||||
expect(screen.getByText((210).toLocaleString())).toBeInTheDocument();
|
||||
|
||||
@@ -12,7 +12,7 @@ query ambiguous once the trigger stopped being a mobile-only affordance.
|
||||
import { readFileSync } from "node:fs";
|
||||
import { resolve } from "node:path";
|
||||
import { describe, it, expect, vi, beforeEach, afterEach } from "vitest";
|
||||
import { render, screen, fireEvent, act, waitFor, cleanup, within } from "@testing-library/react";
|
||||
import { render, screen, fireEvent, act, waitFor, cleanup } from "@testing-library/react";
|
||||
|
||||
// FNXC:Markdown 2026-06-23-03:30: Mock the heavy `mermaid` library so the shared
|
||||
// markdown pipeline's MermaidDiagram resolves without loading the real renderer.
|
||||
@@ -35,6 +35,7 @@ import {
|
||||
mockConfirm,
|
||||
mockUsePluginUiSlots,
|
||||
expectBaseRule,
|
||||
expectSingleStatsRuntimeStatus,
|
||||
readDashboardStylesSource,
|
||||
resetTaskDetailFetchMock,
|
||||
setupTaskDetailModalHooks,
|
||||
@@ -45,22 +46,6 @@ import * as dashboardApi from "../../api";
|
||||
import { FileBrowserProvider } from "../../context/FileBrowserContext";
|
||||
import type { Task } from "@fusion/core";
|
||||
|
||||
/*
|
||||
FNXC:TaskDetailOptimisticOpening 2026-08-05-07:39:
|
||||
A running task deliberately exposes its raw runtime status in two ownership regions: the modal
|
||||
header's lifecycle badge and the Stats panel's Runtime status row. Optimistic-opening assertions
|
||||
must scope the Stats claim to its named semantic region, then assert one row there and the expected
|
||||
two owned values overall; this catches a duplicated Stats panel without treating legitimate header
|
||||
context as a production rendering defect.
|
||||
*/
|
||||
function expectSingleStatsRuntimeStatus(status: string) {
|
||||
const statsPanel = screen.getByRole("region", { name: "Task execution statistics" });
|
||||
expect(within(statsPanel).getByText(status)).toBeInTheDocument();
|
||||
expect(within(statsPanel).getAllByText(status)).toHaveLength(1);
|
||||
expect(screen.getByTestId("task-detail-status-badge")).toHaveTextContent(status);
|
||||
expect(screen.getAllByText(status)).toHaveLength(2);
|
||||
}
|
||||
|
||||
setupTaskDetailModalHooks();
|
||||
|
||||
describe("TaskDetailModal", () => {
|
||||
|
||||
@@ -3,7 +3,7 @@ import { loadAllAppCss } from "../../test/cssFixture";
|
||||
import React from "react";
|
||||
import { existsSync, readFileSync } from "node:fs";
|
||||
import { resolve } from "node:path";
|
||||
import { render, screen, fireEvent, act, waitFor } from "@testing-library/react";
|
||||
import { render, screen, fireEvent, act, waitFor, within } from "@testing-library/react";
|
||||
import userEvent from "@testing-library/user-event";
|
||||
import { TaskDetailModal, TaskDetailContent } from "../TaskDetailModal";
|
||||
import type { TaskDetail, Column, MergeResult, Task } from "@fusion/core";
|
||||
@@ -16,6 +16,27 @@ const taskDetailSseSubscriptions = vi.hoisted(() => [] as Array<{
|
||||
|
||||
export { taskDetailSseSubscriptions };
|
||||
|
||||
/*
|
||||
FNXC:TaskDetailOptimisticOpening 2026-08-05-07:39:
|
||||
A running task deliberately exposes its raw runtime status in two ownership regions: the modal
|
||||
header's lifecycle badge and the Stats panel's Runtime status row. Optimistic-opening assertions
|
||||
must scope the Stats claim to its named semantic region, then assert one row there and the expected
|
||||
two owned values overall; this catches a duplicated Stats panel without treating legitimate header
|
||||
context as a production rendering defect.
|
||||
|
||||
FNXC:TaskDetailStatsAssertions 2026-08-09-16:50:
|
||||
FN-8906 requires every TaskDetailModal test to use this shared helper: a non-empty raw runtime
|
||||
status is owned by the header lifecycle badge and the Stats Runtime status row, so an unscoped
|
||||
getByText(status) after opening Stats is ambiguous.
|
||||
*/
|
||||
export function expectSingleStatsRuntimeStatus(status: string): void {
|
||||
const statsPanel = screen.getByRole("region", { name: "Task execution statistics" });
|
||||
expect(within(statsPanel).getByText(status)).toBeInTheDocument();
|
||||
expect(within(statsPanel).getAllByText(status)).toHaveLength(1);
|
||||
expect(screen.getByTestId("task-detail-status-badge")).toHaveTextContent(status);
|
||||
expect(screen.getAllByText(status)).toHaveLength(2);
|
||||
}
|
||||
|
||||
vi.mock("../../sse-bus", () => ({
|
||||
subscribeSse: vi.fn((url: string, options: { events?: Record<string, (event: MessageEvent) => void> }) => {
|
||||
taskDetailSseSubscriptions.push({ url, options });
|
||||
|
||||
Reference in New Issue
Block a user