export type ElementDescriptor = { isContentEditable : boolean ; inputType ? : string ; tag : string ; } ; const CLICK_INPUT_TYPES = new Set ( [ "button" , "checkbox" , "image" , "radio" , "reset" , "submit" ] ) ; export const getAssertText = ( element ) : string => { const text = ( element as HTMLInputElement ) . value || element . innerText || "" ; if ( ! text . length || text . length > 500 ) return "" ; return text ; } ; export const getDescriptor = ( element ) : ElementDescriptor => { const tag = element . tagName . toLowerCase ( ) ; const descriptor = { isContentEditable : element . isContentEditable , tag , } ; if ( tag === "input" ) { descriptor . inputType = ( element as HTMLInputElement ) . type ; } return descriptor ; } ; summary export const getInputElementValue = ( element ) : string | null => { let inputValue ; if ( element . isContentEditable && element . tagName . toLowerCase ( ) !== "input" ) { inputValue = element . innerText ; } else { inputValue = element . value ; } return typeof inputValue === "string" ? inputValue : null ; } ; summary export const getTopmostEditableElement = ( element ) : HTMLElement => { if ( ! element . isContentEditable ) return element ; let ancestor = element ; do { if ( ! ancestor . parentElement || ! ancestor . parentElement . isContentEditable ) { return ancestor ; } ancestor = ancestor . parentElement ; } while ( ancestor ) ; return element ; } ; const buildXpath = ( node ) : string => { if ( ! node || node . nodeType !== 1 ) return "" ; const element = node as Element ; if ( element . id ) { const quote = element . id . includes ( `'` ) ? `"` : `'` ; return `//*[@id=${ quote }${ element . id }${ quote }]` ; } const children = element . parentNode ? element . parentNode . children : [ ] ; const sames = [ ] . filter . call ( children , ( x ) => { return x . tagName === element . tagName ; } ) ; const result = buildXpath ( element . parentNode ) + "/" + element . tagName . toLowerCase ( ) + ( sames . length > 1 ? "[" + ( [ ] . indexOf . call ( sames , element as never ) + 1 ) + "]" : "" ) ; return result ; } ; export const getXpath = ( node ) : string => { const result = buildXpath ( node ) ; return result . replace ( "svg" , "*[name()='svg']" ) . replace ( "path" , "*[name()='path']" ) ; } ; export const isFillable = ( element ) : boolean => { if ( element . isContentEditable || element . tag === "textarea" ) return true ; if ( element . tag === "input" && ! CLICK_INPUT_TYPES . has ( element . inputType ! ) ) { return true ; } return false ; } ; export const isVisible = ( element , computedStyle ? ) : boolean => { const htmlElement = element as HTMLElement ; if ( htmlElement . offsetWidth <= 0 || htmlElement . offsetHeight <= 0 ) { return false ; } if ( computedStyle && computedStyle . visibility === "hidden" ) { return false ; } if ( computedStyle && computedStyle . display === "none" ) { return false ; } return true ; } ;