Q182: dialogs stay busy while their request runs and ignore repeat submits
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
3039835644
commit
3f8832702e
19 files changed
+115
-39
No files matched your search
@@ -0,0 +1,38 @@
|
||||
import { _electron as electron, expect, test } from "@playwright/test";
|
||||
import { mkdirSync } from "node:fs";
|
||||
import { tmpdir } from "node:os";
|
||||
import { join, resolve } from "node:path";
|
||||
import { randomUUID } from "node:crypto";
|
||||
import { seedBuiltinSkillsFixture } from "./builtin-skills-fixture";
|
||||
import { onboard } from "./onboard";
|
||||
|
||||
test("a dialog submitted twice in a row creates one record", async () => {
|
||||
const profileDir = join(tmpdir(), `agentcompany-new-e2e-double-${randomUUID()}`);
|
||||
mkdirSync(profileDir, { recursive: true });
|
||||
const builtinDir = seedBuiltinSkillsFixture(join(tmpdir(), `agentcompany-new-e2e-double-builtin-${randomUUID()}`));
|
||||
const app = await electron.launch({
|
||||
args: [resolve("out/main/index.js")],
|
||||
env: { ...process.env, AGENTCOMPANY_NEW_PROFILE_DIR: profileDir, AGENTCOMPANY_NEW_AUTORUN: "0", AGENTCOMPANY_NEW_BUILTIN_SKILLS_DIR: builtinDir },
|
||||
});
|
||||
try {
|
||||
const page = await app.firstWindow();
|
||||
await onboard(page, "Double Co");
|
||||
await page.getByRole("button", { name: "Work" }).click();
|
||||
await page.getByRole("button", { name: "Goal", exact: true }).click();
|
||||
await page.locator(".modal").getByLabel("Title").fill("Only once");
|
||||
await page.locator(".modal").getByLabel("Description").fill("d");
|
||||
// Two submits in the same tick, as an impatient double click sends them.
|
||||
await page.locator(".modal").evaluate((form) => {
|
||||
(form as HTMLFormElement).requestSubmit();
|
||||
(form as HTMLFormElement).requestSubmit();
|
||||
});
|
||||
await expect(page.locator(".modal")).toHaveCount(0);
|
||||
const titles = await page.evaluate(async () => {
|
||||
const api = (window as unknown as { agentCompany: { loadSnapshot: () => Promise<{ ok: true; data: { goals: Array<{ title: string }> } }> } }).agentCompany;
|
||||
return (await api.loadSnapshot()).data.goals.map((goal) => goal.title).filter((title) => title === "Only once");
|
||||
});
|
||||
expect(titles).toEqual(["Only once"]);
|
||||
} finally {
|
||||
await app.close();
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,19 @@
|
||||
import { expect, type Page } from "@playwright/test";
|
||||
|
||||
/** Runs the setup wizard with a fake OpenAI key and enters the app. */
|
||||
export async function onboard(page: Page, company: string): Promise<void> {
|
||||
await page.getByRole("button", { name: "Get started" }).click();
|
||||
await page.getByLabel("API key").fill("e2e-secret");
|
||||
await page.getByLabel("Model").fill("gpt-5.4");
|
||||
await page.getByRole("button", { name: "Continue" }).click();
|
||||
await page.getByLabel("Company name").fill(company);
|
||||
await page.getByLabel("Your name").fill("Dana Lee");
|
||||
await page.getByLabel("Description").fill("d");
|
||||
await page.getByRole("button", { name: "Continue" }).click();
|
||||
await page.getByRole("button", { name: "Continue" }).click();
|
||||
await page.getByLabel("Goal").fill("Ship.");
|
||||
await page.getByLabel("Acceptance criteria").fill("It ships.");
|
||||
await page.getByRole("button", { name: "Launch" }).click();
|
||||
await page.getByRole("button", { name: "Finish" }).click();
|
||||
await expect(page.getByRole("button", { name: "Settings" })).toBeVisible();
|
||||
}
|
||||
@@ -5,6 +5,7 @@ import { join, resolve } from "node:path";
|
||||
import { randomUUID } from "node:crypto";
|
||||
import { DatabaseSync } from "node:sqlite";
|
||||
import { seedBuiltinSkillsFixture } from "./builtin-skills-fixture";
|
||||
import { onboard } from "./onboard";
|
||||
|
||||
test("a record that breaks one page leaves the rest of the app working", async () => {
|
||||
const profileDir = join(tmpdir(), `agentcompany-new-e2e-render-${randomUUID()}`);
|
||||
@@ -16,19 +17,7 @@ test("a record that breaks one page leaves the rest of the app working", async (
|
||||
});
|
||||
try {
|
||||
const page = await app.firstWindow();
|
||||
await page.getByRole("button", { name: "Get started" }).click();
|
||||
await page.getByLabel("API key").fill("e2e-secret");
|
||||
await page.getByLabel("Model").fill("gpt-5.4");
|
||||
await page.getByRole("button", { name: "Continue" }).click();
|
||||
await page.getByLabel("Company name").fill("Render Co");
|
||||
await page.getByLabel("Your name").fill("Dana Lee");
|
||||
await page.getByLabel("Description").fill("d");
|
||||
await page.getByRole("button", { name: "Continue" }).click();
|
||||
await page.getByRole("button", { name: "Continue" }).click();
|
||||
await page.getByLabel("Goal").fill("Ship.");
|
||||
await page.getByLabel("Acceptance criteria").fill("It ships.");
|
||||
await page.getByRole("button", { name: "Launch" }).click();
|
||||
await page.getByRole("button", { name: "Finish" }).click();
|
||||
await onboard(page, "Render Co");
|
||||
|
||||
// A pending request with a risk level the Approvals page cannot draw.
|
||||
const db = new DatabaseSync(join(profileDir, "agentcompany.db"));
|
||||
|
||||
Reference in new issue
Block a user