fix: retain completed results during live editing

This commit is contained in:
2026-07-27 13:05:02 +02:00
parent 7f3a91ad37
commit d2e9b3b569
22 changed files with 576 additions and 117 deletions

View File

@@ -446,6 +446,7 @@ test("rapid pattern and replacement edits cannot run with stale syntax", async (
await page.goto("./");
await waitForReady(page);
await page.getByLabel("Live").uncheck();
const initialExtractionCount = await page.locator(".extraction-row").count();
await page.getByRole("button", { name: "Replace", exact: true }).click();
await setEditor(page, "editor-regular-expression-pattern", "(?<stale>\\w+)");
@@ -462,7 +463,10 @@ test("rapid pattern and replacement edits cannot run with stale syntax", async (
await expect(runButton).toBeDisabled();
await runButton.evaluate((button: HTMLButtonElement) => button.click());
await expect(page.locator(".run-status")).not.toHaveClass(/status-running/u);
await expect(page.locator(".extraction-row")).toHaveCount(0);
await expect(page.locator(".extraction-row")).toHaveCount(
initialExtractionCount,
);
await expect(page.getByTestId("stale-result-frame")).toBeVisible();
await expect(runButton).toBeEnabled();
const currentNamedToken = page.locator(".token-row").filter({
@@ -484,22 +488,31 @@ test("rapid pattern and replacement edits cannot run with stale syntax", async (
).toHaveText("[A] [B]");
});
test("manual editing clears results that no longer describe the inputs", async ({
test("manual editing retains an explicitly stale result without applying its ranges", async ({
page,
}) => {
await page.goto("./");
await waitForReady(page);
await page.getByLabel("Live").uncheck();
const extractionRows = page.locator(".extraction-row");
const captureRows = page.locator(".capture-table-scroll tbody tr");
const initialExtractionCount = await extractionRows.count();
const initialCaptureCount = await captureRows.count();
expect(initialExtractionCount).toBeGreaterThan(0);
expect(initialCaptureCount).toBeGreaterThan(0);
await setEditor(page, "editor-regular-expression-pattern", "nomatch");
await expect(page.locator(".run-status")).toHaveClass(/status-idle/u);
await expect(page.locator(".run-status")).toContainText(
"previous results were cleared",
"last completed result remains visible until the current inputs complete",
);
await expect(page.locator(".run-status small")).toHaveCount(0);
await expect(page.locator(".extraction-row")).toHaveCount(0);
await expect(page.locator(".capture-table-scroll tbody tr")).toHaveCount(0);
await expect(page.getByTestId("stale-result-frame")).toContainText(
"no ranges are applied to current editors",
);
await expect(extractionRows).toHaveCount(initialExtractionCount);
await expect(captureRows).toHaveCount(initialCaptureCount);
await expect(page.locator(".cm-subject-match")).toHaveCount(0);
});
@@ -509,6 +522,10 @@ test("capture-group resource limits block execution visibly", async ({
await page.goto("./");
await waitForReady(page);
await page.getByLabel("Live").uncheck();
const initialExtractionCount = await page.locator(".extraction-row").count();
const initialCaptureCount = await page
.locator(".capture-table-scroll tbody tr")
.count();
await setEditor(
page,
@@ -520,8 +537,14 @@ test("capture-group resource limits block execution visibly", async ({
await expect(page.locator(".run-status")).toContainText(
"above the 1,000 group execution limit",
);
await expect(page.locator(".run-status small")).toHaveCount(0);
await expect(page.locator(".extraction-row")).toHaveCount(0);
await expect(page.getByTestId("stale-result-frame")).toBeVisible();
await expect(page.locator(".extraction-row")).toHaveCount(
initialExtractionCount,
);
await expect(page.locator(".capture-table-scroll tbody tr")).toHaveCount(
initialCaptureCount,
);
await expect(page.locator(".cm-subject-match")).toHaveCount(0);
});
test("large valid patterns bound syntax tree nodes and editor decorations", async ({
@@ -779,6 +802,25 @@ test("replacement and list modes use native and typed templates", async ({
page.getByTestId("editor-replacement-output").locator(".cm-selected-range"),
).toHaveCount(1);
await page.getByLabel("Live").uncheck();
await setEditor(page, "editor-replacement-template", "[$<user> — $<date>]");
await expect(page.getByTestId("stale-replacement-syntax")).not.toBeVisible();
await expect(page.getByTestId("stale-result-frame")).toBeVisible();
await userContribution.click();
await expect(
page
.getByTestId("editor-replacement-template")
.locator(".cm-selected-range"),
).toHaveCount(0);
await expect(
page
.getByTestId("editor-regular-expression-pattern")
.locator(".cm-selected-range"),
).toHaveCount(0);
await expect(
page.getByTestId("editor-test-text").locator(".cm-selected-range"),
).toHaveCount(0);
await page.getByRole("button", { name: "List", exact: true }).click();
await expect(
page.getByRole("heading", { name: "Generated rows" }),
@@ -1117,6 +1159,10 @@ test("a timeout kills the worker and the next request uses a fresh engine", asyn
await page.goto("./");
await waitForReady(page);
await page.getByLabel("Live").uncheck();
const initialExtractionCount = await page.locator(".extraction-row").count();
const initialCaptureCount = await page
.locator(".capture-table-scroll tbody tr")
.count();
await page.getByLabel("Manual limit").selectOption("250");
await setEditor(page, "editor-regular-expression-pattern", "^(a|aa)+$");
await setEditor(page, "editor-test-text", `${"a".repeat(48)}!`);
@@ -1127,9 +1173,13 @@ test("a timeout kills the worker and the next request uses a fresh engine", asyn
await expect(page.locator(".run-status")).toContainText(
"worker was terminated",
);
await expect(page.locator(".run-status small")).toHaveCount(0);
await expect(page.locator(".extraction-row")).toHaveCount(0);
await expect(page.locator(".capture-table-scroll tbody tr")).toHaveCount(0);
await expect(page.getByTestId("stale-result-frame")).toBeVisible();
await expect(page.locator(".extraction-row")).toHaveCount(
initialExtractionCount,
);
await expect(page.locator(".capture-table-scroll tbody tr")).toHaveCount(
initialCaptureCount,
);
await expect(page.locator(".cm-subject-match")).toHaveCount(0);
await setEditor(page, "editor-regular-expression-pattern", "^ok$");