test(06): add failing BottomTabBar hidden-on-desktop test (FIX 4)
This commit is contained in:
@@ -0,0 +1,82 @@
|
|||||||
|
/**
|
||||||
|
* BottomTabBar visibility test — verifies the bar is hidden on desktop (≥768px).
|
||||||
|
*
|
||||||
|
* FIX 4: BottomTabBar must be phone-only (≤767px). On desktop it was
|
||||||
|
* position:fixed bottom:0 with no hide rule, overlaying the Settings/avatar
|
||||||
|
* in AppNav's sidebar.
|
||||||
|
*
|
||||||
|
* The test environment's matchMedia polyfill (test-setup.ts) returns
|
||||||
|
* matches:false for all queries, simulating a desktop viewport.
|
||||||
|
* The BottomTabBar should NOT render on desktop.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import React from 'react'
|
||||||
|
import { describe, it, expect, vi, beforeEach } from 'vitest'
|
||||||
|
import { render, screen } from '@testing-library/react'
|
||||||
|
import { MemoryRouter } from 'react-router'
|
||||||
|
import { BottomTabBar } from './BottomTabBar.js'
|
||||||
|
|
||||||
|
describe('BottomTabBar visibility (FIX 4)', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
vi.clearAllMocks()
|
||||||
|
})
|
||||||
|
|
||||||
|
it('does NOT render on desktop (matchMedia max-width:767px returns false)', () => {
|
||||||
|
// test-setup.ts matchMedia polyfill returns matches:false for all queries
|
||||||
|
// → (max-width: 767px) matches false → desktop → BottomTabBar should not render
|
||||||
|
render(
|
||||||
|
<MemoryRouter>
|
||||||
|
<BottomTabBar />
|
||||||
|
</MemoryRouter>,
|
||||||
|
)
|
||||||
|
|
||||||
|
// The nav element should not be in the document on desktop
|
||||||
|
const nav = screen.queryByRole('navigation', { name: /Main navigation/i })
|
||||||
|
// BottomTabBar renders a <nav aria-label="Main navigation"> — on desktop it must be absent
|
||||||
|
// (note: AppNav also renders a <nav aria-label="Main navigation"> on desktop; but we're
|
||||||
|
// only rendering BottomTabBar here, so the absence confirms it returns null on desktop)
|
||||||
|
expect(nav).toBeNull()
|
||||||
|
})
|
||||||
|
|
||||||
|
it('renders on phone (matchMedia max-width:767px returns true)', () => {
|
||||||
|
// Override matchMedia to simulate phone
|
||||||
|
Object.defineProperty(window, 'matchMedia', {
|
||||||
|
writable: true,
|
||||||
|
value: (query: string) => ({
|
||||||
|
matches: query === '(max-width: 767px)',
|
||||||
|
media: query,
|
||||||
|
onchange: null,
|
||||||
|
addListener: () => undefined,
|
||||||
|
removeListener: () => undefined,
|
||||||
|
addEventListener: () => undefined,
|
||||||
|
removeEventListener: () => undefined,
|
||||||
|
dispatchEvent: () => false,
|
||||||
|
}),
|
||||||
|
})
|
||||||
|
|
||||||
|
render(
|
||||||
|
<MemoryRouter>
|
||||||
|
<BottomTabBar />
|
||||||
|
</MemoryRouter>,
|
||||||
|
)
|
||||||
|
|
||||||
|
// On phone, BottomTabBar nav must be present
|
||||||
|
const nav = screen.queryByRole('navigation', { name: /Main navigation/i })
|
||||||
|
expect(nav).not.toBeNull()
|
||||||
|
|
||||||
|
// Restore default (matches:false) for subsequent tests
|
||||||
|
Object.defineProperty(window, 'matchMedia', {
|
||||||
|
writable: true,
|
||||||
|
value: (query: string) => ({
|
||||||
|
matches: false,
|
||||||
|
media: query,
|
||||||
|
onchange: null,
|
||||||
|
addListener: () => undefined,
|
||||||
|
removeListener: () => undefined,
|
||||||
|
addEventListener: () => undefined,
|
||||||
|
removeEventListener: () => undefined,
|
||||||
|
dispatchEvent: () => false,
|
||||||
|
}),
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
Reference in New Issue
Block a user