Port the start menu, the party menu and the pack outside battle
Checks / web (push) Canceled after 0s

Start opens the original start menu. POKéMON shows the party with the
Pokémon submenu (stats, switching, move order, held items); PACK shows the
four pockets with the field item effects for healing, PP and the Bicycle,
plus giving and tossing. The menu runs on a script draft, and its cursors
persist until a battle clears them. Select keeps the Key Items shortcut.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Sébastien QUEROLandClaude Opus 5.5 committed 2026-09-30 16:10:22 +02:00
1 parent 60e06ae678
commit 1af2beacdc
18 files changed
+1918 -49

No files matched your search

+59 -4
View File
@@ -43,11 +43,11 @@ async function backup(page: Page) {
state: JSON.parse(Buffer.from(record.state, "base64").toString("utf8")),
};
}
test("Start opens Key Items, freezes movement, and uses the Bicycle with keyboard and touch", async ({
test("Select opens Key Items, freezes movement, and uses the Bicycle with keyboard and touch", async ({
page,
}) => {
await start(page);
await page.keyboard.press("Enter");
await page.keyboard.press("ShiftLeft");
await expect(page.locator("#field-menu")).toBeVisible();
await page.keyboard.down("ArrowDown");
await page.clock.runFor(1000);
@@ -92,10 +92,10 @@ test("B cancels the pack and an indoor Bicycle attempt leaves the player walking
page,
}) => {
await start(page, true);
await page.keyboard.press("Enter");
await page.keyboard.press("ShiftLeft");
await page.keyboard.press("KeyZ");
await expect(page.locator("#field-menu")).toBeHidden();
await page.keyboard.press("Enter");
await page.keyboard.press("ShiftLeft");
await page
.locator("#field-items")
.getByRole("button", { name: "BICYCLE", exact: true })
@@ -184,3 +184,58 @@ test("the Pokémon Center PC deposits a Pokémon and an item", async ({
expect(state.pcItems).toEqual([{ item: 18, quantity: 2 }]);
expect(state.bag.items).toEqual([{ item: 18, quantity: 3 }]);
});
test("Start opens the start menu: SWITCH reorders the party and the pack tosses an item", async ({
page,
}) => {
await start(page, "center");
const text = page.locator("#dialogue-text"),
choices = page.locator("#dialogue-choice"),
pack = page.locator("#mart");
await page.keyboard.press("Enter");
await expect(choices.getByRole("option", { name: /^POKéMON/ })).toBeVisible();
await expect(choices.getByRole("option", { name: /^PACK/ })).toBeVisible();
// Movement is frozen while the menu is open.
await page.keyboard.down("ArrowLeft");
await page.clock.runFor(500);
await page.keyboard.up("ArrowLeft");
await expect(page.locator("#game-screen")).toHaveAttribute("data-x", "9");
await choices.getByRole("option", { name: /^POKéMON/ }).click();
await expect(text).toHaveText("Choose a POKéMON.");
await choices.getByRole("option", { name: /^CYNDAQUIL/ }).click();
await choices.getByRole("option", { name: "SWITCH", exact: true }).click();
await expect(text).toHaveText("Move to where?");
await choices.getByRole("option", { name: /^PIDGEY/ }).click();
await expect(choices.getByRole("option").first()).toHaveAccessibleName(
/^PIDGEY/,
);
// B leaves the party menu for the start menu.
await page.keyboard.press("KeyZ");
await choices.getByRole("option", { name: /^PACK/ }).click();
await expect(pack).toHaveAttribute("aria-label", "Pack");
await expect(
pack.getByRole("button", { name: "ITEM POCKET", exact: true }),
).toHaveAttribute("aria-pressed", "true");
// Right twice: the Balls pocket, then Key Items.
await page.keyboard.press("ArrowRight");
await page.keyboard.press("ArrowRight");
await expect(pack.getByRole("button", { name: "BICYCLE" })).toBeVisible();
await pack.getByRole("button", { name: "ITEM POCKET", exact: true }).click();
await pack.getByRole("button", { name: /POTION/ }).click();
await choices.getByRole("option", { name: "TOSS", exact: true }).click();
await expect(page.locator("#mart-prompt")).toContainText("Throw away how");
await pack.getByRole("button", { name: "TOSS", exact: true }).click();
await expect(text).toContainText("Throw away 1 POTION(S)?");
await choices.getByRole("button", { name: /YES/ }).click();
await expect(text).toContainText("Threw away");
await page.keyboard.press("KeyX");
await pack.getByRole("button", { name: "BACK", exact: true }).click();
await choices.getByRole("option", { name: /^EXIT/ }).click();
await page.clock.runFor(500);
await expect(page.locator("#game-notice")).toHaveText("");
const { state } = await backup(page);
expect(state.party.map((mon: { species: number }) => mon.species)).toEqual([
16, 155,
]);
expect(state.bag.items).toEqual([{ item: 18, quantity: 4 }]);
});