ui: export events for e2e
This commit is contained in:
parent
735b86d778
commit
4b16e50e5f
4 changed files with 85 additions and 7 deletions
|
|
@ -21,6 +21,7 @@ import { Bookmark as BookmarkIcn, BookmarkCheck, Vault } from 'lucide-react';
|
|||
import { useModal } from 'Components/ModalContext';
|
||||
import IssueForm from 'Components/Session_/Issues/IssueForm';
|
||||
import ShareModal from '../shared/SharePopup/SharePopup';
|
||||
import UnitStepsModal from "./UnitStepsModal";
|
||||
|
||||
const disableDevtools = 'or_devtools_uxt_toggle';
|
||||
|
||||
|
|
@ -116,6 +117,13 @@ function SubHeader(props) {
|
|||
});
|
||||
};
|
||||
|
||||
const exportEvents = () => {
|
||||
const allEvents = sessionStore.current.events;
|
||||
const width = store.get().width;
|
||||
const height = store.get().height;
|
||||
openModal(<UnitStepsModal width={width} height={height} events={allEvents} />, { title: 'Export Events', width: 640 });
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<div
|
||||
|
|
@ -187,6 +195,11 @@ function SubHeader(props) {
|
|||
<span>Keyboard Shortcuts</span>
|
||||
</div>,
|
||||
onClick: showKbHelp
|
||||
},
|
||||
{
|
||||
key: '5',
|
||||
label: <div className={'flex items-center gap-2'}>Export Events</div>,
|
||||
onClick: exportEvents,
|
||||
}
|
||||
]
|
||||
}}
|
||||
|
|
|
|||
62
frontend/app/components/Session_/UnitStepsModal/index.tsx
Normal file
62
frontend/app/components/Session_/UnitStepsModal/index.tsx
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
import React from "react";
|
||||
import { TYPES, Input, Click, Location } from 'App/types/session/event'
|
||||
import { CodeBlock, CopyButton } from "UI";
|
||||
import { Segmented } from 'antd';
|
||||
|
||||
interface Props {
|
||||
events: Input[] | Click[] | Location[];
|
||||
width: number;
|
||||
height: number;
|
||||
}
|
||||
|
||||
function UnitStepsModal({ events, width, height }: Props) {
|
||||
const [eventStr, setEventStr] = React.useState('')
|
||||
const [activeFramework, setActiveFramework] = React.useState('puppeteer')
|
||||
|
||||
React.useEffect(() => {
|
||||
const userEventTypes = [TYPES.LOCATION, TYPES.CLICK, TYPES.INPUT]
|
||||
const puppeteerEvents = {
|
||||
[TYPES.LOCATION]: (event: Location) => `await page.goto('${event.url}')`,
|
||||
[TYPES.CLICK]: (event: Click) => `await page.locator('${event.selector.length ? event.selector : event.label}').click()`,
|
||||
[TYPES.INPUT]: (event: Input) => `await page.locator('${event.label}').type('Test Input')`,
|
||||
'screen': () => `await page.setViewport({width: ${width}, height: ${height})`
|
||||
}
|
||||
const cypressEvents = {
|
||||
[TYPES.LOCATION]: (event: Location) => `cy.visit('${event.url}')`,
|
||||
[TYPES.CLICK]: (event: Click) => `cy.get('${event.selector.length ? event.selector : event.label}').click()`,
|
||||
[TYPES.INPUT]: (event: Input) => `cy.get('${event.label}').type('Test Input')`,
|
||||
'screen': () => `cy.viewport(${width}, ${height})`
|
||||
}
|
||||
const usedCollection = activeFramework === 'puppeteer' ? puppeteerEvents : cypressEvents
|
||||
|
||||
let finalScript = ''
|
||||
events.forEach((ev) => {
|
||||
if (userEventTypes.includes(ev.type)) {
|
||||
finalScript += usedCollection[ev.type](ev)
|
||||
finalScript += '\n'
|
||||
}
|
||||
})
|
||||
setEventStr(finalScript)
|
||||
}, [events, activeFramework])
|
||||
|
||||
return (
|
||||
<div className={'bg-white h-full flex flex-col items-start gap-2'}>
|
||||
<div className={'flex items-center gap-4'}>
|
||||
<Segmented
|
||||
options={[
|
||||
{ label: 'Puppeteer', value: 'puppeteer' },
|
||||
{ label: 'Cypress', value: 'cypress' }
|
||||
]}
|
||||
value={activeFramework}
|
||||
onChange={(value) => setActiveFramework(value)}
|
||||
/>
|
||||
<CopyButton size={'middle'} variant={'default'} content={eventStr} className={'capitalize font-medium text-neutral-400'} />
|
||||
</div>
|
||||
<div className={'w-full'}>
|
||||
<CodeBlock code={eventStr} language={'javascript'} />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default UnitStepsModal;
|
||||
|
|
@ -3,7 +3,7 @@ import { useState } from 'react';
|
|||
import copy from 'copy-to-clipboard';
|
||||
import { Button } from 'antd';
|
||||
|
||||
function CopyButton({ content, variant="text-primary", className = '', btnText = 'copy' }) {
|
||||
function CopyButton({ content, variant="text", className = 'capitalize mt-2 font-medium text-neutral-400', btnText = 'copy', size = "small" }) {
|
||||
const [copied, setCopied] = useState(false)
|
||||
|
||||
const copyHandler = () => {
|
||||
|
|
@ -16,14 +16,14 @@ function CopyButton({ content, variant="text-primary", className = '', btnText
|
|||
|
||||
return (
|
||||
<Button
|
||||
type='text'
|
||||
onClick={ copyHandler }
|
||||
size='small'
|
||||
className='capitalize mt-2 font-medium text-neutral-400'
|
||||
type={variant}
|
||||
onClick={copyHandler}
|
||||
size={size}
|
||||
className={className}
|
||||
>
|
||||
{ copied ? 'copied' : btnText }
|
||||
{copied ? 'copied' : btnText}
|
||||
</Button>
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
export default CopyButton
|
||||
|
|
|
|||
|
|
@ -49,6 +49,7 @@ interface ClickEvent extends IEvent {
|
|||
targetContent: string;
|
||||
count: number;
|
||||
hesitation: number;
|
||||
selector: string;
|
||||
}
|
||||
|
||||
interface TouchEvent extends IEvent {
|
||||
|
|
@ -141,12 +142,14 @@ export class Click extends Event {
|
|||
targetContent = '';
|
||||
count: number;
|
||||
hesitation: number = 0;
|
||||
selector: string;
|
||||
|
||||
constructor(evt: ClickEvent, isClickRage?: boolean) {
|
||||
super(evt);
|
||||
this.targetContent = evt.targetContent;
|
||||
this.count = evt.count;
|
||||
this.hesitation = evt.hesitation;
|
||||
this.selector = evt.selector;
|
||||
if (isClickRage) {
|
||||
this.type = CLICKRAGE;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue