[Time to Visualize] Add functional tests for adding visualizations from Visualize, Lens, and Maps and adjust capabilities for new modal (#89245) (#91004)

Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>

Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
Poff Poffenberger 2021-02-10 14:46:37 -06:00 committed by GitHub
parent 9d8296ea5d
commit 97a83fb45f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
17 changed files with 675 additions and 62 deletions

View file

@ -64,6 +64,7 @@ export function DashboardPicker(props: DashboardPickerProps) {
return (
<EuiComboBox
data-test-subj="dashboardPickerInput"
placeholder={i18n.translate('presentationUtil.dashboardPicker.searchDashboardPlaceholder', {
defaultMessage: 'Search dashboards...',
})}

View file

@ -40,14 +40,10 @@ export function SavedObjectSaveModalDashboard(props: SaveModalDashboardProps) {
const initialCopyOnSave = !Boolean(documentId);
const { capabilities } = pluginServices.getHooks();
const {
canAccessDashboards,
canCreateNewDashboards,
canEditDashboards,
} = capabilities.useService();
const { canAccessDashboards, canCreateNewDashboards } = capabilities.useService();
const disableDashboardOptions =
!canAccessDashboards() || (!canCreateNewDashboards && !canEditDashboards);
// Disable the dashboard options if the user can't access dashboards or if they're read-only
const disableDashboardOptions = !canAccessDashboards() || !canCreateNewDashboards();
const [dashboardOption, setDashboardOption] = useState<'new' | 'existing' | null>(
documentId || disableDashboardOptions ? null : 'existing'

View file

@ -21,7 +21,6 @@ import {
EuiSpacer,
} from '@elastic/eui';
import { pluginServices } from '../services';
import { DashboardPicker, DashboardPickerProps } from './dashboard_picker';
import './saved_object_save_modal_dashboard.scss';
@ -37,9 +36,6 @@ export interface SaveModalDashboardSelectorProps {
export function SaveModalDashboardSelector(props: SaveModalDashboardSelectorProps) {
const { documentId, onSelectDashboard, dashboardOption, onChange, copyOnSave } = props;
const { capabilities } = pluginServices.getHooks();
const { canCreateNewDashboards, canEditDashboards } = capabilities.useService();
const isDisabled = !copyOnSave && !!documentId;
return (
@ -70,50 +66,44 @@ export function SaveModalDashboardSelector(props: SaveModalDashboardSelectorProp
>
<EuiPanel color="subdued" hasShadow={false} data-test-subj="add-to-dashboard-options">
<div>
{canEditDashboards() && (
<>
{' '}
<EuiRadio
checked={dashboardOption === 'existing'}
id="existing-dashboard-option"
name="dashboard-option"
label={i18n.translate(
'presentationUtil.saveModalDashboard.existingDashboardOptionLabel',
{
defaultMessage: 'Existing',
}
)}
onChange={() => onChange('existing')}
disabled={isDisabled}
<>
<EuiRadio
checked={dashboardOption === 'existing'}
id="existing-dashboard-option"
name="dashboard-option"
label={i18n.translate(
'presentationUtil.saveModalDashboard.existingDashboardOptionLabel',
{
defaultMessage: 'Existing',
}
)}
onChange={() => onChange('existing')}
disabled={isDisabled}
/>
<div className="savAddDashboard__searchDashboards">
<DashboardPicker
isDisabled={dashboardOption !== 'existing'}
onChange={onSelectDashboard}
/>
<div className="savAddDashboard__searchDashboards">
<DashboardPicker
isDisabled={dashboardOption !== 'existing'}
onChange={onSelectDashboard}
/>
</div>
<EuiSpacer size="s" />
</>
)}
{canCreateNewDashboards() && (
<>
{' '}
<EuiRadio
checked={dashboardOption === 'new'}
id="new-dashboard-option"
name="dashboard-option"
label={i18n.translate(
'presentationUtil.saveModalDashboard.newDashboardOptionLabel',
{
defaultMessage: 'New',
}
)}
onChange={() => onChange('new')}
disabled={isDisabled}
/>
<EuiSpacer size="s" />
</>
)}
</div>
<EuiSpacer size="s" />
</>
<>
<EuiRadio
checked={dashboardOption === 'new'}
id="new-dashboard-option"
name="dashboard-option"
label={i18n.translate(
'presentationUtil.saveModalDashboard.newDashboardOptionLabel',
{
defaultMessage: 'New',
}
)}
onChange={() => onChange('new')}
disabled={isDisabled}
/>
<EuiSpacer size="s" />
</>
<EuiRadio
checked={dashboardOption === null}
id="add-to-library-option"

View file

@ -20,7 +20,6 @@ export interface PresentationDashboardsService {
export interface PresentationCapabilitiesService {
canAccessDashboards: () => boolean;
canCreateNewDashboards: () => boolean;
canEditDashboards: () => boolean;
}
export interface PresentationUtilServices {

View file

@ -21,6 +21,5 @@ export const capabilitiesServiceFactory: CapabilitiesServiceFactory = ({ coreSta
return {
canAccessDashboards: () => Boolean(dashboard.show),
canCreateNewDashboards: () => Boolean(dashboard.createNew),
canEditDashboards: () => !Boolean(dashboard.hideWriteControls),
};
};

View file

@ -149,6 +149,7 @@ export const VisualizeListing = () => {
const calloutMessage = (
<>
<FormattedMessage
data-test-subj="visualize-dashboard-flow-prompt"
id="visualize.visualizeListingDashboardFlowDescription"
defaultMessage="Building a dashboard? Create content directly from the {dashboardApp} using a new integrated workflow."
values={{

View file

@ -0,0 +1,147 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
import { FtrProviderContext } from 'test/functional/ftr_provider_context';
import expect from '@kbn/expect';
export default function ({ getService, getPageObjects }: FtrProviderContext) {
const dashboardExpect = getService('dashboardExpect');
const testSubjects = getService('testSubjects');
const listingTable = getService('listingTable');
const PageObjects = getPageObjects([
'common',
'dashboard',
'header',
'visualize',
'visEditor',
'discover',
'timePicker',
'timeToVisualize',
]);
describe('Add to Dashboard', function describeIndexTests() {
it('adding a new metric to a new dashboard', async function () {
await PageObjects.visualize.navigateToNewAggBasedVisualization();
await PageObjects.visualize.clickMetric();
await PageObjects.visualize.clickNewSearch();
await PageObjects.timePicker.setDefaultAbsoluteRange();
await testSubjects.click('visualizeSaveButton');
await PageObjects.timeToVisualize.saveFromModal('My New Vis 1', {
addToDashboard: 'new',
});
await PageObjects.dashboard.waitForRenderComplete();
await dashboardExpect.metricValuesExist(['14,004']);
const panelCount = await PageObjects.dashboard.getPanelCount();
expect(panelCount).to.eql(1);
await PageObjects.timeToVisualize.resetNewDashboard();
});
it('adding a existing metric to a new dashboard', async function () {
await PageObjects.visualize.navigateToNewAggBasedVisualization();
await PageObjects.visualize.clickMetric();
await PageObjects.visualize.clickNewSearch();
await PageObjects.timePicker.setDefaultAbsoluteRange();
await testSubjects.click('visualizeSaveButton');
// Save this new viz to library
await PageObjects.timeToVisualize.saveFromModal('My New Vis 1', {
addToDashboard: null,
});
await testSubjects.click('visualizeSaveButton');
// All the options should be disabled
await PageObjects.timeToVisualize.ensureDashboardOptionsAreDisabled();
// Save a new copy of this viz to a new dashboard
await PageObjects.timeToVisualize.saveFromModal('My New Vis 1 Copy', {
addToDashboard: 'new',
saveAsNew: true,
});
await PageObjects.dashboard.waitForRenderComplete();
await dashboardExpect.metricValuesExist(['14,004']);
const panelCount = await PageObjects.dashboard.getPanelCount();
expect(panelCount).to.eql(1);
await PageObjects.timeToVisualize.resetNewDashboard();
});
it('adding a new metric to an existing dashboard', async function () {
await PageObjects.common.navigateToApp('dashboard');
await PageObjects.dashboard.clickNewDashboard();
await PageObjects.dashboard.addVisualizations(['Visualization AreaChart']);
await PageObjects.dashboard.saveDashboard('My Wonderful Dashboard');
await PageObjects.dashboard.gotoDashboardLandingPage();
await listingTable.searchAndExpectItemsCount('dashboard', 'My Wonderful Dashboard', 1);
await PageObjects.visualize.navigateToNewAggBasedVisualization();
await PageObjects.visualize.clickMetric();
await PageObjects.visualize.clickNewSearch();
await PageObjects.timePicker.setDefaultAbsoluteRange();
await testSubjects.click('visualizeSaveButton');
await PageObjects.timeToVisualize.saveFromModal('My New Vis 2', {
addToDashboard: 'existing',
dashboardId: 'My Wonderful Dashboard',
});
await PageObjects.dashboard.waitForRenderComplete();
await dashboardExpect.metricValuesExist(['14,004']);
const panelCount = await PageObjects.dashboard.getPanelCount();
expect(panelCount).to.eql(2);
});
it('adding a existing metric to an existing dashboard', async function () {
await PageObjects.common.navigateToApp('dashboard');
await PageObjects.dashboard.clickNewDashboard();
await PageObjects.dashboard.addVisualizations(['Visualization AreaChart']);
await PageObjects.dashboard.saveDashboard('My Very Cool Dashboard');
await PageObjects.dashboard.gotoDashboardLandingPage();
await listingTable.searchAndExpectItemsCount('dashboard', 'My Very Cool Dashboard', 1);
await PageObjects.visualize.navigateToNewAggBasedVisualization();
await PageObjects.visualize.clickMetric();
await PageObjects.visualize.clickNewSearch();
await PageObjects.timePicker.setDefaultAbsoluteRange();
await testSubjects.click('visualizeSaveButton');
// Save this new viz to library
await PageObjects.timeToVisualize.saveFromModal('My New Vis 2', {
addToDashboard: null,
});
await testSubjects.click('visualizeSaveButton');
// All the options should be disabled
await PageObjects.timeToVisualize.ensureDashboardOptionsAreDisabled();
// Save a new copy of this viz to an existing dashboard
await PageObjects.timeToVisualize.saveFromModal('My New Vis 2 Copy', {
addToDashboard: 'existing',
dashboardId: 'My Very Cool Dashboard',
saveAsNew: true,
});
await PageObjects.dashboard.waitForRenderComplete();
await dashboardExpect.metricValuesExist(['14,004']);
const panelCount = await PageObjects.dashboard.getPanelCount();
expect(panelCount).to.eql(2);
});
});
}

View file

@ -102,6 +102,7 @@ export default function ({ getService, loadTestFile }: FtrProviderContext) {
loadTestFile(require.resolve('./_lab_mode'));
loadTestFile(require.resolve('./_linked_saved_searches'));
loadTestFile(require.resolve('./_visualize_listing'));
loadTestFile(require.resolve('./_add_to_dashboard.ts'));
if (isOss) {
loadTestFile(require.resolve('./_tile_map'));

View file

@ -25,6 +25,7 @@ import { VisualizePageProvider } from './visualize_page';
import { VisualizeEditorPageProvider } from './visualize_editor_page';
import { VisualizeChartPageProvider } from './visualize_chart_page';
import { TileMapPageProvider } from './tile_map_page';
import { TimeToVisualizePageProvider } from './time_to_visualize_page';
import { TagCloudPageProvider } from './tag_cloud_page';
import { VegaChartPageProvider } from './vega_chart_page';
import { SavedObjectsPageProvider } from './management/saved_objects_page';
@ -51,6 +52,7 @@ export const pageObjects = {
visEditor: VisualizeEditorPageProvider,
visChart: VisualizeChartPageProvider,
tileMap: TileMapPageProvider,
timeToVisualize: TimeToVisualizePageProvider,
tagCloud: TagCloudPageProvider,
vegaChart: VegaChartPageProvider,
savedObjects: SavedObjectsPageProvider,

View file

@ -0,0 +1,101 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
import { FtrProviderContext } from '../ftr_provider_context';
interface SaveModalArgs {
addToDashboard?: 'new' | 'existing' | null;
dashboardId?: string;
saveAsNew?: boolean;
redirectToOrigin?: boolean;
}
type DashboardPickerOption =
| 'add-to-library-option'
| 'existing-dashboard-option'
| 'new-dashboard-option';
export function TimeToVisualizePageProvider({ getService, getPageObjects }: FtrProviderContext) {
const testSubjects = getService('testSubjects');
const log = getService('log');
const find = getService('find');
const { common, dashboard } = getPageObjects(['common', 'dashboard']);
class TimeToVisualizePage {
public async ensureSaveModalIsOpen() {
await testSubjects.exists('savedObjectSaveModal', { timeout: 5000 });
}
public async ensureDashboardOptionsAreDisabled() {
const dashboardSelector = await testSubjects.find('add-to-dashboard-options');
await dashboardSelector.findByCssSelector(`input[id="new-dashboard-option"]:disabled`);
await dashboardSelector.findByCssSelector(`input[id="existing-dashboard-option"]:disabled`);
await dashboardSelector.findByCssSelector(`input[id="add-to-library-option"]:disabled`);
}
public async resetNewDashboard() {
await common.navigateToApp('dashboard');
await dashboard.gotoDashboardLandingPage(true);
await dashboard.clickNewDashboard(false);
}
public async setSaveModalValues(
vizName: string,
{ saveAsNew, redirectToOrigin, addToDashboard, dashboardId }: SaveModalArgs = {}
) {
await testSubjects.setValue('savedObjectTitle', vizName);
const hasSaveAsNew = await testSubjects.exists('saveAsNewCheckbox');
if (hasSaveAsNew && saveAsNew !== undefined) {
const state = saveAsNew ? 'check' : 'uncheck';
log.debug('save as new checkbox exists. Setting its state to', state);
await testSubjects.setEuiSwitch('saveAsNewCheckbox', state);
}
const hasRedirectToOrigin = await testSubjects.exists('returnToOriginModeSwitch');
if (hasRedirectToOrigin && redirectToOrigin !== undefined) {
const state = redirectToOrigin ? 'check' : 'uncheck';
log.debug('redirect to origin checkbox exists. Setting its state to', state);
await testSubjects.setEuiSwitch('returnToOriginModeSwitch', state);
}
const hasDashboardSelector = await testSubjects.exists('add-to-dashboard-options');
if (hasDashboardSelector && addToDashboard !== undefined) {
let option: DashboardPickerOption = 'add-to-library-option';
if (addToDashboard) {
option = dashboardId ? 'existing-dashboard-option' : 'new-dashboard-option';
}
log.debug('save modal dashboard selector, choosing option:', option);
const dashboardSelector = await testSubjects.find('add-to-dashboard-options');
const label = await dashboardSelector.findByCssSelector(`label[for="${option}"]`);
await label.click();
if (dashboardId) {
await testSubjects.setValue('dashboardPickerInput', dashboardId);
await find.clickByButtonText(dashboardId);
}
}
}
public async saveFromModal(
vizName: string,
saveModalArgs: SaveModalArgs = { addToDashboard: null }
) {
await this.ensureSaveModalIsOpen();
await this.setSaveModalValues(vizName, saveModalArgs);
log.debug('Click Save Visualization button');
await testSubjects.click('confirmSaveSavedObjectButton');
await common.waitForSaveModalToClose();
}
}
return new TimeToVisualizePage();
}

View file

@ -9,6 +9,7 @@
import { FtrProviderContext } from '../ftr_provider_context';
import { VisualizeConstants } from '../../../src/plugins/visualize/public/application/visualize_constants';
// TODO: Remove & Refactor to use the TTV page objects
interface VisualizeSaveModalArgs {
saveAsNew?: boolean;
redirectToOrigin?: boolean;

View file

@ -65,7 +65,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
field: 'geo.src',
});
await PageObjects.lens.save('vis1', true, true);
await PageObjects.lens.save('vis1', false, true);
await PageObjects.header.waitUntilLoadingHasFinished();
await dashboardAddPanel.clickCreateNewLink();
await dashboardAddPanel.clickVisType('lens');
@ -85,7 +85,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
await filterBar.addFilter('geo.src', 'is not', 'CN');
await PageObjects.lens.save('vis2', true, true);
await PageObjects.lens.save('vis2', false, true);
await PageObjects.header.waitUntilLoadingHasFinished();
const colorMapping1 = getColorMapping(await PageObjects.dashboard.getPanelChartDebugState(0));
const colorMapping2 = getColorMapping(await PageObjects.dashboard.getPanelChartDebugState(1));

View file

@ -0,0 +1,243 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import expect from '@kbn/expect';
import { FtrProviderContext } from '../../ftr_provider_context';
export default function ({ getService, getPageObjects }: FtrProviderContext) {
const PageObjects = getPageObjects([
'dashboard',
'visualize',
'lens',
'timeToVisualize',
'common',
'header',
]);
const find = getService('find');
const listingTable = getService('listingTable');
const dashboardAddPanel = getService('dashboardAddPanel');
const testSubjects = getService('testSubjects');
const security = getService('security');
describe('lens add-to-dashboards tests', () => {
it('should allow new lens vizs be added to a new dashboard', async () => {
await PageObjects.visualize.navigateToNewVisualization();
await PageObjects.visualize.clickVisType('lens');
await PageObjects.lens.goToTimeRange();
await PageObjects.lens.configureDimension({
dimension: 'lnsXY_yDimensionPanel > lns-empty-dimension',
operation: 'avg',
field: 'bytes',
});
await PageObjects.lens.switchToVisualization('lnsMetric');
await PageObjects.header.waitUntilLoadingHasFinished();
await PageObjects.lens.assertMetric('Average of bytes', '5,727.322');
await PageObjects.lens.save('New Lens from Modal', false, false, 'new');
await PageObjects.dashboard.waitForRenderComplete();
await PageObjects.lens.assertMetric('Average of bytes', '5,727.322');
const panelCount = await PageObjects.dashboard.getPanelCount();
expect(panelCount).to.eql(1);
await PageObjects.timeToVisualize.resetNewDashboard();
});
it('should allow existing lens vizs be added to a new dashboard', async () => {
await PageObjects.visualize.gotoVisualizationLandingPage();
await listingTable.searchForItemWithName('Artistpreviouslyknownaslens');
await PageObjects.lens.clickVisualizeListItemTitle('Artistpreviouslyknownaslens');
await PageObjects.lens.goToTimeRange();
await PageObjects.lens.assertMetric('Maximum of bytes', '19,986');
await PageObjects.lens.save('Artistpreviouslyknownaslens Copy', true, false, 'new');
await PageObjects.dashboard.waitForRenderComplete();
await PageObjects.lens.assertMetric('Maximum of bytes', '19,986');
const panelCount = await PageObjects.dashboard.getPanelCount();
expect(panelCount).to.eql(1);
await PageObjects.timeToVisualize.resetNewDashboard();
});
it('should allow new lens vizs be added to an existing dashboard', async () => {
await PageObjects.common.navigateToApp('dashboard');
await PageObjects.dashboard.clickNewDashboard();
await dashboardAddPanel.clickOpenAddPanel();
await dashboardAddPanel.filterEmbeddableNames('lnsXYvis');
await find.clickByButtonText('lnsXYvis');
await dashboardAddPanel.closeAddPanel();
await PageObjects.lens.goToTimeRange();
await PageObjects.dashboard.saveDashboard('My Very Cool Dashboard');
await PageObjects.dashboard.gotoDashboardLandingPage();
await listingTable.searchAndExpectItemsCount('dashboard', 'My Very Cool Dashboard', 1);
await PageObjects.visualize.navigateToNewVisualization();
await PageObjects.visualize.clickVisType('lens');
await PageObjects.lens.goToTimeRange();
await PageObjects.lens.configureDimension({
dimension: 'lnsXY_yDimensionPanel > lns-empty-dimension',
operation: 'avg',
field: 'bytes',
});
await PageObjects.lens.switchToVisualization('lnsMetric');
await PageObjects.header.waitUntilLoadingHasFinished();
await PageObjects.lens.assertMetric('Average of bytes', '5,727.322');
await PageObjects.lens.save(
'New Lens from Modal',
false,
false,
'existing',
'My Very Cool Dashboard'
);
await PageObjects.dashboard.waitForRenderComplete();
await PageObjects.lens.assertMetric('Average of bytes', '5,727.322');
const panelCount = await PageObjects.dashboard.getPanelCount();
expect(panelCount).to.eql(2);
});
it('should allow existing lens vizs be added to an existing dashboard', async () => {
await PageObjects.common.navigateToApp('dashboard');
await PageObjects.dashboard.clickNewDashboard();
await dashboardAddPanel.clickOpenAddPanel();
await dashboardAddPanel.filterEmbeddableNames('lnsXYvis');
await find.clickByButtonText('lnsXYvis');
await dashboardAddPanel.closeAddPanel();
await PageObjects.lens.goToTimeRange();
await PageObjects.dashboard.saveDashboard('My Wonderful Dashboard');
await PageObjects.dashboard.gotoDashboardLandingPage();
await listingTable.searchAndExpectItemsCount('dashboard', 'My Wonderful Dashboard', 1);
await PageObjects.visualize.gotoVisualizationLandingPage();
await listingTable.searchForItemWithName('Artistpreviouslyknownaslens');
await PageObjects.lens.clickVisualizeListItemTitle('Artistpreviouslyknownaslens');
await PageObjects.lens.goToTimeRange();
await PageObjects.lens.assertMetric('Maximum of bytes', '19,986');
await PageObjects.lens.save(
'Artistpreviouslyknownaslens Copy',
true,
false,
'existing',
'My Wonderful Dashboard'
);
await PageObjects.dashboard.waitForRenderComplete();
await PageObjects.lens.assertMetric('Maximum of bytes', '19,986');
const panelCount = await PageObjects.dashboard.getPanelCount();
expect(panelCount).to.eql(2);
});
describe('Capabilities', function capabilitiesTests() {
describe('dashboard no-access privileges', () => {
before(async () => {
await PageObjects.common.navigateToApp('visualize');
await security.testUser.setRoles(['test_logstash_reader', 'global_visualize_all'], true);
});
after(async () => {
await security.testUser.restoreDefaults();
});
it('should not display dashboard flow prompt', async () => {
await PageObjects.common.navigateToApp('visualize');
await PageObjects.header.waitUntilLoadingHasFinished();
await PageObjects.visualize.gotoLandingPage();
const hasPrompt = await testSubjects.exists('visualize-dashboard-flow-prompt');
expect(hasPrompt).to.eql(false);
});
it('should not display add-to-dashboard options', async () => {
await PageObjects.visualize.navigateToNewVisualization();
await PageObjects.visualize.clickVisType('lens');
await PageObjects.lens.goToTimeRange();
await PageObjects.lens.configureDimension({
dimension: 'lnsXY_yDimensionPanel > lns-empty-dimension',
operation: 'avg',
field: 'bytes',
});
await PageObjects.lens.switchToVisualization('lnsMetric');
await PageObjects.header.waitUntilLoadingHasFinished();
await PageObjects.lens.assertMetric('Average of bytes', '5,727.322');
await PageObjects.header.waitUntilLoadingHasFinished();
await testSubjects.click('lnsApp_saveButton');
const hasOptions = await testSubjects.exists('add-to-dashboard-options');
expect(hasOptions).to.eql(false);
});
});
describe('dashboard read-only privileges', () => {
before(async () => {
await security.testUser.setRoles(
['test_logstash_reader', 'global_visualize_all', 'global_dashboard_read'],
true
);
});
after(async () => {
await security.testUser.restoreDefaults();
});
it('should not display dashboard flow prompt', async () => {
await PageObjects.common.navigateToApp('visualize');
await PageObjects.header.waitUntilLoadingHasFinished();
await PageObjects.visualize.gotoLandingPage();
const hasPrompt = await testSubjects.exists('visualize-dashboard-flow-prompt');
expect(hasPrompt).to.eql(false);
});
it('should not display add-to-dashboard options', async () => {
await PageObjects.visualize.navigateToNewVisualization();
await PageObjects.visualize.clickVisType('lens');
await PageObjects.lens.goToTimeRange();
await PageObjects.lens.configureDimension({
dimension: 'lnsXY_yDimensionPanel > lns-empty-dimension',
operation: 'avg',
field: 'bytes',
});
await PageObjects.lens.switchToVisualization('lnsMetric');
await PageObjects.header.waitUntilLoadingHasFinished();
await PageObjects.lens.assertMetric('Average of bytes', '5,727.322');
await PageObjects.header.waitUntilLoadingHasFinished();
await testSubjects.click('lnsApp_saveButton');
const hasOptions = await testSubjects.exists('add-to-dashboard-options');
expect(hasOptions).to.eql(false);
});
});
});
});
}

View file

@ -29,6 +29,7 @@ export default function ({ getService, loadTestFile }: FtrProviderContext) {
this.tags(['ciGroup4', 'skipFirefox']);
loadTestFile(require.resolve('./smokescreen'));
loadTestFile(require.resolve('./add_to_dashboard'));
loadTestFile(require.resolve('./table'));
loadTestFile(require.resolve('./dashboard'));
loadTestFile(require.resolve('./persistent_context'));

View file

@ -0,0 +1,122 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import expect from '@kbn/expect';
export default function ({ getPageObjects, getService }) {
const PageObjects = getPageObjects([
'common',
'dashboard',
'header',
'maps',
'timeToVisualize',
'visualize',
]);
const listingTable = getService('listingTable');
const testSubjects = getService('testSubjects');
const security = getService('security');
describe('maps add-to-dashboard save flow', () => {
before(async () => {
await security.testUser.setRoles(
[
'test_logstash_reader',
'global_maps_all',
'geoshape_data_reader',
'global_dashboard_all',
'meta_for_geoshape_data_reader',
],
false
);
});
after(async () => {
await security.testUser.restoreDefaults();
});
it('should allow new map be added to a new dashboard', async () => {
await PageObjects.maps.openNewMap();
await PageObjects.header.waitUntilLoadingHasFinished();
await PageObjects.maps.waitForLayersToLoad();
await testSubjects.click('mapSaveButton');
await PageObjects.timeToVisualize.saveFromModal('map 1', { addToDashboard: 'new' });
await PageObjects.dashboard.waitForRenderComplete();
const panelCount = await PageObjects.dashboard.getPanelCount();
expect(panelCount).to.eql(1);
await PageObjects.timeToVisualize.resetNewDashboard();
});
it('should allow existing maps be added to a new dashboard', async () => {
await PageObjects.maps.loadSavedMap('document example');
await testSubjects.click('mapSaveButton');
await PageObjects.timeToVisualize.saveFromModal('document example copy', {
addToDashboard: 'new',
saveAsNew: true,
});
await PageObjects.dashboard.waitForRenderComplete();
const panelCount = await PageObjects.dashboard.getPanelCount();
expect(panelCount).to.eql(1);
await PageObjects.timeToVisualize.resetNewDashboard();
});
it('should allow new map be added to an existing dashboard', async () => {
await PageObjects.common.navigateToApp('dashboard');
await PageObjects.dashboard.clickNewDashboard();
await PageObjects.dashboard.saveDashboard('My Very Cool Dashboard');
await PageObjects.dashboard.gotoDashboardLandingPage();
await listingTable.searchAndExpectItemsCount('dashboard', 'My Very Cool Dashboard', 1);
await PageObjects.maps.openNewMap();
await PageObjects.header.waitUntilLoadingHasFinished();
await PageObjects.maps.waitForLayersToLoad();
await testSubjects.click('mapSaveButton');
await PageObjects.timeToVisualize.saveFromModal('My New Map 2', {
addToDashboard: 'existing',
dashboardId: 'My Very Cool Dashboard',
});
await PageObjects.dashboard.waitForRenderComplete();
const panelCount = await PageObjects.dashboard.getPanelCount();
expect(panelCount).to.eql(1);
});
it('should allow existing maps be added to an existing dashboard', async () => {
await PageObjects.common.navigateToApp('dashboard');
await PageObjects.dashboard.clickNewDashboard();
await PageObjects.dashboard.saveDashboard('My Wonderful Dashboard');
await PageObjects.dashboard.gotoDashboardLandingPage();
await listingTable.searchAndExpectItemsCount('dashboard', 'My Wonderful Dashboard', 1);
await PageObjects.maps.loadSavedMap('document example');
await testSubjects.click('mapSaveButton');
await PageObjects.timeToVisualize.saveFromModal('document example copy 2', {
addToDashboard: 'existing',
dashboardId: 'My Wonderful Dashboard',
saveAsNew: true,
});
await PageObjects.dashboard.waitForRenderComplete();
const panelCount = await PageObjects.dashboard.getPanelCount();
expect(panelCount).to.eql(1);
});
});
}

View file

@ -7,6 +7,7 @@
export default function ({ loadTestFile }) {
describe('embeddable', function () {
loadTestFile(require.resolve('./add_to_dashboard'));
loadTestFile(require.resolve('./save_and_return'));
loadTestFile(require.resolve('./dashboard'));
loadTestFile(require.resolve('./embeddable_state'));

View file

@ -17,7 +17,15 @@ export function LensPageProvider({ getService, getPageObjects }: FtrProviderCont
const find = getService('find');
const comboBox = getService('comboBox');
const browser = getService('browser');
const PageObjects = getPageObjects(['header', 'timePicker', 'common', 'visualize', 'dashboard']);
const PageObjects = getPageObjects([
'header',
'timePicker',
'common',
'visualize',
'dashboard',
'timeToVisualize',
]);
return logWrapper('lensPage', log, {
/**
@ -341,16 +349,16 @@ export function LensPageProvider({ getService, getPageObjects }: FtrProviderCont
title: string,
saveAsNew?: boolean,
redirectToOrigin?: boolean,
addToDashboard?: boolean,
addToDashboard?: 'new' | 'existing' | null,
dashboardId?: string
) {
await PageObjects.header.waitUntilLoadingHasFinished();
await testSubjects.click('lnsApp_saveButton');
await PageObjects.visualize.setSaveModalValues(title, {
await PageObjects.timeToVisualize.setSaveModalValues(title, {
saveAsNew,
redirectToOrigin,
addToDashboard,
addToDashboard: addToDashboard ? addToDashboard : null,
dashboardId,
});