Skip to content

Commit 8c66649

Browse files
authored
test(query-devtools/contexts/PiPContext): add tests for 'requestPipWindow' copying parent stylesheets into the PiP document head (TanStack#10800)
1 parent 1b7d28a commit 8c66649

1 file changed

Lines changed: 86 additions & 0 deletions

File tree

packages/query-devtools/src/__tests__/contexts/PiPContext.test.tsx

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,4 +145,90 @@ describe('PiPContext', () => {
145145
expect(pipDocument.body.querySelector('#leftover')).toBeNull()
146146
})
147147
})
148+
149+
describe('styleSheet propagation', () => {
150+
type FakeCssRule = { readonly cssText: string }
151+
type FakeStyleSheet = {
152+
readonly cssRules?: ArrayLike<FakeCssRule>
153+
readonly href?: string | null
154+
readonly type?: string
155+
readonly media?: { toString: () => string }
156+
readonly ownerNode?: Element | null
157+
}
158+
159+
function makeCssRules(...cssTexts: Array<string>): ArrayLike<FakeCssRule> {
160+
return cssTexts.map((cssText) => ({ cssText }))
161+
}
162+
163+
function stubParentStyleSheet(sheet: FakeStyleSheet) {
164+
return vi
165+
.spyOn(document, 'styleSheets', 'get')
166+
.mockReturnValue([sheet] as unknown as StyleSheetList)
167+
}
168+
169+
it('should copy parent stylesheets as "<style>" with the same id into the PiP document head', () => {
170+
const sourceStyle = document.createElement('style')
171+
sourceStyle.id = 'tsqd-source'
172+
const sheetSpy = stubParentStyleSheet({
173+
cssRules: makeCssRules('.tsqd { color: red; }'),
174+
ownerNode: sourceStyle,
175+
})
176+
const { pipDocument } = stubPipWindow()
177+
178+
try {
179+
renderAndAct((pip) => pip().requestPipWindow(640, 480))
180+
181+
const copied = pipDocument.head.querySelector('style#tsqd-source')
182+
expect(copied).not.toBeNull()
183+
expect(copied?.textContent).toBe('.tsqd { color: red; }')
184+
} finally {
185+
sheetSpy.mockRestore()
186+
}
187+
})
188+
189+
it('should fall back to a "<link>" for cross-origin stylesheets whose "cssRules" throw', () => {
190+
const sheetSpy = stubParentStyleSheet({
191+
get cssRules(): CSSRuleList {
192+
throw new DOMException('blocked', 'SecurityError')
193+
},
194+
href: 'https://example.com/external.css',
195+
type: 'text/css',
196+
media: { toString: () => 'all' },
197+
})
198+
const { pipDocument } = stubPipWindow()
199+
200+
try {
201+
renderAndAct((pip) => pip().requestPipWindow(640, 480))
202+
203+
const link = pipDocument.head.querySelector<HTMLLinkElement>(
204+
'link[href="https://example.com/external.css"]',
205+
)
206+
expect(link).not.toBeNull()
207+
expect(link?.rel).toBe('stylesheet')
208+
} finally {
209+
sheetSpy.mockRestore()
210+
}
211+
})
212+
213+
it('should skip the "<link>" fallback when the cross-origin stylesheet has no "href"', () => {
214+
const sheetSpy = stubParentStyleSheet({
215+
get cssRules(): CSSRuleList {
216+
throw new DOMException('blocked', 'SecurityError')
217+
},
218+
href: null,
219+
type: 'text/css',
220+
media: { toString: () => 'all' },
221+
})
222+
const { pipDocument } = stubPipWindow()
223+
224+
try {
225+
renderAndAct((pip) => pip().requestPipWindow(640, 480))
226+
227+
expect(pipDocument.head.querySelector('link')).toBeNull()
228+
expect(pipDocument.head.querySelector('style')).toBeNull()
229+
} finally {
230+
sheetSpy.mockRestore()
231+
}
232+
})
233+
})
148234
})

0 commit comments

Comments
 (0)