import EventRecording from "./ui/eventRecording" ; import { getSelectors } from "./utils/selector" ; import { ActionsInTestEnum } from "@shared/constants/recordedActions" ; import { iSelectorInfo } from "@shared/types/selectorInfo" ; import { v4 as uuidv4 } from "uuid" ; import { findDistanceBetweenNodes } from "./utils/helper" ; import { ElementsIdMap } from "./elementsMap" ; import { recordAction } from "./host-proxy" ; export default class EventsController { recordingOverlay : EventRecording ; _recordedEvents : Array < { eventType : string ; element : Node ; } > = [ ] ; constructor ( recordingOverlay ) { this . recordingOverlay = recordingOverlay ; } getRelevantHoverRecordsFromSavedEvents ( nodes , rootElement ) { console . log ( "Recorded events" , [ ... this . _recordedEvents ] , nodes ) ; if ( ! this . _recordedEvents . length ) return nodes ; const reverseRecordedEvents = this . _recordedEvents . reverse ( ) . filter ( ( a ) => { return [ ActionsInTestEnum . CLICK , ActionsInTestEnum . HOVER ] . includes ( a . eventType as ActionsInTestEnum ) ; } ) ; function getListTillNoMatching ( list ) { const out = [ ] ; for ( const item of list ) { const result = nodes . some ( ( node ) => { return item . element === node || node . contains ( item . element ) ; } ) ; out . push ( item ) ; if ( ! result ) break ; } return out ; } const listTillNomatching = getListTillNoMatching ( reverseRecordedEvents ) . reverse ( ) ; console . log ( "LIst till no mathcinbg" , listTillNomatching ) ; const finalOut = new Map < Node , Node > ( ) ; for ( const item of listTillNomatching ) { for ( const node of nodes ) { if ( node === item . element && ! finalOut . has ( node ) ) { finalOut . set ( node , node ) ; } } if ( finalOut . size === nodes . length ) break ; } return nodes . filter ( ( a ) => ! finalOut . has ( a ) ) . map ( ( node ) => { const nodeDistance = findDistanceBetweenNodes ( node , rootElement ) ; if ( nodeDistance <= 2 ) { const boundingBox = ( node as HTMLElement ) . getBoundingClientRect ( ) ; const centerX = boundingBox . x + boundingBox . width / 2 ; const centerY = boundingBox . y + boundingBox . height / 2 ; const nodeAtCenter = document . elementFromPoint ( centerX , centerY ) ; if ( nodeAtCenter === rootElement ) return nodeAtCenter ; } return node ; } ) . filter ( ( e ) => ! ! e ) ; } simulateClickOnElement ( element ) { try { const event = new MouseEvent ( "click" , { view : window , bubbles : true , cancelable : false , } ) ; ( event as any ) . simulatedEvent = true ; element . dispatchEvent ( event ) ; } catch ( err ) { console . error ( element , err ) ; } } simulateHoverOnElement ( el ) { try { const event = new Event ( "MS" ) ; event . initEvent ( "mouseover" , true , true ) ; el . dispatchEvent ( event ) ; } catch ( err ) { console . error ( el , err ) ; } } getSelectorsOfNodes ( nodes ) { return nodes . map ( ( node ) => { const selectors = node ? getSelectors ( node ) : null ; return { selectors } ; } ) ; } async _getUniqueNodeId ( node ) { const id = uuidv4 ( ) ; ( window as any ) [ id ] = node ; return id ; } getRecordedEvents ( ) { return this . _recordedEvents ; } getSelectors ( _capturedTarget ) { const capturedTarget = _capturedTarget instanceof SVGElement && _capturedTarget . tagName . toLocaleLowerCase ( ) !== "svg" ? _capturedTarget . ownerSVGElement : _capturedTarget ; return getSelectors ( capturedTarget instanceof SVGAElement ? capturedTarget . ownerSVGElement : capturedTarget ) ; } async saveCapturedEventInBackground ( event_type , _capturedTarget , value = "" , callback ? , shouldLogImage = true ) { const capturedTarget = _capturedTarget instanceof SVGElement && _capturedTarget . tagName . toLocaleLowerCase ( ) !== "svg" ? _capturedTarget . ownerSVGElement : _capturedTarget ; const selectors = capturedTarget ? getSelectors ( capturedTarget instanceof SVGAElement ? capturedTarget . ownerSVGElement : capturedTarget ) : null ; let capturedElementScreenshot = null ; if ( shouldLogImage && ! [ ActionsInTestEnum . NAVIGATE_URL , ActionsInTestEnum . PAGE_SCREENSHOT , ActionsInTestEnum . PAGE_SCROLL , ActionsInTestEnum . SET_DEVICE , ActionsInTestEnum . WAIT_FOR_NAVIGATION , ActionsInTestEnum . VALIDATE_SEO , ] . includes ( event_type as any ) ) { console . log ( capturedTarget ) ; console . log ( "Tryng to take screenshot" ) ; capturedElementScreenshot = null ; console . log ( "Finsihed" ) ; } console . log ( "Captured target" , capturedTarget ) ; this . _recordedEvents . push ( { element : capturedTarget , eventType : event_type , } ) ; recordAction ( { type : event_type as ActionsInTestEnum , payload : { selectors : selectors , meta : { value , uniqueNodeId : capturedTarget && ! [ document . body , document ] . includes ( capturedTarget ) ? ElementsIdMap . getUniqueId ( capturedTarget ) : null , } , } , screenshot : capturedElementScreenshot , url : window . location . href , } ) ; } }