feat(ui): hide GCG export in honest-AI games
CI / changes (pull_request) Successful in 2s
CI / unit (pull_request) Successful in 9s
CI / integration (pull_request) Successful in 14s
CI / ui (pull_request) Successful in 51s
CI / gate (pull_request) Successful in 0s
CI / deploy (pull_request) Successful in 1m1s
CI / changes (pull_request) Successful in 2s
CI / unit (pull_request) Successful in 9s
CI / integration (pull_request) Successful in 14s
CI / ui (pull_request) Successful in 51s
CI / gate (pull_request) Successful in 0s
CI / deploy (pull_request) Successful in 1m1s
A vs_ai game is throwaway practice, so its finished history header no longer
offers the 📤 GCG export (an empty slot keeps the comms icon pinned right).
Docs note the AI exclusion; UI_DESIGN also records that confirming a resign
reveals the full board (closes the history drawer, zooms out).
This commit is contained in:
@@ -59,6 +59,29 @@ test('AI game: 🤖 opponent, no wait, chat disabled, dictionary still works', a
|
||||
await expect(page.locator('.check input')).toBeEnabled();
|
||||
});
|
||||
|
||||
// GCG export is pointless for a practice AI game, so the finished AI game hides the 📤 export
|
||||
// (the comms hub stays). Start an AI game, resign it, reopen the history and check the header.
|
||||
test('AI game: no GCG export offered after it ends', async ({ page }) => {
|
||||
await page.goto('/');
|
||||
await page.getByRole('button', { name: /guest/i }).click();
|
||||
await page.getByRole('button', { name: /New/ }).click();
|
||||
await page.locator('.variant').first().click(); // AI is the default opponent
|
||||
await page.getByRole('button', { name: /Start game/i }).click();
|
||||
await expect(page.locator('.scoreboard').getByText('🤖')).toBeVisible();
|
||||
|
||||
// Resign the practice game from the history header.
|
||||
await page.locator('.scoreboard').click();
|
||||
await page.getByRole('button', { name: 'Drop game' }).click();
|
||||
await page.locator('button.danger').click();
|
||||
await expect(page.locator('.status .over')).toBeVisible();
|
||||
|
||||
// Reopen the history (resigning auto-closed it): the finished AI game offers no GCG export,
|
||||
// while the comms hub stays reachable.
|
||||
await page.locator('.scoreboard').click();
|
||||
await expect(page.getByRole('button', { name: 'Export GCG' })).toHaveCount(0);
|
||||
await expect(page.getByRole('button', { name: 'Chat' })).toBeVisible();
|
||||
});
|
||||
|
||||
// The opponent_joined push is best-effort and never replayed, so a join that lands while the live
|
||||
// stream is down is lost. The waiting game screen recovers it without a push: a poll while the
|
||||
// stream is down, and a refetch on stream reconnect. The __stream hook (lib/app.svelte.ts) drops /
|
||||
|
||||
@@ -986,7 +986,13 @@
|
||||
{#if view}
|
||||
<div class="hhead">
|
||||
{#if gameOver}
|
||||
<button class="hicon" onclick={exportGcg} aria-label={t('game.exportGcg')}>📤</button>
|
||||
{#if view.game.vsAi}
|
||||
<!-- GCG export is not offered for a practice AI game; an empty slot keeps the comms
|
||||
icon pinned right (the header is space-between). -->
|
||||
<span aria-hidden="true"></span>
|
||||
{:else}
|
||||
<button class="hicon" onclick={exportGcg} aria-label={t('game.exportGcg')}>📤</button>
|
||||
{/if}
|
||||
{:else}
|
||||
<button class="hicon" onclick={() => (resignOpen = true)} disabled={waitingForOpponent} aria-label={t('game.dropGame')}>🏁</button>
|
||||
{/if}
|
||||
|
||||
Reference in New Issue
Block a user