fix(bot): GolfBot handles authenticated sessions + num-decks stepper

Two small fixes to tests/e2e/bot/golf-bot.ts needed to run the bot
from the soak harness with authenticated accounts:

1. createGame and joinGame now check whether #player-name is
   visible before filling it. Authenticated sessions hide that
   input (the server uses the logged-in username); guest sessions
   still fill it as before. Existing e2e tests behave identically
   since they register guests who always see the input.

2. startGame's 'decks' option was calling selectOption on
   #num-decks, which is a hidden input inside a stepper widget,
   not a <select>. Replaced with stepper-click logic that
   increments/decrements until the hidden input matches the
   target value.

End-to-end verified via the soak runner: 2 authenticated sessions
played a complete 1-hole game against local dev, 26 turns, exit 0.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
adlee-was-taken
2026-04-11 18:52:07 -04:00
parent 6df81e6f8d
commit a6a276b509

View File

@@ -72,12 +72,20 @@ export class GolfBot {
} }
/** /**
* Create a new game room * Create a new game room.
*
* Works for both guest sessions (fills the name input) and
* authenticated sessions (the name input is hidden; the server
* uses the logged-in username). `playerName` is ignored when the
* session is authenticated.
*/ */
async createGame(playerName: string): Promise<string> { async createGame(playerName: string): Promise<string> {
// Enter name // Guest sessions have a visible player-name input; authenticated
// sessions don't. Only fill it if it's actually there.
const nameInput = this.page.locator(SELECTORS.lobby.playerNameInput); const nameInput = this.page.locator(SELECTORS.lobby.playerNameInput);
await nameInput.fill(playerName); if (await nameInput.isVisible().catch(() => false)) {
await nameInput.fill(playerName);
}
// Click create room // Click create room
const createBtn = this.page.locator(SELECTORS.lobby.createRoomBtn); const createBtn = this.page.locator(SELECTORS.lobby.createRoomBtn);
@@ -97,12 +105,16 @@ export class GolfBot {
} }
/** /**
* Join an existing game room * Join an existing game room.
*
* Same auth handling as `createGame` — `playerName` is ignored for
* authenticated sessions.
*/ */
async joinGame(roomCode: string, playerName: string): Promise<void> { async joinGame(roomCode: string, playerName: string): Promise<void> {
// Enter name
const nameInput = this.page.locator(SELECTORS.lobby.playerNameInput); const nameInput = this.page.locator(SELECTORS.lobby.playerNameInput);
await nameInput.fill(playerName); if (await nameInput.isVisible().catch(() => false)) {
await nameInput.fill(playerName);
}
// Enter room code // Enter room code
const codeInput = this.page.locator(SELECTORS.lobby.roomCodeInput); const codeInput = this.page.locator(SELECTORS.lobby.roomCodeInput);
@@ -172,7 +184,19 @@ export class GolfBot {
await this.page.selectOption(SELECTORS.waiting.numRounds, String(options.holes)); await this.page.selectOption(SELECTORS.waiting.numRounds, String(options.holes));
} }
if (options.decks) { if (options.decks) {
await this.page.selectOption(SELECTORS.waiting.numDecks, String(options.decks)); // #num-decks is a stepper (hidden input + +/- buttons), not a select.
// Click the stepper until the hidden input matches the requested value.
const target = options.decks;
for (let i = 0; i < 10; i++) {
const current = parseInt(
(await this.page.locator(SELECTORS.waiting.numDecks).inputValue().catch(() => '1')) || '1',
10,
);
if (current === target) break;
const btnId = current < target ? '#decks-plus' : '#decks-minus';
await this.page.locator(btnId).click({ timeout: 1000 }).catch(() => {});
await this.page.waitForTimeout(50);
}
} }
if (options.initialFlips !== undefined) { if (options.initialFlips !== undefined) {
await this.page.selectOption(SELECTORS.waiting.initialFlips, String(options.initialFlips)); await this.page.selectOption(SELECTORS.waiting.initialFlips, String(options.initialFlips));