Merge pull request #2291 from modelcontextprotocol/v2/fix/2278-skills-story-geometry-flake
fix: two load-dependent Storybook flakes — SkillsScreen geometry and the Ace-worker wait
This commit is contained in:
commit
d8100e8d89
3 changed files with 32 additions and 6 deletions
|
|
@ -209,9 +209,12 @@ export const AnnotatesTheOffendingLine: Story = {
|
|||
await expect(annotations.length).toBeGreaterThan(0);
|
||||
await expect(annotations.some((a) => a.type === "error")).toBe(true);
|
||||
},
|
||||
// The worker is asynchronous and debounced, so this needs a real wait
|
||||
// rather than a tick.
|
||||
{ timeout: 5000 },
|
||||
// The worker is asynchronous, starts out of process and debounces its
|
||||
// result, so this needs a real wait rather than a tick — and a budget
|
||||
// that survives a loaded machine, where 5000ms did not (#2292). It also
|
||||
// has to stay under the storybook project's `testTimeout`, or the test is
|
||||
// killed before the wait can report what it saw.
|
||||
{ timeout: 10000 },
|
||||
);
|
||||
},
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import { useState } from "react";
|
||||
import type { ComponentProps } from "react";
|
||||
import type { Meta, StoryObj } from "@storybook/react-vite";
|
||||
import { expect, fn, userEvent, within } from "storybook/test";
|
||||
import { expect, fn, userEvent, waitFor, within } from "storybook/test";
|
||||
import type { SkillEntry } from "@inspector/core/mcp/skillsSchemas";
|
||||
import { SkillsScreen } from "./SkillsScreen";
|
||||
import type { SkillsUiState } from "./SkillsScreen";
|
||||
|
|
@ -428,9 +428,22 @@ export const LongSkillDocument: Story = {
|
|||
detailCard.clientHeight + 1,
|
||||
);
|
||||
|
||||
// Collapse then reopen restores the same geometry.
|
||||
// Collapse then reopen restores the same geometry. There is no panel
|
||||
// animation to wait out — the accordion sets `transitionDuration={0}`
|
||||
// because a height animation fights its flex sizing — but the reopen is
|
||||
// still not settled when the click resolves: `userEvent.click` returns once
|
||||
// the event is dispatched, ahead of React committing the `openSections`
|
||||
// update, remounting the panel's content, and the browser running the
|
||||
// layout pass that redistributes height across the flex sections. Sampling
|
||||
// once lands mid-redistribution under load and fails intermittently
|
||||
// (#2278), so read the geometry under `waitFor` and let it retry until the
|
||||
// panes stop moving. The reopened layout only ever converges ON `before`
|
||||
// rather than passing through it, so retrying cannot mask a real
|
||||
// regression.
|
||||
await userEvent.click(viewerControl);
|
||||
await userEvent.click(viewerControl);
|
||||
await expect(geometry()).toEqual(before);
|
||||
await waitFor(async () => {
|
||||
await expect(geometry()).toEqual(before);
|
||||
});
|
||||
},
|
||||
};
|
||||
|
|
|
|||
|
|
@ -375,6 +375,16 @@ export default defineConfig(({ command }) => {
|
|||
],
|
||||
test: {
|
||||
name: "storybook",
|
||||
// Vitest's default is 5000ms, which is the whole budget a play
|
||||
// function gets — including work that is genuinely slow rather than
|
||||
// racy. `JsonObjectInput`'s "Annotates The Offending Line" waits on
|
||||
// Ace's JSON worker, which starts out of process and debounces its
|
||||
// result; its own `waitFor` asked for 5000ms and so could never win
|
||||
// against the per-test ceiling, and it lost on a loaded machine
|
||||
// (#2292). A larger ceiling does not hide a defect here: a story
|
||||
// that blows 15s has genuinely failed, and every assertion stays as
|
||||
// strict as it was.
|
||||
testTimeout: 15000,
|
||||
browser: {
|
||||
enabled: true,
|
||||
headless: true,
|
||||
|
|
|
|||
Loading…
Reference in a new issue