import { WebElementWrapper } from 'test/functional/services/lib/web_element_wrapper' ; import { FtrService } from '../ftr_provider_context' ; interface Node { circle : WebElementWrapper ; label : string ; } interface Edge { sourceNode : Node ; targetNode : Node ; width : number ; element : WebElementWrapper ; } export class GraphPageObject extends FtrService { private readonly find = this . ctx . getService ( 'find' ) ; private readonly log = this . ctx . getService ( 'log' ) ; private readonly testSubjects = this . ctx . getService ( 'testSubjects' ) ; private readonly retry = this . ctx . getService ( 'retry' ) ; private readonly browser = this . ctx . getService ( 'browser' ) ; private readonly common = this . ctx . getPageObject ( 'common' ) ; private readonly header = this . ctx . getPageObject ( 'header' ) ; async selectIndexPattern ( pattern ) { await this . testSubjects . click ( 'graphDatasourceButton' ) ; await this . testSubjects . click ( `savedObjectTitle${ pattern . split ( ' ' ) . join ( '-' ) }` ) ; await this . testSubjects . waitForAttributeToChange ( 'graph-add-field-button' , 'aria-disabled' , 'false' ) ; await this . testSubjects . click ( 'queryInput' ) ; } async clickAddField ( ) { await this . retry . try ( async ( ) => { await this . testSubjects . click ( 'graph-add-field-button' ) ; await this . testSubjects . existOrFail ( 'graph-field-search' , { timeout : 3000 } ) ; } ) ; } async selectField ( field ) { await this . testSubjects . setValue ( 'graph-field-search' , field ) ; await this . find . clickDisplayedByCssSelector ( `[title="${ field }"]` ) ; } async addFields ( fields ) { this . log . debug ( 'click Add Field icon' ) ; await this . clickAddField ( ) ; for ( const field of fields ) { this . log . debug ( 'select field ' + field ) ; await this . selectField ( field ) ; } } async query ( str ) { await this . testSubjects . click ( 'queryInput' ) ; await this . testSubjects . setValue ( 'queryInput' , str ) ; await this . testSubjects . click ( 'graph-explore-button' ) ; } private getPositionAsString ( x , y ) { return `${ x }-${ y }` ; } private async getCirclePosition ( element ) { const x = await element . getAttribute ( 'cx' ) ; const y = await element . getAttribute ( 'cy' ) ; return this . getPositionAsString ( x , y ) ; } private async getLinePositions ( element ) { const x1 = await element . getAttribute ( 'x1' ) ; const y1 = await element . getAttribute ( 'y1' ) ; const x2 = await element . getAttribute ( 'x2' ) ; const y2 = await element . getAttribute ( 'y2' ) ; return [ this . getPositionAsString ( x1 , y1 ) , this . getPositionAsString ( x2 , y2 ) ] ; } async isolateEdge ( from , to ) { await this . testSubjects . click ( 'graphSelectAll' ) ; const selections = await this . find . allByCssSelector ( '.gphSelectionList__field' ) ; for ( const selection of selections ) { const labelElement = await selection . findByTagName ( 'span' ) ; const selectionLabel = await labelElement . getVisibleText ( ) ; this . log . debug ( 'Looking at selection ' + selectionLabel ) ; if ( selectionLabel !== from && selectionLabel !== to ) { ( await selection . findByClassName ( 'gphNode__text' ) ) . click ( ) ; await this . common . sleep ( 200 ) ; } } await this . testSubjects . click ( 'graphInvertSelection' ) ; await this . testSubjects . click ( 'graphRemoveSelection' ) ; } async stopLayout ( ) { if ( await this . testSubjects . exists ( 'graphPauseLayout' ) ) { await this . testSubjects . click ( 'graphPauseLayout' ) ; } } async startLayout ( ) { if ( await this . testSubjects . exists ( 'graphResumeLayout' ) ) { await this . testSubjects . click ( 'graphResumeLayout' ) ; } } async getGraphObjects ( ) { await this . stopLayout ( ) ; const nodeNames = await this . browser . execute ( `
      const elements = document.querySelectorAll('#graphSvg text.gphNode__label');
      return [...elements].map(element => element.innerHTML);
    ` ) ; const graphElements = await this . find . allByCssSelector ( '#graphSvg line, #graphSvg circle' ) ; const nodes = [ ] ; const nodePositionMap = { } ; const edges = [ ] ; for ( const element of graphElements ) { const tagName = await element . getTagName ( ) ; if ( tagName === 'circle' ) { nodes . push ( { circle : element , label : nodeNames [ nodes . length ] } ) ; const position = await this . getCirclePosition ( element ) ; nodePositionMap [ position ] = nodes . length - 1 ; } } for ( const element of graphElements ) { const tagName = await element . getTagName ( ) ; if ( tagName === 'line' ) { const [ sourcePosition , targetPosition ] = await this . getLinePositions ( element ) ; const lineStyle = await element . getAttribute ( 'style' ) ; const strokeWidth = Number ( /stroke-width: ?(\d+(\.\d+)?)/ . exec ( lineStyle ) ! [ 1 ] ) ; edges . push ( { element , width : strokeWidth , sourceNode : nodes [ nodePositionMap [ sourcePosition ] ] , targetNode : nodes [ nodePositionMap [ targetPosition ] ] , } ) ; } } await this . startLayout ( ) ; return { nodes , edges , } ; } async createWorkspace ( ) { await this . testSubjects . click ( 'graphCreateGraphPromptButton' ) ; } async newGraph ( ) { this . log . debug ( 'Click New Workspace' ) ; await this . retry . try ( async ( ) => { await this . testSubjects . click ( 'graphNewButton' ) ; await this . testSubjects . existOrFail ( 'confirmModal' , { timeout : 3000 } ) ; } ) ; await this . common . clickConfirmOnModal ( ) ; await this . testSubjects . existOrFail ( 'graphGuidancePanel' ) ; } async saveGraph ( name ) { await this . retry . try ( async ( ) => { await this . testSubjects . click ( 'graphSaveButton' ) ; await this . testSubjects . existOrFail ( 'savedObjectTitle' , { timeout : 3000 } ) ; } ) ; await this . testSubjects . setValue ( 'savedObjectTitle' , name ) ; await this . testSubjects . click ( 'confirmSaveSavedObjectButton' ) ; return await this . testSubjects . exists ( 'saveGraphSuccess' , { timeout : 10000 } ) ; } async getSearchFilter ( ) { const searchFilter = await this . find . allByCssSelector ( '[data-test-subj="graphLandingPage"] .euiFieldSearch' ) ; return searchFilter [ 0 ] ; } async searchForWorkspaceWithName ( name ) { await this . retry . try ( async ( ) => { const searchFilter = await this . getSearchFilter ( ) ; await searchFilter . clearValue ( ) ; await searchFilter . click ( ) ; await searchFilter . type ( name ) ; await this . common . pressEnterKey ( ) ; await this . find . waitForDeletedByCssSelector ( '.euiBasicTable-loading' , 5000 ) ; } ) ; await this . header . waitUntilLoadingHasFinished ( ) ; } async goToListingPage ( ) { await this . retry . try ( async ( ) => { await this . testSubjects . click ( 'breadcrumb graphHomeBreadcrumb first' ) ; await this . testSubjects . existOrFail ( 'graphLandingPage' , { timeout : 3000 } ) ; } ) ; } async openGraph ( name ) { await this . goToListingPage ( ) ; await this . searchForWorkspaceWithName ( name ) ; await this . find . clickByLinkText ( name ) ; if ( ! ( await this . find . existsByCssSelector ( '.gphNode' , 10000 ) ) ) { throw new Error ( 'nodes did not show up' ) ; } await this . common . sleep ( 5000 ) ; } async deleteGraph ( name ) { await this . testSubjects . click ( 'checkboxSelectAll' ) ; await this . clickDeleteSelectedWorkspaces ( ) ; await this . common . clickConfirmOnModal ( ) ; await this . testSubjects . find ( 'graphCreateGraphPromptButton' ) ; } async getWorkspaceCount ( ) { const workspaceTitles = await this . find . allByCssSelector ( '[data-test-subj^="graphListingTitleLink"]' ) ; return workspaceTitles . length ; } async clickDeleteSelectedWorkspaces ( ) { await this . testSubjects . click ( 'deleteSelectedItems' ) ; } async getVennTerm1 ( ) { const el = await this . find . byCssSelector ( 'span.gphLinkSummary__term--1' ) ; return await el . getVisibleText ( ) ; } async getVennTerm2 ( ) { const el = await this . find . byCssSelector ( 'span.gphLinkSummary__term--2' ) ; return await el . getVisibleText ( ) ; } async getSmallVennTerm1 ( ) { const el = await this . find . byCssSelector ( 'small.gphLinkSummary__term--1' ) ; return await el . getVisibleText ( ) ; } async getSmallVennTerm12 ( ) { const el = await this . find . byCssSelector ( 'small.gphLinkSummary__term--1-2' ) ; return await el . getVisibleText ( ) ; } async getSmallVennTerm2 ( ) { const el = await this . find . byCssSelector ( 'small.gphLinkSummary__term--2' ) ; return await el . getVisibleText ( ) ; } }