fix: clear remaining full-suite floaters after #2287 (#2288)

## Summary
#2287 cleared most of Full Suite run 29633869887 / post-merge
29634793317. Shards 1 and 2 went green; remaining floaters:

- **TaskDetailModal.css FN-8154** — assert FN-8166 zeroed mobile
`.detail-activity` inset (`padding-inline-end: 0`), not the pre-8166
`var(--space-md)` residual
- **QuickEntryBox** — wait for cleared input / priority button after
create under shard load (not only `onCreate` mock call)
- **grok process-lifecycle** — prove Symbol.for exit-hook bound with 2
reimports so transform cost stays under 5s on full-suite shards

## Test plan
- [x] Local: FN-8154, QuickEntry clear/priority, process-lifecycle
- [ ] PR merge gate green
- [ ] Post-merge Full Suite on `main` green

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **Tests**
* Improved Quick Entry tests to wait for textarea clearing and verify
priority resets to normal after task creation.
* Updated CSS contract assertions for mobile task-detail activity
spacing to match the latest overlay/inset behavior.
* Streamlined the Grok plugin process lifecycle test loop to run fewer
module-evaluation iterations while keeping existing lifecycle and
warning checks.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
gsxdsm
2026-07-18 00:31:41 -07:00
committed by GitHub
parent 755063715a
commit 8da52767b6
6 changed files with 33 additions and 14 deletions

View File

@@ -2,6 +2,6 @@
"@runfusion/fusion": patch
---
summary: Creating a new folder in project setup now selects it fully — the browser panel follows the created folder so Select confirms it.
summary: Creating a folder in project setup now selects it so Select confirms it.
category: fix
dev: "DirectoryPicker: with selectCreatedDirectory, handleCreateFolder now navigates the browse panel into the created directory instead of refreshing the parent; the footer Select button commits browser.currentPath, so staying on the parent let the next click overwrite the auto-selected new folder."

View File

@@ -2,6 +2,6 @@
"@runfusion/fusion": minor
---
summary: Project creation now warns up front when Git is missing, with the choice to open the Git downloads or create the project without a git repo.
summary: Project creation warns when Git is missing, with install or create-anyway options.
category: feature
dev: "SetupWizardModal probes gitCli before registering and shows a three-way ConfirmDialog (create anyway / open downloads / cancel; clone mode offers install-only). New skipGitInit passthrough: ProjectCreateInput → POST /api/projects (rejected for clone mode) → EnsureProjectForPathInput → ensureProjectForPath skips ensureGitRepositoryForProjectPath."

View File

@@ -2,6 +2,6 @@
"@runfusion/fusion": patch
---
summary: Git installed while Fusion is running is now detected without a restart — project setup no longer fails with spawn git ENOENT.
summary: Git installed while Fusion runs is detected without restart for project setup.
category: fix
dev: "New core git-binary resolver: on PATH ENOENT, probes well-known install locations (win32 Program Files/LocalAppData Git\\cmd, macOS homebrew//usr/local//usr/bin, linux /usr/bin//usr/local/bin) with caching + invalidation on later ENOENT. Wired into ensureGitRepositoryForProjectPath's runner, probeGitCliStatus (onboarding git indicator), and the dashboard clone route."

View File

@@ -1596,7 +1596,7 @@ describe("QuickEntryBox", () => {
it("clears input after successful creation", async () => {
const { props } = renderQuickEntryBox({});
const textarea = screen.getByTestId("quick-entry-input");
const textarea = screen.getByTestId("quick-entry-input") as HTMLTextAreaElement;
fireEvent.change(textarea, { target: { value: "Task to create" } });
fireEvent.keyDown(textarea, { key: "Enter" });
@@ -1604,8 +1604,12 @@ describe("QuickEntryBox", () => {
await waitFor(() => {
expect(props.onCreate).toHaveBeenCalled();
});
expect((textarea as HTMLTextAreaElement).value).toBe("");
/*
FNXC:DashboardTests 2026-07-18-07:25:
Full-suite shard load can observe onCreate before the optimistic setDescription("")
commit flushes into the DOM. Wait for the cleared value, not only the mock call.
*/
await waitForSubmitSuccessToClear(textarea);
});
it("shows error toast on failure and keeps input content", async () => {
@@ -2759,9 +2763,12 @@ describe("QuickEntryBox", () => {
it("resets priority to normal after successful task creation", async () => {
const { props } = renderQuickEntryBox({});
expandQuickEntry();
const textarea = screen.getByTestId("quick-entry-input");
const textarea = screen.getByTestId("quick-entry-input") as HTMLTextAreaElement;
fireEvent.change(textarea, { target: { value: "Priority reset after save" } });
await waitFor(() => {
expect(screen.getByTestId("quick-entry-priority-button")).toBeTruthy();
});
openPriorityMenu();
fireEvent.click(screen.getByTestId("quick-entry-priority-option-high"));
fireEvent.keyDown(textarea, { key: "Enter" });
@@ -2769,9 +2776,12 @@ describe("QuickEntryBox", () => {
await waitFor(() => {
expect(props.onCreate).toHaveBeenCalledTimes(1);
});
await waitForSubmitSuccessToClear(textarea);
expandQuickEntry();
expectQuickEntryPriorityButton("normal");
await waitFor(() => {
expectQuickEntryPriorityButton("normal");
});
});
it("resets priority to normal after Subtask flow", async () => {

View File

@@ -44,6 +44,13 @@ describe("TaskDetailModal CSS contract", () => {
expect(planBlock).toContain("max-width: 100%;");
});
/*
FNXC:TaskDetailActivity 2026-07-18-07:25:
FN-8166 zeroed mobile `.detail-activity` padding-inline-end (equal insets from
`.detail-body`); overlay clearance lives only on first-row selectors. Keep the
contract aligned with TaskDetailModal.css so full-suite does not assert the
pre-8166 `var(--space-md)` residual inset.
*/
it("FN-8154 keeps the mobile Feed inset narrow while clearing its overlay toggle from first rows", async () => {
const css = await loadAllAppCss();
const baseCss = await loadAllAppCssBaseOnly();
@@ -57,8 +64,9 @@ describe("TaskDetailModal CSS contract", () => {
];
expect(baseCss).toContain(".detail-activity {\n position: relative;\n padding-inline-end: calc(var(--space-2xl) + var(--space-md));\n}");
expect(mobileCss).toContain(" .detail-activity {\n padding-inline-end: var(--space-md);\n }");
expect(mobileCss).toContain(" .detail-activity {\n padding-inline-end: 0;\n }");
expect(mobileCss).not.toContain(" .detail-activity {\n padding-inline-end: calc(var(--space-2xl) + var(--space-lg));\n }");
expect(mobileCss).not.toContain(" .detail-activity {\n padding-inline-end: var(--space-md);\n }");
expect(mobileCss).toContain(" .detail-activity--interventions {\n padding-inline-end: 0;\n }");
for (const selector of firstRowSelectors) {
const escapedSelector = selector.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");

View File

@@ -15,10 +15,11 @@ describe("Grok plugin process lifecycle", () => {
});
/*
FNXC:GrokRuntimeTests 2026-07-18-07:15:
Bound is proven by a few re-evaluations (Symbol.for exit-hook guard). Full-suite
shard load made 15 dynamic imports hit the default 5s testTimeout (transform-heavy
plugin graph), not a product hang — keep the assertion, reduce iterations.
FNXC:GrokRuntimeTests 2026-07-18-07:25:
Symbol.for exit-hook guard is proven by two re-evaluations after the baseline
import. Full-suite shard transform load made 5–15 dynamic imports of the full
plugin graph hit the default 5s testTimeout; keep the bound assertion, not the
iteration marathon.
*/
it("keeps its process cleanup owner bounded across repeated module evaluation", async () => {
const baseline = listenerCounts();
@@ -27,7 +28,7 @@ describe("Grok plugin process lifecycle", () => {
process.on("warning", onWarning);
try {
for (let iteration = 0; iteration < 5; iteration += 1) {
for (let iteration = 0; iteration < 2; iteration += 1) {
vi.resetModules();
await import("../index.js");
}