import '../support/polyfills'; import {DEFAULT_THEME} from '../../../src/defaults'; import {createOrUpdateDynamicTheme, removeDynamicTheme} from '../../../src/inject/dynamic-theme'; import {isFirefox, isSafari} from '../../../src/utils/platform'; import {multiline, timeout} from '../support/test-utils'; const theme = { ...DEFAULT_THEME, darkSchemeBackgroundColor: 'black', darkSchemeTextColor: 'white', }; let container: HTMLElement; beforeEach(() => { container = document.body; container.innerHTML = ''; }); afterEach(() => { removeDynamicTheme(); container.innerHTML = ''; }); describe('SHADOW DOM', () => { it('should add static overrides', async () => { container.innerHTML = multiline( '
', ); document.querySelector('.shadow-dom-wrapper')!.attachShadow({mode: 'open'}); createOrUpdateDynamicTheme(theme, null, false); const shadowRoot = document.querySelector('.shadow-dom-wrapper')!.shadowRoot!; expect(shadowRoot.firstElementChild!.classList.contains('darkreader--inline')).toBe(true); expect(shadowRoot.firstElementChild!.nextElementSibling!.classList.contains('darkreader--override')).toBe(true); expect(shadowRoot.firstElementChild!.nextElementSibling!.nextElementSibling!.classList.contains('darkreader--invert')).toBe(true); }); it('should override styles', async () => { container.innerHTML = multiline( '', ); const shadow = document.querySelector('.shadow-dom-wrapper')!.attachShadow({mode: 'open'}); const style = document.createElement('style'); style.classList.add('test-case-style'); shadow.appendChild(style); style.sheet!.insertRule('h1 { color: gray }'); style.sheet!.insertRule('strong { color: red }'); createOrUpdateDynamicTheme(theme, null, false); const shadowRoot = document.querySelector('.shadow-dom-wrapper')!.shadowRoot!; const testCase = shadowRoot.querySelector('.test-case-style')!; expect(testCase.nextElementSibling!.classList.contains('darkreader--sync')).toBe(true); expect((testCase.nextElementSibling as HTMLStyleElement).sheet!.cssRules.length).toBe(2); }); it('should react to DOM changes', async () => { container.innerHTML = multiline( '', ); const shadow = document.querySelector('.shadow-dom-wrapper')!.attachShadow({mode: 'open'}); createOrUpdateDynamicTheme(theme, null, false); const style = document.createElement('style'); style.classList.add('test-case-style'); shadow.appendChild(style); style.sheet!.insertRule('h1 { color: gray }'); style.sheet!.insertRule('strong { color: red }'); await timeout(0); const shadowRoot = document.querySelector('.shadow-dom-wrapper')!.shadowRoot!; const testCase = shadowRoot.querySelector('.test-case-style')!; expect(shadowRoot.firstElementChild!.classList.contains('darkreader--inline')).toBe(true); expect(shadowRoot.firstElementChild!.nextElementSibling!.classList.contains('darkreader--override')).toBe(true); expect(testCase.nextElementSibling!.classList.contains('darkreader--sync')).toBe(true); expect((testCase.nextElementSibling as HTMLStyleElement).sheet!.cssRules.length).toBe(2); }); it('should override inline styles', async () => { container.innerHTML = multiline( '', ); const shadow = document.querySelector('.shadow-dom-wrapper')!.attachShadow({mode: 'open'}); createOrUpdateDynamicTheme(theme, null, false); const standardElement = document.createElement('p'); standardElement.style.color = 'red'; shadow.appendChild(standardElement); await timeout(0); const shadowRoot = document.querySelector('.shadow-dom-wrapper')!.shadowRoot!; expect(getComputedStyle(shadowRoot.querySelector('p')!).color).toBe('rgb(255, 26, 26)'); }); it('should handle defined custom elements', async () => { container.innerHTML = multiline( '