Skip to content

Commit

Permalink
Fix bug where negative time offsets in visual builder will shift x-ax…
Browse files Browse the repository at this point in the history
…is range (elastic#15554)

* Shift negative series before drawing, fix elastic#15553

* Add tests fot TSVB markdown

* Use waitUntilLoadingHasFinished

* Remove forgotten skip

* Switch test order

* Use generic seriesOption

* Rename test from chart to metric

* Use test subj to find metric tabs

* Improve TSVB tests
  • Loading branch information
timroes authored Dec 16, 2017
1 parent 769bb66 commit 4671aa5
Show file tree
Hide file tree
Showing 13 changed files with 153 additions and 25 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,7 @@ class MarkdownPanelConfig extends Component {
>Markdown
</button>
<button
data-test-subj="markdownDataBtn"
role="tab"
aria-selected={selectedTab === 'data'}
className={`kbnTabs__tab${selectedTab === 'data' && '-active' || ''}`}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ export const SeriesConfig = props => {
Offset series time by (1m, 1h, 1w, 1d)
</label>
<input
data-test-subj="offsetTimeSeries"
style={{ width: 100 }}
id={htmlId('offsetSeries')}
className="vis_editor__input-grows"
Expand Down
7 changes: 6 additions & 1 deletion src/core_plugins/metrics/public/components/vis_picker.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,12 @@ function VisPickerItem(props) {
labelClassName += ' selected';
}
return (
<button role="tab" className={itemClassName} onClick={() => props.onClick(type)}>
<button
role="tab"
className={itemClassName}
onClick={() => props.onClick(type)}
data-test-subj={`${type}TsvbTypeBtn`}
>
<div className={iconClassName}>
<i className={`fa ${icon}`} />
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ function GaugeSeries(props) {
</button>
<button
role="tab"
data-test-subj="seriesOptions"
aria-selected={selectedTab === 'options'}
className={optionsClassname}
onClick={() => props.switchTab('options')}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ function MarkdownSeries(props) {
</button>
<button
role="tab"
data-test-subj="seriesOptions"
aria-selected={selectedTab === 'metrics'}
className={optionsClassname}
onClick={() => props.switchTab('options')}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ function MetricSeries(props) {
</button>
<button
role="tab"
data-test-subj="seriesOptions"
aria-selected={selectedTab === 'options'}
className={optionsClassname}
onClick={() => props.switchTab('options')}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ function TopNSeries(props) {
Metrics
</div>
<div
data-test-subj="seriesOptions"
className={optionsClassname}
onClick={() => props.switchTab('options')}
>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,7 @@ function TimeseriesConfig(props) {
</label>
<input
id={htmlId('offset')}
data-test-subj="offsetTimeSeries"
className="vis_editor__input-grows"
type="text"
onChange={handleTextChange('offset_time')}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ function TimeseriesSeries(props) {
</button>
<button
role="tab"
data-test-subj="seriesOptions"
aria-selected={selectedTab === 'options'}
className={optionsClassname}
onClick={() => props.switchTab('options')}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ function TopNSeries(props) {
</button>
<button
role="tab"
data-test-subj="seriesOptions"
aria-selected={selectedTab === 'options'}
className={optionsClassname}
onClick={() => props.switchTab('options')}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ import _ from 'lodash';
import moment from 'moment';
export default function timeShift(resp, panel, series) {
return next => results => {
if (/^([\d]+)([shmdwMy]|ms)$/.test(series.offset_time)) {
const matches = series.offset_time.match(/^([\d]+)([shmdwMy]|ms)$/);
if (/^([+-]?[\d]+)([shmdwMy]|ms)$/.test(series.offset_time)) {
const matches = series.offset_time.match(/^([+-]?[\d]+)([shmdwMy]|ms)$/);
if (matches) {
const offsetValue = matches[1];
const offsetUnit = matches[2];
Expand Down
86 changes: 78 additions & 8 deletions test/functional/apps/visualize/_tsvb_chart.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,26 +22,50 @@ export default function ({ getService, getPageObjects }) {
.then(function () {
return PageObjects.header.waitUntilLoadingHasFinished();
})
.then(function sleep() {
return PageObjects.common.sleep(1003);
})
.then(function clickMetric() {
return PageObjects.visualBuilder.clickMetric();
})
.then(function sleep() {
return PageObjects.common.sleep(1003);
});
});

describe('Visual Builder Time Series', function () {

it('should show the correct count in the legend', async function () {
const actualCount = await PageObjects.visualBuilder.getRhythmChartLegendValue();
expect(actualCount).to.be('156');
});

it('should show the correct count in the legend with 2h offset', async function () {
await PageObjects.visualBuilder.clickSeriesOption();
await PageObjects.visualBuilder.enterOffsetSeries('2h');
const actualCount = await PageObjects.visualBuilder.getRhythmChartLegendValue();
expect(actualCount).to.be('293');
});

it('should show the correct count in the legend with -2h offset', async function () {
await PageObjects.visualBuilder.enterOffsetSeries('-2h');
const actualCount = await PageObjects.visualBuilder.getRhythmChartLegendValue();
expect(actualCount).to.be('53');
});

after(async () => {
// set back to no offset for the next test, an empty string didn't seem to work here
await PageObjects.visualBuilder.enterOffsetSeries('0h');
});

});

describe('Visual Builder chart', function indexPatternCreation() {
describe('Visual Builder metric', () => {
before(async () => {
await PageObjects.visualBuilder.clickMetric();
await PageObjects.common.sleep(1003);
});

it('should not display spy panel toggle button', async function () {
const spyToggleExists = await PageObjects.visualize.getSpyToggleExists();
expect(spyToggleExists).to.be(false);
});

it('should show correct data', function () {
it('should show correct data', async function () {
const expectedMetricValue = '156';

return PageObjects.visualBuilder.getMetricValue()
Expand All @@ -51,5 +75,51 @@ export default function ({ getService, getPageObjects }) {
});
});
});

describe('Visual Builder markdown', () => {

before(async () => {
await PageObjects.visualBuilder.clickMarkdown();
await PageObjects.common.sleep(1003);
await PageObjects.header.setAbsoluteRange('2015-09-22 06:00:00.000', '2015-09-22 11:00:00.000');
});

it('should allow printing raw timestamp of data', async () => {
await PageObjects.visualBuilder.enterMarkdown('{{ count.data.raw.[0].[0] }}');
const text = await PageObjects.visualBuilder.getMarkdownText();
expect(text).to.be('1442901600000');
});

it('should allow printing raw value of data', async () => {
await PageObjects.visualBuilder.enterMarkdown('{{ count.data.raw.[0].[1] }}');
const text = await PageObjects.visualBuilder.getMarkdownText();
expect(text).to.be('6');
});

describe('allow time offsets', () => {
before(async () => {
await PageObjects.visualBuilder.enterMarkdown('{{ count.data.raw.[0].[0] }}#{{ count.data.raw.[0].[1] }}');
await PageObjects.visualBuilder.clickMarkdownData();
await PageObjects.visualBuilder.clickSeriesOption();
});

it('allow positive time offsets', async () => {
await PageObjects.visualBuilder.enterOffsetSeries('2h');
const text = await PageObjects.visualBuilder.getMarkdownText();
const [timestamp, value] = text.split('#');
expect(timestamp).to.be('1442901600000');
expect(value).to.be('3');
});

it('allow negative time offsets', async () => {
await PageObjects.visualBuilder.enterOffsetSeries('-2h');
const text = await PageObjects.visualBuilder.getMarkdownText();
const [timestamp, value] = text.split('#');
expect(timestamp).to.be('1442901600000');
expect(value).to.be('23');
});
});

});
});
}
72 changes: 58 additions & 14 deletions test/functional/page_objects/visual_builder_page.js
Original file line number Diff line number Diff line change
@@ -1,27 +1,71 @@
export function VisualBuilderPageProvider({ getService }) {
const config = getService('config');
const find = getService('find');
const log = getService('log');
import Keys from 'leadfoot/keys';

const defaultFindTimeout = config.get('timeouts.find');
export function VisualBuilderPageProvider({ getService, getPageObjects }) {
const find = getService('find');
const testSubjects = getService('testSubjects');
const PageObjects = getPageObjects(['common', 'header']);

class VisualBuilderPage {
async clickMetric() {
const nav = await find.allByCssSelector('.vis_editor__vis_picker-label', defaultFindTimeout);
log.debug('found navigation items: ' + nav.length);
await Promise.all(nav.map(async function (link) {
const text = await link.getVisibleText();
log.debug('nav text:' + text);
if (text === 'Metric') {
await link.click();
}
}));
const button = await testSubjects.find('metricTsvbTypeBtn');
await button.click();
}

async clickMarkdown() {
const button = await testSubjects.find('markdownTsvbTypeBtn');
await button.click();
}

async getMetricValue() {
const metricValue = await find.byCssSelector('.rhythm_metric__primary-value');
return metricValue.getVisibleText();
}

async enterMarkdown(markdown) {
const input = await find.byCssSelector('.vis_editor__markdown-editor textarea');
// Since we use ACE editor and that isn't really storing its value inside
// a textarea we must really select all text and remove it, and cannot use
// clearValue().
await input.session.pressKeys([Keys.CONTROL, 'a']); // Select all text
await input.session.pressKeys(Keys.NULL); // Release modifier keys
await input.session.pressKeys(Keys.BACKSPACE); // Delete all content
await input.type(markdown);
await PageObjects.header.waitUntilLoadingHasFinished();
}

async getMarkdownText() {
const el = await find.byCssSelector('.vis_editor__visualization');
return await el.getVisibleText();
}

async clickMarkdownData() {
await testSubjects.click('markdownDataBtn');
}

async clickSeriesOption(nth = 0) {
const el = await testSubjects.findAll('seriesOptions');
await el[nth].click();
await PageObjects.common.sleep(300);
}

async clearOffsetSeries() {
const el = await testSubjects.find('offsetTimeSeries');
await el.clearValue();
await PageObjects.header.waitUntilLoadingHasFinished();
}

async enterOffsetSeries(value) {
const el = await testSubjects.find('offsetTimeSeries');
await el.clearValue();
await el.type(value);
await PageObjects.header.waitUntilLoadingHasFinished();
}

async getRhythmChartLegendValue() {
const metricValue = await find.byCssSelector('.rhythm_chart__legend_value');
await metricValue.session.moveMouseTo(metricValue);
return await metricValue.getVisibleText();
}
}

return new VisualBuilderPage();
Expand Down

0 comments on commit 4671aa5

Please sign in to comment.