Adding attributes to be used by sharing (#10234)

* Adding attributes to be used by sharing

* Moving the shared-item tags for dashboard panels

* Switching from shared-item-title/description to just title/description

* Removing move noise

* Fixing typo

* Adding data- prefix before attributes, began writing tests

Adding shared-item title tests

Switching up the panel tests

Adding description tests

Fixing linting

Adding dashboard timefilter test

Adding visualization shared-item tests

Adding shared-timefilter tests

Adding discover shared-item tests

* Fixing shared-items-count on dashboard

* Fixing functional test data for discover and visualize
This commit is contained in:
Brandon Kobel 2017-02-17 06:59:36 -05:00 committed by GitHub
parent 60b36f7f9a
commit 2fb2b4ca6c
23 changed files with 185 additions and 31 deletions

View file

@ -70,6 +70,7 @@
toggle-expand="toggleExpandPanel"
create-child-ui-state="createChildUiState"
toggle-expand="toggleExpandPanel"
shared-items-count="{{panels.length}}"
></dashboard-grid>
<dashboard-panel ng-if="hasExpandedPanel()"

View file

@ -31,6 +31,9 @@
search-source="savedObj.searchSource"
show-spy-panel="!isFullScreenMode"
ui-state="uiState"
shared-item
data-title="{{savedObj.title}}"
data-description="{{savedObj.description}}"
render-counter
class="panel-content">
</visualize>
@ -40,6 +43,9 @@
search-source="savedObj.searchSource"
sorting="panel.sort"
columns="panel.columns"
shared-item
data-title="{{savedObj.title}}"
data-description="{{savedObj.description}}"
render-counter
class="panel-content"
filter="filter">

View file

@ -126,6 +126,9 @@
columns="state.columns"
infinite-scroll="true"
filter="filterQuery"
shared-item
data-title="{{opts.savedSearch.lastSavedTitle}}"
data-description="{{opts.savedSearch.description}}"
render-counter>
</doc-table>

View file

@ -81,6 +81,9 @@
<div class="vis-editor-canvas" ng-if="!vis.type.fullEditor" ng-class="{ embedded: !chrome.getVisible() }">
<visualize
vis="vis"
shared-item
data-title="{{savedVis.lastSavedTitle}}"
data-description="{{savedVis.description}}"
render-counter
ui-state="uiState"
show-spy-panel="chrome.getVisible()"

View file

@ -5,15 +5,17 @@ import $ from 'jquery';
describe('kbnGlobalTimepicker', function () {
let compile;
let scope;
beforeEach(() => {
ngMock.module('kibana');
ngMock.inject(($compile, $rootScope) => {
scope = $rootScope.$new();
compile = () => {
const $el = $('<kbn-global-timepicker></kbn-global-timepicker>');
$el.data('$kbnTopNavController', {}); // Mock the kbnTopNav
$rootScope.$apply();
$compile($el)($rootScope);
$compile($el)(scope);
scope.$apply();
return $el;
};
});
@ -22,4 +24,18 @@ describe('kbnGlobalTimepicker', function () {
const $el = compile();
expect($el.attr('data-test-subj')).to.be('globalTimepicker');
});
it('sets shared-timefilter to false when timefilter.enabled is false', function () {
scope.timefilter = {
enabled: false
};
const $el = compile();
expect($el.attr('shared-timefilter')).to.eql('false');
});
it('sets shared-timefilter to true when timefilter.enabled is true', function () {
scope.timefilter = {
enabled: true
};
const $el = compile();
expect($el.attr('shared-timefilter')).to.eql('true');
});
});

View file

@ -1,4 +1,4 @@
<div ng-show="timefilter.enabled" class="kuiLocalMenu" data-test-subj="globalTimepicker">
<div ng-show="timefilter.enabled" shared-timefilter="{{timefilter.enabled}}" class="kuiLocalMenu" data-test-subj="globalTimepicker">
<div
class="kuiLocalMenuItem"
ng-click="toggleRefresh()"

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1 @@
{".kibana":{"mappings":{"index-pattern":{"properties":{"fields":{"type":"text","fields":{"keyword":{"type":"keyword","ignore_above":256}}},"timeFieldName":{"type":"text","fields":{"keyword":{"type":"keyword","ignore_above":256}}},"title":{"type":"text","fields":{"keyword":{"type":"keyword","ignore_above":256}}},"sourceFilters":{"type":"text","fields":{"keyword":{"type":"keyword","ignore_above":256}}}}}}}}

File diff suppressed because one or more lines are too long

View file

@ -1 +1 @@
{".kibana":{"mappings":{"index-pattern":{"properties":{"fields":{"type":"text","fields":{"keyword":{"type":"keyword","ignore_above":256}}},"timeFieldName":{"type":"text","fields":{"keyword":{"type":"keyword","ignore_above":256}}},"title":{"type":"text","fields":{"keyword":{"type":"keyword","ignore_above":256}}},"sourceFilters":{"type":"text","fields":{"keyword":{"type":"keyword","ignore_above":256}}}}}}}}
{".kibana":{"mappings":{"index-pattern":{"properties":{"fields":{"type":"text","fields":{"keyword":{"type":"keyword","ignore_above":256}}},"timeFieldName":{"type":"text","fields":{"keyword":{"type":"keyword","ignore_above":256}}},"title":{"type":"text","fields":{"keyword":{"type":"keyword","ignore_above":256}}},"sourceFilters":{"type":"text","fields":{"keyword":{"type":"keyword","ignore_above":256}}}}},"visualization":{"properties":{"description":{"type":"text","fields":{"keyword":{"type":"keyword","ignore_above":256}}},"kibanaSavedObjectMeta":{"properties":{"searchSourceJSON":{"type":"text","fields":{"keyword":{"type":"keyword","ignore_above":256}}}}},"title":{"type":"text","fields":{"keyword":{"type":"keyword","ignore_above":256}}},"uiStateJSON":{"type":"text","fields":{"keyword":{"type":"keyword","ignore_above":256}}},"version":{"type":"integer"},"visState":{"type":"text","fields":{"keyword":{"type":"keyword","ignore_above":256}}}}}}}}

View file

@ -78,7 +78,7 @@ bdd.describe('dashboard tab', function describeIndexTests() {
{ dataCol: '1', dataRow: (height * 3) + 1, dataSizeX: width, dataSizeY: height, title: titles[6] }
];
return PageObjects.common.tryForTime(10000, function () {
return PageObjects.dashboard.getPanelData()
return PageObjects.dashboard.getPanelSizeData()
.then(function (panelTitles) {
PageObjects.common.log('visualization titles = ' + panelTitles);
PageObjects.common.saveScreenshot('Dashboard-visualization-sizes');
@ -87,6 +87,7 @@ bdd.describe('dashboard tab', function describeIndexTests() {
});
});
bdd.it('filters when a pie chart slice is clicked', async function () {
let descriptions = await PageObjects.dashboard.getFilterDescriptions(1000);
expect(descriptions.length).to.equal(0);
@ -103,4 +104,24 @@ bdd.describe('dashboard tab', function describeIndexTests() {
const isDarkThemeOn = await PageObjects.dashboard.isDarkThemeOn();
expect(isDarkThemeOn).to.equal(true);
});
bdd.it('should have shared-items-count set to the number of visualizations', function checkSavedItemsCount() {
const visualizations = PageObjects.dashboard.getTestVisualizations();
return PageObjects.common.tryForTime(10000, () => PageObjects.dashboard.getSharedItemsCount())
.then(function (count) {
PageObjects.common.log('shared-items-count = ' + count);
expect(count).to.eql(visualizations.length);
});
});
bdd.it('should have panels with expected shared-item title and description', function checkTitles() {
const visualizations = PageObjects.dashboard.getTestVisualizations();
return PageObjects.common.tryForTime(10000, function () {
return PageObjects.dashboard.getPanelSharedItemData()
.then(function (data) {
expect(data.map(item => item.title)).to.eql(visualizations.map(v => v.name));
expect(data.map(item => item.description)).to.eql(visualizations.map(v => v.description));
});
});
});
});

View file

@ -19,7 +19,7 @@ bdd.describe('discover tab', function describeIndexTests() {
return esClient.deleteAndUpdateConfigDoc({ 'dateFormat:tz':'UTC', 'defaultIndex':'logstash-*' })
.then(function loadkibanaIndexPattern() {
PageObjects.common.debug('load kibana index with default index pattern');
return elasticDump.elasticLoad('visualize','.kibana');
return elasticDump.elasticLoad('discover','.kibana');
})
// and load a set of makelogs data
.then(function loadIfEmptyMakelogs() {

View file

@ -20,7 +20,7 @@ bdd.describe('discover app', function describeIndexTests() {
// delete .kibana index and update configDoc
await esClient.deleteAndUpdateConfigDoc({ 'dateFormat:tz':'UTC', 'defaultIndex':'logstash-*' });
PageObjects.common.debug('load kibana index with default index pattern');
await elasticDump.elasticLoad('visualize','.kibana');
await elasticDump.elasticLoad('discover','.kibana');
// and load a set of makelogs data
await scenarioManager.loadIfEmpty('logstashFunctional');
@ -32,6 +32,7 @@ bdd.describe('discover app', function describeIndexTests() {
bdd.describe('query', function () {
const queryName1 = 'Query # 1';
const queryDescription1 = 'Query # 1 Description';
bdd.it('should show correct time range string by timepicker', async function () {
const actualTimeString = await PageObjects.discover.getTimespanText();
@ -226,4 +227,19 @@ bdd.describe('discover app', function describeIndexTests() {
expect(await PageObjects.header.isTimepickerOpen()).to.be(false);
});
});
bdd.describe('shared-item', function () {
bdd.it('should have correct shared-item title and description', async () => {
const expected = {
title: 'A Saved Search',
description: 'A Saved Search Description'
};
await PageObjects.discover.loadSavedSearch(expected.title);
const { title, description } = await PageObjects.common.getSharedItemTitleAndDescription();
expect(title).to.eql(expected.title);
expect(description).to.eql(expected.description);
});
});
});

View file

@ -19,7 +19,7 @@ bdd.describe('discover app', function describeIndexTests() {
return esClient.deleteAndUpdateConfigDoc({ 'dateFormat:tz':'UTC', 'defaultIndex':'logstash-*' })
.then(function loadkibanaIndexPattern() {
PageObjects.common.debug('load kibana index with default index pattern');
return elasticDump.elasticLoad('visualize','.kibana');
return elasticDump.elasticLoad('discover','.kibana');
})
// and load a set of makelogs data
.then(function loadIfEmptyMakelogs() {

View file

@ -33,7 +33,7 @@ bdd.describe('shared links', function describeIndexTests() {
return esClient.deleteAndUpdateConfigDoc({ 'dateFormat:tz':'UTC', 'defaultIndex':'logstash-*' })
.then(function loadkibanaIndexPattern() {
PageObjects.common.debug('load kibana index with default index pattern');
return elasticDump.elasticLoad('visualize','.kibana');
return elasticDump.elasticLoad('discover','.kibana');
})
// and load a set of makelogs data
.then(function loadIfEmptyMakelogs() {

View file

@ -0,0 +1,31 @@
import expect from 'expect.js';
import {
bdd
} from '../../../support';
import PageObjects from '../../../support/page_objects';
bdd.describe('visualize app', function describeIndexTests() {
bdd.before(function () {
PageObjects.common.debug('navigateToApp visualize');
return PageObjects.common.navigateToApp('visualize');
});
bdd.describe('shared-item', function indexPatternCreation() {
bdd.it('should have the correct shared-item title and description', function () {
const expected = {
title: 'Visualization AreaChart',
description: 'AreaChart'
};
return PageObjects.visualize.clickVisualizationByName('Visualization AreaChart')
.then(() => PageObjects.common.getSharedItemTitleAndDescription())
.then(({ title, description }) => {
expect(title).to.eql(expected.title);
expect(description).to.eql(expected.description);
});
});
});
});

View file

@ -42,4 +42,5 @@ bdd.describe('visualize app', function () {
require('./_vertical_bar_chart');
require('./_heatmap_chart');
require('./_point_series_options');
require('./_shared_item');
});

View file

@ -330,4 +330,15 @@ export default class Common {
this.debug(`Found ${elements.length} for selector ${selector}`);
return elements;
}
async getSharedItemTitleAndDescription() {
const element = await this.remote
.setFindTimeout(defaultFindTimeout)
.findByCssSelector('[shared-item]');
return {
title: await element.getAttribute('data-title'),
description: await element.getAttribute('data-description')
};
}
}

View file

@ -94,7 +94,7 @@ export default class DashboardPage {
clickVizNameLink(vizName) {
return this.findTimeout
.findByLinkText(vizName)
.findByPartialLinkText(vizName)
.click();
}
@ -200,8 +200,8 @@ export default class DashboardPage {
});
}
getPanelData() {
PageObjects.common.debug('in getPanelData');
getPanelSizeData() {
PageObjects.common.debug('in getPanelSizeData');
return this.findTimeout
.findAllByCssSelector('li.gs-w')
.then(function (titleObjects) {
@ -251,18 +251,22 @@ export default class DashboardPage {
});
}
getTestVisualizationNames() {
getTestVisualizations() {
return [
'Visualization PieChart',
'Visualization☺ VerticalBarChart',
'Visualization漢字 AreaChart',
'Visualization☺漢字 DataTable',
'Visualization漢字 LineChart',
'Visualization TileMap',
'Visualization MetricChart'
{ name: 'Visualization PieChart', description: 'PieChart' },
{ name: 'Visualization☺ VerticalBarChart', description: 'VerticalBarChart' },
{ name: 'Visualization漢字 AreaChart', description: 'AreaChart' },
{ name: 'Visualization☺漢字 DataTable', description: 'DataTable' },
{ name: 'Visualization漢字 LineChart', description: 'LineChart' },
{ name: 'Visualization TileMap', description: 'TileMap' },
{ name: 'Visualization MetricChart', description: 'MetricChart' }
];
}
getTestVisualizationNames() {
return this.getTestVisualizations().map(visualization => visualization.name);
}
addVisualizations(visualizations) {
return visualizations.reduce(function (promise, vizName) {
return promise
@ -301,4 +305,33 @@ export default class DashboardPage {
return slices[0].click();
}
getSharedItemsCount() {
PageObjects.common.debug('in getSharedItemsCount');
const attributeName = 'shared-items-count';
return this.findTimeout
.findByCssSelector(`[${attributeName}]`)
.then(function (element) {
if (element) {
return element.getAttribute(attributeName);
}
return Promise.reject();
});
}
getPanelSharedItemData() {
PageObjects.common.debug('in getPanelSharedItemData');
return this.findTimeout
.findAllByCssSelector('li.gs-w')
.then(function (elements) {
return Promise.all(elements.map(async element => {
const sharedItem = await element.findByCssSelector('[shared-item]');
return {
title: await sharedItem.getAttribute('data-title'),
description: await sharedItem.getAttribute('data-description')
};
}));
});
}
}

View file

@ -49,7 +49,7 @@ export default class DiscoverPage {
loadSavedSearch(searchName) {
return this.clickLoadSavedSearchButton()
.then(() => {
this.findTimeout.findByLinkText(searchName).click();
this.findTimeout.findByPartialLinkText(searchName).click();
})
.then(() => {
return PageObjects.header.waitUntilLoadingHasFinished();

View file

@ -186,4 +186,12 @@ export default class HeaderPage {
async getPrettyDuration() {
return await PageObjects.common.findTestSubject('globalTimepickerRange').getVisibleText();
}
async isSharedTimefilterEnabled() {
const element = await this.remote
.setFindTimeout(defaultFindTimeout)
.findByCssSelector(`[shared-timefilter=true]`);
return new Boolean(element);
}
}

View file

@ -359,14 +359,14 @@ export default class VisualizePage {
.type(vizName.replace('-',' '));
}
clickVisualizationByLinkText(vizName) {
clickVisualizationByName(vizName) {
const self = this;
PageObjects.common.debug('clickVisualizationByLinkText(' + vizName + ')');
return PageObjects.common.try(function tryingForTime() {
return self.remote
.setFindTimeout(defaultFindTimeout)
.findByLinkText(vizName)
.findByPartialLinkText(vizName)
.click();
});
}
@ -382,7 +382,7 @@ export default class VisualizePage {
}
openSavedVisualization(vizName) {
return this.clickVisualizationByLinkText(vizName);
return this.clickVisualizationByName(vizName);
}
getXAxisLabels() {