Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
SeleniumHQ
GitHub Repository: SeleniumHQ/Selenium
Path: blob/trunk/javascript/grid-ui/src/tests/components/ThemeToggle.test.tsx
1989 views
1
// Licensed to the Software Freedom Conservancy (SFC) under one
2
// or more contributor license agreements. See the NOTICE file
3
// distributed with this work for additional information
4
// regarding copyright ownership. The SFC licenses this file
5
// to you under the Apache License, Version 2.0 (the
6
// "License"); you may not use this file except in compliance
7
// with the License. You may obtain a copy of the License at
8
//
9
// http://www.apache.org/licenses/LICENSE-2.0
10
//
11
// Unless required by applicable law or agreed to in writing,
12
// software distributed under the License is distributed on an
13
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14
// KIND, either express or implied. See the License for the
15
// specific language governing permissions and limitations
16
// under the License.
17
18
import React from 'react'
19
import { render, screen, fireEvent } from '@testing-library/react'
20
import { ThemeToggle } from '../../components/ThemeToggle/ThemeToggle'
21
import { CustomThemeProvider } from '../../contexts/ThemeContext'
22
23
const mockMatchMedia = (matches: boolean) => ({
24
matches,
25
addEventListener: jest.fn(),
26
removeEventListener: jest.fn()
27
})
28
29
beforeEach(() => {
30
Object.defineProperty(window, 'matchMedia', {
31
writable: true,
32
value: jest.fn().mockImplementation(() => mockMatchMedia(false))
33
})
34
})
35
36
it('cycles through theme modes on click', () => {
37
render(
38
<CustomThemeProvider>
39
<ThemeToggle />
40
</CustomThemeProvider>
41
)
42
43
const button = screen.getByRole('button')
44
45
// Should start with system mode (AutoMode icon)
46
expect(button).toHaveAttribute('aria-label', 'Toggle theme')
47
expect(screen.getByTestId('AutoModeIcon')).toBeInTheDocument()
48
49
// Click to light mode
50
fireEvent.click(button)
51
expect(screen.getByTestId('LightModeIcon')).toBeInTheDocument()
52
expect(screen.queryByTestId('AutoModeIcon')).not.toBeInTheDocument()
53
54
// Click to dark mode
55
fireEvent.click(button)
56
expect(screen.getByTestId('DarkModeIcon')).toBeInTheDocument()
57
expect(screen.queryByTestId('LightModeIcon')).not.toBeInTheDocument()
58
59
// Click back to system mode
60
fireEvent.click(button)
61
expect(screen.getByTestId('AutoModeIcon')).toBeInTheDocument()
62
expect(screen.queryByTestId('DarkModeIcon')).not.toBeInTheDocument()
63
})
64
65
it('responds to system preference changes', () => {
66
const listeners: Array<(e: any) => void> = []
67
const mockMediaQuery = {
68
matches: false,
69
addEventListener: jest.fn((_, handler) => listeners.push(handler)),
70
removeEventListener: jest.fn()
71
}
72
73
window.matchMedia = jest.fn(() => mockMediaQuery)
74
75
render(
76
<CustomThemeProvider>
77
<ThemeToggle />
78
</CustomThemeProvider>
79
)
80
81
// Simulate system preference change
82
listeners.forEach(listener => listener({ matches: true }))
83
84
expect(mockMediaQuery.addEventListener).toHaveBeenCalledWith('change', expect.any(Function))
85
})
86