Every registered trainer's callee and caller scripts run, with the missing specials and commands (RandomPhoneWildMon, RandomUnseenWildMon, swarms, gettrainerclassname, Kenji's break, the Blue Card and Buena's password variables). Fight counts are saved, so rematches and gifts work on every open map, and the daily reset clears the phone's flags. Random calls follow CheckPhoneCall and the 20/10/5/3-minute call timer; received calls ring twice with the caller's name, and calls play their ringing, hang-up and no-signal sounds. Grass and fishing swarms use the swarm tables. The radio ports PlayRadioShow and every station frame by frame, with its music: the Pokégear's radio card tunes by knob, house radios play through MapRadio, and Buena's show takes the day's password for Blue Card points that her receptionist exchanges for prizes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
50 lines
2.2 KiB
TypeScript
50 lines
2.2 KiB
TypeScript
import { test, expect, type Page } from "@playwright/test";
|
|
import { existsSync } from "node:fs";
|
|
import { resolve } from "node:path";
|
|
|
|
const romPath = resolve(
|
|
process.env.CRYSTAL_ROM_PATH ?? "Pokemon - Crystal Version (UE) (V1.1) [C][!].gbc",
|
|
);
|
|
test.beforeEach(() => test.skip(!existsSync(romPath), "Requires the local user ROM."));
|
|
|
|
async function start(page: Page) {
|
|
await page.route("**/src/game/runtime.ts", async (route) => {
|
|
const response = await route.fetch(),
|
|
source = await response.text();
|
|
const needle = "const world = new GameWorld(assets);";
|
|
expect(source).toContain(needle);
|
|
await route.fulfill({
|
|
response,
|
|
body: source.replace("this.world?.beginIntro();", "").replace(
|
|
needle,
|
|
`const { radioFixtureWorld } = await import('/tests/radio-fixture.ts'); const world = radioFixtureWorld(assets);`,
|
|
),
|
|
});
|
|
});
|
|
await page.goto("/");
|
|
await page.locator("#rom-file").setInputFiles(romPath);
|
|
await expect(page.locator("#status")).toContainText("verified");
|
|
await page.locator("#play").click();
|
|
}
|
|
|
|
test("the Pokégear's radio card tunes in Oak's Pokémon Talk and plays it", async ({ page }) => {
|
|
const errors: string[] = [];
|
|
page.on("pageerror", (error) => errors.push(error.message));
|
|
await start(page);
|
|
await page.keyboard.press("Enter");
|
|
await page.locator("#dialogue-choice").getByRole("option", { name: /^POKéGEAR/ }).click();
|
|
await expect(page.locator("#pokegear")).toBeVisible();
|
|
await page.keyboard.press("ArrowRight");
|
|
const radio = page.locator(".pokegear-radio");
|
|
await expect(radio).toBeVisible();
|
|
await expect(radio.locator(".pokegear-frequency")).toHaveText("FM 0.5");
|
|
for (let press = 0; press < 8; press++) await page.keyboard.press("ArrowUp");
|
|
await expect(radio.locator(".pokegear-frequency")).toHaveText("FM 4.5");
|
|
await expect(radio.locator("strong")).toContainText("Talk");
|
|
await expect(radio.locator(".pokegear-radio-text")).toContainText("MARY: PROF.OAK'S");
|
|
await expect(radio.locator(".pokegear-radio-text")).toContainText("TALK!", { timeout: 10_000 });
|
|
await page.keyboard.press("KeyZ");
|
|
await expect(page.locator("#pokegear")).toBeHidden();
|
|
expect(errors).toEqual([]);
|
|
});
|