chore: render browser window in trace (#18870)
This commit is contained in:
parent
2dc51f6c46
commit
228f78c89d
|
|
@ -20,6 +20,7 @@
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: stretch;
|
align-items: stretch;
|
||||||
outline: none;
|
outline: none;
|
||||||
|
--window-header-height: 40px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.snapshot-controls {
|
.snapshot-controls {
|
||||||
|
|
@ -64,32 +65,68 @@
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.snapshot-url {
|
|
||||||
color: var(--vscode-input-foreground);
|
|
||||||
background-color: var(--vscode-input-background);
|
|
||||||
margin: 10px;
|
|
||||||
padding: 4px;
|
|
||||||
height: 28px;
|
|
||||||
white-space: nowrap;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
overflow: hidden;
|
|
||||||
display: block;
|
|
||||||
flex: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.snapshot-container {
|
.snapshot-container {
|
||||||
display: block;
|
display: block;
|
||||||
background: white;
|
box-shadow: 0 12px 28px 0 rgba(0,0,0,.2),0 2px 4px 0 rgba(0,0,0,.1);
|
||||||
box-shadow: rgb(0 0 0 / 15%) 0px 0.1em 4.5em;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
iframe#snapshot {
|
iframe#snapshot {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: calc(100% - var(--window-header-height));
|
||||||
border: none;
|
border: none;
|
||||||
|
background: white;
|
||||||
}
|
}
|
||||||
|
|
||||||
.no-snapshot {
|
.no-snapshot {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
padding: 50px;
|
padding: 50px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.window-dot {
|
||||||
|
border-radius: 50%;
|
||||||
|
display: inline-block;
|
||||||
|
height: 12px;
|
||||||
|
margin-right: 6px;
|
||||||
|
margin-top: 4px;
|
||||||
|
width: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.window-address-bar {
|
||||||
|
background-color: white;
|
||||||
|
border-radius: 12.5px;
|
||||||
|
color: #1c1e21;
|
||||||
|
flex: 1 0;
|
||||||
|
font: 400 13px Arial,sans-serif;
|
||||||
|
margin: 0 16px 0 8px;
|
||||||
|
padding: 5px 15px;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
body.dark-mode .window-address-bar {
|
||||||
|
background-color: #1b1b1d;
|
||||||
|
color: #e3e3e3;
|
||||||
|
}
|
||||||
|
|
||||||
|
.window-menu-bar {
|
||||||
|
background-color: #aaa;
|
||||||
|
display: block;
|
||||||
|
height: 3px;
|
||||||
|
margin: 3px 0;
|
||||||
|
width: 17px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.window-header {
|
||||||
|
align-items: center;
|
||||||
|
background: #ebedf0;
|
||||||
|
display: flex;
|
||||||
|
padding: 8px 16px;
|
||||||
|
border-top-left-radius: 6px;
|
||||||
|
border-top-right-radius: 6px;
|
||||||
|
height: var(--window-header-height);
|
||||||
|
}
|
||||||
|
|
||||||
|
body.dark-mode .window-header {
|
||||||
|
background: #444950;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -78,11 +78,12 @@ export const SnapshotTab: React.FunctionComponent<{
|
||||||
})();
|
})();
|
||||||
}, [iframeRef, snapshotUrl, snapshotInfoUrl, pointX, pointY]);
|
}, [iframeRef, snapshotUrl, snapshotInfoUrl, pointX, pointY]);
|
||||||
|
|
||||||
|
const windowHeaderHeight = 40;
|
||||||
const snapshotSize = snapshotInfo.viewport;
|
const snapshotSize = snapshotInfo.viewport;
|
||||||
const scale = Math.min(measure.width / snapshotSize.width, measure.height / snapshotSize.height, 1);
|
const scale = Math.min(measure.width / snapshotSize.width, measure.height / (snapshotSize.height + windowHeaderHeight), 1);
|
||||||
const scaledSize = {
|
const scaledSize = {
|
||||||
width: snapshotSize.width * scale,
|
width: snapshotSize.width * scale,
|
||||||
height: snapshotSize.height * scale,
|
height: (snapshotSize.height + windowHeaderHeight) * scale,
|
||||||
};
|
};
|
||||||
return <div
|
return <div
|
||||||
className='snapshot-tab'
|
className='snapshot-tab'
|
||||||
|
|
@ -102,13 +103,27 @@ export const SnapshotTab: React.FunctionComponent<{
|
||||||
</div>;
|
</div>;
|
||||||
})}
|
})}
|
||||||
</div>
|
</div>
|
||||||
<div className='snapshot-url' title={snapshotInfo.url}>{snapshotInfo.url}</div>
|
|
||||||
<div ref={ref} className='snapshot-wrapper'>
|
<div ref={ref} className='snapshot-wrapper'>
|
||||||
{ snapshots.length ? <div className='snapshot-container' style={{
|
{ snapshots.length ? <div className='snapshot-container' style={{
|
||||||
width: snapshotSize.width + 'px',
|
width: snapshotSize.width + 'px',
|
||||||
height: snapshotSize.height + 'px',
|
height: (snapshotSize.height + windowHeaderHeight) + 'px',
|
||||||
transform: `translate(${-snapshotSize.width * (1 - scale) / 2 + (measure.width - scaledSize.width) / 2}px, ${-snapshotSize.height * (1 - scale) / 2 + (measure.height - scaledSize.height) / 2}px) scale(${scale})`,
|
transform: `translate(${-snapshotSize.width * (1 - scale) / 2 + (measure.width - scaledSize.width) / 2}px, ${-snapshotSize.height * (1 - scale) / 2 + (measure.height - scaledSize.height) / 2}px) scale(${scale})`,
|
||||||
}}>
|
}}>
|
||||||
|
<div className='window-header'>
|
||||||
|
<div style={{ whiteSpace: 'nowrap' }}>
|
||||||
|
<span className='window-dot' style={{ backgroundColor: 'rgb(242, 95, 88)' }}></span>
|
||||||
|
<span className='window-dot' style={{ backgroundColor: 'rgb(251, 190, 60)' }}></span>
|
||||||
|
<span className='window-dot' style={{ backgroundColor: 'rgb(88, 203, 66)' }}></span>
|
||||||
|
</div>
|
||||||
|
<div className='window-address-bar' title={snapshotInfo.url}>{snapshotInfo.url}</div>
|
||||||
|
<div style={{ marginLeft: 'auto' }}>
|
||||||
|
<div>
|
||||||
|
<span className='window-menu-bar'></span>
|
||||||
|
<span className='window-menu-bar'></span>
|
||||||
|
<span className='window-menu-bar'></span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<iframe ref={iframeRef} id='snapshot' name='snapshot'></iframe>
|
<iframe ref={iframeRef} id='snapshot' name='snapshot'></iframe>
|
||||||
</div> : <div className='no-snapshot'>Action does not have snapshots</div>
|
</div> : <div className='no-snapshot'>Action does not have snapshots</div>
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -51,7 +51,7 @@ class TraceViewerPage {
|
||||||
this.consoleStacks = page.locator('.console-stack');
|
this.consoleStacks = page.locator('.console-stack');
|
||||||
this.stackFrames = page.locator('.stack-trace-frame');
|
this.stackFrames = page.locator('.stack-trace-frame');
|
||||||
this.networkRequests = page.locator('.network-request-title');
|
this.networkRequests = page.locator('.network-request-title');
|
||||||
this.snapshotContainer = page.locator('.snapshot-container');
|
this.snapshotContainer = page.locator('.snapshot-container iframe');
|
||||||
}
|
}
|
||||||
|
|
||||||
async actionIconsText(action: string) {
|
async actionIconsText(action: string) {
|
||||||
|
|
|
||||||
|
|
@ -204,7 +204,7 @@ test('should show snapshot URL', async ({ page, runAndTrace, server }) => {
|
||||||
await page.evaluate('2+2');
|
await page.evaluate('2+2');
|
||||||
});
|
});
|
||||||
await traceViewer.snapshotFrame('page.evaluate');
|
await traceViewer.snapshotFrame('page.evaluate');
|
||||||
await expect(traceViewer.page.locator('.snapshot-url')).toHaveText(server.EMPTY_PAGE);
|
await expect(traceViewer.page.locator('.window-address-bar')).toHaveText(server.EMPTY_PAGE);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should capture iframe with sandbox attribute', async ({ page, server, runAndTrace }) => {
|
test('should capture iframe with sandbox attribute', async ({ page, server, runAndTrace }) => {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue