import expect from '@kbn/expect' ; import { setTimeout as setTimeoutAsync } from 'timers/promises' ; import { FtrProviderContext } from '../ftr_provider_context' ; import { logWrapper } from './log_wrapper' ; export function LensPageProvider ( { getService , getPageObjects } ) { const log = getService ( 'log' ) ; const testSubjects = getService ( 'testSubjects' ) ; const retry = getService ( 'retry' ) ; const elasticChart = getService ( 'elasticChart' ) ; const find = getService ( 'find' ) ; const comboBox = getService ( 'comboBox' ) ; const browser = getService ( 'browser' ) ; const dashboardAddPanel = getService ( 'dashboardAddPanel' ) ; const PageObjects = getPageObjects ( [ 'common' , 'header' , 'timePicker' , 'common' , 'visualize' , 'dashboard' , 'timeToVisualize' , ] ) ; return logWrapper ( 'lensPage' , log , { /**
         * Clicks the index pattern filters toggle.
         */ async toggleIndexPatternFiltersPopover ( ) { await testSubjects . click ( 'lnsIndexPatternFiltersToggle' ) ; } , async findAllFields ( ) { const fields = await testSubjects . findAll ( 'lnsFieldListPanelField' ) ; return await Promise . all ( fields . map ( ( field ) => field . getVisibleText ( ) ) ) ; } , async isLensPageOrFail ( ) { return await testSubjects . existOrFail ( 'lnsApp' , { timeout : 1000 } ) ; } , /**
         * Move the date filter to the specified time range, defaults to
         * a range that has data in our dataset.
         */ async goToTimeRange ( fromTime ? , toTime ? ) { await PageObjects . timePicker . ensureHiddenNoDataPopover ( ) ; fromTime = fromTime || PageObjects . timePicker . defaultStartTime ; toTime = toTime || PageObjects . timePicker . defaultEndTime ; await PageObjects . timePicker . setAbsoluteRange ( fromTime , toTime ) ; } , param selector param test async assertExpectedText ( selector , test ) { let actualText ; await retry . waitForWithTimeout ( 'assertExpectedText' , 1000 , async ( ) => { actualText = await find . byCssSelector ( selector ) . then ( ( el ) => el . getVisibleText ( ) ) ; return test ( actualText ) ; } ) ; if ( ! test ( actualText ) ) { throw new Error ( `"${ actualText }" did not match expectation.` ) ; } } , param selector param expectedText assertExactText ( selector , expectedText ) { return this . assertExpectedText ( selector , ( value ) => value === expectedText ) ; } , param title clickVisualizeListItemTitle ( title ) { return retry . try ( async ( ) => { await testSubjects . click ( `visListingTitleLink-${ title }` ) ; await this . isLensPageOrFail ( ) ; } ) ; } , param opts . dimension param opts . operation param opts . field param layerIndex async configureDimension ( opts , layerIndex = 0 ) { await retry . try ( async ( ) => { await testSubjects . click ( `lns-layerPanel-${ layerIndex } > ${ opts . dimension }` ) ; await testSubjects . exists ( `lns-indexPatternDimension-${ opts . operation }` ) ; } ) ; if ( opts . operation === 'formula' ) { await this . switchToFormula ( ) ; } else { const operationSelector = opts . isPreviousIncompatible ? `lns-indexPatternDimension-${ opts . operation } incompatible` : `lns-indexPatternDimension-${ opts . operation }` ; async function getAriaPressed ( ) { const operationSelectorContainer = await testSubjects . find ( operationSelector ) ; await testSubjects . click ( operationSelector ) ; const ariaPressed = await operationSelectorContainer . getAttribute ( 'aria-pressed' ) ; return ariaPressed ; } await retry . waitFor ( 'aria pressed to be true' , async ( ) => { const ariaPressedStatus = await getAriaPressed ( ) ; return ariaPressedStatus === 'true' ; } ) ; } if ( opts . field ) { const target = await testSubjects . find ( 'indexPattern-dimension-field' ) ; await comboBox . openOptionsList ( target ) ; await comboBox . setElement ( target , opts . field ) ; } if ( opts . formula ) { await PageObjects . common . sleep ( 500 ) ; await this . typeFormula ( opts . formula ) ; } if ( opts . palette ) { await this . setPalette ( opts . palette ) ; } if ( ! opts . keepOpen ) { await this . closeDimensionEditor ( ) ; } } , param opts . dimension param opts . operation param opts . field param layerIndex async configureReference ( opts ) { if ( opts . operation ) { const target = await testSubjects . find ( 'indexPattern-subFunction-selection-row' ) ; await comboBox . openOptionsList ( target ) ; await comboBox . setElement ( target , opts . operation ) ; } if ( opts . field ) { const target = await testSubjects . find ( 'indexPattern-reference-field-selection-row' ) ; await comboBox . openOptionsList ( target ) ; await comboBox . setElement ( target , opts . field ) ; } } , param field async dragFieldToWorkspace ( field ) { const from = `lnsFieldListPanelField-${ field }` ; await find . existsByCssSelector ( from ) ; await browser . html5DragAndDrop ( testSubjects . getCssSelector ( from ) , testSubjects . getCssSelector ( 'lnsWorkspace' ) ) ; await this . waitForLensDragDropToFinish ( ) ; await PageObjects . header . waitUntilLoadingHasFinished ( ) ; } , param field async dragFieldToGeoFieldWorkspace ( field ) { const from = `lnsFieldListPanelField-${ field }` ; await find . existsByCssSelector ( from ) ; await browser . html5DragAndDrop ( testSubjects . getCssSelector ( from ) , testSubjects . getCssSelector ( 'lnsGeoFieldWorkspace' ) ) ; await this . waitForLensDragDropToFinish ( ) ; await PageObjects . header . waitUntilLoadingHasFinished ( ) ; } , param field async clickField ( field ) { await testSubjects . click ( `lnsFieldListPanelField-${ field }` ) ; } , async editField ( ) { await retry . try ( async ( ) => { await testSubjects . click ( 'lnsFieldListPanelEdit' ) ; await testSubjects . missingOrFail ( 'lnsFieldListPanelEdit' ) ; } ) ; } , async removeField ( ) { await retry . try ( async ( ) => { await testSubjects . click ( 'lnsFieldListPanelRemove' ) ; await testSubjects . missingOrFail ( 'lnsFieldListPanelRemove' ) ; } ) ; } , async searchField ( name ) { await testSubjects . setValue ( 'lnsIndexPatternFieldSearch' , name , { clearWithKeyboard : true , typeCharByChar : true , } ) ; } , async waitForField ( field ) { await retry . try ( async ( ) => { await testSubjects . existOrFail ( `lnsFieldListPanelField-${ field }` ) ; } ) ; } , async waitForMissingDataViewWarning ( ) { await retry . try ( async ( ) => { await testSubjects . existOrFail ( `missing-refs-failure` ) ; } ) ; } , async waitForMissingDataViewWarningDisappear ( ) { await retry . try ( async ( ) => { await testSubjects . missingOrFail ( `missing-refs-failure` ) ; } ) ; } , async waitForEmptyWorkspace ( ) { await retry . try ( async ( ) => { await testSubjects . existOrFail ( `empty-workspace` ) ; } ) ; } , async waitForWorkspaceWithVisualization ( ) { await retry . try ( async ( ) => { await testSubjects . existOrFail ( `lnsVisualizationContainer` ) ; } ) ; } , async waitForFieldMissing ( field ) { await retry . try ( async ( ) => { await testSubjects . missingOrFail ( `lnsFieldListPanelField-${ field }` ) ; } ) ; } , param fieldName param steps param reverse async dragFieldWithKeyboard ( fieldName , steps = 1 , reverse = false ) { const field = await find . byCssSelector ( `[data-test-subj="lnsDragDrop_draggable-${ fieldName }"] [data-test-subj="lnsDragDrop-keyboardHandler"]` ) ; await field . focus ( ) ; await retry . try ( async ( ) => { await browser . pressKeys ( browser . keys . ENTER ) ; await testSubjects . exists ( '.lnsDragDrop-isDropTarget' ) ; } ) ; for ( let i = 0 ; i < steps ; i ++ ) { await browser . pressKeys ( reverse ? browser . keys . LEFT : browser . keys . RIGHT ) ; } await browser . pressKeys ( browser . keys . ENTER ) ; await this . waitForLensDragDropToFinish ( ) ; await PageObjects . header . waitUntilLoadingHasFinished ( ) ; } , param group param index param steps param reverse async dimensionKeyboardDragDrop ( group , index = 0 , steps = 1 , reverse = false ) { const elements = await find . allByCssSelector ( `[data-test-subj="${ group }"]  [data-test-subj="lnsDragDrop-keyboardHandler"]` ) ; const el = elements [ index ] ; await el . focus ( ) ; await browser . pressKeys ( browser . keys . ENTER ) ; for ( let i = 0 ; i < steps ; i ++ ) { await browser . pressKeys ( reverse ? browser . keys . LEFT : browser . keys . RIGHT ) ; } await browser . pressKeys ( browser . keys . ENTER ) ; await this . waitForLensDragDropToFinish ( ) ; await PageObjects . header . waitUntilLoadingHasFinished ( ) ; } , param group param index param steps param reverse async dimensionKeyboardReorder ( group , index = 0 , steps = 1 , reverse = false ) { const elements = await find . allByCssSelector ( `[data-test-subj="${ group }"]  [data-test-subj="lnsDragDrop-keyboardHandler"]` ) ; const el = elements [ index ] ; await el . focus ( ) ; await browser . pressKeys ( browser . keys . ENTER ) ; for ( let i = 0 ; i < steps ; i ++ ) { await browser . pressKeys ( reverse ? browser . keys . ARROW_UP : browser . keys . ARROW_DOWN ) ; } await browser . pressKeys ( browser . keys . ENTER ) ; await this . waitForLensDragDropToFinish ( ) ; await PageObjects . header . waitUntilLoadingHasFinished ( ) ; } , async waitForLensDragDropToFinish ( ) { await retry . try ( async ( ) => { const exists = await find . existsByCssSelector ( '.lnsDragDrop-isActiveGroup' ) ; if ( exists ) { throw new Error ( 'UI still in drag/drop mode' ) ; } } ) ; } , param field param dimension async dragFieldToDimensionTrigger ( field , dimension ) { const from = `lnsFieldListPanelField-${ field }` ; await find . existsByCssSelector ( from ) ; await browser . html5DragAndDrop ( testSubjects . getCssSelector ( from ) , testSubjects . getCssSelector ( dimension ) ) ; await this . waitForLensDragDropToFinish ( ) ; await PageObjects . header . waitUntilLoadingHasFinished ( ) ; } , param from param to async dragDimensionToDimension ( from , to ) { await find . existsByCssSelector ( from ) ; await browser . html5DragAndDrop ( testSubjects . getCssSelector ( from ) , testSubjects . getCssSelector ( to ) ) ; await this . waitForLensDragDropToFinish ( ) ; await PageObjects . header . waitUntilLoadingHasFinished ( ) ; } , param startIndex param endIndex async reorderDimensions ( dimension , startIndex , endIndex ) { const dragging = `[data-test-subj='${ dimension }']:nth-of-type(${ startIndex }) .lnsDragDrop` ; const dropping = `[data-test-subj='${ dimension }']:nth-of-type(${ endIndex }) [data-test-subj='lnsDragDrop-reorderableDropLayer'` ; await find . existsByCssSelector ( dragging ) ; await browser . html5DragAndDrop ( dragging , dropping ) ; await this . waitForLensDragDropToFinish ( ) ; await PageObjects . header . waitUntilLoadingHasFinished ( ) ; } , async assertPalette ( palette ) { await retry . try ( async ( ) => { await testSubjects . click ( 'lns-palettePicker' ) ; const currentPalette = await ( await find . byCssSelector ( '[role=option][aria-selected=true]' ) ) . getAttribute ( 'id' ) ; expect ( currentPalette ) . to . equal ( palette ) ; } ) ; } , async toggleToolbarPopover ( buttonTestSub ) { await testSubjects . click ( buttonTestSub ) ; } , param dimension param layerIndex async openDimensionEditor ( dimension , layerIndex = 0 ) { await retry . try ( async ( ) => { await testSubjects . click ( `lns-layerPanel-${ layerIndex } > ${ dimension }` ) ; } ) ; } , async isDimensionEditorOpen ( ) { return await testSubjects . exists ( 'lns-indexPattern-dimensionContainerBack' ) ; } , async closeDimensionEditor ( ) { await retry . try ( async ( ) => { await testSubjects . click ( 'lns-indexPattern-dimensionContainerBack' ) ; await testSubjects . missingOrFail ( 'lns-indexPattern-dimensionContainerBack' ) ; } ) ; } , async enableTimeShift ( ) { await testSubjects . click ( 'indexPattern-advanced-popover' ) ; await retry . try ( async ( ) => { await testSubjects . click ( 'indexPattern-time-shift-enable' ) ; } ) ; } , async setTimeShift ( shift ) { await comboBox . setCustom ( 'indexPattern-dimension-time-shift' , shift ) ; } , async enableFilter ( ) { await testSubjects . click ( 'indexPattern-advanced-popover' ) ; await retry . try ( async ( ) => { await testSubjects . click ( 'indexPattern-filter-by-enable' ) ; } ) ; } , async setFilterBy ( queryString ) { this . typeFilter ( queryString ) ; await retry . try ( async ( ) => { await testSubjects . click ( 'indexPattern-filters-existingFilterTrigger' ) ; } ) ; } , async typeFilter ( queryString ) { const queryInput = await testSubjects . find ( 'indexPattern-filters-queryStringInput' ) ; await queryInput . type ( queryString ) ; } , async hasFixAction ( ) { return await testSubjects . exists ( 'errorFixAction' ) ; } , async useFixAction ( ) { await testSubjects . click ( 'errorFixAction' ) ; await this . waitForVisualization ( ) ; } , async isTopLevelAggregation ( ) { return await testSubjects . isEuiSwitchChecked ( 'indexPattern-nesting-switch' ) ; } , /**
         * Removes the dimension matching a specific test subject
         */ async removeDimension ( dimensionTestSubj ) { await testSubjects . click ( `${ dimensionTestSubj } > indexPattern-dimension-remove` ) ; } , /**
         * adds new filter to filters agg
         */ async addFilterToAgg ( queryString ) { await testSubjects . click ( 'lns-newBucket-add' ) ; this . typeFilter ( queryString ) ; await PageObjects . common . pressTabKey ( ) ; await PageObjects . common . pressTabKey ( ) ; await PageObjects . common . pressEnterKey ( ) ; await PageObjects . common . sleep ( 1000 ) ; } , param opts async addTermToAgg ( field ) { const lastIndex = ( await find . allByCssSelector ( '[data-test-subj^="indexPattern-dimension-field"]' ) ) . length ; await testSubjects . click ( 'indexPattern-terms-add-field' ) ; const target = await testSubjects . find ( `indexPattern-dimension-field-${ lastIndex }` ) ; await comboBox . openOptionsList ( target ) ; await comboBox . setElement ( target , field ) ; } , async checkTermsAreNotAvailableToAgg ( fields ) { const lastIndex = ( await find . allByCssSelector ( '[data-test-subj^="indexPattern-dimension-field"]' ) ) . length ; await testSubjects . click ( 'indexPattern-terms-add-field' ) ; const target = await testSubjects . find ( `indexPattern-dimension-field-${ lastIndex }` ) ; for ( const field of fields ) { await comboBox . setCustom ( `indexPattern-dimension-field-${ lastIndex }` , field ) ; await comboBox . openOptionsList ( target ) ; await testSubjects . missingOrFail ( `lns-fieldOption-${ field }` ) ; } } , /**
         * Save the current Lens visualization.
         */ async save ( title , saveAsNew ? , redirectToOrigin ? , saveToLibrary ? , addToDashboard ? , dashboardId ? ) { await PageObjects . header . waitUntilLoadingHasFinished ( ) ; await testSubjects . click ( 'lnsApp_saveButton' ) ; await PageObjects . timeToVisualize . setSaveModalValues ( title , { saveAsNew , redirectToOrigin , addToDashboard : addToDashboard ? addToDashboard : null , dashboardId , saveToLibrary , } ) ; await testSubjects . click ( 'confirmSaveSavedObjectButton' ) ; await retry . waitForWithTimeout ( 'Save modal to disappear' , 1000 , ( ) => testSubjects . missingOrFail ( 'confirmSaveSavedObjectButton' ) . then ( ( ) => true ) . catch ( ( ) => false ) ) ; } , async saveAndReturn ( ) { await testSubjects . click ( 'lnsApp_saveAndReturnButton' ) ; } , async expectSaveAndReturnButtonDisabled ( ) { const button = await testSubjects . find ( 'lnsApp_saveAndReturnButton' , 10000 ) ; const disabledAttr = await button . getAttribute ( 'disabled' ) ; expect ( disabledAttr ) . to . be ( 'true' ) ; } , async editDimensionLabel ( label ) { await testSubjects . setValue ( 'indexPattern-label-edit' , label , { clearWithKeyboard : true } ) ; } , async editDimensionFormat ( format ) { const formatInput = await testSubjects . find ( 'indexPattern-dimension-format' ) ; await comboBox . openOptionsList ( formatInput ) ; await comboBox . setElement ( formatInput , format ) ; } , async editDimensionColor ( color ) { const colorPickerInput = await testSubjects . find ( '~indexPattern-dimension-colorPicker' ) ; await colorPickerInput . type ( color ) ; await PageObjects . common . sleep ( 1000 ) ; } , hasVisualOptionsButton ( ) { return testSubjects . exists ( 'lnsVisualOptionsButton' ) ; } , async openVisualOptions ( ) { await retry . try ( async ( ) => { await testSubjects . click ( 'lnsVisualOptionsButton' ) ; await testSubjects . exists ( 'lnsVisualOptionsButton' ) ; } ) ; } , async retrySetValue ( input , value , options = { clearWithKeyboard : true , typeCharByChar : true , } as Record < string , boolean > ) { await retry . try ( async ( ) => { await testSubjects . setValue ( input , value , options ) ; expect ( await ( await testSubjects . find ( input ) ) . getAttribute ( 'value' ) ) . to . eql ( value ) ; } ) ; } , async useCurvedLines ( ) { await testSubjects . click ( 'lnsCurveStyleToggle' ) ; } , async editMissingValues ( option ) { await testSubjects . click ( 'lnsMissingValuesSelect' ) ; const optionSelector = await find . byCssSelector ( `#${ option }` ) ; await optionSelector . click ( ) ; } , getTitle ( ) { return testSubjects . getAttribute ( 'lns_ChartTitle' , 'innerText' ) ; } , async getFiltersAggLabels ( ) { const labels = [ ] ; const filters = await testSubjects . findAll ( 'indexPattern-filters-existingFilterContainer' ) ; for ( let i = 0 ; i < filters . length ; i ++ ) { labels . push ( await filters [ i ] . getVisibleText ( ) ) ; } log . debug ( `Found ${ labels . length } filters on current page` ) ; return labels ; } , param subVisualizationId async switchToVisualization ( subVisualizationId , searchTerm ? ) { await this . openChartSwitchPopover ( ) ; await this . searchOnChartSwitch ( subVisualizationId , searchTerm ) ; await testSubjects . click ( `lnsChartSwitchPopover_${ subVisualizationId }` ) ; await PageObjects . header . waitUntilLoadingHasFinished ( ) ; } , async openChartSwitchPopover ( ) { if ( await testSubjects . exists ( 'lnsChartSwitchList' ) ) { return ; } await retry . try ( async ( ) => { await testSubjects . click ( 'lnsChartSwitchPopover' ) ; await testSubjects . existOrFail ( 'lnsChartSwitchList' ) ; } ) ; } , async changeAxisSide ( newSide ) { await testSubjects . click ( `lnsXY_axisSide_groups_${ newSide }` ) ; } , /** Counts the visible warnings in the config panel */ async getErrorCount ( ) { const moreButton = await testSubjects . exists ( 'configuration-failure-more-errors' ) ; if ( moreButton ) { await retry . try ( async ( ) => { await testSubjects . click ( 'configuration-failure-more-errors' ) ; await testSubjects . missingOrFail ( 'configuration-failure-more-errors' ) ; } ) ; } const errors = await testSubjects . findAll ( 'configuration-failure-error' ) ; const expressionErrors = await testSubjects . findAll ( 'expression-failure' ) ; return ( errors ?. length ?? 0 ) + ( expressionErrors ?. length ?? 0 ) ; } , async searchOnChartSwitch ( subVisualizationId , searchTerm ? ) { const queryTerm = searchTerm ?? subVisualizationId . substring ( subVisualizationId . length - 3 ) ; return await testSubjects . setValue ( 'lnsChartSwitchSearch' , queryTerm , { clearWithKeyboard : true , } ) ; } , param subVisualizationId async hasChartSwitchWarning ( subVisualizationId , searchTerm ? ) { await this . openChartSwitchPopover ( ) ; await this . searchOnChartSwitch ( subVisualizationId , searchTerm ) ; const element = await testSubjects . find ( `lnsChartSwitchPopover_${ subVisualizationId }` ) ; return await testSubjects . descendantExists ( `lnsChartSwitchPopoverAlert_${ subVisualizationId }` , element ) ; } , param subVisualizationId async switchLayerSeriesType ( seriesType ) { await retry . try ( async ( ) => { await testSubjects . click ( 'lns_layer_settings' ) ; await testSubjects . exists ( `lnsXY_seriesType-${ seriesType }` ) ; } ) ; return await testSubjects . click ( `lnsXY_seriesType-${ seriesType }` ) ; } , /**
         * Returns the number of layers visible in the chart configuration
         */ async getLayerCount ( ) { const elements = await testSubjects . findAll ( 'lnsLayerRemove' ) ; return elements . length ; } , /**
         * Adds a new layer to the chart, fails if the chart does not support new layers
         */ async createLayer ( layerType = 'data' ) { await testSubjects . click ( 'lnsLayerAddButton' ) ; const layerCount = ( await find . allByCssSelector ( `[data-test-subj^="lns-layerPanel-"]` ) ) . length ; await retry . waitFor ( 'check for layer type support' , async ( ) => { const fasterChecks = await Promise . all ( [ ( await find . allByCssSelector ( `[data-test-subj^="lns-layerPanel-"]` ) ) . length > layerCount , testSubjects . exists ( `lnsLayerAddButton-${ layerType }` ) , ] ) ; return fasterChecks . filter ( Boolean ) . length > 0 ; } ) ; if ( await testSubjects . exists ( `lnsLayerAddButton-${ layerType }` ) ) { await testSubjects . click ( `lnsLayerAddButton-${ layerType }` ) ; } } , /**
         * Changes the index pattern in the data panel
         */ async switchDataPanelIndexPattern ( name ) { await testSubjects . click ( 'indexPattern-switch-link' ) ; await find . clickByCssSelector ( `[title="${ name }"]` ) ; await PageObjects . header . waitUntilLoadingHasFinished ( ) ; } , /**
         * Changes the index pattern for the first layer
         */ async switchFirstLayerIndexPattern ( name ) { await testSubjects . click ( 'lns_layerIndexPatternLabel' ) ; await find . clickByCssSelector ( `.lnsChangeIndexPatternPopover [title="${ name }"]` ) ; await PageObjects . header . waitUntilLoadingHasFinished ( ) ; } , /**
         * Returns the current index pattern of the data panel
         */ async getDataPanelIndexPattern ( ) { return await ( await testSubjects . find ( 'indexPattern-switch-link' ) ) . getAttribute ( 'title' ) ; } , /**
         * Returns the current index pattern of the first layer
         */ async getFirstLayerIndexPattern ( ) { return await ( await testSubjects . find ( 'lns_layerIndexPatternLabel' ) ) . getAttribute ( 'title' ) ; } , async linkedToOriginatingApp ( ) { await PageObjects . header . waitUntilLoadingHasFinished ( ) ; await testSubjects . existOrFail ( 'lnsApp_saveAndReturnButton' ) ; } , async notLinkedToOriginatingApp ( ) { await PageObjects . header . waitUntilLoadingHasFinished ( ) ; await testSubjects . missingOrFail ( 'lnsApp_saveAndReturnButton' ) ; } , param dimension param index async getDimensionTriggerText ( dimension , index = 0 ) { const dimensionTexts = await this . getDimensionTriggersTexts ( dimension ) ; return dimensionTexts [ index ] ; } , param dimension async getDimensionTriggersTexts ( dimension ) { return retry . try ( async ( ) => { const dimensionElements = await testSubjects . findAll ( `${ dimension } > lns-dimensionTrigger` ) ; const dimensionTexts = await Promise . all ( await dimensionElements . map ( async ( el ) => await el . getVisibleText ( ) ) ) ; return dimensionTexts ; } ) ; } , async isShowingNoResults ( ) { return ( ( await ( await testSubjects . find ( 'lnsWorkspace' ) ) . getVisibleText ( ) ) === 'No results found' ) ; } , async getCurrentChartDebugState ( ) { return await elasticChart . getChartDebugData ( 'lnsWorkspace' ) ; } , param index async getDatatableHeaderText ( index = 0 ) { const el = await this . getDatatableHeader ( index ) ; return el . getVisibleText ( ) ; } , param rowIndex param colIndex async getDatatableCellText ( rowIndex = 0 , colIndex = 0 ) { const el = await this . getDatatableCell ( rowIndex , colIndex ) ; return el . getVisibleText ( ) ; } , async getDatatableCellStyle ( rowIndex = 0 , colIndex = 0 ) { const el = await this . getDatatableCell ( rowIndex , colIndex ) ; const styleString = await el . getAttribute ( 'style' ) ; return styleString . split ( ';' ) . reduce < Record < string , string > > ( ( memo , cssLine ) => { const [ prop , value ] = cssLine . split ( ':' ) ; if ( prop && value ) { memo [ prop . trim ( ) ] = value . trim ( ) ; } return memo ; } , { } ) ; } , async getCountOfDatatableColumns ( ) { const table = await find . byCssSelector ( '.euiDataGrid' ) ; const $ = await table . parseDomContent ( ) ; return ( await $ ( '.euiDataGridHeaderCell__content' ) ) . length ; } , async getDatatableHeader ( index = 0 ) { log . debug ( `All headers ${ await testSubjects . getVisibleText ( 'dataGridHeader' ) }` ) ; return find . byCssSelector ( `[data-test-subj="lnsDataTable"] [data-test-subj="dataGridHeader"] [role=columnheader]:nth-child(${ index + 1 })` ) ; } , async getDatatableCell ( rowIndex = 0 , colIndex = 0 ) { return await find . byCssSelector ( `[data-test-subj="lnsDataTable"] [data-test-subj="dataGridRowCell"][data-gridcell-id="${ rowIndex },${ colIndex }"]` ) ; } , async isDatatableHeaderSorted ( index = 0 ) { return find . existsByCssSelector ( `[data-test-subj="lnsDataTable"] [data-test-subj="dataGridHeader"] [role=columnheader]:nth-child(${ index + 1 }) [data-test-subj^="dataGridHeaderCellSortingIcon"]` ) ; } , async changeTableSortingBy ( colIndex = 0 , direction ) { const el = await this . getDatatableHeader ( colIndex ) ; await el . click ( ) ; let buttonEl ; if ( direction !== 'none' ) { buttonEl = await find . byCssSelector ( `[data-test-subj^="dataGridHeaderCellActionGroup"] [title="Sort ${ direction }"]` ) ; } else { buttonEl = await find . byCssSelector ( `[data-test-subj^="dataGridHeaderCellActionGroup"] li[class$="selected"] [title^="Sort"]` ) ; } return buttonEl . click ( ) ; } , async setTableSummaryRowFunction ( summaryFunction ) { await testSubjects . click ( 'lnsDatatable_summaryrow_function' ) ; await testSubjects . click ( 'lns-datatable-summary-' + summaryFunction ) ; } , async setTableSummaryRowLabel ( newLabel ) { await testSubjects . setValue ( 'lnsDatatable_summaryrow_label' , newLabel , { clearWithKeyboard : true , typeCharByChar : true , } ) ; } , async setTableDynamicColoring ( coloringType ) { await testSubjects . click ( 'lnsDatatable_dynamicColoring_groups_' + coloringType ) ; } , async openPalettePanel ( chartType ) { await retry . try ( async ( ) => { await testSubjects . click ( `${ chartType }_dynamicColoring_trigger` ) ; await PageObjects . common . sleep ( 100 ) ; await testSubjects . existOrFail ( 'lns-indexPattern-PalettePanelContainer' , { timeout : 2500 } ) ; } ) ; } , async closePalettePanel ( ) { await testSubjects . click ( 'lns-indexPattern-PalettePanelContainerBack' ) ; } , async changePaletteTo ( paletteName ) { await testSubjects . click ( `lnsPalettePanel_dynamicColoring_palette_picker` ) ; await testSubjects . click ( `${ paletteName }-palette` ) ; } , async setPalette ( paletteName ) { await testSubjects . click ( 'lns-palettePicker' ) ; await find . clickByCssSelector ( `#${ paletteName }` ) ; } , async closePaletteEditor ( ) { await retry . try ( async ( ) => { await testSubjects . click ( 'lns-indexPattern-PalettePanelContainerBack' ) ; await testSubjects . missingOrFail ( 'lns-indexPattern-PalettePanelContainerBack' ) ; } ) ; } , async openColorStopPopup ( index = 0 ) { const stopEls = await testSubjects . findAll ( 'euiColorStopThumb' ) ; if ( stopEls [ index ] ) { await stopEls [ index ] . click ( ) ; } } , async setColorStopValue ( value ) { await testSubjects . setValue ( 'lnsPalettePanel_dynamicColoring_progression_custom_stops_value' , String ( value ) ) ; } , async toggleColumnVisibility ( dimension , no = 1 ) { await this . openDimensionEditor ( dimension ) ; const id = 'lns-table-column-hidden' ; await PageObjects . common . sleep ( 500 ) ; const isChecked = await testSubjects . isEuiSwitchChecked ( id ) ; log . debug ( `switch status before the toggle = ${ isChecked }` ) ; await testSubjects . setEuiSwitch ( id , isChecked ? 'uncheck' : 'check' ) ; await PageObjects . common . sleep ( 500 ) ; const isChecked2 = await testSubjects . isEuiSwitchChecked ( id ) ; log . debug ( `switch status after the toggle = ${ isChecked2 }` ) ; await this . closeDimensionEditor ( ) ; await PageObjects . common . sleep ( 500 ) ; await PageObjects . header . waitUntilLoadingHasFinished ( ) ; } , async clickTableCellAction ( rowIndex = 0 , colIndex = 0 , actionTestSub ) { const el = await this . getDatatableCell ( rowIndex , colIndex ) ; await el . focus ( ) ; const action = await el . findByTestSubject ( actionTestSub ) ; return action . click ( ) ; } , param title param count async assertMetric ( title , count ) { await this . assertExactText ( '[data-test-subj="lns_metric_title"]' , title ) ; await this . assertExactText ( '[data-test-subj="lns_metric_value"]' , count ) ; } , async setMetricDynamicColoring ( coloringType ) { await testSubjects . click ( 'lnsMetric_dynamicColoring_groups_' + coloringType ) ; } , async getMetricStyle ( ) { const el = await testSubjects . find ( 'lns_metric_value' ) ; const styleString = await el . getAttribute ( 'style' ) ; return styleString . split ( ';' ) . reduce < Record < string , string > > ( ( memo , cssLine ) => { const [ prop , value ] = cssLine . split ( ':' ) ; if ( prop && value ) { memo [ prop . trim ( ) ] = value . trim ( ) ; } return memo ; } , { } ) ; } , async assertMissingValues ( option ) { await this . assertExactText ( '[data-test-subj="lnsMissingValuesSelect"]' , option ) ; } , async assertColor ( color ) { await testSubjects . getAttribute ( '~indexPattern-dimension-colorPicker' , color ) ; } , param title param redirectToOrigin async createAndAddLensFromDashboard ( { title , redirectToOrigin , } ) { log . debug ( `createAndAddLens${ title }` ) ; const inViewMode = await PageObjects . dashboard . getIsInViewMode ( ) ; if ( inViewMode ) { await PageObjects . dashboard . switchToEditMode ( ) ; } await dashboardAddPanel . clickCreateNewLink ( ) ; await this . goToTimeRange ( ) ; await this . configureDimension ( { dimension : 'lnsXY_xDimensionPanel > lns-empty-dimension' , operation : 'date_histogram' , field : '@timestamp' , } ) ; await this . configureDimension ( { dimension : 'lnsXY_yDimensionPanel > lns-empty-dimension' , operation : 'average' , field : 'bytes' , } ) ; await this . configureDimension ( { dimension : 'lnsXY_splitDimensionPanel > lns-empty-dimension' , operation : 'terms' , field : 'ip' , } ) ; if ( title ) { await this . save ( title , false , redirectToOrigin ) ; } else { await this . saveAndReturn ( ) ; } } , param name async assertFocusedField ( name ) { const input = await find . activeElement ( ) ; const fieldAncestor = await input . findByXpath ( './../../..' ) ; const focusedElementText = await fieldAncestor . getVisibleText ( ) ; const dataTestSubj = await fieldAncestor . getAttribute ( 'data-test-subj' ) ; expect ( focusedElementText ) . to . eql ( name ) ; expect ( dataTestSubj ) . to . eql ( 'lnsFieldListPanelField' ) ; } , param name async assertFocusedDimension ( name ) { const input = await find . activeElement ( ) ; const fieldAncestor = await input . findByXpath ( './../../..' ) ; const focusedElementText = await fieldAncestor . getVisibleText ( ) ; expect ( focusedElementText ) . to . eql ( name ) ; } , async waitForVisualization ( ) { async function getRenderingCount ( ) { const visualizationContainer = await testSubjects . find ( 'lnsVisualizationContainer' ) ; const renderingCount = await visualizationContainer . getAttribute ( 'data-rendering-count' ) ; return Number ( renderingCount ) ; } await PageObjects . header . waitUntilLoadingHasFinished ( ) ; await retry . waitFor ( 'rendering count to stabilize' , async ( ) => { const firstCount = await getRenderingCount ( ) ; await PageObjects . common . sleep ( 1000 ) ; const secondCount = await getRenderingCount ( ) ; return firstCount === secondCount ; } ) ; } , async clickAddField ( ) { await testSubjects . click ( 'lnsIndexPatternActions' ) ; await testSubjects . existOrFail ( 'indexPattern-add-field' ) ; await testSubjects . click ( 'indexPattern-add-field' ) ; } , /** resets visualization/layer or removes a layer */ async removeLayer ( ) { await testSubjects . click ( 'lnsLayerRemove' ) ; } , /**
         * Starts dragging @param dragging, drags over @param draggedOver and drops it into @dropTarget
         */ async dragEnterDrop ( dragging , draggedOver , dropTarget ) { await browser . execute ( `
          function createEvent(typeOfEvent) {
            const event = document.createEvent("CustomEvent");
            event.initCustomEvent(typeOfEvent, true, true, null);
            event.dataTransfer = {
                data: {},
                setData: function(key, value) {
                    this.data[key] = value;
                },
                getData: function(key) {
                    return this.data[key];
                }
            };
            return event;
          }
          function dispatchEvent(element, event, transferData) {
            if (transferData !== undefined) {
                event.dataTransfer = transferData;
            }
            if (element.dispatchEvent) {
                element.dispatchEvent(event);
            } else if (element.fireEvent) {
                element.fireEvent("on" + event.type, event);
            }
          }

          const origin = document.querySelector(arguments[0]);
          const dragStartEvent = createEvent('dragstart');
          dispatchEvent(origin, dragStartEvent);

          setTimeout(() => {
            const target = document.querySelector(arguments[1]);
            const dragenter = createEvent('dragenter');
            const dragover = createEvent('dragover');
            dispatchEvent(target, dragenter, dragStartEvent.dataTransfer);
            dispatchEvent(target, dragover, dragStartEvent.dataTransfer);
            setTimeout(() => {
              const target = document.querySelector(arguments[2]);
              const dropEvent = createEvent('drop');
              dispatchEvent(target, dropEvent, dragStartEvent.dataTransfer);
              const dragEndEvent = createEvent('dragend');
              dispatchEvent(origin, dragEndEvent, dropEvent.dataTransfer);
            }, 100)
          }, 100);
      ` , dragging , draggedOver , dropTarget ) ; await setTimeoutAsync ( 150 ) ; } , param from param to param type async dragDimensionToExtraDropType ( from , to , type ) { await this . dragEnterDrop ( testSubjects . getCssSelector ( from ) , testSubjects . getCssSelector ( `${ to } > lnsDragDrop` ) , testSubjects . getCssSelector ( `${ to } > lnsDragDrop-${ type }` ) ) ; await PageObjects . header . waitUntilLoadingHasFinished ( ) ; } , async switchToQuickFunctions ( ) { await testSubjects . click ( 'lens-dimensionTabs-quickFunctions' ) ; } , async switchToFormula ( ) { await testSubjects . click ( 'lens-dimensionTabs-formula' ) ; } , async switchToStaticValue ( ) { await testSubjects . click ( 'lens-dimensionTabs-static_value' ) ; } , async toggleFullscreen ( ) { await testSubjects . click ( 'lnsFormula-fullscreen' ) ; } , async goToListingPageViaBreadcrumbs ( ) { await retry . try ( async ( ) => { await testSubjects . click ( 'breadcrumb first' ) ; if ( await testSubjects . exists ( 'appLeaveConfirmModal' ) ) { await testSubjects . exists ( 'confirmModalConfirmButton' ) ; await testSubjects . click ( 'confirmModalConfirmButton' ) ; } await testSubjects . existOrFail ( 'visualizationLandingPage' , { timeout : 3000 } ) ; } ) ; } , async typeFormula ( formula ) { await find . byCssSelector ( '.monaco-editor' ) ; await find . clickByCssSelectorWhenNotDisabled ( '.monaco-editor' ) ; const input = await find . activeElement ( ) ; await input . clearValueWithKeyboard ( { charByChar : true } ) ; await input . type ( formula ) ; await PageObjects . common . sleep ( 300 ) ; } , async expectFormulaText ( formula ) { const element = await find . byCssSelector ( '.monaco-editor' ) ; expect ( await element . getVisibleText ( ) ) . to . equal ( formula ) ; } , async filterLegend ( value ) { await testSubjects . click ( `legend-${ value }` ) ; const filterIn = await testSubjects . find ( `legend-${ value }-filterIn` ) ; await filterIn . click ( ) ; } , hasEmptySizeRatioButtonGroup ( ) { return testSubjects . exists ( 'lnsEmptySizeRatioButtonGroup' ) ; } , } ) ; }