diff --git a/packages/playwright-core/src/server/trace/recorder/snapshotterInjected.ts b/packages/playwright-core/src/server/trace/recorder/snapshotterInjected.ts index ee503eb043..458c393695 100644 --- a/packages/playwright-core/src/server/trace/recorder/snapshotterInjected.ts +++ b/packages/playwright-core/src/server/trace/recorder/snapshotterInjected.ts @@ -46,6 +46,7 @@ export function frameSnapshotStreamer(snapshotStreamer: string) { const kStyleSheetAttribute = '__playwright_style_sheet_'; const kTargetAttribute = '__playwright_target__'; const kCustomElementsAttribute = '__playwright_custom_elements__'; + const kCurrentSrcAttribute = '__playwright_current_src__'; // Symbols for our own info on Nodes/StyleSheets. const kSnapshotFrameId = Symbol('__playwright_snapshot_frameid_'); @@ -485,6 +486,14 @@ export function frameSnapshotStreamer(snapshotStreamer: string) { attrs[kCustomElementsAttribute] = value; } + // Process currentSrc before bailing out since it depends on JS, not the DOM. + if (nodeName === 'IMG' || nodeName === 'PICTURE') { + const value = nodeName === 'PICTURE' ? '' : this._sanitizeUrl((node as HTMLImageElement).currentSrc); + expectValue(kCurrentSrcAttribute); + expectValue(value); + attrs[kCurrentSrcAttribute] = value; + } + // We can skip attributes comparison because nothing else has changed, // and mutation observer didn't tell us about the attributes. if (equals && data.attributesCached && !shadowDomNesting) diff --git a/packages/trace-viewer/src/snapshotRenderer.ts b/packages/trace-viewer/src/snapshotRenderer.ts index e156dcbaf9..da0de98eb4 100644 --- a/packages/trace-viewer/src/snapshotRenderer.ts +++ b/packages/trace-viewer/src/snapshotRenderer.ts @@ -42,7 +42,7 @@ export class SnapshotRenderer { } render(): RenderedFrameSnapshot { - const visit = (n: NodeSnapshot, snapshotIndex: number, parentTag: string | undefined): string => { + const visit = (n: NodeSnapshot, snapshotIndex: number, parentTag: string | undefined, parentAttrs: [string, string][] | undefined): string => { // Text node. if (typeof n === 'string') { const text = escapeText(n); @@ -61,29 +61,45 @@ export class SnapshotRenderer { const nodes = snapshotNodes(this._snapshots[referenceIndex]); const nodeIndex = n[0][1]; if (nodeIndex >= 0 && nodeIndex < nodes.length) - (n as any)._string = visit(nodes[nodeIndex], referenceIndex, parentTag); + (n as any)._string = visit(nodes[nodeIndex], referenceIndex, parentTag, parentAttrs); } } else if (typeof n[0] === 'string') { // Element node. const builder: string[] = []; builder.push('<', n[0]); - // Never set relative URLs as