diff --git a/web/e2e/game.spec.ts b/web/e2e/game.spec.ts index c1ae2a3..dce4a90 100644 --- a/web/e2e/game.spec.ts +++ b/web/e2e/game.spec.ts @@ -375,3 +375,59 @@ test.describe('Mobile viewport', () => { await expect(page.getByRole('button', { name: 'Close menu' })).toBeHidden() }) }) + +/* ------------------------------------------------------------------ */ +/* Mobile toolbar overflow fix */ +/* ------------------------------------------------------------------ */ + +test.describe('Mobile toolbar overflow fix', () => { + test.use({ viewport: { width: 390, height: 844 } }) + + test.beforeEach(async ({ page }) => { + await page.goto(APP_URL) + await expect(page.locator('.loading-spinner')).toBeVisible({ + timeout: 10_000, + }) + await injectMockGameState(page) + }) + + test('Quicksave, Quickload, Save, Load, Help are hidden in toolbar on mobile', async ({ + page, + }) => { + await expect( + page.getByRole('button', { name: /Quicksave/i }).first(), + ).toBeHidden() + await expect( + page.getByRole('button', { name: /Quickload/i }).first(), + ).toBeHidden() + await expect( + page.getByRole('button', { name: /^💾 Save$/i }), + ).toBeHidden() + await expect( + page.getByRole('button', { name: /^📂 Load$/i }), + ).toBeHidden() + await expect( + page.getByRole('button', { name: /^❓ Help$/i }), + ).toBeHidden() + }) + + test('drawer shows Quicksave, Quickload, Save, Load, Help action chips', async ({ + page, + }) => { + await page.getByRole('button', { name: 'Open sidebar' }).click() + const drawer = page.getByTestId('mobile-drawer-panel') + await expect(drawer.getByRole('button', { name: /Quicksave/i })).toBeVisible() + await expect(drawer.getByRole('button', { name: /Quickload/i })).toBeVisible() + await expect(drawer.getByRole('button', { name: /Save/i }).first()).toBeVisible() + await expect(drawer.getByRole('button', { name: /Load/i }).first()).toBeVisible() + await expect(drawer.getByRole('button', { name: /Help/i }).first()).toBeVisible() + }) + + test('tapping a drawer action chip closes the drawer', async ({ page }) => { + await page.getByRole('button', { name: 'Open sidebar' }).click() + const drawer = page.getByTestId('mobile-drawer-panel') + await expect(drawer).toBeVisible() + await drawer.getByRole('button', { name: /Quicksave/i }).click() + await expect(drawer).toBeHidden() + }) +}) diff --git a/web/src/components/GameLayout.vue b/web/src/components/GameLayout.vue index 9462ca6..e8cd3cd 100644 --- a/web/src/components/GameLayout.vue +++ b/web/src/components/GameLayout.vue @@ -256,6 +256,11 @@ function closeMenus() { @close="showDrawer = false" @inventory-click="onInventoryClick" @spell-click="onSpellClick" + @quick-save="store.saveGame()" + @quick-load="store.loadGame()" + @save="onOpenSaveDialog" + @load="onOpenLoadDialog" + @help="onHelp" /> () -defineEmits<{ +const emit = defineEmits<{ close: [] inventoryClick: [event: MouseEvent, name: string] spellClick: [event: MouseEvent, name: string] + quickSave: [] + quickLoad: [] + save: [] + load: [] + help: [] }>() + +function emitAndClose( + action: 'quickSave' | 'quickLoad' | 'save' | 'load' | 'help', +) { + if (action === 'quickSave') emit('quickSave') + else if (action === 'quickLoad') emit('quickLoad') + else if (action === 'save') emit('save') + else if (action === 'load') emit('load') + else emit('help') + emit('close') +}