mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 17:28:26 -04:00
Expand coverage of dashboard tests (#17703)
* Expand coverage of dashboard tests and decrease time * Fix timing error when sub urls fail to save from too fast app link clicking * discover doesn't have breadcrumbs * Check top nav text so it works on both listing and saved object edit/view pages * need to do the add panel operations one at a time * Need both types of input in filter * Give test data a title * Remove incorrect and unnecessary comment * Move data around and get rid of 6_3 specific naming as we will end up migrating the data as we progress * Remove code accidentally checked in
This commit is contained in:
parent
c10dc7560a
commit
3c8c23c9ef
50 changed files with 2169 additions and 663 deletions
|
@ -10,13 +10,16 @@ exports[`DashboardPanel matches snapshot 1`] = `
|
|||
>
|
||||
<div
|
||||
class="panel-heading"
|
||||
data-test-subj="dashboardPanelHeading-myembeddabletitle"
|
||||
>
|
||||
<span
|
||||
aria-label="Dashboard panel: "
|
||||
aria-label="Dashboard panel: my embeddable title"
|
||||
class="panel-title"
|
||||
data-test-subj="dashboardPanelTitle"
|
||||
title=""
|
||||
/>
|
||||
title="my embeddable title"
|
||||
>
|
||||
my embeddable title
|
||||
</span>
|
||||
<div
|
||||
class="kuiMicroButtonGroup"
|
||||
>
|
||||
|
|
|
@ -11,6 +11,7 @@ import {
|
|||
updateViewMode,
|
||||
setPanels,
|
||||
updateTimeRange,
|
||||
embeddableIsInitialized,
|
||||
} from '../actions';
|
||||
import { Provider } from 'react-redux';
|
||||
|
||||
|
@ -37,6 +38,8 @@ beforeAll(() => {
|
|||
store.dispatch(updateTimeRange({ to: 'now', from: 'now-15m' }));
|
||||
store.dispatch(updateViewMode(DashboardViewMode.EDIT));
|
||||
store.dispatch(setPanels({ 'foo1': { panelIndex: 'foo1' } }));
|
||||
const metadata = { title: 'my embeddable title', editUrl: 'editme' };
|
||||
store.dispatch(embeddableIsInitialized({ metadata, panelId: 'foo1' }));
|
||||
});
|
||||
|
||||
test('DashboardPanel matches snapshot', () => {
|
||||
|
|
|
@ -13,7 +13,7 @@ export function PanelHeader({ title, actions, isViewOnlyMode, hidePanelTitles })
|
|||
}
|
||||
|
||||
return (
|
||||
<div className="panel-heading">
|
||||
<div className="panel-heading" data-test-subj={`dashboardPanelHeading-${title.replace(/\s/g, '')}`}>
|
||||
<span
|
||||
data-test-subj="dashboardPanelTitle"
|
||||
className="panel-title"
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
ng-switch="mode"
|
||||
ng-init="mode = 'visualization'"
|
||||
>
|
||||
<h2 class="kuiLocalDropdownTitle">
|
||||
<h2 class="kuiLocalDropdownTitle" data-test-subj="dashboardAddPanel">
|
||||
Add Panels
|
||||
</h2>
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@ import React from 'react';
|
|||
|
||||
function NoDataComponent() {
|
||||
return (
|
||||
<div className="metrics_issue">
|
||||
<div className="metrics_issue" data-test-subj="noTSVBDataMessage">
|
||||
<div className="metrics_issue__title">No data to display for the selected metrics .</div>
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -34,7 +34,7 @@ function MarkdownVisualization(props) {
|
|||
if (reversed) className += ' reversed';
|
||||
const markdownError = markdownSource instanceof Error ? markdownSource : null;
|
||||
markdown = (
|
||||
<div className={className}>
|
||||
<div className={className} data-test-subj="tsvbMarkdown">
|
||||
{markdownError && <ErrorComponent error={markdownError} />}
|
||||
<style type="text/css">{model.markdown_css}</style>
|
||||
<div className={contentClassName}>
|
||||
|
|
|
@ -135,7 +135,13 @@ class Metric extends Component {
|
|||
<div ref={(el) => this.inner = el} className="rhythm_metric__inner" style={styles.inner}>
|
||||
<div className="rhythm_metric__primary">
|
||||
{ primaryLabel }
|
||||
<div style={styles.primary_value} className="rhythm_metric__primary-value">{ primaryValue }</div>
|
||||
<div
|
||||
style={styles.primary_value}
|
||||
data-test-subj="tsvbMetricValue"
|
||||
className="rhythm_metric__primary-value"
|
||||
>
|
||||
{ primaryValue }
|
||||
</div>
|
||||
</div>
|
||||
{ secondarySnippet }
|
||||
{additionalLabel}
|
||||
|
|
|
@ -47,7 +47,7 @@ class TopN extends Component {
|
|||
style={styles.innerBar}
|
||||
/>
|
||||
</td>
|
||||
<td width="1*" className="rhythm_top_n__value">{ value }</td>
|
||||
<td width="1*" className="rhythm_top_n__value" data-test-subj="tsvbTopNValue">{ value }</td>
|
||||
</tr>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -17,6 +17,7 @@ export default props => (row, i) => {
|
|||
<div
|
||||
key={key}
|
||||
className={classes.join(' ')}
|
||||
data-test-subj="tsvbLegendItem"
|
||||
>
|
||||
<button
|
||||
onClick={event => props.onToggle(event, row.id)}
|
||||
|
|
|
@ -16,6 +16,7 @@ export class TagCloudVisualization {
|
|||
|
||||
const cloudContainer = document.createElement('div');
|
||||
cloudContainer.classList.add('tagcloud-vis');
|
||||
cloudContainer.setAttribute('data-test-subj', 'tagCloudVisualization');
|
||||
this._containerNode.appendChild(cloudContainer);
|
||||
|
||||
this._vis = vis;
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
</div>
|
||||
|
||||
<button
|
||||
data-test-subj="filterEditorModalCloseButton"
|
||||
class="kuiModalHeaderCloseButton kuiIcon fa-times"
|
||||
ng-click="filterEditor.onCancel()"
|
||||
aria-label="Close filter popover"
|
||||
|
|
|
@ -2010,7 +2010,7 @@ Licensed under the MIT license.
|
|||
ctx.lineTo(xrange.to + subPixel, yrange.to);
|
||||
} else {
|
||||
ctx.moveTo(xrange.from, yrange.to + subPixel);
|
||||
ctx.lineTo(xrange.to, yrange.to + subPixel);
|
||||
ctx.lineTo(xrange.to, yrange.to + subPixel);
|
||||
}
|
||||
ctx.stroke();
|
||||
} else {
|
||||
|
@ -2525,9 +2525,9 @@ Licensed under the MIT license.
|
|||
radius = series.points.radius,
|
||||
symbol = series.points.symbol;
|
||||
|
||||
// If the user sets the line width to 0, we change it to a very
|
||||
// If the user sets the line width to 0, we change it to a very
|
||||
// small value. A line width of 0 seems to force the default of 1.
|
||||
// Doing the conditional here allows the shadow setting to still be
|
||||
// Doing the conditional here allows the shadow setting to still be
|
||||
// optional even with a lineWidth of 0.
|
||||
|
||||
if( lw == 0 )
|
||||
|
@ -2771,7 +2771,7 @@ Licensed under the MIT license.
|
|||
|
||||
fragments.push(
|
||||
'<td class="legendColorBox"><div style="border:1px solid ' + options.legend.labelBoxBorderColor + ';padding:1px"><div style="width:4px;height:0;border:5px solid ' + entry.color + ';overflow:hidden"></div></div></td>' +
|
||||
'<td class="legendLabel">' + entry.label + '</td>'
|
||||
'<td class="legendLabel" data-test-subj="flotLegendLabel">' + entry.label + '</td>'
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -65,6 +65,7 @@
|
|||
<li ng-style="{'visibility':'hidden'}" ng-if="page.last">
|
||||
<button
|
||||
class="euiButtonEmpty euiButtonEmpty--text euiButtonEmpty--small euiPaginationButton"
|
||||
data-test-subj="paginateNext"
|
||||
ng-click="paginate.goToPage(page.next)"
|
||||
>
|
||||
<span class="euiButtonEmpty__content">»</span>
|
||||
|
@ -73,6 +74,7 @@
|
|||
<li ng-style="{'visibility':'visible'}" ng-if="!page.last">
|
||||
<button
|
||||
class="euiButtonEmpty euiButtonEmpty--text euiButtonEmpty--small euiPaginationButton"
|
||||
data-test-subj="paginateNext"
|
||||
ng-click="paginate.goToPage(page.next)"
|
||||
>
|
||||
<span class="euiButtonEmpty__content">»</span>
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
import expect from 'expect.js';
|
||||
|
||||
import {
|
||||
VisualizeConstants
|
||||
} from '../../../../src/core_plugins/kibana/public/visualize/visualize_constants';
|
||||
|
||||
export default function ({ getService, getPageObjects }) {
|
||||
const retry = getService('retry');
|
||||
const PageObjects = getPageObjects(['dashboard', 'header', 'visualize']);
|
||||
const remote = getService('remote');
|
||||
const dashboardAddPanel = getService('dashboardAddPanel');
|
||||
|
||||
describe('create and add embeddables', async () => {
|
||||
before(async () => {
|
||||
await PageObjects.dashboard.loadSavedDashboard('few panels');
|
||||
});
|
||||
|
||||
describe('add new visualization link', () => {
|
||||
it('adds a new visualization', async () => {
|
||||
const originalPanelCount = await PageObjects.dashboard.getPanelCount();
|
||||
await PageObjects.dashboard.clickEdit();
|
||||
await dashboardAddPanel.ensureAddPanelIsShowing();
|
||||
await dashboardAddPanel.clickAddNewEmbeddableLink();
|
||||
await PageObjects.visualize.clickAreaChart();
|
||||
await PageObjects.visualize.clickNewSearch();
|
||||
await PageObjects.visualize.saveVisualization('visualization from add new link');
|
||||
|
||||
return retry.try(async () => {
|
||||
const panelCount = await PageObjects.dashboard.getPanelCount();
|
||||
expect(panelCount).to.eql(originalPanelCount + 1);
|
||||
});
|
||||
});
|
||||
|
||||
it('saves the saved visualization url to the app link', async () => {
|
||||
await PageObjects.header.clickVisualize();
|
||||
const currentUrl = await remote.getCurrentUrl();
|
||||
expect(currentUrl).to.contain(VisualizeConstants.EDIT_PATH);
|
||||
});
|
||||
|
||||
after(async () => {
|
||||
await PageObjects.header.clickDashboard();
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
@ -1,266 +0,0 @@
|
|||
import expect from 'expect.js';
|
||||
import {
|
||||
VisualizeConstants
|
||||
} from '../../../../src/core_plugins/kibana/public/visualize/visualize_constants';
|
||||
|
||||
export default function ({ getService, getPageObjects }) {
|
||||
const retry = getService('retry');
|
||||
const log = getService('log');
|
||||
const dashboardVisualizations = getService('dashboardVisualizations');
|
||||
const remote = getService('remote');
|
||||
const PageObjects = getPageObjects(['common', 'dashboard', 'header', 'visualize', 'discover']);
|
||||
const testVisualizationTitles = [];
|
||||
const testVisualizationDescriptions = [];
|
||||
|
||||
describe('dashboard tab', function describeIndexTests() {
|
||||
before(async function () {
|
||||
await PageObjects.dashboard.initTests();
|
||||
await PageObjects.dashboard.preserveCrossAppState();
|
||||
});
|
||||
|
||||
after(async function () {
|
||||
// avoids any 'Object with id x not found' errors when switching tests.
|
||||
await PageObjects.header.clickVisualize();
|
||||
await PageObjects.visualize.gotoLandingPage();
|
||||
await PageObjects.header.clickDashboard();
|
||||
await PageObjects.dashboard.gotoDashboardLandingPage();
|
||||
});
|
||||
|
||||
it('should be able to add visualizations to dashboard', async function addVisualizations() {
|
||||
await PageObjects.dashboard.clickNewDashboard();
|
||||
await dashboardVisualizations.createAndAddTSVBVisualization('TSVB');
|
||||
await PageObjects.dashboard.addVisualizations(PageObjects.dashboard.getTestVisualizationNames());
|
||||
await dashboardVisualizations.createAndAddSavedSearch({ name: 'saved search', fields: ['bytes', 'agent'] });
|
||||
testVisualizationTitles.push('TSVB');
|
||||
testVisualizationTitles.splice(1, 0, ...PageObjects.dashboard.getTestVisualizationNames());
|
||||
testVisualizationTitles.push('saved search');
|
||||
|
||||
testVisualizationDescriptions.push('');
|
||||
testVisualizationDescriptions.splice(
|
||||
1, 0, ...PageObjects.dashboard.getTestVisualizations().map(visualization => visualization.description)
|
||||
);
|
||||
testVisualizationDescriptions.push('');
|
||||
});
|
||||
|
||||
it('set the timepicker time to that which contains our test data', async function setTimepicker() {
|
||||
await PageObjects.dashboard.setTimepickerInDataRange();
|
||||
});
|
||||
|
||||
it('saved search loaded with columns', async () => {
|
||||
const headers = await PageObjects.discover.getColumnHeaders();
|
||||
expect(headers.length).to.be(3);
|
||||
expect(headers[1]).to.be('bytes');
|
||||
expect(headers[2]).to.be('agent');
|
||||
});
|
||||
|
||||
it('should save and load dashboard', async function saveAndLoadDashboard() {
|
||||
const dashboardName = 'Dashboard Test 1';
|
||||
await PageObjects.dashboard.saveDashboard(dashboardName);
|
||||
await PageObjects.dashboard.gotoDashboardLandingPage();
|
||||
|
||||
await retry.try(function () {
|
||||
log.debug('now re-load previously saved dashboard');
|
||||
return PageObjects.dashboard.loadSavedDashboard(dashboardName);
|
||||
});
|
||||
});
|
||||
|
||||
it('should have all the expected visualizations', function checkVisualizations() {
|
||||
return retry.tryForTime(10000, function () {
|
||||
return PageObjects.dashboard.getPanelTitles()
|
||||
.then(function (panelTitles) {
|
||||
expect(panelTitles).to.eql(testVisualizationTitles);
|
||||
});
|
||||
})
|
||||
.then(function () {
|
||||
});
|
||||
});
|
||||
|
||||
it('retains dark theme in state', async function () {
|
||||
await PageObjects.dashboard.clickEdit();
|
||||
await PageObjects.dashboard.useDarkTheme(true);
|
||||
await PageObjects.header.clickVisualize();
|
||||
await PageObjects.header.clickDashboard();
|
||||
const isDarkThemeOn = await PageObjects.dashboard.isDarkThemeOn();
|
||||
expect(isDarkThemeOn).to.equal(true);
|
||||
});
|
||||
|
||||
it('should be able to hide all panel titles', async function () {
|
||||
await PageObjects.dashboard.checkHideTitle();
|
||||
await retry.tryForTime(10000, async function () {
|
||||
const titles = await PageObjects.dashboard.getPanelTitles();
|
||||
expect(titles[0]).to.eql('');
|
||||
});
|
||||
});
|
||||
|
||||
it('should be able to unhide all panel titles', async function () {
|
||||
await PageObjects.dashboard.checkHideTitle();
|
||||
await retry.tryForTime(10000, async function () {
|
||||
const titles = await PageObjects.dashboard.getPanelTitles();
|
||||
expect(titles[0]).to.eql('TSVB');
|
||||
});
|
||||
});
|
||||
|
||||
describe('expanding a panel', () => {
|
||||
it('hides other panels', async () => {
|
||||
// Don't expand TSVB since it doesn't have the spy panel.
|
||||
const panels = await PageObjects.dashboard.getDashboardPanels();
|
||||
await PageObjects.dashboard.toggleExpandPanel(panels[1]);
|
||||
await retry.try(async () => {
|
||||
const panels = await PageObjects.dashboard.getDashboardPanels();
|
||||
expect(panels.length).to.eql(1);
|
||||
});
|
||||
});
|
||||
|
||||
it('does not show the spy pane toggle if mouse is not hovering', async () => {
|
||||
// move mouse off the panel.
|
||||
await PageObjects.header.clickTimepicker();
|
||||
await PageObjects.header.clickTimepicker();
|
||||
|
||||
// no spy pane without hover
|
||||
const spyToggleExists = await PageObjects.visualize.getSpyToggleExists();
|
||||
expect(spyToggleExists).to.be(false);
|
||||
});
|
||||
|
||||
it('shows the spy pane toggle on hover', async () => {
|
||||
const panels = await PageObjects.dashboard.getDashboardPanels();
|
||||
// Simulate hover
|
||||
await remote.moveMouseTo(panels[0]);
|
||||
const spyToggleExists = await PageObjects.visualize.getSpyToggleExists();
|
||||
expect(spyToggleExists).to.be(true);
|
||||
});
|
||||
|
||||
// This was an actual bug that appeared, where the spy pane appeared on panels after adding them, but
|
||||
// disappeared when a new dashboard was opened up.
|
||||
it('shows the spy pane toggle directly after opening a dashboard', async () => {
|
||||
await PageObjects.dashboard.saveDashboard('spy pane test');
|
||||
await PageObjects.dashboard.gotoDashboardLandingPage();
|
||||
await PageObjects.dashboard.loadSavedDashboard('spy pane test');
|
||||
const panels = await PageObjects.dashboard.getDashboardPanels();
|
||||
// Simulate hover
|
||||
await remote.moveMouseTo(panels[1]);
|
||||
const spyToggleExists = await PageObjects.visualize.getSpyToggleExists();
|
||||
expect(spyToggleExists).to.be(true);
|
||||
});
|
||||
|
||||
it('shows other panels after being minimized', async () => {
|
||||
// Panels are all minimized on a fresh open of a dashboard, so we need to re-expand in order to then minimize.
|
||||
await PageObjects.dashboard.toggleExpandPanel();
|
||||
await PageObjects.dashboard.toggleExpandPanel();
|
||||
|
||||
// Add a retry to fix https://github.com/elastic/kibana/issues/14574. Perhaps the recent changes to this
|
||||
// being a CSS update is causing the UI to change slower than grabbing the panels?
|
||||
retry.try(async () => {
|
||||
const panels = await PageObjects.dashboard.getDashboardPanels();
|
||||
expect(panels.length).to.eql(testVisualizationTitles.length);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('embed mode', () => {
|
||||
it('hides the chrome', async () => {
|
||||
let isChromeVisible = await PageObjects.common.isChromeVisible();
|
||||
expect(isChromeVisible).to.be(true);
|
||||
|
||||
const currentUrl = await remote.getCurrentUrl();
|
||||
const newUrl = currentUrl + '&embed=true';
|
||||
// Embed parameter only works on a hard refresh.
|
||||
const useTimeStamp = true;
|
||||
await remote.get(newUrl.toString(), useTimeStamp);
|
||||
|
||||
await retry.try(async () => {
|
||||
isChromeVisible = await PageObjects.common.isChromeVisible();
|
||||
expect(isChromeVisible).to.be(false);
|
||||
});
|
||||
});
|
||||
|
||||
after(async function () {
|
||||
console.log('showing chrome again');
|
||||
const currentUrl = await remote.getCurrentUrl();
|
||||
const newUrl = currentUrl.replace('&embed=true', '');
|
||||
// First use the timestamp to cause a hard refresh so the new embed parameter works correctly.
|
||||
let useTimeStamp = true;
|
||||
await remote.get(newUrl.toString(), useTimeStamp);
|
||||
// Then get rid of the timestamp so the rest of the tests work with state and app switching.
|
||||
useTimeStamp = false;
|
||||
await remote.get(newUrl.toString(), useTimeStamp);
|
||||
});
|
||||
});
|
||||
|
||||
describe('full screen mode', () => {
|
||||
it('option not available in edit mode', async () => {
|
||||
await PageObjects.dashboard.clickEdit();
|
||||
const exists = await PageObjects.dashboard.fullScreenModeMenuItemExists();
|
||||
expect(exists).to.be(false);
|
||||
});
|
||||
|
||||
it('available in view mode', async () => {
|
||||
await PageObjects.dashboard.saveDashboard('full screen test');
|
||||
const exists = await PageObjects.dashboard.fullScreenModeMenuItemExists();
|
||||
expect(exists).to.be(true);
|
||||
});
|
||||
|
||||
it('hides the chrome', async () => {
|
||||
let isChromeVisible = await PageObjects.common.isChromeVisible();
|
||||
expect(isChromeVisible).to.be(true);
|
||||
|
||||
await PageObjects.dashboard.clickFullScreenMode();
|
||||
|
||||
await retry.try(async () => {
|
||||
isChromeVisible = await PageObjects.common.isChromeVisible();
|
||||
expect(isChromeVisible).to.be(false);
|
||||
});
|
||||
});
|
||||
|
||||
it('displays exit full screen logo button', async () => {
|
||||
const exists = await PageObjects.dashboard.exitFullScreenLogoButtonExists();
|
||||
expect(exists).to.be(true);
|
||||
});
|
||||
|
||||
it('displays exit full screen logo button when panel is expanded', async () => {
|
||||
await PageObjects.dashboard.toggleExpandPanel();
|
||||
|
||||
const exists = await PageObjects.dashboard.exitFullScreenTextButtonExists();
|
||||
expect(exists).to.be(true);
|
||||
});
|
||||
|
||||
it('exits when the text button is clicked on', async () => {
|
||||
const logoButton = await PageObjects.dashboard.getExitFullScreenLogoButton();
|
||||
await remote.moveMouseTo(logoButton);
|
||||
await PageObjects.dashboard.clickExitFullScreenTextButton();
|
||||
|
||||
await retry.try(async () => {
|
||||
const isChromeVisible = await PageObjects.common.isChromeVisible();
|
||||
expect(isChromeVisible).to.be(true);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
});
|
||||
|
||||
describe('add new visualization link', () => {
|
||||
it('adds a new visualization', async () => {
|
||||
await PageObjects.dashboard.clickEdit();
|
||||
await PageObjects.dashboard.clickAddVisualization();
|
||||
await PageObjects.dashboard.clickAddNewVisualizationLink();
|
||||
await PageObjects.visualize.clickAreaChart();
|
||||
await PageObjects.visualize.clickNewSearch();
|
||||
await PageObjects.visualize.saveVisualization('visualization from add new link');
|
||||
|
||||
return retry.try(async () => {
|
||||
const panelCount = await PageObjects.dashboard.getPanelCount();
|
||||
expect(panelCount).to.eql(testVisualizationTitles.length + 1);
|
||||
});
|
||||
});
|
||||
|
||||
it('saves the saved visualization url to the app link', async () => {
|
||||
await PageObjects.header.clickVisualize();
|
||||
const currentUrl = await remote.getCurrentUrl();
|
||||
expect(currentUrl).to.contain(VisualizeConstants.EDIT_PATH);
|
||||
});
|
||||
|
||||
after(async () => {
|
||||
await PageObjects.header.clickDashboard();
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
|
@ -1,42 +1,105 @@
|
|||
import { PIE_CHART_VIS_NAME } from '../../page_objects/dashboard_page';
|
||||
import expect from 'expect.js';
|
||||
|
||||
export default function ({ getService, getPageObjects }) {
|
||||
const dashboardExpect = getService('dashboardExpect');
|
||||
const dashboardVisualizations = getService('dashboardVisualizations');
|
||||
const dashboardAddPanel = getService('dashboardAddPanel');
|
||||
const testSubjects = getService('testSubjects');
|
||||
const filterBar = getService('filterBar');
|
||||
const PageObjects = getPageObjects(['dashboard', 'header', 'visualize']);
|
||||
|
||||
describe('dashboard filter bar', function describeIndexTests() {
|
||||
before(async function () {
|
||||
await PageObjects.dashboard.initTests();
|
||||
await PageObjects.dashboard.preserveCrossAppState();
|
||||
});
|
||||
|
||||
after(async function () {
|
||||
// avoids any 'Object with id x not found' errors when switching tests.
|
||||
await PageObjects.header.clickVisualize();
|
||||
await PageObjects.visualize.gotoLandingPage();
|
||||
await PageObjects.header.clickDashboard();
|
||||
describe('dashboard filter bar', async () => {
|
||||
before(async () => {
|
||||
await PageObjects.dashboard.gotoDashboardLandingPage();
|
||||
});
|
||||
|
||||
it('Filter bar field list uses default index pattern on an empty dashboard', async () => {
|
||||
await PageObjects.dashboard.clickNewDashboard();
|
||||
await testSubjects.click('addFilter');
|
||||
await dashboardExpect.fieldSuggestionIndexPatterns(['logstash-*']);
|
||||
describe('Add a filter bar', async function () {
|
||||
before(async () => {
|
||||
await PageObjects.dashboard.gotoDashboardLandingPage();
|
||||
});
|
||||
|
||||
it('should show on an empty dashboard', async function () {
|
||||
await PageObjects.dashboard.clickNewDashboard();
|
||||
const hasAddFilter = await testSubjects.exists('addFilter');
|
||||
expect(hasAddFilter).to.be(true);
|
||||
});
|
||||
|
||||
it ('should continue to show for visualizations with no search source', async () => {
|
||||
await dashboardAddPanel.addVisualization('input control');
|
||||
const hasAddFilter = await testSubjects.exists('addFilter');
|
||||
expect(hasAddFilter).to.be(true);
|
||||
});
|
||||
});
|
||||
|
||||
// TODO: Use a data set that has more than one index pattern to better test this.
|
||||
it('Filter bar field list shows index pattern of vis when one is added', async () => {
|
||||
await PageObjects.dashboard.addVisualizations([PIE_CHART_VIS_NAME]);
|
||||
await testSubjects.click('filterfieldSuggestionList');
|
||||
await dashboardExpect.fieldSuggestionIndexPatterns(['logstash-*']);
|
||||
describe('filter editor field list', async () => {
|
||||
before(async () => {
|
||||
await PageObjects.dashboard.gotoDashboardLandingPage();
|
||||
await PageObjects.dashboard.clickNewDashboard();
|
||||
});
|
||||
|
||||
it('uses default index pattern on an empty dashboard', async () => {
|
||||
await testSubjects.click('addFilter');
|
||||
await dashboardExpect.fieldSuggestionIndexPatterns(['logstash-*']);
|
||||
});
|
||||
|
||||
it('shows index pattern of vis when one is added', async () => {
|
||||
await dashboardAddPanel.addVisualization('animal sounds pie');
|
||||
await PageObjects.header.waitUntilLoadingHasFinished();
|
||||
await filterBar.ensureFieldEditorModalIsClosed();
|
||||
await testSubjects.click('addFilter');
|
||||
await dashboardExpect.fieldSuggestionIndexPatterns(['animals-*']);
|
||||
});
|
||||
|
||||
it('works when a vis with no index pattern is added', async () => {
|
||||
await dashboardAddPanel.addVisualization('markdown');
|
||||
await PageObjects.header.waitUntilLoadingHasFinished();
|
||||
await filterBar.ensureFieldEditorModalIsClosed();
|
||||
await testSubjects.click('addFilter');
|
||||
await dashboardExpect.fieldSuggestionIndexPatterns(['animals-*']);
|
||||
});
|
||||
});
|
||||
|
||||
it('Filter bar field list works when a vis with no index pattern is added', async () => {
|
||||
await dashboardVisualizations.createAndAddMarkdown({ name: 'markdown', markdown: 'hi ima markdown' });
|
||||
await testSubjects.click('addFilter');
|
||||
await dashboardExpect.fieldSuggestionIndexPatterns(['logstash-*']);
|
||||
describe('filter pills', async function () {
|
||||
before(async () => {
|
||||
await PageObjects.dashboard.gotoDashboardLandingPage();
|
||||
await PageObjects.dashboard.clickNewDashboard();
|
||||
await PageObjects.dashboard.setTimepickerIn63DataRange();
|
||||
});
|
||||
|
||||
it('are not selected by default', async function () {
|
||||
const filters = await PageObjects.dashboard.getFilters(1000);
|
||||
expect(filters.length).to.equal(0);
|
||||
});
|
||||
|
||||
it('are added when a pie chart slice is clicked', async function () {
|
||||
await dashboardAddPanel.addVisualization('Rendering Test: pie');
|
||||
await PageObjects.dashboard.waitForRenderComplete();
|
||||
await PageObjects.dashboard.filterOnPieSlice('4,886');
|
||||
const filters = await PageObjects.dashboard.getFilters();
|
||||
expect(filters.length).to.equal(1);
|
||||
|
||||
await dashboardExpect.pieSliceCount(1);
|
||||
});
|
||||
|
||||
it('are preserved after saving a dashboard', async () => {
|
||||
await PageObjects.dashboard.saveDashboard('with filters');
|
||||
await PageObjects.header.waitUntilLoadingHasFinished();
|
||||
|
||||
const filters = await PageObjects.dashboard.getFilters();
|
||||
expect(filters.length).to.equal(1);
|
||||
|
||||
await dashboardExpect.pieSliceCount(1);
|
||||
});
|
||||
|
||||
it('are preserved after opening a dashboard saved with filters', async () => {
|
||||
await PageObjects.dashboard.gotoDashboardLandingPage();
|
||||
await PageObjects.dashboard.loadSavedDashboard('with filters');
|
||||
await PageObjects.header.waitUntilLoadingHasFinished();
|
||||
|
||||
const filters = await PageObjects.dashboard.getFilters();
|
||||
expect(filters.length).to.equal(1);
|
||||
|
||||
await dashboardExpect.pieSliceCount(1);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
198
test/functional/apps/dashboard/_dashboard_filtering.js
Normal file
198
test/functional/apps/dashboard/_dashboard_filtering.js
Normal file
|
@ -0,0 +1,198 @@
|
|||
import expect from 'expect.js';
|
||||
|
||||
/**
|
||||
* Test the querying capabilities of dashboard, and make sure visualizations show the expected results, especially
|
||||
* with nested queries and filters on the visualizations themselves.
|
||||
*/
|
||||
export default function ({ getService, getPageObjects }) {
|
||||
const dashboardExpect = getService('dashboardExpect');
|
||||
const dashboardAddPanel = getService('dashboardAddPanel');
|
||||
const testSubjects = getService('testSubjects');
|
||||
const filterBar = getService('filterBar');
|
||||
const PageObjects = getPageObjects(['dashboard', 'header', 'visualize']);
|
||||
|
||||
describe('dashboard filtering', async () => {
|
||||
before(async () => {
|
||||
await PageObjects.dashboard.gotoDashboardLandingPage();
|
||||
});
|
||||
|
||||
describe('adding a filter that excludes all data', async () => {
|
||||
before(async () => {
|
||||
await PageObjects.dashboard.clickNewDashboard();
|
||||
await PageObjects.dashboard.setTimepickerIn63DataRange();
|
||||
await dashboardAddPanel.addEveryVisualization('"Filter Bytes Test"');
|
||||
await dashboardAddPanel.addEverySavedSearch('"Filter Bytes Test"');
|
||||
await dashboardAddPanel.closeAddPanel();
|
||||
await PageObjects.header.waitUntilLoadingHasFinished();
|
||||
await PageObjects.dashboard.waitForRenderComplete();
|
||||
await filterBar.addFilter('bytes', 'is', '12345678', 'kuiTextInput');
|
||||
await PageObjects.header.waitUntilLoadingHasFinished();
|
||||
await PageObjects.dashboard.waitForRenderComplete();
|
||||
});
|
||||
|
||||
it('filters on pie charts', async () => {
|
||||
await dashboardExpect.pieSliceCount(0);
|
||||
});
|
||||
|
||||
it('area, bar and heatmap charts filtered', async () => {
|
||||
await dashboardExpect.seriesElementCount(0);
|
||||
});
|
||||
|
||||
it('data tables are filtered', async () => {
|
||||
await dashboardExpect.dataTableRowCount(0);
|
||||
});
|
||||
|
||||
it('goal and guages are filtered', async () => {
|
||||
await dashboardExpect.goalAndGuageLabelsExist(['0', '0%']);
|
||||
});
|
||||
|
||||
it('tsvb time series shows no data message', async () => {
|
||||
expect(await testSubjects.exists('noTSVBDataMessage')).to.be(true);
|
||||
await dashboardExpect.tsvbTimeSeriesLegendCount(0);
|
||||
});
|
||||
|
||||
it('metric value shows no data', async () => {
|
||||
await dashboardExpect.metricValuesExist(['-']);
|
||||
});
|
||||
|
||||
it('tag cloud values are filtered', async () => {
|
||||
await dashboardExpect.emptyTagCloudFound();
|
||||
});
|
||||
|
||||
it('tsvb metric is filtered', async () => {
|
||||
await dashboardExpect.tsvbMetricValuesExist(['0 custom template']);
|
||||
});
|
||||
|
||||
it('tsvb top n is filtered', async () => {
|
||||
await dashboardExpect.tsvbTopNValuesExist(['0', '0']);
|
||||
});
|
||||
|
||||
it('saved search is filtered', async () => {
|
||||
await dashboardExpect.savedSearchRowCount(0);
|
||||
});
|
||||
|
||||
it('timelion is filtered', async () => {
|
||||
await dashboardExpect.timelionLegendCount(0);
|
||||
});
|
||||
|
||||
it('vega is filtered', async () => {
|
||||
await dashboardExpect.vegaTextsDoNotExist(['5,000']);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
describe('disabling a filter unfilters the data on', async () => {
|
||||
before(async () => {
|
||||
await testSubjects.click('disableFilter-bytes');
|
||||
await PageObjects.header.waitUntilLoadingHasFinished();
|
||||
await PageObjects.dashboard.waitForRenderComplete();
|
||||
});
|
||||
|
||||
it('pie charts', async () => {
|
||||
await dashboardExpect.pieSliceCount(5);
|
||||
});
|
||||
|
||||
it('area, bar and heatmap charts', async () => {
|
||||
await dashboardExpect.seriesElementCount(3);
|
||||
});
|
||||
|
||||
it('data tables', async () => {
|
||||
await dashboardExpect.dataTableRowCount(10);
|
||||
});
|
||||
|
||||
it('goal and guages', async () => {
|
||||
await dashboardExpect.goalAndGuageLabelsExist(['40%', '7,544']);
|
||||
});
|
||||
|
||||
it('tsvb time series', async () => {
|
||||
expect(await testSubjects.exists('noTSVBDataMessage')).to.be(false);
|
||||
await dashboardExpect.tsvbTimeSeriesLegendCount(10);
|
||||
});
|
||||
|
||||
it('metric value', async () => {
|
||||
await dashboardExpect.metricValuesExist(['101']);
|
||||
});
|
||||
|
||||
it('tag cloud', async () => {
|
||||
await dashboardExpect.tagCloudWithValuesFound(['9,972', '4,886', '1,944', '9,025']);
|
||||
});
|
||||
|
||||
it('tsvb metric', async () => {
|
||||
await dashboardExpect.tsvbMetricValuesExist(['50,465 custom template']);
|
||||
});
|
||||
|
||||
it('tsvb top n', async () => {
|
||||
await dashboardExpect.tsvbTopNValuesExist(['6,308.13', '6,308.13']);
|
||||
});
|
||||
|
||||
it('tsvb markdown', async () => {
|
||||
await dashboardExpect.tsvbMarkdownWithValuesExists(['7,209.29']);
|
||||
});
|
||||
|
||||
it('saved searches', async () => {
|
||||
await dashboardExpect.savedSearchRowCount(1);
|
||||
});
|
||||
|
||||
it('vega', async () => {
|
||||
await dashboardExpect.vegaTextsExist(['5,000']);
|
||||
});
|
||||
});
|
||||
|
||||
describe('nested filtering', async () => {
|
||||
before(async () => {
|
||||
await PageObjects.dashboard.gotoDashboardLandingPage();
|
||||
});
|
||||
|
||||
it('visualization saved with a query filters data', async () => {
|
||||
await PageObjects.dashboard.clickNewDashboard();
|
||||
await PageObjects.dashboard.setTimepickerIn63DataRange();
|
||||
|
||||
await dashboardAddPanel.addVisualization('animal sounds pie');
|
||||
await PageObjects.header.waitUntilLoadingHasFinished();
|
||||
await PageObjects.dashboard.waitForRenderComplete();
|
||||
await dashboardExpect.pieSliceCount(5);
|
||||
|
||||
await PageObjects.dashboard.clickEditVisualization();
|
||||
await PageObjects.dashboard.setQuery('weightLbs:>50');
|
||||
await PageObjects.dashboard.clickFilterButton();
|
||||
await PageObjects.header.waitUntilLoadingHasFinished();
|
||||
await PageObjects.dashboard.waitForRenderComplete();
|
||||
await dashboardExpect.pieSliceCount(3);
|
||||
|
||||
await PageObjects.visualize.saveVisualization('animal sounds pie');
|
||||
await PageObjects.header.clickDashboard();
|
||||
await PageObjects.header.waitUntilLoadingHasFinished();
|
||||
await PageObjects.dashboard.waitForRenderComplete();
|
||||
await dashboardExpect.pieSliceCount(3);
|
||||
});
|
||||
|
||||
it('Nested visualization filter pills filters data as expected', async () => {
|
||||
await PageObjects.dashboard.clickEditVisualization();
|
||||
await PageObjects.header.waitUntilLoadingHasFinished();
|
||||
await PageObjects.dashboard.waitForRenderComplete();
|
||||
await PageObjects.dashboard.filterOnPieSlice('grr');
|
||||
await PageObjects.header.waitUntilLoadingHasFinished();
|
||||
await dashboardExpect.pieSliceCount(1);
|
||||
|
||||
await PageObjects.visualize.saveVisualization('animal sounds pie');
|
||||
await PageObjects.header.clickDashboard();
|
||||
|
||||
await dashboardExpect.pieSliceCount(1);
|
||||
});
|
||||
|
||||
it('Pie chart linked to saved search filters data', async () => {
|
||||
await dashboardAddPanel.addVisualization('Filter Test: animals: linked to search with filter');
|
||||
await dashboardExpect.pieSliceCount(3);
|
||||
});
|
||||
|
||||
it('Pie chart linked to saved search filters shows no data with conflicting dashboard query', async () => {
|
||||
await PageObjects.dashboard.setQuery('weightLbs:<40');
|
||||
await PageObjects.dashboard.clickFilterButton();
|
||||
await PageObjects.header.waitUntilLoadingHasFinished();
|
||||
await PageObjects.dashboard.waitForRenderComplete();
|
||||
|
||||
await dashboardExpect.pieSliceCount(0);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
|
@ -1,51 +1,21 @@
|
|||
import expect from 'expect.js';
|
||||
|
||||
export default function ({ getService, getPageObjects }) {
|
||||
const find = getService('find');
|
||||
const remote = getService('remote');
|
||||
const PageObjects = getPageObjects(['dashboard', 'header', 'common']);
|
||||
|
||||
const VIS_TITLES = [
|
||||
PageObjects.dashboard.getTestVisualizationNames()[0],
|
||||
PageObjects.dashboard.getTestVisualizationNames()[1],
|
||||
PageObjects.dashboard.getTestVisualizationNames()[2],
|
||||
];
|
||||
|
||||
// Order returned by find.allByCssSelector is not guaranteed and can change based on timing
|
||||
// Use this function to avoid looking for elements by hard-coded array index.
|
||||
const getPanelTitleElement = async (title) => {
|
||||
const panelTitleElements = await find.allByCssSelector('.panel-title');
|
||||
for (let i = 0; i < panelTitleElements.length; i++) {
|
||||
const panelText = await panelTitleElements[i].getVisibleText();
|
||||
if (panelText === title) {
|
||||
return panelTitleElements[i];
|
||||
}
|
||||
}
|
||||
|
||||
throw new Error(`Unable to find panel with title: "${title}"`);
|
||||
};
|
||||
const PageObjects = getPageObjects(['dashboard']);
|
||||
|
||||
describe('dashboard grid', () => {
|
||||
|
||||
before(async () => {
|
||||
return PageObjects.dashboard.initTests();
|
||||
});
|
||||
|
||||
after(async () => {
|
||||
// avoids any 'Object with id x not found' errors when switching tests.
|
||||
await PageObjects.header.clickDashboard();
|
||||
await PageObjects.dashboard.gotoDashboardLandingPage();
|
||||
await PageObjects.dashboard.loadSavedDashboard('few panels');
|
||||
await PageObjects.dashboard.clickEdit();
|
||||
});
|
||||
|
||||
describe('move panel', () => {
|
||||
// Specific test after https://github.com/elastic/kibana/issues/14764 fix
|
||||
it('Can move panel from bottom to top row', async () => {
|
||||
await PageObjects.dashboard.clickNewDashboard();
|
||||
await PageObjects.dashboard.addVisualizations(VIS_TITLES);
|
||||
|
||||
const lastVisTitle = VIS_TITLES[VIS_TITLES.length - 1];
|
||||
|
||||
const panelTitleBeforeMove = await getPanelTitleElement(lastVisTitle);
|
||||
const lastVisTitle = 'Rendering Test: datatable';
|
||||
const panelTitleBeforeMove = await PageObjects.dashboard.getPanelHeading(lastVisTitle);
|
||||
const position1 = await panelTitleBeforeMove.getPosition();
|
||||
|
||||
remote
|
||||
|
@ -54,7 +24,7 @@ export default function ({ getService, getPageObjects }) {
|
|||
.moveMouseTo(null, -20, -450)
|
||||
.releaseMouseButton();
|
||||
|
||||
const panelTitleAfterMove = await getPanelTitleElement(lastVisTitle);
|
||||
const panelTitleAfterMove = await PageObjects.dashboard.getPanelHeading(lastVisTitle);
|
||||
const position2 = await panelTitleAfterMove.getPosition();
|
||||
|
||||
expect(position1.y).to.be.greaterThan(position2.y);
|
||||
|
|
32
test/functional/apps/dashboard/_dashboard_options.js
Normal file
32
test/functional/apps/dashboard/_dashboard_options.js
Normal file
|
@ -0,0 +1,32 @@
|
|||
import expect from 'expect.js';
|
||||
|
||||
export default function ({ getService, getPageObjects }) {
|
||||
const retry = getService('retry');
|
||||
const PageObjects = getPageObjects(['dashboard']);
|
||||
|
||||
describe('dashboard data-shared attributes', async () => {
|
||||
let originalTitles = [];
|
||||
|
||||
before(async () => {
|
||||
await PageObjects.dashboard.loadSavedDashboard('few panels');
|
||||
await PageObjects.dashboard.clickEdit();
|
||||
originalTitles = await PageObjects.dashboard.getPanelTitles();
|
||||
});
|
||||
|
||||
it('should be able to hide all panel titles', async () => {
|
||||
await PageObjects.dashboard.checkHideTitle();
|
||||
await retry.try(async () => {
|
||||
const titles = await PageObjects.dashboard.getPanelTitles();
|
||||
expect(titles[0]).to.eql('');
|
||||
});
|
||||
});
|
||||
|
||||
it('should be able to unhide all panel titles', async () => {
|
||||
await PageObjects.dashboard.checkHideTitle();
|
||||
await retry.try(async () => {
|
||||
const titles = await PageObjects.dashboard.getPanelTitles();
|
||||
expect(titles[0]).to.eql(originalTitles[0]);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
|
@ -1,152 +0,0 @@
|
|||
import expect from 'expect.js';
|
||||
|
||||
import { PIE_CHART_VIS_NAME } from '../../page_objects/dashboard_page';
|
||||
|
||||
/**
|
||||
* Test the querying capabilities of dashboard, and make sure visualizations show the expected results, especially
|
||||
* with nested queries and filters on the visualizations themselves.
|
||||
*/
|
||||
export default function ({ getService, getPageObjects }) {
|
||||
const dashboardExpect = getService('dashboardExpect');
|
||||
const dashboardVisualizations = getService('dashboardVisualizations');
|
||||
const testSubjects = getService('testSubjects');
|
||||
const PageObjects = getPageObjects(['dashboard', 'header', 'visualize']);
|
||||
|
||||
describe('dashboard queries', function describeIndexTests() {
|
||||
before(async function () {
|
||||
await PageObjects.dashboard.initTests();
|
||||
await PageObjects.dashboard.preserveCrossAppState();
|
||||
});
|
||||
|
||||
after(async function () {
|
||||
// avoids any 'Object with id x not found' errors when switching tests.
|
||||
await PageObjects.header.clickVisualize();
|
||||
await PageObjects.visualize.gotoLandingPage();
|
||||
await PageObjects.header.clickDashboard();
|
||||
await PageObjects.dashboard.gotoDashboardLandingPage();
|
||||
});
|
||||
|
||||
it('Nested visualization query filters data as expected', async () => {
|
||||
await PageObjects.dashboard.clickNewDashboard();
|
||||
await PageObjects.dashboard.setTimepickerInDataRange();
|
||||
|
||||
await PageObjects.dashboard.addVisualizations([PIE_CHART_VIS_NAME]);
|
||||
await PageObjects.dashboard.clickEditVisualization();
|
||||
await PageObjects.dashboard.setQuery('memory:<80000');
|
||||
await PageObjects.dashboard.clickFilterButton();
|
||||
await PageObjects.header.waitUntilLoadingHasFinished();
|
||||
await dashboardExpect.pieSliceCount(2);
|
||||
|
||||
await PageObjects.visualize.saveVisualization(PIE_CHART_VIS_NAME);
|
||||
await PageObjects.header.clickDashboard();
|
||||
|
||||
await dashboardExpect.pieSliceCount(2);
|
||||
});
|
||||
|
||||
it('Nested visualization filter pills filters data as expected', async () => {
|
||||
await PageObjects.dashboard.clickEditVisualization();
|
||||
await PageObjects.header.waitUntilLoadingHasFinished();
|
||||
await PageObjects.dashboard.waitForRenderComplete();
|
||||
await PageObjects.dashboard.filterOnPieSlice();
|
||||
await PageObjects.header.waitUntilLoadingHasFinished();
|
||||
await dashboardExpect.pieSliceCount(1);
|
||||
|
||||
await PageObjects.visualize.saveVisualization(PIE_CHART_VIS_NAME);
|
||||
await PageObjects.header.clickDashboard();
|
||||
|
||||
await dashboardExpect.pieSliceCount(1);
|
||||
});
|
||||
|
||||
it('Pie chart attached to saved search filters data as expected', async () => {
|
||||
await dashboardVisualizations.createAndAddSavedSearch({
|
||||
name: 'bytes < 90',
|
||||
query: 'bytes:<90',
|
||||
fields: ['bytes']
|
||||
});
|
||||
|
||||
await PageObjects.header.clickDashboard();
|
||||
await PageObjects.dashboard.gotoDashboardLandingPage();
|
||||
await PageObjects.dashboard.clickNewDashboard();
|
||||
|
||||
await PageObjects.dashboard.clickAddVisualization();
|
||||
await PageObjects.dashboard.clickAddNewVisualizationLink();
|
||||
await PageObjects.visualize.clickPieChart();
|
||||
await PageObjects.visualize.selectSearch('bytes < 90');
|
||||
await PageObjects.visualize.clickBucket('Split Slices');
|
||||
await PageObjects.visualize.selectAggregation('Terms');
|
||||
await PageObjects.visualize.selectField('memory');
|
||||
await PageObjects.visualize.clickGo();
|
||||
await PageObjects.visualize.saveVisualization('memory with bytes < 90 pie');
|
||||
|
||||
await dashboardExpect.pieSliceCount(3);
|
||||
});
|
||||
|
||||
it('Pie chart attached to saved search filters shows no data with conflicting dashboard query', async () => {
|
||||
await PageObjects.dashboard.setQuery('bytes:>100');
|
||||
await PageObjects.dashboard.clickFilterButton();
|
||||
await PageObjects.header.waitUntilLoadingHasFinished();
|
||||
|
||||
await dashboardExpect.pieSliceCount(0);
|
||||
});
|
||||
|
||||
describe('visualizations without SearchSource', async function () {
|
||||
before(async () => {
|
||||
await PageObjects.dashboard.gotoDashboardLandingPage();
|
||||
await PageObjects.dashboard.clickNewDashboard();
|
||||
await PageObjects.dashboard.addVisualizations(['Visualization InputControl']);
|
||||
});
|
||||
|
||||
it(`should have filter bar with 'Add a filter'`, async function () {
|
||||
const hasAddFilter = await testSubjects.exists('addFilter');
|
||||
expect(hasAddFilter).to.be(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('filters', async function () {
|
||||
before(async () => {
|
||||
await PageObjects.dashboard.gotoDashboardLandingPage();
|
||||
await PageObjects.dashboard.clickNewDashboard();
|
||||
});
|
||||
|
||||
it('are not selected by default', async function () {
|
||||
const filters = await PageObjects.dashboard.getFilters(1000);
|
||||
expect(filters.length).to.equal(0);
|
||||
});
|
||||
|
||||
it('are added when a pie chart slice is clicked', async function () {
|
||||
await PageObjects.dashboard.addVisualizations([PIE_CHART_VIS_NAME]);
|
||||
// Click events not added until visualization is finished rendering.
|
||||
// See https://github.com/elastic/kibana/issues/15480#issuecomment-350195245 for more info on why
|
||||
// this is necessary.
|
||||
await PageObjects.dashboard.waitForRenderComplete();
|
||||
await PageObjects.dashboard.filterOnPieSlice();
|
||||
const filters = await PageObjects.dashboard.getFilters();
|
||||
expect(filters.length).to.equal(1);
|
||||
|
||||
await dashboardExpect.pieSliceCount(1);
|
||||
});
|
||||
|
||||
it('are preserved after saving a dashboard', async () => {
|
||||
await PageObjects.dashboard.saveDashboard('with filters');
|
||||
await PageObjects.header.waitUntilLoadingHasFinished();
|
||||
|
||||
const filters = await PageObjects.dashboard.getFilters();
|
||||
expect(filters.length).to.equal(1);
|
||||
|
||||
await dashboardExpect.pieSliceCount(1);
|
||||
});
|
||||
|
||||
it('are preserved after opening a dashboard saved with filters', async () => {
|
||||
await PageObjects.dashboard.gotoDashboardLandingPage();
|
||||
await PageObjects.dashboard.loadSavedDashboard('with filters');
|
||||
await PageObjects.header.waitUntilLoadingHasFinished();
|
||||
|
||||
const filters = await PageObjects.dashboard.getFilters();
|
||||
expect(filters.length).to.equal(1);
|
||||
|
||||
await dashboardExpect.pieSliceCount(1);
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
}
|
|
@ -10,6 +10,7 @@ export default function ({ getService, getPageObjects }) {
|
|||
const testSubjects = getService('testSubjects');
|
||||
const remote = getService('remote');
|
||||
const retry = getService('retry');
|
||||
const dashboardAddPanel = getService('dashboardAddPanel');
|
||||
|
||||
describe('dashboard state', function describeIndexTests() {
|
||||
before(async function () {
|
||||
|
@ -27,7 +28,7 @@ export default function ({ getService, getPageObjects }) {
|
|||
await PageObjects.dashboard.clickNewDashboard();
|
||||
await PageObjects.dashboard.setTimepickerInDataRange();
|
||||
|
||||
await PageObjects.dashboard.addVisualizations([AREA_CHART_VIS_NAME]);
|
||||
await dashboardAddPanel.addVisualization(AREA_CHART_VIS_NAME);
|
||||
await PageObjects.dashboard.saveDashboard('Overridden colors');
|
||||
|
||||
await PageObjects.dashboard.clickEdit();
|
||||
|
@ -59,7 +60,7 @@ export default function ({ getService, getPageObjects }) {
|
|||
await PageObjects.header.clickDashboard();
|
||||
await PageObjects.dashboard.clickNewDashboard();
|
||||
|
||||
await PageObjects.dashboard.addSavedSearch('my search');
|
||||
await dashboardAddPanel.addSavedSearch('my search');
|
||||
await PageObjects.dashboard.saveDashboard('No local edits');
|
||||
|
||||
const inViewMode = await testSubjects.exists('dashboardEditMode');
|
||||
|
@ -103,7 +104,7 @@ export default function ({ getService, getPageObjects }) {
|
|||
await PageObjects.dashboard.clickNewDashboard();
|
||||
await PageObjects.dashboard.setTimepickerInDataRange();
|
||||
|
||||
await PageObjects.dashboard.addVisualizations(['Visualization TileMap']);
|
||||
await dashboardAddPanel.addVisualization('Visualization TileMap');
|
||||
await PageObjects.dashboard.saveDashboard('No local edits');
|
||||
|
||||
await testSubjects.moveMouseTo('dashboardPanel');
|
||||
|
@ -129,10 +130,17 @@ export default function ({ getService, getPageObjects }) {
|
|||
const changedTileMapData = await PageObjects.visualize.getDataTableData();
|
||||
await testSubjects.moveMouseTo('dashboardPanel');
|
||||
await PageObjects.visualize.closeSpyPanel();
|
||||
|
||||
expect(changedTileMapData.length).to.not.equal(tileMapData.length);
|
||||
});
|
||||
|
||||
it('retains dark theme', async function () {
|
||||
await PageObjects.dashboard.useDarkTheme(true);
|
||||
await PageObjects.header.clickVisualize();
|
||||
await PageObjects.header.clickDashboard();
|
||||
const isDarkThemeOn = await PageObjects.dashboard.isDarkThemeOn();
|
||||
expect(isDarkThemeOn).to.equal(true);
|
||||
});
|
||||
|
||||
describe('Directly modifying url updates dashboard state', () => {
|
||||
it('for query parameter', async function () {
|
||||
await PageObjects.dashboard.gotoDashboardLandingPage();
|
||||
|
@ -150,7 +158,7 @@ export default function ({ getService, getPageObjects }) {
|
|||
});
|
||||
|
||||
it('for panel size parameters', async function () {
|
||||
await PageObjects.dashboard.addVisualization(PIE_CHART_VIS_NAME);
|
||||
await dashboardAddPanel.addVisualization(PIE_CHART_VIS_NAME);
|
||||
const currentUrl = await remote.getCurrentUrl();
|
||||
const currentPanelDimensions = await PageObjects.dashboard.getPanelDimensions();
|
||||
const newUrl = currentUrl.replace(`w:${DEFAULT_PANEL_WIDTH}`, `w:${DEFAULT_PANEL_WIDTH * 2}`);
|
||||
|
@ -184,7 +192,7 @@ export default function ({ getService, getPageObjects }) {
|
|||
|
||||
describe('for embeddable config color parameters on a visualization', () => {
|
||||
it('updates a pie slice color on a soft refresh', async function () {
|
||||
await PageObjects.dashboard.addVisualization(PIE_CHART_VIS_NAME);
|
||||
await dashboardAddPanel.addVisualization(PIE_CHART_VIS_NAME);
|
||||
await PageObjects.visualize.clickLegendOption('80,000');
|
||||
await PageObjects.visualize.selectNewLegendColorChoice('#F9D9F9');
|
||||
const currentUrl = await remote.getCurrentUrl();
|
||||
|
|
|
@ -8,7 +8,7 @@ const toTime = '2015-09-23 18:31:44.000';
|
|||
export default function ({ getPageObjects }) {
|
||||
const PageObjects = getPageObjects(['dashboard', 'header']);
|
||||
|
||||
describe('dashboard time', function dashboardSaveWithTime() {
|
||||
describe('dashboard time', () => {
|
||||
before(async function () {
|
||||
await PageObjects.dashboard.initTests();
|
||||
await PageObjects.dashboard.preserveCrossAppState();
|
||||
|
@ -18,15 +18,15 @@ export default function ({ getPageObjects }) {
|
|||
await PageObjects.dashboard.gotoDashboardLandingPage();
|
||||
});
|
||||
|
||||
describe('dashboard without stored timed', async function () {
|
||||
it('is saved', async function () {
|
||||
describe('dashboard without stored timed', () => {
|
||||
it('is saved', async () => {
|
||||
await PageObjects.dashboard.clickNewDashboard();
|
||||
await PageObjects.dashboard.addVisualizations([PageObjects.dashboard.getTestVisualizationNames()[0]]);
|
||||
const isDashboardSaved = await PageObjects.dashboard.saveDashboard(dashboardName, { storeTimeWithDashboard: false });
|
||||
expect(isDashboardSaved).to.eql(true);
|
||||
});
|
||||
|
||||
it('Does not set the time picker on open', async function () {
|
||||
it('Does not set the time picker on open', async () => {
|
||||
await PageObjects.header.setAbsoluteRange(fromTime, toTime);
|
||||
|
||||
await PageObjects.dashboard.loadSavedDashboard(dashboardName);
|
||||
|
|
|
@ -2,41 +2,40 @@ import expect from 'expect.js';
|
|||
|
||||
export default function ({ getService, getPageObjects }) {
|
||||
const retry = getService('retry');
|
||||
const log = getService('log');
|
||||
const dashboardVisualizations = getService('dashboardVisualizations');
|
||||
const testSubjects = getService('testSubjects');
|
||||
const PageObjects = getPageObjects(['dashboard']);
|
||||
const testVisualizationTitles = [PageObjects.dashboard.getTestVisualizationNames()[0], 'saved search'];
|
||||
const testVisualizationDescriptions = [PageObjects.dashboard.getTestVisualizationDescriptions()[0], ''];
|
||||
|
||||
describe('dashboard shared attributes', function describeIndexTests() {
|
||||
before(async function () {
|
||||
await PageObjects.dashboard.initTests();
|
||||
await PageObjects.dashboard.preserveCrossAppState();
|
||||
await PageObjects.dashboard.clickNewDashboard();
|
||||
await PageObjects.dashboard.addVisualizations([PageObjects.dashboard.getTestVisualizationNames()[0]]);
|
||||
await dashboardVisualizations.createAndAddSavedSearch({ name: 'saved search', fields: ['bytes', 'agent'] });
|
||||
describe('dashboard data-shared attributes', function describeIndexTests() {
|
||||
let originalPanelTitles;
|
||||
|
||||
before(async () => {
|
||||
await PageObjects.dashboard.loadSavedDashboard('dashboard with everything');
|
||||
});
|
||||
|
||||
it('should have data-shared-items-count set to the number of visualizations', function checkSavedItemsCount() {
|
||||
return retry.tryForTime(10000, () => PageObjects.dashboard.getSharedItemsCount())
|
||||
.then(function (count) {
|
||||
log.info('data-shared-items-count = ' + count);
|
||||
expect(count).to.eql(testVisualizationTitles.length);
|
||||
});
|
||||
});
|
||||
|
||||
it('should have panels with expected data-shared-item title and description', async () => {
|
||||
it('should have data-shared-items-count set to the number of embeddables on the dashboard', async () => {
|
||||
await retry.try(async () => {
|
||||
await PageObjects.dashboard.getPanelSharedItemData()
|
||||
.then(function (data) {
|
||||
expect(data.map(item => item.title)).to.eql(testVisualizationTitles);
|
||||
expect(data.map(item => item.description)).to.eql(testVisualizationDescriptions);
|
||||
});
|
||||
const sharedItemsCount = await PageObjects.dashboard.getSharedItemsCount();
|
||||
const panelCount = await PageObjects.dashboard.getPanelCount();
|
||||
expect(sharedItemsCount).to.eql(panelCount);
|
||||
});
|
||||
});
|
||||
|
||||
it('should have panels with expected data-shared-item title', async () => {
|
||||
await retry.try(async () => {
|
||||
const sharedData = await PageObjects.dashboard.getPanelSharedItemData();
|
||||
originalPanelTitles = await PageObjects.dashboard.getPanelTitles();
|
||||
expect(sharedData.map(item => item.title)).to.eql(originalPanelTitles);
|
||||
});
|
||||
});
|
||||
|
||||
it('data shared item container data has description and title set', async () => {
|
||||
const sharedContainerData = await PageObjects.dashboard.getSharedContainerData();
|
||||
expect(sharedContainerData.title).to.be('dashboard with everything');
|
||||
expect(sharedContainerData.description).to.be(
|
||||
'I have one of every visualization type since the last time I was created!');
|
||||
});
|
||||
|
||||
it('data-shared-item title should update a viz when using a custom panel title', async () => {
|
||||
await PageObjects.dashboard.clickEdit();
|
||||
const CUSTOM_VIS_TITLE = 'ima custom title for a vis!';
|
||||
await PageObjects.dashboard.setCustomPanelTitle(CUSTOM_VIS_TITLE);
|
||||
await retry.try(async () => {
|
||||
|
@ -64,7 +63,7 @@ export default function ({ getService, getPageObjects }) {
|
|||
await retry.try(async () => {
|
||||
const sharedData = await PageObjects.dashboard.getPanelSharedItemData();
|
||||
const foundOriginalSharedItemTitle = !!sharedData.find(item => {
|
||||
return item.title === testVisualizationTitles[0];
|
||||
return item.title === originalPanelTitles[0];
|
||||
});
|
||||
expect(foundOriginalSharedItemTitle).to.be(true);
|
||||
});
|
||||
|
@ -72,25 +71,12 @@ export default function ({ getService, getPageObjects }) {
|
|||
|
||||
it('data-shared-item title should update a saved search when using a custom panel title', async () => {
|
||||
const CUSTOM_SEARCH_TITLE = 'ima custom title for a search!';
|
||||
const panels = await PageObjects.dashboard.getDashboardPanels();
|
||||
// The reverse is only to take advantage of the fact that the saved search is last at the time of writing this
|
||||
// test which speeds things up.
|
||||
const searchPanel = await Promise.race(panels.map(async panel => {
|
||||
return new Promise(async resolve => {
|
||||
const savedSearchPanel = await testSubjects.descendantExists('embeddedSavedSearchDocTable', panel);
|
||||
if (savedSearchPanel) {
|
||||
resolve(panel);
|
||||
}
|
||||
});
|
||||
}));
|
||||
await PageObjects.dashboard.setCustomPanelTitle(CUSTOM_SEARCH_TITLE, searchPanel);
|
||||
await PageObjects.dashboard.setCustomPanelTitle(CUSTOM_SEARCH_TITLE, 'Rendering Test: saved search');
|
||||
await retry.try(async () => {
|
||||
const sharedData = await PageObjects.dashboard.getPanelSharedItemData();
|
||||
const foundSharedItemTitle = !!sharedData.find(item => {
|
||||
return item.title === CUSTOM_SEARCH_TITLE;
|
||||
});
|
||||
console.log('foundSharedItemTitle: ' + foundSharedItemTitle);
|
||||
|
||||
expect(foundSharedItemTitle).to.be(true);
|
||||
});
|
||||
});
|
41
test/functional/apps/dashboard/_embed_mode.js
Normal file
41
test/functional/apps/dashboard/_embed_mode.js
Normal file
|
@ -0,0 +1,41 @@
|
|||
import expect from 'expect.js';
|
||||
|
||||
export default function ({ getService, getPageObjects }) {
|
||||
const retry = getService('retry');
|
||||
const PageObjects = getPageObjects(['dashboard', 'common']);
|
||||
const remote = getService('remote');
|
||||
|
||||
describe('embed mode', async () => {
|
||||
before(async () => {
|
||||
await PageObjects.dashboard.loadSavedDashboard('few panels');
|
||||
});
|
||||
|
||||
it('hides the chrome', async () => {
|
||||
let isChromeVisible = await PageObjects.common.isChromeVisible();
|
||||
expect(isChromeVisible).to.be(true);
|
||||
|
||||
const currentUrl = await remote.getCurrentUrl();
|
||||
const newUrl = currentUrl + '&embed=true';
|
||||
// Embed parameter only works on a hard refresh.
|
||||
const useTimeStamp = true;
|
||||
await remote.get(newUrl.toString(), useTimeStamp);
|
||||
|
||||
await retry.try(async () => {
|
||||
isChromeVisible = await PageObjects.common.isChromeVisible();
|
||||
expect(isChromeVisible).to.be(false);
|
||||
});
|
||||
});
|
||||
|
||||
after(async function () {
|
||||
const currentUrl = await remote.getCurrentUrl();
|
||||
const newUrl = currentUrl.replace('&embed=true', '');
|
||||
// First use the timestamp to cause a hard refresh so the new embed parameter works correctly.
|
||||
let useTimeStamp = true;
|
||||
await remote.get(newUrl.toString(), useTimeStamp);
|
||||
// Then get rid of the timestamp so the rest of the tests work with state and app switching.
|
||||
useTimeStamp = false;
|
||||
await remote.get(newUrl.toString(), useTimeStamp);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
119
test/functional/apps/dashboard/_embeddable_rendering.js
Normal file
119
test/functional/apps/dashboard/_embeddable_rendering.js
Normal file
|
@ -0,0 +1,119 @@
|
|||
import expect from 'expect.js';
|
||||
|
||||
/**
|
||||
* This tests both that one of each visualization can be added to a dashboard (as opposed to opening an existing
|
||||
* dashboard with the visualizations already on it), as well as conducts a rough type of snapshot testing by checking
|
||||
* for various ui components. The downside is these tests are a bit fragile to css changes (though not as fragile as
|
||||
* actual screenshot snapshot regression testing), and can be difficult to diagnose failures (which visualization
|
||||
* broke?). The upside is that this offers very good coverage with a minimal time investment.
|
||||
*/
|
||||
|
||||
export default function ({ getService, getPageObjects }) {
|
||||
const find = getService('find');
|
||||
const dashboardExpect = getService('dashboardExpect');
|
||||
const dashboardAddPanel = getService('dashboardAddPanel');
|
||||
const PageObjects = getPageObjects(['common', 'dashboard', 'header', 'visualize', 'discover']);
|
||||
|
||||
describe('dashboard embeddable rendering', function describeIndexTests() {
|
||||
before(async () => {
|
||||
await PageObjects.dashboard.clickNewDashboard();
|
||||
const fromTime = '2018-01-01 00:00:00.000';
|
||||
const toTime = '2018-04-13 00:00:00.000';
|
||||
await PageObjects.header.setAbsoluteRange(fromTime, toTime);
|
||||
});
|
||||
|
||||
it('adding visualizations', async () => {
|
||||
await dashboardAddPanel.addEveryVisualization('"Rendering Test"');
|
||||
await PageObjects.header.waitUntilLoadingHasFinished();
|
||||
const panelCount = await PageObjects.dashboard.getPanelCount();
|
||||
expect(panelCount).to.be(26);
|
||||
});
|
||||
|
||||
it('adding saved searches', async () => {
|
||||
await dashboardAddPanel.addEverySavedSearch('"Rendering Test"');
|
||||
await dashboardAddPanel.closeAddPanel();
|
||||
await PageObjects.header.waitUntilLoadingHasFinished();
|
||||
const panelCount = await PageObjects.dashboard.getPanelCount();
|
||||
expect(panelCount).to.be(27);
|
||||
|
||||
await PageObjects.dashboard.waitForRenderComplete();
|
||||
|
||||
// Not neccessary but helpful for local debugging.
|
||||
await PageObjects.dashboard.saveDashboard('embeddable rendering test');
|
||||
});
|
||||
|
||||
it('pie charts rendered', async () => {
|
||||
await dashboardExpect.pieSliceCount(16);
|
||||
});
|
||||
|
||||
it('area, bar and heatmap charts rendered', async () => {
|
||||
await dashboardExpect.seriesElementCount(19);
|
||||
});
|
||||
|
||||
it('data tables render', async () => {
|
||||
await dashboardExpect.dataTableRowCount(5);
|
||||
});
|
||||
|
||||
it('saved searches render', async () => {
|
||||
await dashboardExpect.savedSearchRowCount(50);
|
||||
});
|
||||
|
||||
it('goal and guage render', async () => {
|
||||
await dashboardExpect.goalAndGuageLabelsExist(['63%', '56%', '11.915 GB']);
|
||||
});
|
||||
|
||||
it('input controls render', async () => {
|
||||
await dashboardExpect.inputControlItemCount(5);
|
||||
});
|
||||
|
||||
it('metric vis renders', async () => {
|
||||
await dashboardExpect.metricValuesExist(['7,544']);
|
||||
});
|
||||
|
||||
it('markdown renders', async () => {
|
||||
await dashboardExpect.markdownWithValuesExists(['I\'m a markdown!']);
|
||||
});
|
||||
|
||||
it('line charts render', async () => {
|
||||
await dashboardExpect.lineChartPointsCount(5);
|
||||
});
|
||||
|
||||
it('tag cloud renders', async () => {
|
||||
await dashboardExpect.tagCloudWithValuesFound(['CN', 'IN', 'US', 'BR', 'ID']);
|
||||
});
|
||||
|
||||
it('timelion chart renders', async () => {
|
||||
await dashboardExpect.timelionLegendCount(0);
|
||||
});
|
||||
|
||||
it('tsvb guage renders', async () => {
|
||||
const tsvbGuageExists = await find.existsByCssSelector('.thorHalfGauge');
|
||||
expect(tsvbGuageExists).to.be(true);
|
||||
});
|
||||
|
||||
it('tsvb metric chart renders', async () => {
|
||||
await dashboardExpect.tsvbMetricValuesExist(['210,007,889,606']);
|
||||
});
|
||||
|
||||
it('tsvb markdown renders', async () => {
|
||||
await dashboardExpect.tsvbMarkdownWithValuesExists(['Hi Avg last bytes: 6286.674715909091']);
|
||||
});
|
||||
|
||||
it('tsvb table chart renders', async () => {
|
||||
await dashboardExpect.tsvbTableCellCount(20);
|
||||
});
|
||||
|
||||
it('tsvb time series renders', async () => {
|
||||
await dashboardExpect.tsvbTimeSeriesLegendCount(1);
|
||||
});
|
||||
|
||||
it('tsvb top n chart renders', async () => {
|
||||
await dashboardExpect.tsvbTopNValuesExist(['5,734.79', '6,286.67']);
|
||||
});
|
||||
|
||||
it('vega chart renders', async () => {
|
||||
const tsvb = await find.existsByCssSelector('.vega-view-container');
|
||||
expect(tsvb).to.be(true);
|
||||
});
|
||||
});
|
||||
}
|
60
test/functional/apps/dashboard/_full_screen_mode.js
Normal file
60
test/functional/apps/dashboard/_full_screen_mode.js
Normal file
|
@ -0,0 +1,60 @@
|
|||
import expect from 'expect.js';
|
||||
|
||||
export default function ({ getService, getPageObjects }) {
|
||||
const retry = getService('retry');
|
||||
const remote = getService('remote');
|
||||
const PageObjects = getPageObjects(['dashboard', 'common']);
|
||||
|
||||
describe('full screen mode', async () => {
|
||||
before(async () => {
|
||||
await PageObjects.dashboard.loadSavedDashboard('few panels');
|
||||
});
|
||||
|
||||
it('option not available in edit mode', async () => {
|
||||
await PageObjects.dashboard.clickEdit();
|
||||
const exists = await PageObjects.dashboard.fullScreenModeMenuItemExists();
|
||||
expect(exists).to.be(false);
|
||||
});
|
||||
|
||||
it('available in view mode', async () => {
|
||||
await PageObjects.dashboard.saveDashboard('full screen test', { saveAsNew: true });
|
||||
const exists = await PageObjects.dashboard.fullScreenModeMenuItemExists();
|
||||
expect(exists).to.be(true);
|
||||
});
|
||||
|
||||
it('hides the chrome', async () => {
|
||||
let isChromeVisible = await PageObjects.common.isChromeVisible();
|
||||
expect(isChromeVisible).to.be(true);
|
||||
|
||||
await PageObjects.dashboard.clickFullScreenMode();
|
||||
|
||||
await retry.try(async () => {
|
||||
isChromeVisible = await PageObjects.common.isChromeVisible();
|
||||
expect(isChromeVisible).to.be(false);
|
||||
});
|
||||
});
|
||||
|
||||
it('displays exit full screen logo button', async () => {
|
||||
const exists = await PageObjects.dashboard.exitFullScreenLogoButtonExists();
|
||||
expect(exists).to.be(true);
|
||||
});
|
||||
|
||||
it('displays exit full screen logo button when panel is expanded', async () => {
|
||||
await PageObjects.dashboard.toggleExpandPanel();
|
||||
|
||||
const exists = await PageObjects.dashboard.exitFullScreenTextButtonExists();
|
||||
expect(exists).to.be(true);
|
||||
});
|
||||
|
||||
it('exits when the text button is clicked on', async () => {
|
||||
const logoButton = await PageObjects.dashboard.getExitFullScreenLogoButton();
|
||||
await remote.moveMouseTo(logoButton);
|
||||
await PageObjects.dashboard.clickExitFullScreenTextButton();
|
||||
|
||||
await retry.try(async () => {
|
||||
const isChromeVisible = await PageObjects.common.isChromeVisible();
|
||||
expect(isChromeVisible).to.be(true);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
|
@ -9,6 +9,7 @@ export default function ({ getService, getPageObjects }) {
|
|||
const testSubjects = getService('testSubjects');
|
||||
const kibanaServer = getService('kibanaServer');
|
||||
const remote = getService('remote');
|
||||
const dashboardAddPanel = getService('dashboardAddPanel');
|
||||
const PageObjects = getPageObjects(['dashboard', 'header', 'visualize', 'discover']);
|
||||
const dashboardName = 'Dashboard Panel Controls Test';
|
||||
|
||||
|
@ -34,7 +35,7 @@ export default function ({ getService, getPageObjects }) {
|
|||
before(async () => {
|
||||
await PageObjects.dashboard.clickNewDashboard();
|
||||
await PageObjects.dashboard.setTimepickerInDataRange();
|
||||
await PageObjects.dashboard.addVisualization(PIE_CHART_VIS_NAME);
|
||||
await dashboardAddPanel.addVisualization(PIE_CHART_VIS_NAME);
|
||||
});
|
||||
|
||||
it('are hidden in view mode', async function () {
|
||||
|
@ -126,7 +127,7 @@ export default function ({ getService, getPageObjects }) {
|
|||
await PageObjects.discover.saveSearch('my search');
|
||||
await PageObjects.header.waitUntilLoadingHasFinished();
|
||||
await PageObjects.header.clickDashboard();
|
||||
await PageObjects.dashboard.addSavedSearch('my search');
|
||||
await dashboardAddPanel.addSavedSearch('my search');
|
||||
|
||||
const panelCount = await PageObjects.dashboard.getPanelCount();
|
||||
expect(panelCount).to.be(1);
|
||||
|
|
67
test/functional/apps/dashboard/_panel_expand_toggle.js
Normal file
67
test/functional/apps/dashboard/_panel_expand_toggle.js
Normal file
|
@ -0,0 +1,67 @@
|
|||
import expect from 'expect.js';
|
||||
|
||||
export default function ({ getService, getPageObjects }) {
|
||||
const retry = getService('retry');
|
||||
const remote = getService('remote');
|
||||
const PageObjects = getPageObjects(['dashboard', 'visualize', 'header']);
|
||||
|
||||
describe('expanding a panel', () => {
|
||||
before(async () => {
|
||||
await PageObjects.dashboard.loadSavedDashboard('few panels');
|
||||
});
|
||||
|
||||
it('hides other panels', async () => {
|
||||
await PageObjects.dashboard.toggleExpandPanel();
|
||||
await retry.try(async () => {
|
||||
const panelCount = await PageObjects.dashboard.getPanelCount();
|
||||
expect(panelCount).to.eql(1);
|
||||
});
|
||||
});
|
||||
|
||||
it('does not show the spy pane toggle if mouse is not hovering', async () => {
|
||||
// move mouse off the panel.
|
||||
await PageObjects.header.clickTimepicker();
|
||||
|
||||
// no spy pane without hover
|
||||
const spyToggleExists = await PageObjects.visualize.getSpyToggleExists();
|
||||
expect(spyToggleExists).to.be(false);
|
||||
});
|
||||
|
||||
it('shows the spy pane toggle on hover', async () => {
|
||||
const panels = await PageObjects.dashboard.getDashboardPanels();
|
||||
// Simulate hover
|
||||
await remote.moveMouseTo(panels[0]);
|
||||
const spyToggleExists = await PageObjects.visualize.getSpyToggleExists();
|
||||
expect(spyToggleExists).to.be(true);
|
||||
});
|
||||
|
||||
// This was an actual bug that appeared, where the spy pane appeared on panels after adding them, but
|
||||
// disappeared when a new dashboard was opened up.
|
||||
it('shows the spy pane toggle directly after opening a dashboard', async () => {
|
||||
await PageObjects.dashboard.clickEdit();
|
||||
await PageObjects.dashboard.saveDashboard('spy pane test', { saveAsNew: true });
|
||||
await PageObjects.dashboard.gotoDashboardLandingPage();
|
||||
await PageObjects.dashboard.loadSavedDashboard('spy pane test');
|
||||
const panels = await PageObjects.dashboard.getDashboardPanels();
|
||||
// Simulate hover
|
||||
await remote.moveMouseTo(panels[1]);
|
||||
const spyToggleExists = await PageObjects.visualize.getSpyToggleExists();
|
||||
expect(spyToggleExists).to.be(true);
|
||||
});
|
||||
|
||||
it('shows other panels after being minimized', async () => {
|
||||
const panelCount = await PageObjects.dashboard.getPanelCount();
|
||||
// Panels are all minimized on a fresh open of a dashboard, so we need to re-expand in order to then minimize.
|
||||
await PageObjects.dashboard.toggleExpandPanel();
|
||||
await PageObjects.dashboard.toggleExpandPanel();
|
||||
|
||||
// Add a retry to fix https://github.com/elastic/kibana/issues/14574. Perhaps the recent changes to this
|
||||
// being a CSS update is causing the UI to change slower than grabbing the panels?
|
||||
retry.try(async () => {
|
||||
const panelCountAfterMaxThenMinimize = await PageObjects.dashboard.getPanelCount();
|
||||
expect(panelCountAfterMaxThenMinimize).to.be(panelCount);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
}
|
|
@ -5,6 +5,7 @@ export default function ({ getService, getPageObjects }) {
|
|||
const kibanaServer = getService('kibanaServer');
|
||||
const retry = getService('retry');
|
||||
const remote = getService('remote');
|
||||
const dashboardAddPanel = getService('dashboardAddPanel');
|
||||
const PageObjects = getPageObjects(['dashboard', 'header', 'common', 'visualize']);
|
||||
const dashboardName = 'Dashboard View Edit Test';
|
||||
|
||||
|
@ -28,7 +29,7 @@ export default function ({ getService, getPageObjects }) {
|
|||
it('create test dashboard', async function () {
|
||||
await PageObjects.dashboard.gotoDashboardLandingPage();
|
||||
await PageObjects.dashboard.clickNewDashboard();
|
||||
await PageObjects.dashboard.addVisualizations(PageObjects.dashboard.getTestVisualizationNames());
|
||||
await dashboardAddPanel.addVisualizations(PageObjects.dashboard.getTestVisualizationNames());
|
||||
const isDashboardSaved = await PageObjects.dashboard.saveDashboard(dashboardName);
|
||||
expect(isDashboardSaved).to.eql(true);
|
||||
});
|
||||
|
@ -125,8 +126,8 @@ export default function ({ getService, getPageObjects }) {
|
|||
});
|
||||
|
||||
it('when a new vis is added', async function () {
|
||||
await PageObjects.dashboard.clickAddVisualization();
|
||||
await PageObjects.dashboard.clickAddNewVisualizationLink();
|
||||
await dashboardAddPanel.ensureAddPanelIsShowing();
|
||||
await dashboardAddPanel.clickAddNewEmbeddableLink();
|
||||
await PageObjects.visualize.clickAreaChart();
|
||||
await PageObjects.visualize.clickNewSearch();
|
||||
await PageObjects.visualize.saveVisualization('new viz panel');
|
||||
|
@ -142,7 +143,7 @@ export default function ({ getService, getPageObjects }) {
|
|||
});
|
||||
|
||||
it('when an existing vis is added', async function () {
|
||||
await PageObjects.dashboard.addVisualization('new viz panel');
|
||||
await dashboardAddPanel.addVisualization('new viz panel');
|
||||
await PageObjects.dashboard.clickCancelOutOfEditMode();
|
||||
|
||||
// confirm lose changes
|
||||
|
|
|
@ -1,22 +1,56 @@
|
|||
export default function ({ getService, loadTestFile }) {
|
||||
export default function ({ getService, loadTestFile, getPageObjects }) {
|
||||
const remote = getService('remote');
|
||||
const esArchiver = getService('esArchiver');
|
||||
const PageObjects = getPageObjects(['dashboard']);
|
||||
|
||||
describe('dashboard app', function () {
|
||||
before(() => remote.setWindowSize(1200, 900));
|
||||
loadTestFile(require.resolve('./_dashboard_filter_bar'));
|
||||
loadTestFile(require.resolve('./_dashboard_time_picker'));
|
||||
loadTestFile(require.resolve('./_dashboard_shared_attributes'));
|
||||
loadTestFile(require.resolve('./_bwc_shared_urls'));
|
||||
loadTestFile(require.resolve('./_dashboard_queries'));
|
||||
loadTestFile(require.resolve('./_dashboard_snapshots'));
|
||||
loadTestFile(require.resolve('./_dashboard_grid'));
|
||||
loadTestFile(require.resolve('./_panel_controls'));
|
||||
loadTestFile(require.resolve('./_view_edit'));
|
||||
loadTestFile(require.resolve('./_dashboard'));
|
||||
loadTestFile(require.resolve('./_dashboard_state'));
|
||||
loadTestFile(require.resolve('./_dashboard_save'));
|
||||
loadTestFile(require.resolve('./_dashboard_time'));
|
||||
loadTestFile(require.resolve('./_dashboard_listing'));
|
||||
loadTestFile(require.resolve('./_dashboard_clone'));
|
||||
describe('using current data', function () {
|
||||
before(async () => {
|
||||
await remote.setWindowSize(1300, 900);
|
||||
await PageObjects.dashboard.initTests({
|
||||
kibanaIndex: 'dashboard/current/kibana',
|
||||
dataIndex: 'dashboard/current/data',
|
||||
defaultIndex: 'logstash-*'
|
||||
});
|
||||
await PageObjects.dashboard.preserveCrossAppState();
|
||||
});
|
||||
|
||||
after(async function () {
|
||||
await PageObjects.dashboard.clearSavedObjectsFromAppLinks();
|
||||
await esArchiver.unload('dashboard/current/kibana');
|
||||
await esArchiver.unload('dashboard/current/data');
|
||||
});
|
||||
|
||||
// This has to be first since the other tests create some embeddables as side affects and our counting assumes
|
||||
// a fresh index.
|
||||
loadTestFile(require.resolve('./_embeddable_rendering'));
|
||||
loadTestFile(require.resolve('./_create_and_add_embeddables'));
|
||||
loadTestFile(require.resolve('./_dashboard_options'));
|
||||
loadTestFile(require.resolve('./_data_shared_attributes'));
|
||||
loadTestFile(require.resolve('./_embed_mode'));
|
||||
loadTestFile(require.resolve('./_full_screen_mode'));
|
||||
loadTestFile(require.resolve('./_dashboard_filter_bar'));
|
||||
loadTestFile(require.resolve('./_dashboard_filtering'));
|
||||
loadTestFile(require.resolve('./_panel_expand_toggle'));
|
||||
loadTestFile(require.resolve('./_dashboard_grid'));
|
||||
});
|
||||
|
||||
// Each of these tests call initTests themselves, the way it was originally written. The above tests only load
|
||||
// the data once to save on time. Eventually, all of these tests should just use current data and we can reserve
|
||||
// legacy data only for specifically testing BWC situations.
|
||||
describe('using legacy data', function () {
|
||||
before(() => remote.setWindowSize(1200, 900));
|
||||
|
||||
loadTestFile(require.resolve('./_dashboard_time_picker'));
|
||||
loadTestFile(require.resolve('./_bwc_shared_urls'));
|
||||
loadTestFile(require.resolve('./_dashboard_snapshots'));
|
||||
loadTestFile(require.resolve('./_panel_controls'));
|
||||
loadTestFile(require.resolve('./_view_edit'));
|
||||
loadTestFile(require.resolve('./_dashboard_state'));
|
||||
loadTestFile(require.resolve('./_dashboard_save'));
|
||||
loadTestFile(require.resolve('./_dashboard_time'));
|
||||
loadTestFile(require.resolve('./_dashboard_listing'));
|
||||
loadTestFile(require.resolve('./_dashboard_clone'));
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
|
@ -26,6 +26,8 @@ import {
|
|||
DashboardVisualizationProvider,
|
||||
DashboardExpectProvider,
|
||||
FailureDebuggingProvider,
|
||||
VisualizeListingTableProvider,
|
||||
DashboardAddPanelProvider,
|
||||
} from './services';
|
||||
|
||||
export default async function ({ readConfigFile }) {
|
||||
|
@ -76,6 +78,8 @@ export default async function ({ readConfigFile }) {
|
|||
dashboardVisualizations: DashboardVisualizationProvider,
|
||||
dashboardExpect: DashboardExpectProvider,
|
||||
failureDebugging: FailureDebuggingProvider,
|
||||
visualizeListingTable: VisualizeListingTableProvider,
|
||||
dashboardAddPanel: DashboardAddPanelProvider,
|
||||
},
|
||||
servers: commonConfig.get('servers'),
|
||||
apps: {
|
||||
|
|
Binary file not shown.
|
@ -0,0 +1,617 @@
|
|||
{
|
||||
"type": "index",
|
||||
"value": {
|
||||
"index": "animals-dogs-2018-01-01",
|
||||
"settings": {
|
||||
"index": {
|
||||
"number_of_shards": "5",
|
||||
"number_of_replicas": "1"
|
||||
}
|
||||
},
|
||||
"mappings": {
|
||||
"data": {
|
||||
"properties": {
|
||||
"@timestamp": {
|
||||
"type": "date"
|
||||
},
|
||||
"animal": {
|
||||
"type": "text",
|
||||
"fields": {
|
||||
"keyword": {
|
||||
"type": "keyword",
|
||||
"ignore_above": 256
|
||||
}
|
||||
}
|
||||
},
|
||||
"name": {
|
||||
"type": "text",
|
||||
"fields": {
|
||||
"keyword": {
|
||||
"type": "keyword",
|
||||
"ignore_above": 256
|
||||
}
|
||||
}
|
||||
},
|
||||
"sound": {
|
||||
"type": "text",
|
||||
"fields": {
|
||||
"keyword": {
|
||||
"type": "keyword",
|
||||
"ignore_above": 256
|
||||
}
|
||||
}
|
||||
},
|
||||
"weightLbs": {
|
||||
"type": "long"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
"type": "index",
|
||||
"value": {
|
||||
"index": "animals-dogs-2018-04-10",
|
||||
"settings": {
|
||||
"index": {
|
||||
"number_of_shards": "5",
|
||||
"number_of_replicas": "1"
|
||||
}
|
||||
},
|
||||
"mappings": {
|
||||
"data": {
|
||||
"properties": {
|
||||
"@timestamp": {
|
||||
"type": "date"
|
||||
},
|
||||
"animal": {
|
||||
"type": "text",
|
||||
"fields": {
|
||||
"keyword": {
|
||||
"type": "keyword",
|
||||
"ignore_above": 256
|
||||
}
|
||||
}
|
||||
},
|
||||
"name": {
|
||||
"type": "text",
|
||||
"fields": {
|
||||
"keyword": {
|
||||
"type": "keyword",
|
||||
"ignore_above": 256
|
||||
}
|
||||
}
|
||||
},
|
||||
"sound": {
|
||||
"type": "text",
|
||||
"fields": {
|
||||
"keyword": {
|
||||
"type": "keyword",
|
||||
"ignore_above": 256
|
||||
}
|
||||
}
|
||||
},
|
||||
"weightLbs": {
|
||||
"type": "long"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
"type": "index",
|
||||
"value": {
|
||||
"index": "animals-cats-2018-01-01",
|
||||
"settings": {
|
||||
"index": {
|
||||
"number_of_shards": "5",
|
||||
"number_of_replicas": "1"
|
||||
}
|
||||
},
|
||||
"mappings": {
|
||||
"data": {
|
||||
"properties": {
|
||||
"@timestamp": {
|
||||
"type": "date"
|
||||
},
|
||||
"animal": {
|
||||
"type": "text",
|
||||
"fields": {
|
||||
"keyword": {
|
||||
"type": "keyword",
|
||||
"ignore_above": 256
|
||||
}
|
||||
}
|
||||
},
|
||||
"name": {
|
||||
"type": "text",
|
||||
"fields": {
|
||||
"keyword": {
|
||||
"type": "keyword",
|
||||
"ignore_above": 256
|
||||
}
|
||||
}
|
||||
},
|
||||
"sound": {
|
||||
"type": "text",
|
||||
"fields": {
|
||||
"keyword": {
|
||||
"type": "keyword",
|
||||
"ignore_above": 256
|
||||
}
|
||||
}
|
||||
},
|
||||
"weightLbs": {
|
||||
"type": "long"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
"type": "index",
|
||||
"value": {
|
||||
"index": "animals-cats-2018-04-10",
|
||||
"settings": {
|
||||
"index": {
|
||||
"number_of_shards": "5",
|
||||
"number_of_replicas": "1"
|
||||
}
|
||||
},
|
||||
"mappings": {
|
||||
"data": {
|
||||
"properties": {
|
||||
"@timestamp": {
|
||||
"type": "date"
|
||||
},
|
||||
"animal": {
|
||||
"type": "text",
|
||||
"fields": {
|
||||
"keyword": {
|
||||
"type": "keyword",
|
||||
"ignore_above": 256
|
||||
}
|
||||
}
|
||||
},
|
||||
"name": {
|
||||
"type": "text",
|
||||
"fields": {
|
||||
"keyword": {
|
||||
"type": "keyword",
|
||||
"ignore_above": 256
|
||||
}
|
||||
}
|
||||
},
|
||||
"sound": {
|
||||
"type": "text",
|
||||
"fields": {
|
||||
"keyword": {
|
||||
"type": "keyword",
|
||||
"ignore_above": 256
|
||||
}
|
||||
}
|
||||
},
|
||||
"weightLbs": {
|
||||
"type": "long"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
"type": "index",
|
||||
"value": {
|
||||
"index": "dogbreeds",
|
||||
"settings": {
|
||||
"index": {
|
||||
"number_of_shards": "5",
|
||||
"number_of_replicas": "1"
|
||||
}
|
||||
},
|
||||
"mappings": {
|
||||
"data": {
|
||||
"properties": {
|
||||
"activity level": {
|
||||
"type": "long"
|
||||
},
|
||||
"barking level": {
|
||||
"type": "long"
|
||||
},
|
||||
"breed": {
|
||||
"type": "text",
|
||||
"fields": {
|
||||
"keyword": {
|
||||
"type": "keyword",
|
||||
"ignore_above": 256
|
||||
}
|
||||
}
|
||||
},
|
||||
"size": {
|
||||
"type": "text",
|
||||
"fields": {
|
||||
"keyword": {
|
||||
"type": "keyword",
|
||||
"ignore_above": 256
|
||||
}
|
||||
}
|
||||
},
|
||||
"trainability": {
|
||||
"type": "long"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
"type": "index",
|
||||
"value": {
|
||||
"index": "logstash-0",
|
||||
"settings": {
|
||||
"index": {
|
||||
"number_of_shards": "1",
|
||||
"analysis": {
|
||||
"analyzer": {
|
||||
"makelogs_url": {
|
||||
"type": "standard",
|
||||
"max_token_length": "1000",
|
||||
"tokenizer": "uax_url_email"
|
||||
}
|
||||
}
|
||||
},
|
||||
"number_of_replicas": "0"
|
||||
}
|
||||
},
|
||||
"mappings": {
|
||||
"doc": {
|
||||
"dynamic_templates": [
|
||||
{
|
||||
"string_fields": {
|
||||
"match": "*",
|
||||
"match_mapping_type": "string",
|
||||
"mapping": {
|
||||
"fields": {
|
||||
"raw": {
|
||||
"type": "keyword"
|
||||
}
|
||||
},
|
||||
"type": "text"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"properties": {
|
||||
"@message": {
|
||||
"type": "text",
|
||||
"fields": {
|
||||
"raw": {
|
||||
"type": "keyword"
|
||||
}
|
||||
}
|
||||
},
|
||||
"@tags": {
|
||||
"type": "text",
|
||||
"fields": {
|
||||
"raw": {
|
||||
"type": "keyword"
|
||||
}
|
||||
}
|
||||
},
|
||||
"@timestamp": {
|
||||
"type": "date"
|
||||
},
|
||||
"agent": {
|
||||
"type": "text",
|
||||
"fields": {
|
||||
"raw": {
|
||||
"type": "keyword"
|
||||
}
|
||||
}
|
||||
},
|
||||
"bytes": {
|
||||
"type": "long"
|
||||
},
|
||||
"clientip": {
|
||||
"type": "ip"
|
||||
},
|
||||
"extension": {
|
||||
"type": "text",
|
||||
"fields": {
|
||||
"raw": {
|
||||
"type": "keyword"
|
||||
}
|
||||
}
|
||||
},
|
||||
"geo": {
|
||||
"properties": {
|
||||
"coordinates": {
|
||||
"type": "geo_point"
|
||||
},
|
||||
"dest": {
|
||||
"type": "keyword"
|
||||
},
|
||||
"src": {
|
||||
"type": "keyword"
|
||||
},
|
||||
"srcdest": {
|
||||
"type": "keyword"
|
||||
}
|
||||
}
|
||||
},
|
||||
"headings": {
|
||||
"type": "text",
|
||||
"fields": {
|
||||
"raw": {
|
||||
"type": "keyword"
|
||||
}
|
||||
}
|
||||
},
|
||||
"host": {
|
||||
"type": "text",
|
||||
"fields": {
|
||||
"raw": {
|
||||
"type": "keyword"
|
||||
}
|
||||
}
|
||||
},
|
||||
"id": {
|
||||
"type": "integer"
|
||||
},
|
||||
"index": {
|
||||
"type": "text",
|
||||
"fields": {
|
||||
"raw": {
|
||||
"type": "keyword"
|
||||
}
|
||||
}
|
||||
},
|
||||
"ip": {
|
||||
"type": "ip"
|
||||
},
|
||||
"links": {
|
||||
"type": "text",
|
||||
"fields": {
|
||||
"raw": {
|
||||
"type": "keyword"
|
||||
}
|
||||
}
|
||||
},
|
||||
"machine": {
|
||||
"properties": {
|
||||
"os": {
|
||||
"type": "text",
|
||||
"fields": {
|
||||
"raw": {
|
||||
"type": "keyword"
|
||||
}
|
||||
}
|
||||
},
|
||||
"ram": {
|
||||
"type": "long"
|
||||
}
|
||||
}
|
||||
},
|
||||
"memory": {
|
||||
"type": "double"
|
||||
},
|
||||
"meta": {
|
||||
"properties": {
|
||||
"char": {
|
||||
"type": "keyword"
|
||||
},
|
||||
"related": {
|
||||
"type": "text"
|
||||
},
|
||||
"user": {
|
||||
"properties": {
|
||||
"firstname": {
|
||||
"type": "text"
|
||||
},
|
||||
"lastname": {
|
||||
"type": "integer"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"phpmemory": {
|
||||
"type": "long"
|
||||
},
|
||||
"referer": {
|
||||
"type": "keyword"
|
||||
},
|
||||
"relatedContent": {
|
||||
"properties": {
|
||||
"article:modified_time": {
|
||||
"type": "date"
|
||||
},
|
||||
"article:published_time": {
|
||||
"type": "date"
|
||||
},
|
||||
"article:section": {
|
||||
"type": "text",
|
||||
"fields": {
|
||||
"raw": {
|
||||
"type": "keyword"
|
||||
}
|
||||
}
|
||||
},
|
||||
"article:tag": {
|
||||
"type": "text",
|
||||
"fields": {
|
||||
"raw": {
|
||||
"type": "keyword"
|
||||
}
|
||||
}
|
||||
},
|
||||
"og:description": {
|
||||
"type": "text",
|
||||
"fields": {
|
||||
"raw": {
|
||||
"type": "keyword"
|
||||
}
|
||||
}
|
||||
},
|
||||
"og:image": {
|
||||
"type": "text",
|
||||
"fields": {
|
||||
"raw": {
|
||||
"type": "keyword"
|
||||
}
|
||||
}
|
||||
},
|
||||
"og:image:height": {
|
||||
"type": "text",
|
||||
"fields": {
|
||||
"raw": {
|
||||
"type": "keyword"
|
||||
}
|
||||
}
|
||||
},
|
||||
"og:image:width": {
|
||||
"type": "text",
|
||||
"fields": {
|
||||
"raw": {
|
||||
"type": "keyword"
|
||||
}
|
||||
}
|
||||
},
|
||||
"og:site_name": {
|
||||
"type": "text",
|
||||
"fields": {
|
||||
"raw": {
|
||||
"type": "keyword"
|
||||
}
|
||||
}
|
||||
},
|
||||
"og:title": {
|
||||
"type": "text",
|
||||
"fields": {
|
||||
"raw": {
|
||||
"type": "keyword"
|
||||
}
|
||||
}
|
||||
},
|
||||
"og:type": {
|
||||
"type": "text",
|
||||
"fields": {
|
||||
"raw": {
|
||||
"type": "keyword"
|
||||
}
|
||||
}
|
||||
},
|
||||
"og:url": {
|
||||
"type": "text",
|
||||
"fields": {
|
||||
"raw": {
|
||||
"type": "keyword"
|
||||
}
|
||||
}
|
||||
},
|
||||
"twitter:card": {
|
||||
"type": "text",
|
||||
"fields": {
|
||||
"raw": {
|
||||
"type": "keyword"
|
||||
}
|
||||
}
|
||||
},
|
||||
"twitter:description": {
|
||||
"type": "text",
|
||||
"fields": {
|
||||
"raw": {
|
||||
"type": "keyword"
|
||||
}
|
||||
}
|
||||
},
|
||||
"twitter:image": {
|
||||
"type": "text",
|
||||
"fields": {
|
||||
"raw": {
|
||||
"type": "keyword"
|
||||
}
|
||||
}
|
||||
},
|
||||
"twitter:site": {
|
||||
"type": "text",
|
||||
"fields": {
|
||||
"raw": {
|
||||
"type": "keyword"
|
||||
}
|
||||
}
|
||||
},
|
||||
"twitter:title": {
|
||||
"type": "text",
|
||||
"fields": {
|
||||
"raw": {
|
||||
"type": "keyword"
|
||||
}
|
||||
}
|
||||
},
|
||||
"url": {
|
||||
"type": "text",
|
||||
"fields": {
|
||||
"raw": {
|
||||
"type": "keyword"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"request": {
|
||||
"type": "text",
|
||||
"fields": {
|
||||
"raw": {
|
||||
"type": "keyword"
|
||||
}
|
||||
}
|
||||
},
|
||||
"response": {
|
||||
"type": "text",
|
||||
"fields": {
|
||||
"raw": {
|
||||
"type": "keyword"
|
||||
}
|
||||
}
|
||||
},
|
||||
"spaces": {
|
||||
"type": "text",
|
||||
"fields": {
|
||||
"raw": {
|
||||
"type": "keyword"
|
||||
}
|
||||
}
|
||||
},
|
||||
"url": {
|
||||
"type": "text",
|
||||
"fields": {
|
||||
"raw": {
|
||||
"type": "keyword"
|
||||
}
|
||||
}
|
||||
},
|
||||
"utc_time": {
|
||||
"type": "date"
|
||||
},
|
||||
"xss": {
|
||||
"type": "text",
|
||||
"fields": {
|
||||
"raw": {
|
||||
"type": "keyword"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Binary file not shown.
|
@ -0,0 +1,274 @@
|
|||
{
|
||||
"type": "index",
|
||||
"value": {
|
||||
"index": ".kibana",
|
||||
"settings": {
|
||||
"index": {
|
||||
"number_of_shards": "1",
|
||||
"auto_expand_replicas": "0-1",
|
||||
"number_of_replicas": "0"
|
||||
}
|
||||
},
|
||||
"mappings": {
|
||||
"doc": {
|
||||
"dynamic": "strict",
|
||||
"properties": {
|
||||
"config": {
|
||||
"dynamic": "true",
|
||||
"properties": {
|
||||
"buildNum": {
|
||||
"type": "keyword"
|
||||
},
|
||||
"dateFormat:tz": {
|
||||
"type": "text",
|
||||
"fields": {
|
||||
"keyword": {
|
||||
"type": "keyword",
|
||||
"ignore_above": 256
|
||||
}
|
||||
}
|
||||
},
|
||||
"defaultIndex": {
|
||||
"type": "text",
|
||||
"fields": {
|
||||
"keyword": {
|
||||
"type": "keyword",
|
||||
"ignore_above": 256
|
||||
}
|
||||
}
|
||||
},
|
||||
"notifications:lifetime:banner": {
|
||||
"type": "long"
|
||||
},
|
||||
"notifications:lifetime:error": {
|
||||
"type": "long"
|
||||
},
|
||||
"notifications:lifetime:info": {
|
||||
"type": "long"
|
||||
},
|
||||
"notifications:lifetime:warning": {
|
||||
"type": "long"
|
||||
}
|
||||
}
|
||||
},
|
||||
"dashboard": {
|
||||
"properties": {
|
||||
"description": {
|
||||
"type": "text"
|
||||
},
|
||||
"hits": {
|
||||
"type": "integer"
|
||||
},
|
||||
"kibanaSavedObjectMeta": {
|
||||
"properties": {
|
||||
"searchSourceJSON": {
|
||||
"type": "text"
|
||||
}
|
||||
}
|
||||
},
|
||||
"optionsJSON": {
|
||||
"type": "text"
|
||||
},
|
||||
"panelsJSON": {
|
||||
"type": "text"
|
||||
},
|
||||
"refreshInterval": {
|
||||
"properties": {
|
||||
"display": {
|
||||
"type": "keyword"
|
||||
},
|
||||
"pause": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"section": {
|
||||
"type": "integer"
|
||||
},
|
||||
"value": {
|
||||
"type": "integer"
|
||||
}
|
||||
}
|
||||
},
|
||||
"timeFrom": {
|
||||
"type": "keyword"
|
||||
},
|
||||
"timeRestore": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"timeTo": {
|
||||
"type": "keyword"
|
||||
},
|
||||
"title": {
|
||||
"type": "text"
|
||||
},
|
||||
"uiStateJSON": {
|
||||
"type": "text"
|
||||
},
|
||||
"version": {
|
||||
"type": "integer"
|
||||
}
|
||||
}
|
||||
},
|
||||
"index-pattern": {
|
||||
"properties": {
|
||||
"fieldFormatMap": {
|
||||
"type": "text"
|
||||
},
|
||||
"fields": {
|
||||
"type": "text"
|
||||
},
|
||||
"intervalName": {
|
||||
"type": "keyword"
|
||||
},
|
||||
"notExpandable": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"sourceFilters": {
|
||||
"type": "text"
|
||||
},
|
||||
"timeFieldName": {
|
||||
"type": "keyword"
|
||||
},
|
||||
"title": {
|
||||
"type": "text"
|
||||
}
|
||||
}
|
||||
},
|
||||
"search": {
|
||||
"properties": {
|
||||
"columns": {
|
||||
"type": "keyword"
|
||||
},
|
||||
"description": {
|
||||
"type": "text"
|
||||
},
|
||||
"hits": {
|
||||
"type": "integer"
|
||||
},
|
||||
"kibanaSavedObjectMeta": {
|
||||
"properties": {
|
||||
"searchSourceJSON": {
|
||||
"type": "text"
|
||||
}
|
||||
}
|
||||
},
|
||||
"sort": {
|
||||
"type": "keyword"
|
||||
},
|
||||
"title": {
|
||||
"type": "text"
|
||||
},
|
||||
"version": {
|
||||
"type": "integer"
|
||||
}
|
||||
}
|
||||
},
|
||||
"server": {
|
||||
"properties": {
|
||||
"uuid": {
|
||||
"type": "keyword"
|
||||
}
|
||||
}
|
||||
},
|
||||
"timelion-sheet": {
|
||||
"properties": {
|
||||
"description": {
|
||||
"type": "text"
|
||||
},
|
||||
"hits": {
|
||||
"type": "integer"
|
||||
},
|
||||
"kibanaSavedObjectMeta": {
|
||||
"properties": {
|
||||
"searchSourceJSON": {
|
||||
"type": "text"
|
||||
}
|
||||
}
|
||||
},
|
||||
"timelion_chart_height": {
|
||||
"type": "integer"
|
||||
},
|
||||
"timelion_columns": {
|
||||
"type": "integer"
|
||||
},
|
||||
"timelion_interval": {
|
||||
"type": "keyword"
|
||||
},
|
||||
"timelion_other_interval": {
|
||||
"type": "keyword"
|
||||
},
|
||||
"timelion_rows": {
|
||||
"type": "integer"
|
||||
},
|
||||
"timelion_sheet": {
|
||||
"type": "text"
|
||||
},
|
||||
"title": {
|
||||
"type": "text"
|
||||
},
|
||||
"version": {
|
||||
"type": "integer"
|
||||
}
|
||||
}
|
||||
},
|
||||
"type": {
|
||||
"type": "keyword"
|
||||
},
|
||||
"updated_at": {
|
||||
"type": "date"
|
||||
},
|
||||
"url": {
|
||||
"properties": {
|
||||
"accessCount": {
|
||||
"type": "long"
|
||||
},
|
||||
"accessDate": {
|
||||
"type": "date"
|
||||
},
|
||||
"createDate": {
|
||||
"type": "date"
|
||||
},
|
||||
"url": {
|
||||
"type": "text",
|
||||
"fields": {
|
||||
"keyword": {
|
||||
"type": "keyword",
|
||||
"ignore_above": 2048
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"visualization": {
|
||||
"properties": {
|
||||
"description": {
|
||||
"type": "text"
|
||||
},
|
||||
"kibanaSavedObjectMeta": {
|
||||
"properties": {
|
||||
"searchSourceJSON": {
|
||||
"type": "text"
|
||||
}
|
||||
}
|
||||
},
|
||||
"savedSearchId": {
|
||||
"type": "keyword"
|
||||
},
|
||||
"title": {
|
||||
"type": "text"
|
||||
},
|
||||
"uiStateJSON": {
|
||||
"type": "text"
|
||||
},
|
||||
"version": {
|
||||
"type": "integer"
|
||||
},
|
||||
"visState": {
|
||||
"type": "text"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -250,6 +250,10 @@ export function CommonPageProvider({ getService, getPageObjects }) {
|
|||
return await testSubjects.getVisibleText('breadcrumbPageTitle');
|
||||
}
|
||||
|
||||
async getTopNavText() {
|
||||
return await testSubjects.getVisibleText('top-nav');
|
||||
}
|
||||
|
||||
async doesCssSelectorExist(selector) {
|
||||
log.debug(`doesCssSelectorExist ${selector}`);
|
||||
|
||||
|
|
|
@ -14,23 +14,28 @@ export function DashboardPageProvider({ getService, getPageObjects }) {
|
|||
const esArchiver = getService('esArchiver');
|
||||
const kibanaServer = getService('kibanaServer');
|
||||
const testSubjects = getService('testSubjects');
|
||||
const PageObjects = getPageObjects(['common', 'header']);
|
||||
const dashboardAddPanel = getService('dashboardAddPanel');
|
||||
const PageObjects = getPageObjects(['common', 'header', 'settings', 'visualize']);
|
||||
|
||||
const defaultFindTimeout = config.get('timeouts.find');
|
||||
|
||||
class DashboardPage {
|
||||
async initTests() {
|
||||
async initTests({
|
||||
kibanaIndex = 'dashboard/legacy',
|
||||
dataIndex = 'logstash_functional',
|
||||
defaultIndex = 'logstash-*',
|
||||
} = {}) {
|
||||
log.debug('load kibana index with visualizations and log data');
|
||||
await Promise.all([
|
||||
esArchiver.load('dashboard'),
|
||||
esArchiver.loadIfNeeded('logstash_functional')
|
||||
esArchiver.load(kibanaIndex),
|
||||
esArchiver.loadIfNeeded(dataIndex)
|
||||
]);
|
||||
|
||||
await kibanaServer.uiSettings.replace({
|
||||
'dateFormat:tz': 'UTC',
|
||||
'defaultIndex': 'logstash-*'
|
||||
'defaultIndex': defaultIndex
|
||||
});
|
||||
|
||||
await this.selectDefaultIndex(defaultIndex);
|
||||
await kibanaServer.uiSettings.disableToastAutohide();
|
||||
await PageObjects.common.navigateToApp('dashboard');
|
||||
}
|
||||
|
@ -41,6 +46,13 @@ export function DashboardPageProvider({ getService, getPageObjects }) {
|
|||
await PageObjects.header.waitUntilLoadingHasFinished();
|
||||
}
|
||||
|
||||
async selectDefaultIndex(indexName) {
|
||||
await PageObjects.settings.navigateTo();
|
||||
await PageObjects.settings.clickKibanaIndices();
|
||||
await PageObjects.settings.clickLinkText(indexName);
|
||||
await PageObjects.settings.clickDefaultIndexButton();
|
||||
}
|
||||
|
||||
async clickEditVisualization() {
|
||||
log.debug('clickEditVisualization');
|
||||
|
||||
|
@ -211,14 +223,6 @@ export function DashboardPageProvider({ getService, getPageObjects }) {
|
|||
await testSubjects.click('deleteSelectedDashboards');
|
||||
}
|
||||
|
||||
async clickAddVisualization() {
|
||||
await testSubjects.click('dashboardAddPanelButton');
|
||||
}
|
||||
|
||||
async clickAddNewVisualizationLink() {
|
||||
await testSubjects.click('addNewSavedObjectLink');
|
||||
}
|
||||
|
||||
async clickOptions() {
|
||||
await testSubjects.click('dashboardOptionsButton');
|
||||
}
|
||||
|
@ -236,6 +240,14 @@ export function DashboardPageProvider({ getService, getPageObjects }) {
|
|||
}
|
||||
}
|
||||
|
||||
// avoids any 'Object with id x not found' errors when switching tests.
|
||||
async clearSavedObjectsFromAppLinks() {
|
||||
await PageObjects.header.clickVisualize();
|
||||
await PageObjects.visualize.gotoLandingPage();
|
||||
await PageObjects.header.clickDashboard();
|
||||
await this.gotoDashboardLandingPage();
|
||||
}
|
||||
|
||||
async isDarkThemeOn() {
|
||||
log.debug('isDarkThemeOn');
|
||||
await this.openOptions();
|
||||
|
@ -266,48 +278,11 @@ export function DashboardPageProvider({ getService, getPageObjects }) {
|
|||
}
|
||||
}
|
||||
|
||||
async clickVizNameLink(vizName) {
|
||||
await find.clickByPartialLinkText(vizName);
|
||||
}
|
||||
|
||||
async closeAddVizualizationPanel() {
|
||||
log.debug('closeAddVizualizationPanel');
|
||||
await find.clickByCssSelector('i.fa fa-chevron-up');
|
||||
}
|
||||
|
||||
async gotoDashboardEditMode(dashboardName) {
|
||||
await this.loadSavedDashboard(dashboardName);
|
||||
await this.clickEdit();
|
||||
}
|
||||
|
||||
async filterEmbeddableNames(name) {
|
||||
await testSubjects.setValue('savedObjectFinderSearchInput', name);
|
||||
await PageObjects.header.waitUntilLoadingHasFinished();
|
||||
}
|
||||
|
||||
async clickSavedSearchTab() {
|
||||
await testSubjects.click('addSavedSearchTab');
|
||||
}
|
||||
|
||||
async addSavedSearch(searchName) {
|
||||
await this.clickAddVisualization();
|
||||
await this.clickSavedSearchTab();
|
||||
await this.filterEmbeddableNames(searchName);
|
||||
|
||||
await find.clickByPartialLinkText(searchName);
|
||||
await testSubjects.exists('addSavedSearchToDashboardSuccess');
|
||||
await this.clickAddVisualization();
|
||||
}
|
||||
|
||||
async addVisualization(vizName) {
|
||||
await this.clickAddVisualization();
|
||||
log.debug('filter visualization (' + vizName + ')');
|
||||
await this.filterEmbeddableNames(vizName);
|
||||
await this.clickVizNameLink(vizName);
|
||||
// this second click of 'Add' collapses the Add Visualization pane
|
||||
await this.clickAddVisualization();
|
||||
}
|
||||
|
||||
async renameDashboard(dashName) {
|
||||
log.debug(`Naming dashboard ` + dashName);
|
||||
await testSubjects.click('dashboardRenameButton');
|
||||
|
@ -438,8 +413,8 @@ export function DashboardPageProvider({ getService, getPageObjects }) {
|
|||
return Promise.all(getTitlePromises);
|
||||
}
|
||||
|
||||
async getDashboardPanels() {
|
||||
return await testSubjects.findAll('dashboardPanel');
|
||||
async getPanelHeading(title) {
|
||||
return await testSubjects.find(`dashboardPanelHeading-${title.replace(/\s/g, '')}`);
|
||||
}
|
||||
|
||||
async getPanelDimensions() {
|
||||
|
@ -458,7 +433,7 @@ export function DashboardPageProvider({ getService, getPageObjects }) {
|
|||
|
||||
async getPanelCount() {
|
||||
log.debug('getPanelCount');
|
||||
const panels = await find.allByCssSelector('.react-grid-item');
|
||||
const panels = await testSubjects.findAll('dashboardPanel');
|
||||
return panels.length;
|
||||
}
|
||||
|
||||
|
@ -496,6 +471,10 @@ export function DashboardPageProvider({ getService, getPageObjects }) {
|
|||
});
|
||||
}
|
||||
|
||||
async getDashboardPanels() {
|
||||
return await testSubjects.findAll('dashboardPanel');
|
||||
}
|
||||
|
||||
async clickDashboardPanelEditLink() {
|
||||
await this.showPanelEditControlsDropdownMenu();
|
||||
await testSubjects.click('dashboardPanelEditLink');
|
||||
|
@ -507,9 +486,7 @@ export function DashboardPageProvider({ getService, getPageObjects }) {
|
|||
}
|
||||
|
||||
async addVisualizations(visualizations) {
|
||||
for (const vizName of visualizations) {
|
||||
await this.addVisualization(vizName);
|
||||
}
|
||||
await dashboardAddPanel.addVisualizations(visualizations);
|
||||
}
|
||||
|
||||
async setTimepickerInDataRange() {
|
||||
|
@ -518,6 +495,12 @@ export function DashboardPageProvider({ getService, getPageObjects }) {
|
|||
await PageObjects.header.setAbsoluteRange(fromTime, toTime);
|
||||
}
|
||||
|
||||
async setTimepickerIn63DataRange() {
|
||||
const fromTime = '2018-01-01 00:00:00.000';
|
||||
const toTime = '2018-04-13 00:00:00.000';
|
||||
await PageObjects.header.setAbsoluteRange(fromTime, toTime);
|
||||
}
|
||||
|
||||
async setSaveAsNewCheckBox(checked) {
|
||||
log.debug('saveAsNewCheckbox: ' + checked);
|
||||
const saveAsNewCheckbox = await testSubjects.find('saveAsNewCheckbox');
|
||||
|
@ -549,59 +532,73 @@ export function DashboardPageProvider({ getService, getPageObjects }) {
|
|||
return _.map(filters, async (filter) => await filter.getVisibleText());
|
||||
}
|
||||
|
||||
async getPieSliceCount() {
|
||||
async getPieSliceCount(timeout) {
|
||||
log.debug('getPieSliceCount');
|
||||
return await retry.try(async () => {
|
||||
const slices = await find.allByCssSelector('svg > g > g.arcs > path.slice');
|
||||
const slices = await find.allByCssSelector('svg > g > g.arcs > path.slice', timeout);
|
||||
return slices.length;
|
||||
});
|
||||
}
|
||||
|
||||
async filterOnPieSlice() {
|
||||
log.debug('Filtering on a pie slice');
|
||||
await retry.try(async () => {
|
||||
const slices = await find.allByCssSelector('svg > g > g.arcs > path.slice');
|
||||
log.debug('Slices found:' + slices.length);
|
||||
return slices[0].click();
|
||||
});
|
||||
async filterOnPieSlice(sliceValue) {
|
||||
log.debug(`Filtering on a pie slice with optional value ${sliceValue}`);
|
||||
if (sliceValue) {
|
||||
await testSubjects.click(`pieSlice-${sliceValue}`);
|
||||
} else {
|
||||
await retry.try(async () => {
|
||||
const slices = await find.allByCssSelector('svg > g > g.arcs > path.slice');
|
||||
log.debug('Slices found:' + slices.length);
|
||||
return slices[0].click();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
async arePanelMainMenuOptionsOpen(panel) {
|
||||
async arePanelMainMenuOptionsOpen(parent) {
|
||||
log.debug('arePanelMainMenuOptionsOpen');
|
||||
// Sub menu used arbitrarily - any option on the main menu panel would do.
|
||||
return panel ?
|
||||
await testSubjects.descendantExists('dashboardPanelOptionsSubMenuLink', panel) :
|
||||
return parent ?
|
||||
await testSubjects.descendantExists('dashboardPanelOptionsSubMenuLink', parent) :
|
||||
await testSubjects.exists('dashboardPanelOptionsSubMenuLink');
|
||||
}
|
||||
|
||||
async openPanelOptions(panel) {
|
||||
async openPanelOptions(parent) {
|
||||
log.debug('openPanelOptions');
|
||||
const panelOpen = await this.arePanelMainMenuOptionsOpen(panel);
|
||||
const panelOpen = await this.arePanelMainMenuOptionsOpen(parent);
|
||||
if (!panelOpen) {
|
||||
await retry.try(async () => {
|
||||
await (panel ? remote.moveMouseTo(panel) : testSubjects.moveMouseTo('dashboardPanelTitle'));
|
||||
const toggleMenuItem = panel ?
|
||||
await testSubjects.findDescendant('dashboardPanelToggleMenuIcon', panel) :
|
||||
await (parent ? remote.moveMouseTo(parent) : testSubjects.moveMouseTo('dashboardPanelTitle'));
|
||||
const toggleMenuItem = parent ?
|
||||
await testSubjects.findDescendant('dashboardPanelToggleMenuIcon', parent) :
|
||||
await testSubjects.find('dashboardPanelToggleMenuIcon');
|
||||
await toggleMenuItem.click();
|
||||
const panelOpen = await this.arePanelMainMenuOptionsOpen(panel);
|
||||
const panelOpen = await this.arePanelMainMenuOptionsOpen(parent);
|
||||
if (!panelOpen) { throw new Error('Panel menu still not open'); }
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
async toggleExpandPanel(panel) {
|
||||
await (panel ? remote.moveMouseTo(panel) : testSubjects.moveMouseTo('dashboardPanelTitle'));
|
||||
async toggleExpandPanel(parent) {
|
||||
await (parent ? remote.moveMouseTo(parent) : testSubjects.moveMouseTo('dashboardPanelTitle'));
|
||||
const expandShown = await testSubjects.exists('dashboardPanelExpandIcon');
|
||||
if (!expandShown) {
|
||||
await this.openPanelOptions(panel);
|
||||
await this.openPanelOptions(parent);
|
||||
}
|
||||
await testSubjects.click('dashboardPanelExpandIcon');
|
||||
}
|
||||
|
||||
async setCustomPanelTitle(customTitle, panel) {
|
||||
log.debug(`setCustomPanelTitle(${customTitle}, ${panel})`);
|
||||
await this.openPanelOptions(panel);
|
||||
/**
|
||||
*
|
||||
* @param customTitle
|
||||
* @param originalTitle - optional to specify which panel to change the title on.
|
||||
* @return {Promise<void>}
|
||||
*/
|
||||
async setCustomPanelTitle(customTitle, originalTitle) {
|
||||
log.debug(`setCustomPanelTitle(${customTitle}, ${originalTitle})`);
|
||||
let panelOptions = null;
|
||||
if (originalTitle) {
|
||||
panelOptions = await this.getPanelHeading(originalTitle);
|
||||
}
|
||||
await this.openPanelOptions(panelOptions);
|
||||
await testSubjects.click('dashboardPanelOptionsSubMenuLink');
|
||||
await testSubjects.setValue('customDashboardPanelTitleInput', customTitle);
|
||||
}
|
||||
|
@ -640,6 +637,15 @@ export function DashboardPageProvider({ getService, getPageObjects }) {
|
|||
});
|
||||
}
|
||||
|
||||
async getSharedContainerData() {
|
||||
log.debug('getSharedContainerData');
|
||||
const sharedContainer = await find.byCssSelector('[data-shared-items-container]');
|
||||
return {
|
||||
title: await sharedContainer.getAttribute('data-title'),
|
||||
description: await sharedContainer.getAttribute('data-description')
|
||||
};
|
||||
}
|
||||
|
||||
async getPanelSharedItemData() {
|
||||
log.debug('in getPanelSharedItemData');
|
||||
const sharedItems = await find.allByCssSelector('[data-shared-item]');
|
||||
|
|
|
@ -16,6 +16,15 @@ export function HeaderPageProvider({ getService, getPageObjects }) {
|
|||
await retry.try(async () => await remote.findByCssSelector(selector).click());
|
||||
}
|
||||
|
||||
async confirmTopNavTextContains(text) {
|
||||
await retry.try(async () => {
|
||||
const topNavText = await PageObjects.common.getTopNavText();
|
||||
if (topNavText.toLowerCase().indexOf(text.toLowerCase()) < 0) {
|
||||
throw new Error(`Top nav text ${topNavText} does not contain ${text} (case insensitive)`);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
async clickDiscover() {
|
||||
log.debug('click Discover tab');
|
||||
await this.clickSelector('a[href*=\'discover\']');
|
||||
|
@ -27,6 +36,7 @@ export function HeaderPageProvider({ getService, getPageObjects }) {
|
|||
log.debug('click Visualize tab');
|
||||
await this.clickSelector('a[href*=\'visualize\']');
|
||||
await PageObjects.common.waitForTopNavToBeVisible();
|
||||
await this.confirmTopNavTextContains('visualize');
|
||||
await this.isGlobalLoadingIndicatorHidden();
|
||||
}
|
||||
|
||||
|
@ -34,6 +44,7 @@ export function HeaderPageProvider({ getService, getPageObjects }) {
|
|||
log.debug('click Dashboard tab');
|
||||
await this.clickSelector('a[href*=\'dashboard\']');
|
||||
await PageObjects.common.waitForTopNavToBeVisible();
|
||||
await this.confirmTopNavTextContains('dashboard');
|
||||
await this.isGlobalLoadingIndicatorHidden();
|
||||
}
|
||||
|
||||
|
|
|
@ -558,11 +558,14 @@ export function VisualizePageProvider({ getService, getPageObjects }) {
|
|||
});
|
||||
}
|
||||
|
||||
async saveVisualization(vizName) {
|
||||
async saveVisualization(vizName, { saveAsNew = false } = {}) {
|
||||
await this.ensureSavePanelOpen();
|
||||
await testSubjects.setValue('visTitleInput', vizName);
|
||||
log.debug('click submit button');
|
||||
await testSubjects.click('saveVisualizationButton');
|
||||
if (saveAsNew) {
|
||||
await testSubjects.click('saveAsNewCheckbox');
|
||||
}
|
||||
await PageObjects.header.waitUntilLoadingHasFinished();
|
||||
return await testSubjects.exists('saveVisualizationSuccess');
|
||||
}
|
||||
|
@ -753,9 +756,13 @@ export function VisualizePageProvider({ getService, getPageObjects }) {
|
|||
return await dataTable.getVisibleText();
|
||||
}
|
||||
|
||||
async getDataTableHeaders() {
|
||||
async getDataTableHeaders(parent) {
|
||||
const dataTableHeader = await retry.try(
|
||||
async () => testSubjects.find('paginated-table-header'));
|
||||
async () => (
|
||||
parent ?
|
||||
testSubjects.findDescendant('paginated-table-header', parent) :
|
||||
testSubjects.find('paginated-table-header')
|
||||
));
|
||||
return await dataTableHeader.getVisibleText();
|
||||
}
|
||||
|
||||
|
|
144
test/functional/services/dashboard/add_panel.js
Normal file
144
test/functional/services/dashboard/add_panel.js
Normal file
|
@ -0,0 +1,144 @@
|
|||
|
||||
export function DashboardAddPanelProvider({ getService, getPageObjects }) {
|
||||
const log = getService('log');
|
||||
const retry = getService('retry');
|
||||
const testSubjects = getService('testSubjects');
|
||||
const find = getService('find');
|
||||
const PageObjects = getPageObjects(['header']);
|
||||
|
||||
return new class DashboardAddPanel {
|
||||
async clickOpenAddPanel() {
|
||||
log.debug('DashboardAddPanel.clickOpenAddPanel');
|
||||
await testSubjects.click('dashboardAddPanelButton');
|
||||
}
|
||||
|
||||
async clickAddNewEmbeddableLink() {
|
||||
await testSubjects.click('addNewSavedObjectLink');
|
||||
}
|
||||
|
||||
async closeAddVizualizationPanel() {
|
||||
log.debug('closeAddVizualizationPanel');
|
||||
await find.clickByCssSelector('i.fa fa-chevron-up');
|
||||
}
|
||||
|
||||
async clickSavedSearchTab() {
|
||||
await testSubjects.click('addSavedSearchTab');
|
||||
}
|
||||
|
||||
async addEveryEmbeddableOnCurrentPage() {
|
||||
log.debug('addEveryEmbeddableOnCurrentPage');
|
||||
const embeddableRows = await find.allByCssSelector('.list-group-menu-item');
|
||||
for (let i = 0; i < embeddableRows.length; i++) {
|
||||
await embeddableRows[i].click();
|
||||
}
|
||||
log.debug(`Added ${embeddableRows.length} embeddables`);
|
||||
}
|
||||
|
||||
async clickPagerNextButton() {
|
||||
const pagerNextButtonExists = await testSubjects.exists('paginateNext');
|
||||
if (pagerNextButtonExists) {
|
||||
await testSubjects.click('paginateNext');
|
||||
await PageObjects.header.waitUntilLoadingHasFinished();
|
||||
}
|
||||
return pagerNextButtonExists;
|
||||
}
|
||||
|
||||
async isAddPanelOpen() {
|
||||
log.debug('DashboardAddPanel.isAddPanelOpen');
|
||||
return await testSubjects.exists('dashboardAddPanel');
|
||||
}
|
||||
|
||||
async ensureAddPanelIsShowing() {
|
||||
log.debug('DashboardAddPanel.ensureAddPanelIsShowing');
|
||||
const isOpen = await this.isAddPanelOpen();
|
||||
if (!isOpen) {
|
||||
await retry.try(async () => {
|
||||
await this.clickOpenAddPanel();
|
||||
const isOpen = await this.isAddPanelOpen();
|
||||
if (!isOpen) {
|
||||
throw new Error('Add panel still not open, trying again.');
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
async closeAddPanel() {
|
||||
log.debug('closeAddPanel');
|
||||
const isOpen = await this.isAddPanelOpen();
|
||||
if (isOpen) {
|
||||
await retry.try(async () => {
|
||||
await this.clickOpenAddPanel();
|
||||
const isOpen = await this.isAddPanelOpen();
|
||||
if (isOpen) {
|
||||
throw new Error('Add panel still open, trying again.');
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
async addEveryVisualization(filter) {
|
||||
log.debug('DashboardAddPanel.addEveryVisualization');
|
||||
await this.ensureAddPanelIsShowing();
|
||||
if (filter) {
|
||||
await this.filterEmbeddableNames(filter.replace('-', ' '));
|
||||
}
|
||||
let morePages = true;
|
||||
while (morePages) {
|
||||
await this.addEveryEmbeddableOnCurrentPage();
|
||||
morePages = await this.clickPagerNextButton();
|
||||
}
|
||||
}
|
||||
|
||||
async addEverySavedSearch(filter) {
|
||||
log.debug('DashboardAddPanel.addEverySavedSearch');
|
||||
await this.ensureAddPanelIsShowing();
|
||||
await this.clickSavedSearchTab();
|
||||
if (filter) {
|
||||
await this.filterEmbeddableNames(filter.replace('-', ' '));
|
||||
}
|
||||
let morePages = true;
|
||||
while (morePages) {
|
||||
await this.addEveryEmbeddableOnCurrentPage();
|
||||
morePages = await this.clickPagerNextButton();
|
||||
}
|
||||
}
|
||||
|
||||
async addSavedSearch(searchName) {
|
||||
log.debug(`addSavedSearch(${searchName})`);
|
||||
|
||||
await this.ensureAddPanelIsShowing();
|
||||
await this.clickSavedSearchTab();
|
||||
await this.filterEmbeddableNames(searchName);
|
||||
|
||||
await find.clickByPartialLinkText(searchName);
|
||||
await testSubjects.exists('addSavedSearchToDashboardSuccess');
|
||||
await this.closeAddPanel();
|
||||
}
|
||||
|
||||
async addSavedSearches(searches) {
|
||||
for (const name of searches) {
|
||||
await this.addSavedSearch(name);
|
||||
}
|
||||
}
|
||||
|
||||
async addVisualizations(visualizations) {
|
||||
log.debug('DashboardAddPanel.addVisualizations');
|
||||
for (const vizName of visualizations) {
|
||||
await this.addVisualization(vizName);
|
||||
}
|
||||
}
|
||||
|
||||
async addVisualization(vizName) {
|
||||
log.debug(`DashboardAddPanel.addVisualization(${vizName})`);
|
||||
await this.ensureAddPanelIsShowing();
|
||||
await this.filterEmbeddableNames(`"${vizName.replace('-', ' ')}"`);
|
||||
await find.clickByPartialLinkText(vizName);
|
||||
await this.closeAddPanel();
|
||||
}
|
||||
|
||||
async filterEmbeddableNames(name) {
|
||||
await testSubjects.setValue('savedObjectFinderSearchInput', name);
|
||||
await PageObjects.header.waitUntilLoadingHasFinished();
|
||||
}
|
||||
};
|
||||
}
|
|
@ -4,8 +4,9 @@ export function DashboardExpectProvider({ getService, getPageObjects }) {
|
|||
const log = getService('log');
|
||||
const retry = getService('retry');
|
||||
const testSubjects = getService('testSubjects');
|
||||
const find = getService('find');
|
||||
const filterBar = getService('filterBar');
|
||||
const PageObjects = getPageObjects(['dashboard']);
|
||||
const PageObjects = getPageObjects(['dashboard', 'visualize']);
|
||||
|
||||
return new class DashboardExpect {
|
||||
async pieSliceCount(expectedCount) {
|
||||
|
@ -35,8 +36,15 @@ export function DashboardExpectProvider({ getService, getPageObjects }) {
|
|||
async docTableFieldCount(expectedCount) {
|
||||
log.debug(`DashboardExpect.docTableFieldCount(${expectedCount})`);
|
||||
await retry.try(async () => {
|
||||
const docTableCellCounts = await testSubjects.findAll(`docTableField`);
|
||||
expect(docTableCellCounts.length).to.be(expectedCount);
|
||||
const docTableCells = await testSubjects.findAll('docTableField');
|
||||
expect(docTableCells.length).to.be(expectedCount);
|
||||
});
|
||||
}
|
||||
|
||||
async tsvbTimeSeriesLegendCount(expectedCount) {
|
||||
await retry.try(async () => {
|
||||
const tsvbLegendItems = await testSubjects.findAll('tsvbLegendItem');
|
||||
expect(tsvbLegendItems.length).to.be(expectedCount);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -44,5 +52,164 @@ export function DashboardExpectProvider({ getService, getPageObjects }) {
|
|||
const indexPatterns = await filterBar.getFilterFieldIndexPatterns();
|
||||
expect(indexPatterns).to.eql(expectedIndexPatterns);
|
||||
}
|
||||
|
||||
async legendValuesToExist(legendValues) {
|
||||
await Promise.all(legendValues.map(async legend => {
|
||||
await retry.try(async () => {
|
||||
const legendValueExists = await testSubjects.exists(`legend-${legend}`);
|
||||
expect(legendValueExists).to.be(true);
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
async textWithinElementsExists(texts, getElementsFn) {
|
||||
await retry.try(async () => {
|
||||
const elements = await getElementsFn();
|
||||
const elementTexts = [];
|
||||
await Promise.all(elements.map(async element => {
|
||||
elementTexts.push(await element.getVisibleText());
|
||||
}));
|
||||
log.debug(`Found ${elements.length} elements with values: ${JSON.stringify(elementTexts)}`);
|
||||
texts.forEach(value => {
|
||||
const indexOfValue = elementTexts.indexOf(value);
|
||||
expect(indexOfValue).to.be.greaterThan(-1);
|
||||
elementTexts.splice(indexOfValue, 1);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
async textWithinTestSubjectsExists(texts, selector) {
|
||||
log.debug(`textWithinTestSubjectsExists:(${JSON.stringify(texts)},${selector})`);
|
||||
await this.textWithinElementsExists(texts, async () => await testSubjects.findAll(selector));
|
||||
}
|
||||
|
||||
async textWithinCssElementExists(texts, selector) {
|
||||
log.debug(`textWithinCssElementExists:(${JSON.stringify(texts)},${selector})`);
|
||||
await this.textWithinElementsExists(texts, async () => await find.allByCssSelector(selector));
|
||||
}
|
||||
|
||||
async textWithinElementsDoNotExist(texts, getElementsFn) {
|
||||
await retry.try(async () => {
|
||||
const elements = await getElementsFn();
|
||||
const elementTexts = [];
|
||||
await Promise.all(elements.map(async element => {
|
||||
elementTexts.push(await element.getVisibleText());
|
||||
}));
|
||||
log.debug(`Found ${elements.length} elements with values: ${JSON.stringify(elementTexts)}`);
|
||||
texts.forEach(value => {
|
||||
const indexOfValue = elementTexts.indexOf(value);
|
||||
expect(indexOfValue).to.be(-1);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
async textWithinCssElementDoNotExist(texts, selector) {
|
||||
log.debug(`textWithinCssElementExists:(${JSON.stringify(texts)},${selector})`);
|
||||
await this.textWithinElementsDoNotExist(texts, async () => await find.allByCssSelector(selector));
|
||||
}
|
||||
|
||||
async timelionLegendCount(expectedCount) {
|
||||
await retry.try(async () => {
|
||||
const flotLegendLabels = await testSubjects.findAll('flotLegendLabel');
|
||||
expect(flotLegendLabels.length).to.be(expectedCount);
|
||||
});
|
||||
}
|
||||
|
||||
async emptyTagCloudFound() {
|
||||
const tagCloudVisualizations = await testSubjects.findAll('tagCloudVisualization');
|
||||
const tagCloudsHaveContent = await Promise.all(tagCloudVisualizations.map(async tagCloud => {
|
||||
return await find.descendantExistsByCssSelector('text', tagCloud);
|
||||
}));
|
||||
expect(tagCloudsHaveContent.indexOf(false)).to.be.greaterThan(-1);
|
||||
}
|
||||
|
||||
async tagCloudWithValuesFound(values) {
|
||||
const tagCloudVisualizations = await testSubjects.findAll('tagCloudVisualization');
|
||||
const matches = await Promise.all(tagCloudVisualizations.map(async tagCloud => {
|
||||
for (let i = 0; i < values.length; i++) {
|
||||
const valueExists = await testSubjects.descendantExists(values[i], tagCloud);
|
||||
if (!valueExists) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}));
|
||||
expect(matches.indexOf(true)).to.be.greaterThan(-1);
|
||||
}
|
||||
|
||||
async goalAndGuageLabelsExist(labels) {
|
||||
await this.textWithinCssElementExists(labels, '.chart-label');
|
||||
}
|
||||
|
||||
async metricValuesExist(values) {
|
||||
await this.textWithinCssElementExists(values, '.metric-value');
|
||||
}
|
||||
|
||||
async tsvbMetricValuesExist(values) {
|
||||
await this.textWithinTestSubjectsExists(values, 'tsvbMetricValue');
|
||||
}
|
||||
|
||||
async tsvbTopNValuesExist(values) {
|
||||
await this.textWithinTestSubjectsExists(values, 'tsvbTopNValue');
|
||||
}
|
||||
|
||||
async vegaTextsExist(values) {
|
||||
await this.textWithinCssElementExists(values, '.vega-view-container text');
|
||||
}
|
||||
|
||||
async vegaTextsDoNotExist(values) {
|
||||
await this.textWithinCssElementDoNotExist(values, '.vega-view-container text');
|
||||
}
|
||||
|
||||
async tsvbMarkdownWithValuesExists(values) {
|
||||
await this.textWithinTestSubjectsExists(values, 'tsvbMarkdown');
|
||||
}
|
||||
|
||||
async markdownWithValuesExists(values) {
|
||||
await this.textWithinTestSubjectsExists(values, 'markdownBody');
|
||||
}
|
||||
|
||||
async savedSearchRowCount(expectedCount) {
|
||||
await retry.try(async () => {
|
||||
const savedSearchRows = await testSubjects.findAll('docTableExpandToggleColumn');
|
||||
expect(savedSearchRows.length).to.be(expectedCount);
|
||||
});
|
||||
}
|
||||
|
||||
async dataTableRowCount(expectedCount) {
|
||||
await retry.try(async () => {
|
||||
const dataTableRows =
|
||||
await find.allByCssSelector('[data-test-subj="paginated-table-body"] [data-cell-content]');
|
||||
expect(dataTableRows.length).to.be(expectedCount);
|
||||
});
|
||||
}
|
||||
|
||||
async seriesElementCount(expectedCount) {
|
||||
await retry.try(async () => {
|
||||
const seriesElements = await find.allByCssSelector('.series');
|
||||
expect(seriesElements.length).to.be(expectedCount);
|
||||
});
|
||||
}
|
||||
|
||||
async inputControlItemCount(expectedCount) {
|
||||
await retry.try(async () => {
|
||||
const inputControlItems = await testSubjects.findAll('inputControlItem');
|
||||
expect(inputControlItems.length).to.be(expectedCount);
|
||||
});
|
||||
}
|
||||
|
||||
async lineChartPointsCount(expectedCount) {
|
||||
await retry.try(async () => {
|
||||
const points = await find.allByCssSelector('.points');
|
||||
expect(points.length).to.be(expectedCount);
|
||||
});
|
||||
}
|
||||
|
||||
async tsvbTableCellCount(expectedCount) {
|
||||
await retry.try(async () => {
|
||||
const tableCells = await find.allByCssSelector('.tsvb-table__value');
|
||||
expect(tableCells.length).to.be(expectedCount);
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,2 +1,3 @@
|
|||
export { DashboardVisualizationProvider } from './visualizations';
|
||||
export { DashboardExpectProvider } from './expectations';
|
||||
export { DashboardAddPanelProvider } from './add_panel';
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
export function DashboardVisualizationProvider({ getService, getPageObjects }) {
|
||||
const log = getService('log');
|
||||
const testSubjects = getService('testSubjects');
|
||||
const dashboardAddPanel = getService('dashboardAddPanel');
|
||||
const PageObjects = getPageObjects(['dashboard', 'visualize', 'header', 'discover']);
|
||||
|
||||
return new class DashboardVisualizations {
|
||||
|
@ -11,8 +12,8 @@ export function DashboardVisualizationProvider({ getService, getPageObjects }) {
|
|||
if (inViewMode) {
|
||||
await PageObjects.dashboard.clickEdit();
|
||||
}
|
||||
await PageObjects.dashboard.clickAddVisualization();
|
||||
await PageObjects.dashboard.clickAddNewVisualizationLink();
|
||||
await dashboardAddPanel.ensureAddPanelIsShowing();
|
||||
await dashboardAddPanel.clickAddNewEmbeddableLink();
|
||||
await PageObjects.visualize.clickVisualBuilder();
|
||||
await PageObjects.visualize.saveVisualization(name);
|
||||
}
|
||||
|
@ -49,7 +50,7 @@ export function DashboardVisualizationProvider({ getService, getPageObjects }) {
|
|||
if (inViewMode) {
|
||||
await PageObjects.dashboard.clickEdit();
|
||||
}
|
||||
await PageObjects.dashboard.addSavedSearch(name);
|
||||
await dashboardAddPanel.addSavedSearch(name);
|
||||
}
|
||||
|
||||
async createAndAddMarkdown({ name, markdown }) {
|
||||
|
@ -58,8 +59,8 @@ export function DashboardVisualizationProvider({ getService, getPageObjects }) {
|
|||
if (inViewMode) {
|
||||
await PageObjects.dashboard.clickEdit();
|
||||
}
|
||||
await PageObjects.dashboard.clickAddVisualization();
|
||||
await PageObjects.dashboard.clickAddNewVisualizationLink();
|
||||
await dashboardAddPanel.ensureAddPanelIsShowing();
|
||||
await dashboardAddPanel.clickAddNewEmbeddableLink();
|
||||
await PageObjects.visualize.clickMarkdownWidget();
|
||||
await PageObjects.visualize.setMarkdownTxt(markdown);
|
||||
await PageObjects.visualize.clickGo();
|
||||
|
|
|
@ -23,7 +23,7 @@ export function FilterBarProvider({ getService }) {
|
|||
await testSubjects.click(`filter & filter-key-${key} disableFilter-${key}`);
|
||||
}
|
||||
|
||||
async addFilter(field, operator, value) {
|
||||
async addFilter(field, operator, value, inputCssClass = 'ui-select-search') {
|
||||
await testSubjects.click('addFilter');
|
||||
let input = await find.byCssSelector(`filter-field-select input.ui-select-search`);
|
||||
await input.type(field);
|
||||
|
@ -31,7 +31,7 @@ export function FilterBarProvider({ getService }) {
|
|||
input = await find.byCssSelector(`filter-operator-select input.ui-select-search`);
|
||||
await input.type(operator);
|
||||
await remote.pressKeys('\uE006');
|
||||
input = await find.byCssSelector(`filter-params-editor input.ui-select-search`);
|
||||
input = await find.byCssSelector(`filter-params-editor input.${inputCssClass}`);
|
||||
await input.type(value);
|
||||
await remote.pressKeys('\uE006');
|
||||
await testSubjects.click('saveFilter');
|
||||
|
@ -48,6 +48,13 @@ export function FilterBarProvider({ getService }) {
|
|||
return await Promise.all(spans.map(el => el.getVisibleText()));
|
||||
}
|
||||
|
||||
async ensureFieldEditorModalIsClosed() {
|
||||
const closeFilterEditorModalButtonExists = await testSubjects.exists('filterEditorModalCloseButton');
|
||||
if (closeFilterEditorModalButtonExists) {
|
||||
await testSubjects.click('filterEditorModalCloseButton');
|
||||
}
|
||||
}
|
||||
|
||||
async getFilterFieldIndexPatterns() {
|
||||
const indexPatterns = [];
|
||||
const groups = await find.allByCssSelector('.ui-select-choices-group-label');
|
||||
|
|
|
@ -6,4 +6,6 @@ export { RemoteProvider } from './remote';
|
|||
export { DocTableProvider } from './doc_table';
|
||||
export { ScreenshotsProvider } from './screenshots';
|
||||
export { FailureDebuggingProvider } from './failure_debugging';
|
||||
export { VisualizeListingTableProvider } from './visualize_listing_table';
|
||||
|
||||
export * from './dashboard';
|
||||
|
|
|
@ -48,9 +48,9 @@ export function TestSubjectsProvider({ getService }) {
|
|||
return await find.byCssSelector(testSubjSelector(selector), timeout);
|
||||
}
|
||||
|
||||
async findAll(selector) {
|
||||
async findAll(selector, timeout) {
|
||||
log.debug(`TestSubjects.findAll(${selector})`);
|
||||
const all = await find.allByCssSelector(testSubjSelector(selector));
|
||||
const all = await find.allByCssSelector(testSubjSelector(selector), timeout);
|
||||
return await filterAsync(all, el => el.isDisplayed());
|
||||
}
|
||||
|
||||
|
|
36
test/functional/services/visualize_listing_table.js
Normal file
36
test/functional/services/visualize_listing_table.js
Normal file
|
@ -0,0 +1,36 @@
|
|||
export function VisualizeListingTableProvider({ getService, getPageObjects }) {
|
||||
const testSubjects = getService('testSubjects');
|
||||
const find = getService('find');
|
||||
const log = getService('log');
|
||||
const PageObjects = getPageObjects(['dashboard', 'visualize', 'header', 'discover']);
|
||||
|
||||
class VisualizeListingTable {
|
||||
async getAllVisualizationNamesOnCurrentPage() {
|
||||
const visualizationNames = [];
|
||||
const links = await find.allByCssSelector('.kuiLink');
|
||||
for (let i = 0; i < links.length; i++) {
|
||||
visualizationNames.push(await links[i].getVisibleText());
|
||||
}
|
||||
log.debug(`Found ${visualizationNames.length} visualizations on current page`);
|
||||
return visualizationNames;
|
||||
}
|
||||
|
||||
async getAllVisualizationNames() {
|
||||
log.debug('VisualizeListingTable.getAllVisualizationNames');
|
||||
let morePages = true;
|
||||
let visualizationNames = [];
|
||||
while (morePages) {
|
||||
visualizationNames = visualizationNames.concat(await this.getAllVisualizationNamesOnCurrentPage());
|
||||
const pagerNextButton = await testSubjects.find('pagerNextButton');
|
||||
morePages = !(await pagerNextButton.getProperty('disabled'));
|
||||
if (morePages) {
|
||||
await testSubjects.click('pagerNextButton');
|
||||
await PageObjects.header.waitUntilLoadingHasFinished();
|
||||
}
|
||||
}
|
||||
return visualizationNames;
|
||||
}
|
||||
}
|
||||
|
||||
return new VisualizeListingTable();
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue