mirror of
https://github.com/microsoft/playwright.git
synced 2025-01-07 11:46:42 +03:00
fix(trace): account for last child node removal (#7332)
This commit is contained in:
parent
ec47b03722
commit
02538fb587
@ -44,6 +44,7 @@ export function frameSnapshotStreamer(snapshotStreamer: string) {
|
|||||||
// Symbols for our own info on Nodes/StyleSheets.
|
// Symbols for our own info on Nodes/StyleSheets.
|
||||||
const kSnapshotFrameId = Symbol('__playwright_snapshot_frameid_');
|
const kSnapshotFrameId = Symbol('__playwright_snapshot_frameid_');
|
||||||
const kCachedData = Symbol('__playwright_snapshot_cache_');
|
const kCachedData = Symbol('__playwright_snapshot_cache_');
|
||||||
|
const kEndOfList = Symbol('__playwright_end_of_list_');
|
||||||
type CachedData = {
|
type CachedData = {
|
||||||
cached?: any[], // Cached values to determine whether the snapshot will be the same.
|
cached?: any[], // Cached values to determine whether the snapshot will be the same.
|
||||||
ref?: [number, number], // Previous snapshotNumber and nodeIndex.
|
ref?: [number, number], // Previous snapshotNumber and nodeIndex.
|
||||||
@ -355,6 +356,7 @@ export function frameSnapshotStreamer(snapshotStreamer: string) {
|
|||||||
}
|
}
|
||||||
for (let child = node.firstChild; child; child = child.nextSibling)
|
for (let child = node.firstChild; child; child = child.nextSibling)
|
||||||
visitChild(child);
|
visitChild(child);
|
||||||
|
expectValue(kEndOfList);
|
||||||
let documentOrShadowRoot = null;
|
let documentOrShadowRoot = null;
|
||||||
if (node.ownerDocument!.documentElement === node)
|
if (node.ownerDocument!.documentElement === node)
|
||||||
documentOrShadowRoot = node.ownerDocument;
|
documentOrShadowRoot = node.ownerDocument;
|
||||||
@ -363,20 +365,19 @@ export function frameSnapshotStreamer(snapshotStreamer: string) {
|
|||||||
if (documentOrShadowRoot) {
|
if (documentOrShadowRoot) {
|
||||||
for (const sheet of (documentOrShadowRoot as any).adoptedStyleSheets || [])
|
for (const sheet of (documentOrShadowRoot as any).adoptedStyleSheets || [])
|
||||||
visitChildStyleSheet(sheet);
|
visitChildStyleSheet(sheet);
|
||||||
|
expectValue(kEndOfList);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Process iframe src attribute before bailing out since it depends on a symbol, not the DOM.
|
// Process iframe src attribute before bailing out since it depends on a symbol, not the DOM.
|
||||||
if (nodeName === 'IFRAME' || nodeName === 'FRAME') {
|
if (nodeName === 'IFRAME' || nodeName === 'FRAME') {
|
||||||
const element = node as Element;
|
const element = node as Element;
|
||||||
for (let i = 0; i < element.attributes.length; i++) {
|
const frameId = (element as any)[kSnapshotFrameId];
|
||||||
const frameId = (element as any)[kSnapshotFrameId];
|
const name = 'src';
|
||||||
const name = 'src';
|
const value = frameId ? `/snapshot/${frameId}` : '';
|
||||||
const value = frameId ? `/snapshot/${frameId}` : '';
|
expectValue(name);
|
||||||
expectValue(name);
|
expectValue(value);
|
||||||
expectValue(value);
|
attrs[name] = value;
|
||||||
attrs[name] = value;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// We can skip attributes comparison because nothing else has changed,
|
// We can skip attributes comparison because nothing else has changed,
|
||||||
@ -409,6 +410,7 @@ export function frameSnapshotStreamer(snapshotStreamer: string) {
|
|||||||
expectValue(value);
|
expectValue(value);
|
||||||
attrs[name] = value;
|
attrs[name] = value;
|
||||||
}
|
}
|
||||||
|
expectValue(kEndOfList);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (result.length === 2 && !Object.keys(attrs).length)
|
if (result.length === 2 && !Object.keys(attrs).length)
|
||||||
|
@ -75,6 +75,26 @@ it.describe('snapshots', () => {
|
|||||||
expect(distillSnapshot(snapshot2)).toBe('<style>button { color: blue; }</style><BUTTON>Hello</BUTTON>');
|
expect(distillSnapshot(snapshot2)).toBe('<style>button { color: blue; }</style><BUTTON>Hello</BUTTON>');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should respect node removal', async ({ page, toImpl, snapshotter }) => {
|
||||||
|
page.on('console', console.log);
|
||||||
|
await page.setContent('<div><button id="button1"></button><button id="button2"></button></div>');
|
||||||
|
const snapshot1 = await snapshotter.captureSnapshot(toImpl(page), 'snapshot1');
|
||||||
|
expect(distillSnapshot(snapshot1)).toBe('<DIV><BUTTON id=\"button1\"></BUTTON><BUTTON id=\"button2\"></BUTTON></DIV>');
|
||||||
|
await page.evaluate(() => document.getElementById('button2').remove());
|
||||||
|
const snapshot2 = await snapshotter.captureSnapshot(toImpl(page), 'snapshot2');
|
||||||
|
expect(distillSnapshot(snapshot2)).toBe('<DIV><BUTTON id=\"button1\"></BUTTON></DIV>');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should respect attr removal', async ({ page, toImpl, snapshotter }) => {
|
||||||
|
page.on('console', console.log);
|
||||||
|
await page.setContent('<div id="div" attr1="1" attr2="2"></div>');
|
||||||
|
const snapshot1 = await snapshotter.captureSnapshot(toImpl(page), 'snapshot1');
|
||||||
|
expect(distillSnapshot(snapshot1)).toBe('<DIV id=\"div\" attr1=\"1\" attr2=\"2\"></DIV>');
|
||||||
|
await page.evaluate(() => document.getElementById('div').removeAttribute('attr2'));
|
||||||
|
const snapshot2 = await snapshotter.captureSnapshot(toImpl(page), 'snapshot2');
|
||||||
|
expect(distillSnapshot(snapshot2)).toBe('<DIV id=\"div\" attr1=\"1\"></DIV>');
|
||||||
|
});
|
||||||
|
|
||||||
it('should have a custom doctype', async ({page, server, toImpl, snapshotter}) => {
|
it('should have a custom doctype', async ({page, server, toImpl, snapshotter}) => {
|
||||||
await page.goto(server.EMPTY_PAGE);
|
await page.goto(server.EMPTY_PAGE);
|
||||||
await page.setContent('<!DOCTYPE foo><body>hi</body>');
|
await page.setContent('<!DOCTYPE foo><body>hi</body>');
|
||||||
|
Loading…
Reference in New Issue
Block a user