mirror of
https://github.com/microsoft/playwright.git
synced 2025-06-26 21:40:17 +00:00
fix(trace viewer): make red dot to the center of the target element (#26825)
Also make sure red dot is visible in the popout tab. Fixes #24532.
This commit is contained in:
parent
fa286de0b3
commit
f3c02a5b4f
@ -197,6 +197,7 @@ function snapshotScript(...targetIds: (string | undefined)[]) {
|
||||
function applyPlaywrightAttributes(unwrapPopoutUrl: (url: string) => string, ...targetIds: (string | undefined)[]) {
|
||||
const scrollTops: Element[] = [];
|
||||
const scrollLefts: Element[] = [];
|
||||
const targetElements: Element[] = [];
|
||||
|
||||
const visit = (root: Document | ShadowRoot) => {
|
||||
// Collect all scrolled elements for later use.
|
||||
@ -223,6 +224,7 @@ function snapshotScript(...targetIds: (string | undefined)[]) {
|
||||
const style = (target as HTMLElement).style;
|
||||
style.outline = '2px solid #006ab1';
|
||||
style.backgroundColor = '#6fa8dc7f';
|
||||
targetElements.push(target);
|
||||
}
|
||||
}
|
||||
|
||||
@ -231,10 +233,8 @@ function snapshotScript(...targetIds: (string | undefined)[]) {
|
||||
if (!src) {
|
||||
iframe.setAttribute('src', 'data:text/html,<body style="background: #ddd"></body>');
|
||||
} else {
|
||||
// Append query parameters to inherit ?name= or ?time= values from parent.
|
||||
// Retain query parameters to inherit name=, time=, showPoint= and other values from parent.
|
||||
const url = new URL(unwrapPopoutUrl(window.location.href));
|
||||
url.searchParams.delete('pointX');
|
||||
url.searchParams.delete('pointY');
|
||||
// We can be loading iframe from within iframe, reset base to be absolute.
|
||||
const index = url.pathname.lastIndexOf('/snapshot/');
|
||||
if (index !== -1)
|
||||
@ -284,23 +284,25 @@ function snapshotScript(...targetIds: (string | undefined)[]) {
|
||||
element.removeAttribute('__playwright_scroll_left_');
|
||||
}
|
||||
|
||||
const search = new URL(window.location.href).searchParams;
|
||||
const pointX = search.get('pointX');
|
||||
const pointY = search.get('pointY');
|
||||
if (pointX) {
|
||||
const pointElement = document.createElement('x-pw-pointer');
|
||||
pointElement.style.position = 'fixed';
|
||||
pointElement.style.backgroundColor = '#f44336';
|
||||
pointElement.style.width = '20px';
|
||||
pointElement.style.height = '20px';
|
||||
pointElement.style.borderRadius = '10px';
|
||||
pointElement.style.margin = '-10px 0 0 -10px';
|
||||
pointElement.style.zIndex = '2147483647';
|
||||
pointElement.style.left = pointX + 'px';
|
||||
pointElement.style.top = pointY + 'px';
|
||||
document.documentElement.appendChild(pointElement);
|
||||
}
|
||||
document.styleSheets[0].disabled = true;
|
||||
|
||||
const search = new URL(window.location.href).searchParams;
|
||||
if (search.get('showPoint')) {
|
||||
for (const target of targetElements) {
|
||||
const pointElement = document.createElement('x-pw-pointer');
|
||||
pointElement.style.position = 'fixed';
|
||||
pointElement.style.backgroundColor = '#f44336';
|
||||
pointElement.style.width = '20px';
|
||||
pointElement.style.height = '20px';
|
||||
pointElement.style.borderRadius = '10px';
|
||||
pointElement.style.margin = '-10px 0 0 -10px';
|
||||
pointElement.style.zIndex = '2147483647';
|
||||
const box = target.getBoundingClientRect();
|
||||
pointElement.style.left = (box.left + box.width / 2) + 'px';
|
||||
pointElement.style.top = (box.top + box.height / 2) + 'px';
|
||||
document.documentElement.appendChild(pointElement);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const onDOMContentLoaded = () => visit(document);
|
||||
|
||||
@ -42,23 +42,24 @@ export const SnapshotTab: React.FunctionComponent<{
|
||||
const [measure, ref] = useMeasure<HTMLDivElement>();
|
||||
const [snapshotTab, setSnapshotTab] = React.useState<'action'|'before'|'after'>('action');
|
||||
|
||||
type Snapshot = { action: ActionTraceEvent, snapshotName: string, showPoint?: boolean };
|
||||
const { snapshots } = React.useMemo(() => {
|
||||
if (!action)
|
||||
return { snapshots: {} };
|
||||
|
||||
// if the action has no beforeSnapshot, use the last available afterSnapshot.
|
||||
let beforeSnapshot = action.beforeSnapshot ? { action, snapshotName: action.beforeSnapshot } : undefined;
|
||||
let beforeSnapshot: Snapshot | undefined = action.beforeSnapshot ? { action, snapshotName: action.beforeSnapshot } : undefined;
|
||||
let a = action;
|
||||
while (!beforeSnapshot && a) {
|
||||
a = prevInList(a);
|
||||
beforeSnapshot = a?.afterSnapshot ? { action: a, snapshotName: a?.afterSnapshot } : undefined;
|
||||
}
|
||||
const afterSnapshot = action.afterSnapshot ? { action, snapshotName: action.afterSnapshot } : beforeSnapshot;
|
||||
const actionSnapshot = action.inputSnapshot ? { action, snapshotName: action.inputSnapshot } : afterSnapshot;
|
||||
const afterSnapshot: Snapshot | undefined = action.afterSnapshot ? { action, snapshotName: action.afterSnapshot } : beforeSnapshot;
|
||||
const actionSnapshot: Snapshot | undefined = action.inputSnapshot ? { action, snapshotName: action.inputSnapshot, showPoint: !!action.point } : afterSnapshot;
|
||||
return { snapshots: { action: actionSnapshot, before: beforeSnapshot, after: afterSnapshot } };
|
||||
}, [action]);
|
||||
|
||||
const { snapshotInfoUrl, snapshotUrl, pointX, pointY, popoutUrl } = React.useMemo(() => {
|
||||
const { snapshotInfoUrl, snapshotUrl, popoutUrl } = React.useMemo(() => {
|
||||
const snapshot = snapshots[snapshotTab];
|
||||
if (!snapshot)
|
||||
return { snapshotUrl: kBlankSnapshotUrl };
|
||||
@ -66,16 +67,18 @@ export const SnapshotTab: React.FunctionComponent<{
|
||||
const params = new URLSearchParams();
|
||||
params.set('trace', context(snapshot.action).traceUrl);
|
||||
params.set('name', snapshot.snapshotName);
|
||||
if (snapshot.showPoint)
|
||||
params.set('showPoint', '1');
|
||||
const snapshotUrl = new URL(`snapshot/${snapshot.action.pageId}?${params.toString()}`, window.location.href).toString();
|
||||
const snapshotInfoUrl = new URL(`snapshotInfo/${snapshot.action.pageId}?${params.toString()}`, window.location.href).toString();
|
||||
|
||||
const pointX = snapshotTab === 'action' ? snapshot.action.point?.x : undefined;
|
||||
const pointY = snapshotTab === 'action' ? snapshot.action.point?.y : undefined;
|
||||
const popoutParams = new URLSearchParams();
|
||||
popoutParams.set('r', snapshotUrl);
|
||||
popoutParams.set('trace', context(snapshot.action).traceUrl);
|
||||
if (snapshot.showPoint)
|
||||
popoutParams.set('showPoint', '1');
|
||||
const popoutUrl = new URL(`snapshot.html?${popoutParams.toString()}`, window.location.href).toString();
|
||||
return { snapshots, snapshotInfoUrl, snapshotUrl, pointX, pointY, popoutUrl };
|
||||
return { snapshots, snapshotInfoUrl, snapshotUrl, popoutUrl };
|
||||
}, [snapshots, snapshotTab]);
|
||||
|
||||
const iframeRef0 = React.useRef<HTMLIFrameElement>(null);
|
||||
@ -111,12 +114,11 @@ export const SnapshotTab: React.FunctionComponent<{
|
||||
iframe.addEventListener('load', loadedCallback);
|
||||
iframe.addEventListener('error', loadedCallback);
|
||||
|
||||
const newUrl = snapshotUrl + (pointX === undefined ? '' : `&pointX=${pointX}&pointY=${pointY}`);
|
||||
// Try preventing history entry from being created.
|
||||
if (iframe.contentWindow)
|
||||
iframe.contentWindow.location.replace(newUrl);
|
||||
iframe.contentWindow.location.replace(snapshotUrl);
|
||||
else
|
||||
iframe.src = newUrl;
|
||||
iframe.src = snapshotUrl;
|
||||
|
||||
await loadedPromise;
|
||||
} catch {
|
||||
@ -132,7 +134,7 @@ export const SnapshotTab: React.FunctionComponent<{
|
||||
loadingRef.current.visibleIframe = newVisibleIframe;
|
||||
setSnapshotInfo(newSnapshotInfo);
|
||||
})();
|
||||
}, [snapshotUrl, snapshotInfoUrl, pointX, pointY]);
|
||||
}, [snapshotUrl, snapshotInfoUrl]);
|
||||
|
||||
const windowHeaderHeight = 40;
|
||||
const snapshotContainerSize = {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user