diff --git a/packages/playwright-core/src/web/traceViewer/ui/workbench.css b/packages/playwright-core/src/web/traceViewer/ui/workbench.css index a31c9574a0..2c982bb024 100644 --- a/packages/playwright-core/src/web/traceViewer/ui/workbench.css +++ b/packages/playwright-core/src/web/traceViewer/ui/workbench.css @@ -14,6 +14,17 @@ limitations under the License. */ +.drop-target { + display: flex; + align-items: center; + justify-content: center; + box-shadow: var(--box-shadow); + flex: auto; + font-size: 24px; + color: #666; + font-weight: bold; +} + .workbench { contain: size; user-select: none; diff --git a/packages/playwright-core/src/web/traceViewer/ui/workbench.tsx b/packages/playwright-core/src/web/traceViewer/ui/workbench.tsx index 744f8fcf19..701b0cb7c7 100644 --- a/packages/playwright-core/src/web/traceViewer/ui/workbench.tsx +++ b/packages/playwright-core/src/web/traceViewer/ui/workbench.tsx @@ -37,6 +37,18 @@ export const Workbench: React.FunctionComponent<{ const [highlightedAction, setHighlightedAction] = React.useState(); const [selectedTab, setSelectedTab] = React.useState('logs'); + const handleDropEvent = (event: any) => { + event.preventDefault(); + const blobTraceURL = URL.createObjectURL(event.dataTransfer.files[0]); + const url = new URL(window.location.href); + url.searchParams.set('trace', blobTraceURL); + const href = url.toString(); + // Snapshot loaders will inherit the trace url from the query parameters, + // so set it here. + window.history.pushState({}, '', href); + setTraceURL(blobTraceURL); + }; + React.useEffect(() => { (async () => { if (traceURL) { @@ -52,6 +64,21 @@ export const Workbench: React.FunctionComponent<{ const defaultSnapshotSize = contextEntry.options.viewport || { width: 1280, height: 720 }; const boundaries = { minimum: contextEntry.startTime, maximum: contextEntry.endTime }; + if (!traceURL) { + return
+
+
🎭
+
Playwright
+
+
+
{ event.preventDefault(); }} + onDrop={event => handleDropEvent(event)}> + Drop Playwright Trace here +
+
; + } + // Leave some nice free space on the right hand side. boundaries.maximum += (boundaries.maximum - boundaries.minimum) / 20; const { errors, warnings } = selectedAction ? modelUtil.stats(selectedAction) : { errors: 0, warnings: 0 }; @@ -60,17 +87,7 @@ export const Workbench: React.FunctionComponent<{ return
{ event.preventDefault(); }} - onDrop={event => { - event.preventDefault(); - const blobTraceURL = URL.createObjectURL(event.dataTransfer.files[0]); - const url = new URL(window.location.href); - url.searchParams.set('trace', blobTraceURL); - const href = url.toString(); - // Snapshot loaders will inherit the trace url from the query parameters, - // so set it here. - window.history.pushState({}, '', href); - setTraceURL(blobTraceURL); - }}> + onDrop={event => handleDropEvent(event)}>
🎭
Playwright