chore: render browser window in trace (#18870)
This commit is contained in:
Родитель
2dc51f6c46
Коммит
228f78c89d
|
@ -20,6 +20,7 @@
|
|||
flex-direction: column;
|
||||
align-items: stretch;
|
||||
outline: none;
|
||||
--window-header-height: 40px;
|
||||
}
|
||||
|
||||
.snapshot-controls {
|
||||
|
@ -64,32 +65,68 @@
|
|||
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 {
|
||||
display: block;
|
||||
background: white;
|
||||
box-shadow: rgb(0 0 0 / 15%) 0px 0.1em 4.5em;
|
||||
box-shadow: 0 12px 28px 0 rgba(0,0,0,.2),0 2px 4px 0 rgba(0,0,0,.1);
|
||||
}
|
||||
|
||||
iframe#snapshot {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
height: calc(100% - var(--window-header-height));
|
||||
border: none;
|
||||
background: white;
|
||||
}
|
||||
|
||||
.no-snapshot {
|
||||
text-align: center;
|
||||
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]);
|
||||
|
||||
const windowHeaderHeight = 40;
|
||||
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 = {
|
||||
width: snapshotSize.width * scale,
|
||||
height: snapshotSize.height * scale,
|
||||
height: (snapshotSize.height + windowHeaderHeight) * scale,
|
||||
};
|
||||
return <div
|
||||
className='snapshot-tab'
|
||||
|
@ -102,13 +103,27 @@ export const SnapshotTab: React.FunctionComponent<{
|
|||
</div>;
|
||||
})}
|
||||
</div>
|
||||
<div className='snapshot-url' title={snapshotInfo.url}>{snapshotInfo.url}</div>
|
||||
<div ref={ref} className='snapshot-wrapper'>
|
||||
{ snapshots.length ? <div className='snapshot-container' style={{
|
||||
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})`,
|
||||
}}>
|
||||
<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>
|
||||
</div> : <div className='no-snapshot'>Action does not have snapshots</div>
|
||||
}
|
||||
|
|
|
@ -51,7 +51,7 @@ class TraceViewerPage {
|
|||
this.consoleStacks = page.locator('.console-stack');
|
||||
this.stackFrames = page.locator('.stack-trace-frame');
|
||||
this.networkRequests = page.locator('.network-request-title');
|
||||
this.snapshotContainer = page.locator('.snapshot-container');
|
||||
this.snapshotContainer = page.locator('.snapshot-container iframe');
|
||||
}
|
||||
|
||||
async actionIconsText(action: string) {
|
||||
|
|
|
@ -204,7 +204,7 @@ test('should show snapshot URL', async ({ page, runAndTrace, server }) => {
|
|||
await page.evaluate('2+2');
|
||||
});
|
||||
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 }) => {
|
||||
|
|
Загрузка…
Ссылка в новой задаче