fix(soak): multi-hole round transitions, token refresh, dashboard wiring
- Session loop now handles round_over by clicking #ss-next-btn (the
scoresheet modal button) instead of exiting early. Waits for next
round or game_over before continuing.
- SessionPool detects expired tokens on acquire and re-logins
automatically, writing fresh credentials to .env.stresstest.
- Added 2s post-game delay before goto('/') so the server can process
game completion before WebSocket disconnect.
- Wired dashboard metrics (games_completed, moves_total, errors),
activity log entries, and player tiles for both populate and stress
scenarios.
- Bumped screencast resolution to 960x540 and set headless viewport
to 960x800 for better click-to-watch framing.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -266,12 +266,49 @@ export class SessionPool {
|
||||
const context = await targetBrowser.newContext({
|
||||
...this.opts.contextOptions,
|
||||
baseURL: this.opts.targetUrl,
|
||||
...(useHeaded ? { viewport: { width: 960, height: 900 } } : {}),
|
||||
viewport: useHeaded
|
||||
? { width: 960, height: 900 }
|
||||
: { width: 960, height: 800 },
|
||||
});
|
||||
await this.injectAuth(context, account);
|
||||
const page = await context.newPage();
|
||||
await page.goto(this.opts.targetUrl);
|
||||
|
||||
// Verify the token is valid — if expired, re-login and reload
|
||||
const controlsVisible = await page
|
||||
.waitForSelector('#lobby-game-controls:not(.hidden)', {
|
||||
state: 'attached',
|
||||
timeout: 5000,
|
||||
})
|
||||
.then(() => true)
|
||||
.catch(() => false);
|
||||
|
||||
if (!controlsVisible) {
|
||||
this.opts.logger.warn('token_expired_relogin', { account: account.key });
|
||||
const freshToken = await loginAccount(
|
||||
this.opts.targetUrl,
|
||||
account.username,
|
||||
account.password,
|
||||
);
|
||||
account.token = freshToken;
|
||||
writeCredFile(this.opts.credFile, this.accounts);
|
||||
await context.addInitScript(
|
||||
({ token, username }) => {
|
||||
window.localStorage.setItem('authToken', token);
|
||||
window.localStorage.setItem(
|
||||
'authUser',
|
||||
JSON.stringify({ id: '', username, role: 'user', email_verified: true }),
|
||||
);
|
||||
},
|
||||
{ token: freshToken, username: account.username },
|
||||
);
|
||||
await page.goto(this.opts.targetUrl);
|
||||
await page.waitForSelector('#lobby-game-controls:not(.hidden)', {
|
||||
state: 'attached',
|
||||
timeout: 10000,
|
||||
});
|
||||
}
|
||||
|
||||
// Best-effort tile placement. window.moveTo is often a no-op on
|
||||
// modern Chromium (especially under Wayland), so we don't rely on
|
||||
// it — the viewport sized above is what the user actually sees.
|
||||
|
||||
Reference in New Issue
Block a user