AT Mot — a bilingual (EN/FR) daily word game native to the AT Protocol.
0

Configure Feed

Select the types of activity you want to include in your feed.

at trunk 2.2 kB View raw
1// @vitest-environment happy-dom 2import { beforeEach, describe, expect, it } from 'vitest'; 3import { renderPlayView } from '../src/ui/playView.js'; 4import type { Ctx } from '../src/ui/context.js'; 5 6function makeCtx(session: Ctx['session'] = null): Ctx { 7 return { 8 lang: 'en', 9 session, 10 handle: null, 11 pendingRecord: null, 12 setLang() {}, 13 navigate() {}, 14 rerender() {}, 15 async signInWith() {}, 16 async signOut() {}, 17 }; 18} 19 20/** Index of the first top-level child of <main> matching `selector`. */ 21function childIndex(main: Element, selector: string): number { 22 const children = [...main.children]; 23 return children.findIndex((c) => c.matches(selector) || c.querySelector(selector) !== null); 24} 25 26describe('renderPlayView layout order', () => { 27 beforeEach(() => { 28 localStorage.clear(); 29 }); 30 31 // Regression for issue #2: the sign-in prompt used to sit between the board and 32 // the keyboard, pushing the keys off-screen on mobile. Tiles → keyboard → prompt. 33 it('renders the keyboard before the sign-in prompt while signed out', () => { 34 const root = document.createElement('div'); 35 renderPlayView(makeCtx(null), root); 36 37 const main = root.querySelector('main'); 38 expect(main).not.toBeNull(); 39 40 const boardIdx = childIndex(main!, '.board'); 41 const keyboardIdx = childIndex(main!, '.keyboard'); 42 const signInIdx = childIndex(main!, '.signin'); 43 44 expect(boardIdx).toBeGreaterThanOrEqual(0); 45 expect(keyboardIdx).toBeGreaterThan(boardIdx); 46 expect(signInIdx).toBeGreaterThan(keyboardIdx); 47 }); 48 49 // The header sign-in shortcut jumps to the inline bar so mobile players who 50 // miss the prompt below the keyboard can still reach it. 51 it('focuses the inline sign-in input when the header Sign in button is clicked', () => { 52 const root = document.createElement('div'); 53 document.body.replaceChildren(root); 54 renderPlayView(makeCtx(null), root); 55 56 const headerSignIn = [...root.querySelectorAll('header button')].find( 57 (b) => b.textContent === 'Sign in', 58 ) as HTMLButtonElement | undefined; 59 expect(headerSignIn).toBeDefined(); 60 61 headerSignIn!.click(); 62 expect(document.activeElement?.id).toBe('atmot-handle'); 63 }); 64});