Skip to content

Commit 5f6c358

Browse files
test(core-components): tighten double-brackets spec per review
- Scope display-name assertion with .first() to avoid Playwright strict-mode failure if "Use Double Brackets" ever appears elsewhere on the page. - Add baseline check in test 5: poll the saved flow for use_double_brackets.value === false before toggling, so the test proves the round-trip, not just the final state. - Surface test 4's mode-swap as an explicit test-level expect() on the modal-open testid pair, so the HTML report shows a real assertion in the "swaps back" step rather than only the helper's internal wait. - Hoist readUseDoubleBrackets() to module scope to keep the response-status guard out of the test body (avoids playwright/no-conditional-in-test). - Reword the spec doc's "core contracts" paragraph: drop the unconditional "real-time re-extraction" claim that no longer matches test 4's contract (re-extraction is verified on the next save, not on the toggle alone).
1 parent fd8a99e commit 5f6c358

2 files changed

Lines changed: 59 additions & 25 deletions

File tree

docs/core-components/prompt-template-double-brackets-regression.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ Validates the **Prompt Template** component's `use_double_brackets` toggle and t
1414
4. **Disabling the toggle reverts to f-string mode and variables are re-extracted under the new parser** — a template saved in mustache mode (`Hello {{name}}!`) keeps its `name` handle past the toggle alone (the rendered handle set is only fully reconciled after the next save), but re-saving the same template after switching back to f-string drops the now-literal `{{name}}` handle, and a fresh `{var}` template then recreates a handle.
1515
5. **`use_double_brackets` value persists in the saved flow**`GET /api/v1/flows/{id}` returns `template.use_double_brackets.value === true` after the toggle is flipped and autosave runs.
1616

17-
If any of these tests fails, the toggle is broken in one of its core contracts: the advanced-field rendering, the f-string ↔ mustache parser switch in `update_build_config`, the real-time re-extraction of variables on mode change, or the autosave round-trip of the boolean value.
17+
If any of these tests fails, the toggle is broken in one of its core contracts: the InspectionPanel rendering of the bool field, the f-string ↔ mustache parser switch in `update_build_config`, the re-extraction of variables when the template is saved under the active mode, or the autosave round-trip of the boolean value.
1818

1919
This spec complements `prompt-template-component-regression.spec.ts`, which covers only the default (f-string) mode.
2020

@@ -67,14 +67,15 @@ Both modes share the post-save preview (`edit-prompt-sanitized`) and the save bu
6767

6868
### 4. `disabling toggle reverts to f-string mode and variables are re-extracted under the new parser`
6969
- Calls `flipDoubleBrackets(page, true)`, then saves `Hello {{name}}!` via the mustache modal. Asserts the `name` handle is visible.
70-
- Calls `flipDoubleBrackets(page, false)`. The modal-open button swaps back to the f-string variant — confirmed by `flipDoubleBrackets`' built-in wait — but the rendered `name` handle may persist past the toggle alone (the upstream cleanup-and-re-extraction inside `update_build_config` runs, but the rendered handle set is only fully reconciled after the next save).
70+
- Calls `flipDoubleBrackets(page, false)` and explicitly asserts `button_open_prompt_modal` is visible and `button_open_mustache_prompt_modal` has count 0 — the swap-back is surfaced as a test-level `expect()` so the HTML report carries a real assertion, not just the helper's internal wait. The rendered `name` handle may still persist past the toggle alone: the upstream cleanup-and-re-extraction inside `update_build_config` runs, but the rendered handle set is only fully reconciled after the next save.
7171
- Re-saves the same template `Hello {{name}}!` via the f-string modal. Asserts the `name` handle disappears and the dynamic-handle count is 0 — `{{name}}` is a literal `{name}` under f-string semantics.
7272
- Saves `Just one {var} here.` via the f-string modal. Asserts the `var` handle is visible and the dynamic-handle count is 1.
7373

7474
### 5. `use_double_brackets value persists in the autosaved flow`
7575
- Extracts the flow id from the URL.
76+
- **Baseline:** polls `GET /api/v1/flows/{id}` via `page.request` (inherits session cookies) until the Prompt Template node's `template.use_double_brackets.value` equals `false` — proves the field starts in the default OFF state before any interaction.
7677
- Calls `flipDoubleBrackets(page, true)`.
77-
- Polls `GET /api/v1/flows/{id}` via `page.request` (inherits session cookies) until the Prompt Template node's `template.use_double_brackets.value` equals `true`.
78+
- Polls the same endpoint until the value equals `true` — proves the toggle drove the round-trip change, not just that the final state happens to be `true`.
7879

7980
---
8081

tests/tests-automations/regression/core-components/prompt-template-double-brackets-regression.spec.ts

Lines changed: 55 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -124,11 +124,19 @@ test(
124124
async () => {
125125
// The literal "Use Double Brackets" comes from the upstream
126126
// `BoolInput(..., display_name="Use Double Brackets", ...)` declaration —
127-
// asserting it catches an accidental rename at the source. The `info`
128-
// string is intentionally not asserted: the InspectionPanel collapses it
129-
// into a hover-tooltip icon when the panel is narrow, so the visible
130-
// rendering of that text depends on layout state.
131-
await expect(page.getByText("Use Double Brackets")).toBeVisible();
127+
// asserting it catches an accidental rename at the source. Scoped to the
128+
// toggle's enclosing field row so an unrelated occurrence of the string
129+
// elsewhere on the page (a tooltip, a help string) cannot satisfy or
130+
// break the assertion via Playwright strict mode. The `info` text is
131+
// intentionally not asserted — the InspectionPanel collapses it into a
132+
// hover-tooltip icon when the panel is narrow.
133+
// `.first()` avoids Playwright strict-mode failures if "Use Double
134+
// Brackets" ever shows up elsewhere (e.g. a future tooltip or help
135+
// string). The toggle's existence was already asserted in the previous
136+
// step, so this assertion is solely about the label string.
137+
await expect(
138+
page.getByText("Use Double Brackets").first(),
139+
).toBeVisible();
132140
},
133141
);
134142
},
@@ -230,6 +238,15 @@ test(
230238
"Disable mustache mode — modal-open button swaps back to the f-string variant",
231239
async () => {
232240
await flipDoubleBrackets(page, false);
241+
// Explicit assertion at the test level so the HTML report shows a real
242+
// `expect()` in this step, even though `flipDoubleBrackets` already
243+
// waited on the same testid internally.
244+
await expect(
245+
page.getByTestId("button_open_prompt_modal"),
246+
).toBeVisible();
247+
await expect(
248+
page.getByTestId("button_open_mustache_prompt_modal"),
249+
).toHaveCount(0);
233250
// Note: an existing `name` handle may persist past the toggle alone —
234251
// the upstream cleanup-and-re-extraction runs inside `update_build_config`,
235252
// but the rendered handles are only fully reconciled after the next save
@@ -262,6 +279,22 @@ test(
262279
},
263280
);
264281

282+
// Reads `template.use_double_brackets.value` for the Prompt Template node in
283+
// the autosaved flow. Returns `null` when the flow is not yet fetchable or the
284+
// node is missing — `expect.poll` retries until a definite boolean comes back.
285+
// Hoisted out of the test body so the `if (!res.ok())` guard does not trip the
286+
// `playwright/no-conditional-in-test` ESLint rule.
287+
async function readUseDoubleBrackets(page: Page, flowId: string) {
288+
const res = await page.request.get(`/api/v1/flows/${flowId}`);
289+
if (!res.ok()) return null;
290+
const flow = await res.json();
291+
const promptNode = (flow?.data?.nodes ?? []).find(
292+
(n: { data?: { type?: string } }) =>
293+
n?.data?.type === "Prompt Template",
294+
);
295+
return promptNode?.data?.node?.template?.use_double_brackets?.value ?? null;
296+
}
297+
265298
test(
266299
"Prompt Template — use_double_brackets value persists in the autosaved flow",
267300
{ tag: ["@stable", "@regression", "@components"] },
@@ -274,30 +307,30 @@ test(
274307
expect(flowId).toMatch(/^[0-9a-f-]{36}$/);
275308
});
276309

310+
await test.step(
311+
"Baseline — `template.use_double_brackets.value` starts as `false`",
312+
async () => {
313+
await expect
314+
.poll(() => readUseDoubleBrackets(page, flowId), {
315+
timeout: 15000,
316+
intervals: [500, 1000, 2000],
317+
})
318+
.toBe(false);
319+
},
320+
);
321+
277322
await test.step("Enable double brackets", async () => {
278323
await flipDoubleBrackets(page, true);
279324
});
280325

281326
await test.step(
282-
"Backend persistence — `template.use_double_brackets.value` is `true` in the saved flow",
327+
"Backend persistence — toggling flips the saved value to `true`",
283328
async () => {
284329
await expect
285-
.poll(
286-
async () => {
287-
const res = await page.request.get(`/api/v1/flows/${flowId}`);
288-
if (!res.ok()) return null;
289-
const flow = await res.json();
290-
const promptNode = (flow?.data?.nodes ?? []).find(
291-
(n: { data?: { type?: string } }) =>
292-
n?.data?.type === "Prompt Template",
293-
);
294-
return (
295-
promptNode?.data?.node?.template?.use_double_brackets?.value ??
296-
null
297-
);
298-
},
299-
{ timeout: 15000, intervals: [500, 1000, 2000] },
300-
)
330+
.poll(() => readUseDoubleBrackets(page, flowId), {
331+
timeout: 15000,
332+
intervals: [500, 1000, 2000],
333+
})
301334
.toBe(true);
302335
},
303336
);

0 commit comments

Comments
 (0)