fix(trace viewer): preserve dialog.showModal() elements (#35231)

This commit is contained in:
Dmitry Gozman 2025-03-17 14:57:43 +00:00 committed by GitHub
parent ced9abeb22
commit 195fe11e1b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 43 additions and 0 deletions

View File

@ -49,6 +49,7 @@ export function frameSnapshotStreamer(snapshotStreamer: string, removeNoScript:
const kCurrentSrcAttribute = '__playwright_current_src__';
const kBoundingRectAttribute = '__playwright_bounding_rect__';
const kPopoverOpenAttribute = '__playwright_popover_open_';
const kDialogOpenAttribute = '__playwright_dialog_open_';
// Symbols for our own info on Nodes/StyleSheets.
const kSnapshotFrameId = Symbol('__playwright_snapshot_frameid_');
@ -456,6 +457,12 @@ export function frameSnapshotStreamer(snapshotStreamer: string, removeNoScript:
expectValue(value);
attrs[kPopoverOpenAttribute] = value;
}
if (nodeName === 'DIALOG' && (element as HTMLDialogElement).open) {
const value = (element as HTMLDialogElement).matches(':modal') ? 'modal' : 'true';
expectValue(kDialogOpenAttribute);
expectValue(value);
attrs[kDialogOpenAttribute] = value;
}
if (element.scrollTop) {
expectValue(kScrollTopAttribute);
expectValue(element.scrollTop);
@ -542,6 +549,8 @@ export function frameSnapshotStreamer(snapshotStreamer: string, removeNoScript:
continue;
if (nodeName === 'FRAME' && name === 'src')
continue;
if (nodeName === 'DIALOG' && name === 'open')
continue;
let value = element.attributes[i].value;
if (nodeName === 'META')
value = this.__sanitizeMetaAttribute(name, value, (node as HTMLMetaElement).httpEquiv);

View File

@ -313,6 +313,16 @@ function snapshotScript(viewport: ViewportSize, ...targetIds: (string | undefine
}
element.removeAttribute('__playwright_popover_open_');
}
for (const element of root.querySelectorAll(`[__playwright_dialog_open_]`)) {
try {
if (element.getAttribute('__playwright_dialog_open_') === 'modal')
(element as HTMLDialogElement).showModal();
else
(element as HTMLDialogElement).show();
} catch {
}
element.removeAttribute('__playwright_dialog_open_');
}
for (const targetId of targetIds) {
for (const target of root.querySelectorAll(`[__playwright_target__="${targetId}"]`)) {

View File

@ -1694,6 +1694,30 @@ test('should show a popover', async ({ runAndTrace, page, server, platform, brow
await expect.poll(() => popover.evaluate(e => e.matches(':popover-open'))).toBe(true);
});
test('should show a modal dialog', async ({ runAndTrace, page, platform, browserName, macVersion }) => {
test.skip(platform === 'darwin' && macVersion === 13 && browserName === 'webkit', 'WebKit on macOS 13.7 reliably fails on this test for some reason');
const traceViewer = await runAndTrace(async () => {
await page.setContent(`
<button>Show the dialog</button>
<dialog>
<p>This is a modal dialog</p>
</dialog>
<script>
document.querySelector('button').addEventListener('click', () => {
document.querySelector('dialog').showModal();
});
</script>
`);
await page.getByRole('button').click();
await expect(page.locator('p')).toBeVisible();
});
const snapshot = await traceViewer.snapshotFrame('expect.toBeVisible');
const dialog = snapshot.locator('dialog');
await expect.poll(() => dialog.evaluate(e => e.matches(':open'))).toBe(true);
await expect.poll(() => dialog.evaluate(e => e.matches(':modal'))).toBe(true);
});
test('should open settings dialog', async ({ showTraceViewer }) => {
const traceViewer = await showTraceViewer([traceFile]);
await traceViewer.selectAction('http://localhost');