fix(trace viewer): make sure target inside shadow dom is highlighted (#26823)

References #24532.
This commit is contained in:
Dmitry Gozman 2023-08-31 12:46:49 -07:00 committed by GitHub
parent c92ad10f60
commit 741c649d56
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 29 additions and 9 deletions

View File

@ -1133,7 +1133,7 @@ export class InjectedScript {
bubbles: true,
cancelable: true,
detail: callId,
composed: false,
composed: true,
});
for (const element of markedElements)
element.dispatchEvent(customEvent);

View File

@ -114,7 +114,7 @@ export class Snapshotter {
bubbles: true,
cancelable: true,
detail: callId,
composed: false,
composed: true,
});
element.dispatchEvent(customEvent);
}, callId);

View File

@ -136,7 +136,7 @@ export function frameSnapshotStreamer(snapshotStreamer: string) {
if (!event.detail)
return;
const callId = event.detail as string;
(event.target as any).__playwright_target__ = callId;
(event.composedPath()[0] as any).__playwright_target__ = callId;
});
}

View File

@ -104,9 +104,7 @@ export class SnapshotRenderer {
const prefix = snapshot.doctype ? `<!DOCTYPE ${snapshot.doctype}>` : '';
html = prefix + [
'<style>*,*::before,*::after { visibility: hidden }</style>',
`<style>*[__playwright_target__="${this.snapshotName}"] { outline: 2px solid #006ab1 !important; background-color: #6fa8dc7f !important; }</style>`,
`<style>*[__playwright_target__="${this._callId}"] { outline: 2px solid #006ab1 !important; background-color: #6fa8dc7f !important; }</style>`,
`<script>${snapshotScript()}</script>`
`<script>${snapshotScript(this._callId, this.snapshotName)}</script>`
].join('') + html;
return { html, pageId: snapshot.pageId, frameId: snapshot.frameId, index: this._index };
@ -195,8 +193,8 @@ function snapshotNodes(snapshot: FrameSnapshot): NodeSnapshot[] {
return (snapshot as any)._nodes;
}
function snapshotScript() {
function applyPlaywrightAttributes(unwrapPopoutUrl: (url: string) => string) {
function snapshotScript(...targetIds: (string | undefined)[]) {
function applyPlaywrightAttributes(unwrapPopoutUrl: (url: string) => string, ...targetIds: (string | undefined)[]) {
const scrollTops: Element[] = [];
const scrollLefts: Element[] = [];
@ -220,6 +218,14 @@ function snapshotScript() {
element.removeAttribute('__playwright_selected_');
}
for (const targetId of targetIds) {
for (const target of root.querySelectorAll(`[__playwright_target__="${targetId}"]`)) {
const style = (target as HTMLElement).style;
style.outline = '2px solid #006ab1';
style.backgroundColor = '#6fa8dc7f';
}
}
for (const iframe of root.querySelectorAll('iframe, frame')) {
const src = iframe.getAttribute('__playwright_src__');
if (!src) {
@ -303,7 +309,7 @@ function snapshotScript() {
window.addEventListener('DOMContentLoaded', onDOMContentLoaded);
}
return `\n(${applyPlaywrightAttributes.toString()})(${unwrapPopoutUrl.toString()})`;
return `\n(${applyPlaywrightAttributes.toString()})(${unwrapPopoutUrl.toString()}${targetIds.map(id => `, "${id}"`).join('')})`;
}

View File

@ -630,6 +630,20 @@ test('should highlight target elements', async ({ page, runAndTrace, browserName
await expect.poll(() => highlightedDivs(frameExpect2)).toEqual(['multi', 'multi']);
});
test('should highlight target element in shadow dom', async ({ page, server, runAndTrace }) => {
const traceViewer = await runAndTrace(async () => {
await page.goto(server.PREFIX + '/shadow.html');
await page.locator('button').click();
await expect(page.locator('h1')).toHaveText('Hellow Shadow DOM v1');
});
const framePageClick = await traceViewer.snapshotFrame('locator.click');
await expect(framePageClick.locator('button')).toHaveCSS('background-color', 'rgba(111, 168, 220, 0.498)');
const frameExpect = await traceViewer.snapshotFrame('expect.toHaveText');
await expect(frameExpect.locator('h1')).toHaveCSS('background-color', 'rgba(111, 168, 220, 0.498)');
});
test('should show action source', async ({ showTraceViewer }) => {
const traceViewer = await showTraceViewer([traceFile]);
await traceViewer.selectAction('locator.click');