mirror of
https://github.com/microsoft/playwright.git
synced 2025-06-26 21:40:17 +00:00
feat(trace-viewer): show screenshot pointer (#32514)
Follow-up to https://github.com/microsoft/playwright/pull/32248. Adds a glowing red circle that shows the click position. I made it glowing to show that its position is inaccurate. <img width="964" alt="Screenshot 2024-09-09 at 11 33 45" src="https://github.com/user-attachments/assets/1903071d-6dc0-46c7-9951-844e49a51f35">
This commit is contained in:
parent
ae02331d00
commit
31e269ad06
48
packages/trace-viewer/src/ui/clickPointer.tsx
Normal file
48
packages/trace-viewer/src/ui/clickPointer.tsx
Normal file
@ -0,0 +1,48 @@
|
||||
/**
|
||||
* Copyright (c) Microsoft Corporation.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export function ClickPointer({ point }: { point: { x: number; y: number } }) {
|
||||
return (
|
||||
<div
|
||||
style={{
|
||||
position: 'fixed',
|
||||
backgroundColor: '#f44336',
|
||||
width: '20px',
|
||||
height: '20px',
|
||||
borderRadius: '10px',
|
||||
margin: '-10px 0 0 -10px',
|
||||
zIndex: 2147483646,
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
left: `${point.x}px`,
|
||||
top: `${point.y}px`,
|
||||
}}
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
fontSize: '19px',
|
||||
color: 'white',
|
||||
marginTop: '-3.5px',
|
||||
userSelect: 'none'
|
||||
}}
|
||||
title='Click positions on screenshots are inaccurate.'
|
||||
>
|
||||
⚠
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@ -29,6 +29,7 @@ import type { Language } from '@isomorphic/locatorGenerators';
|
||||
import { locatorOrSelectorAsSelector } from '@isomorphic/locatorParser';
|
||||
import { TabbedPaneTab } from '@web/components/tabbedPane';
|
||||
import { BrowserFrame } from './browserFrame';
|
||||
import { ClickPointer } from './clickPointer';
|
||||
|
||||
function findClosest<T extends { timestamp: number }>(items: T[], target: number) {
|
||||
return items.find((item, index) => {
|
||||
@ -73,7 +74,7 @@ export const SnapshotTab: React.FunctionComponent<{
|
||||
return { snapshots: { action: actionSnapshot, before: beforeSnapshot, after: afterSnapshot } };
|
||||
}, [action]);
|
||||
|
||||
const { snapshotInfoUrl, snapshotUrl, popoutUrl } = React.useMemo(() => {
|
||||
const { snapshotInfoUrl, snapshotUrl, popoutUrl, point } = React.useMemo(() => {
|
||||
const snapshot = snapshots[snapshotTab];
|
||||
if (!snapshot)
|
||||
return { snapshotUrl: kBlankSnapshotUrl };
|
||||
@ -96,7 +97,7 @@ export const SnapshotTab: React.FunctionComponent<{
|
||||
popoutParams.set('pointY', String(snapshot.point.y));
|
||||
}
|
||||
const popoutUrl = new URL(`snapshot.html?${popoutParams.toString()}`, window.location.href).toString();
|
||||
return { snapshots, snapshotInfoUrl, snapshotUrl, popoutUrl };
|
||||
return { snapshots, snapshotInfoUrl, snapshotUrl, popoutUrl, point: snapshot.point };
|
||||
}, [snapshots, snapshotTab]);
|
||||
|
||||
const iframeRef0 = React.useRef<HTMLIFrameElement>(null);
|
||||
@ -230,7 +231,12 @@ export const SnapshotTab: React.FunctionComponent<{
|
||||
transform: `translate(${translate.x}px, ${translate.y}px) scale(${scale})`,
|
||||
}}>
|
||||
<BrowserFrame url={snapshotInfo.url} />
|
||||
{(showScreenshotInsteadOfSnapshot && screencastFrame) && <img alt={`Screenshot of ${action?.apiName} > ${renderTitle(snapshotTab)}`} src={`sha1/${screencastFrame.sha1}`} width={screencastFrame.width} height={screencastFrame.height} />}
|
||||
{(showScreenshotInsteadOfSnapshot && screencastFrame) && (
|
||||
<>
|
||||
{point && <ClickPointer point={point} />}
|
||||
<img alt={`Screenshot of ${action?.apiName} > ${renderTitle(snapshotTab)}`} src={`sha1/${screencastFrame.sha1}`} width={screencastFrame.width} height={screencastFrame.height} />
|
||||
</>
|
||||
)}
|
||||
<div className='snapshot-switcher' style={showScreenshotInsteadOfSnapshot ? { display: 'none' } : undefined}>
|
||||
<iframe ref={iframeRef0} name='snapshot' title='DOM Snapshot' className={clsx(loadingRef.current.visibleIframe === 0 && 'snapshot-visible')}></iframe>
|
||||
<iframe ref={iframeRef1} name='snapshot' title='DOM Snapshot' className={clsx(loadingRef.current.visibleIframe === 1 && 'snapshot-visible')}></iframe>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user