Many new tests, updates to tests, and refactoring.

This commit is contained in:
leedr 2015-10-09 09:52:03 -05:00 committed by Joe Fleming
parent d11cc86973
commit d6b82bc4be
6 changed files with 181 additions and 109 deletions

View file

@ -169,6 +169,7 @@
"marked-text-renderer": "0.1.0",
"mocha": "2.3.0",
"nock": "2.10.0",
"Nonsense": "0.1.2",
"npm": "2.11.0",
"portscanner": "1.0.0",
"simple-git": "1.8.0",

View file

@ -7,38 +7,20 @@ define(function (require) {
//var ScenarioManager = require('intern/dojo/node!../fixtures/scenarioManager');
var fs = require('intern/dojo/node!fs');
var pollUntil = require('intern/dojo/node!leadfoot/helpers/pollUntil');
var Common = require('../support/pages/Common');
var SettingsPage = require('../support/pages/SettingsPage');
var HeaderPage = require('../support/pages/HeaderPage');
var DiscoverPage = require('../support/pages/DiscoverPage');
var Promise = require('bluebird');
function tryForTime(timeout, block) {
var start = Date.now();
var lastTry = 0;
function attempt() {
lastTry = Date.now();
if (lastTry - start > timeout) {
throw new Error('timeout');
}
return Promise.try(block).catch(function (err) {
console.log('failed with ' + err.message);
console.log('trying again in 1 second');
return Promise.delay(1000).then(attempt);
});
}
return Promise.try(attempt);
}
var config = require('intern').config;
var url = require('intern/dojo/node!url');
var _ = require('intern/dojo/node!lodash');
registerSuite(function () {
var common;
var settingsPage;
var headerPage;
var url = 'http://localhost:5601';
//var url = 'http://localhost:5601';
var expectedAlertText = 'Are you sure you want to remove this index pattern?';
return {
@ -47,6 +29,7 @@ define(function (require) {
setup: function () {
// curl -XDELETE http://localhost:9200/.kibana
common = new Common(this.remote);
settingsPage = new SettingsPage(this.remote);
headerPage = new HeaderPage(this.remote);
},
@ -56,7 +39,9 @@ define(function (require) {
*/
'testSettingsInitialState': function () {
return this.remote
.get(url)
.get(url.format(_.assign(config.kibana, {
pathname: ''
})))
.then(function () {
return settingsPage
.getTimeBasedEventsCheckbox()
@ -75,12 +60,12 @@ define(function (require) {
return patternField
.getProperty('value')
.then(function (pattern) {
headerPage.log('patternField value = ' + pattern);
common.log('patternField value = ' + pattern);
expect(pattern).to.be('logstash-*');
return settingsPage.getTimeFieldNameField()
.isSelected()
.then(function (timeFieldIsSelected) {
headerPage.log('timeField isSelected = ' + timeFieldIsSelected);
common.log('timeField isSelected = ' + timeFieldIsSelected);
expect(timeFieldIsSelected).to.not.be.ok();
});
});
@ -94,7 +79,9 @@ define(function (require) {
*/
'testCreateButtonDisabledUntilTimeFieldSelected': function () {
return this.remote
.get(url)
.get(url.format(_.assign(config.kibana, {
pathname: ''
})))
.then(function () {
return settingsPage
.getCreateButton()
@ -124,7 +111,9 @@ define(function (require) {
*/
'testSettingsCheckboxHide': function () {
return this.remote
.get('http://localhost:5601')
.get(url.format(_.assign(config.kibana, {
pathname: ''
})))
.then(function () {
return settingsPage
.getTimeBasedEventsCheckbox()
@ -152,7 +141,9 @@ define(function (require) {
'testCreateRemoveIndexPattern': function () {
var self = this.remote;
return this.remote
.get(url)
.get(url.format(_.assign(config.kibana, {
pathname: ''
})))
.then(function () {
// select a time field and then Create button
return settingsPage
@ -167,7 +158,7 @@ define(function (require) {
return settingsPage
.getIndexPageHeading()
.then(function (getIndexPageHeading) {
headerPage.log(getIndexPageHeading.getVisibleText());
common.log(getIndexPageHeading.getVisibleText());
})
.then(function () {
// delete the index pattern
@ -175,7 +166,7 @@ define(function (require) {
.clickDeletePattern();
})
.then(function () {
return tryForTime(3000, function () {
return common.tryForTime(3000, function () {
return self
.getAlertText();
});
@ -189,7 +180,7 @@ define(function (require) {
return self
.getCurrentUrl()
.then(function (currentUrl) {
headerPage.log('currentUrl = ' + currentUrl);
common.log('currentUrl = ' + currentUrl);
});
})
// pollUntil we find the Create button
@ -205,7 +196,7 @@ define(function (require) {
return self
.getCurrentUrl()
.then(function (currentUrl) {
headerPage.log('currentUrl = ' + currentUrl);
common.log('currentUrl = ' + currentUrl);
});
});
});
@ -214,7 +205,9 @@ define(function (require) {
'testIndexPatternResultsHeader': function () {
var self = this.remote;
return this.remote
.get(url)
.get(url.format(_.assign(config.kibana, {
pathname: ''
})))
.then(function () {
// select a time field and then Create button
return settingsPage
@ -240,12 +233,12 @@ define(function (require) {
return settingsPage
.getTableHeader()
.then(function (header) {
headerPage.log('header.length = ' + header.length); // 6 name type format analyzed indexed controls
common.log('header.length = ' + header.length); // 6 name type format analyzed indexed controls
expect(header.length).to.be(6);
return header[0]
.getVisibleText()
.then(function (text) {
headerPage.log('header[0] = ' + text); // name
common.log('header[0] = ' + text); // name
expect(text).to.be('name');
return header;
});
@ -254,7 +247,7 @@ define(function (require) {
return header[1]
.getVisibleText()
.then(function (text) {
headerPage.log('header[1] = ' + text);
common.log('header[1] = ' + text);
expect(text).to.be('type');
return header;
});
@ -263,7 +256,7 @@ define(function (require) {
return header[2]
.getVisibleText()
.then(function (text) {
headerPage.log('header[2] = ' + text);
common.log('header[2] = ' + text);
expect(text).to.be('format');
return header;
});
@ -272,7 +265,7 @@ define(function (require) {
return header[3]
.getVisibleText()
.then(function (text) {
headerPage.log('header[3] = ' + text);
common.log('header[3] = ' + text);
expect(text).to.be('analyzed');
return header;
});
@ -281,7 +274,7 @@ define(function (require) {
return header[4]
.getVisibleText()
.then(function (text) {
headerPage.log('header[4] = ' + text);
common.log('header[4] = ' + text);
expect(text).to.be('indexed');
return header;
});
@ -290,7 +283,7 @@ define(function (require) {
return header[5]
.getVisibleText()
.then(function (text) {
headerPage.log('header[5] = ' + text);
common.log('header[5] = ' + text);
expect(text).to.be('controls');
return header;
});
@ -301,7 +294,7 @@ define(function (require) {
.clickDeletePattern();
})
.then(function () {
return tryForTime(3000, function () {
return common.tryForTime(3000, function () {
return self
.getAlertText();
});
@ -310,7 +303,7 @@ define(function (require) {
return self
.getAlertText()
.then(function (alertText) {
headerPage.log('alertText = ' + alertText);
common.log('alertText = ' + alertText);
expect(alertText).to.be(expectedAlertText);
});
})
@ -327,7 +320,9 @@ define(function (require) {
'testIndexPatternResultsSort': function () {
var self = this.remote;
return this.remote
.get(url)
.get(url.format(_.assign(config.kibana, {
pathname: ''
})))
.then(function () {
// select a time field and then Create button
return settingsPage
@ -364,7 +359,7 @@ define(function (require) {
return row
.getVisibleText()
.then(function (rowText) {
//headerPage.log('After name-sort first row first column = ' + rowText);
//common.log('After name-sort first row first column = ' + rowText);
expect(rowText).to.be('@message');
});
});
@ -382,7 +377,7 @@ define(function (require) {
return row
.getVisibleText()
.then(function (rowText) {
//headerPage.log('After name-sort first row first column = ' + rowText);
//common.log('After name-sort first row first column = ' + rowText);
expect(rowText).to.be('xss.raw');
});
});
@ -400,7 +395,7 @@ define(function (require) {
return row
.getVisibleText()
.then(function (rowText) {
//headerPage.log('After type-sort first row first column = ' + rowText);
//common.log('After type-sort first row first column = ' + rowText);
expect(rowText).to.be('_source');
});
});
@ -418,7 +413,7 @@ define(function (require) {
return row
.getVisibleText()
.then(function (rowText) {
headerPage.log('After type-sort first row first column = ' + rowText);
common.log('After type-sort first row first column = ' + rowText);
expect(rowText).to.be('string');
});
});
@ -433,7 +428,7 @@ define(function (require) {
return settingsPage
.getFieldsTabCount()
.then(function (tabCount) {
headerPage.log('fields item count = ' + tabCount); // 85
common.log('fields item count = ' + tabCount); // 85
expect(tabCount).to.be('85');
});
})
@ -451,7 +446,7 @@ define(function (require) {
return settingsPage
.getPageFieldCount()
.then(function (pageCount) {
headerPage.log('Page 1 count = ' + pageCount.length);
common.log('Page 1 count = ' + pageCount.length);
expect(pageCount.length).to.be(25);
});
})
@ -464,7 +459,7 @@ define(function (require) {
return settingsPage
.getPageFieldCount()
.then(function (pageCount) {
headerPage.log('Page 2 count = ' + pageCount.length);
common.log('Page 2 count = ' + pageCount.length);
expect(pageCount.length).to.be(25);
});
})
@ -477,7 +472,7 @@ define(function (require) {
return settingsPage
.getPageFieldCount()
.then(function (pageCount) {
headerPage.log('Page 3 count = ' + pageCount.length);
common.log('Page 3 count = ' + pageCount.length);
expect(pageCount.length).to.be(25);
});
})
@ -490,7 +485,7 @@ define(function (require) {
return settingsPage
.getPageFieldCount()
.then(function (pageCount) {
headerPage.log('Page 4 count = ' + pageCount.length);
common.log('Page 4 count = ' + pageCount.length);
expect(pageCount.length).to.be(10);
});
})
@ -500,7 +495,7 @@ define(function (require) {
.clickDeletePattern();
})
.then(function () {
return tryForTime(3000, function () {
return common.tryForTime(3000, function () {
return self
.getAlertText();
});
@ -509,7 +504,7 @@ define(function (require) {
return self
.getAlertText()
.then(function (alertText) {
headerPage.log('alertText = ' + alertText);
common.log('alertText = ' + alertText);
expect(alertText).to.be(expectedAlertText);
});
})
@ -523,7 +518,9 @@ define(function (require) {
'testIndexPatternPopularity': function () {
var self = this.remote;
return this.remote
.get(url)
.get(url.format(_.assign(config.kibana, {
pathname: ''
})))
.then(function () {
// select a time field and then Create button
return settingsPage
@ -564,7 +561,7 @@ define(function (require) {
return settingsPage
.getPopularity()
.then(function (popularity) {
headerPage.log('popularity = ' + popularity);
common.log('popularity = ' + popularity);
expect(popularity).to.be('1');
});
})
@ -587,7 +584,7 @@ define(function (require) {
return settingsPage
.getPopularity()
.then(function (popularity) {
headerPage.log('popularity = ' + popularity);
common.log('popularity = ' + popularity);
expect(popularity).to.be('0');
});
})
@ -615,7 +612,7 @@ define(function (require) {
return settingsPage
.getPopularity()
.then(function (popularity) {
headerPage.log('popularity = ' + popularity);
common.log('popularity = ' + popularity);
expect(popularity).to.be('1');
});
})
@ -636,7 +633,7 @@ define(function (require) {
.clickDeletePattern();
})
.then(function () {
return tryForTime(3000, function () {
return common.tryForTime(3000, function () {
return self
.getAlertText();
});
@ -645,7 +642,7 @@ define(function (require) {
return self
.getAlertText()
.then(function (alertText) {
headerPage.log('alertText = ' + alertText);
common.log('alertText = ' + alertText);
expect(alertText).to.be(expectedAlertText);
});
})

View file

@ -12,7 +12,8 @@ define(function (require) {
}],
tunnelOptions: serverConfig.webdriver,
functionalSuites: [
'test/functional/status.js'
'test/functional/status.js',
'test/functional/testSettings'
],
excludeInstrumentation: /(fixtures|node_modules)\//
}, serverConfig);

View file

@ -0,0 +1,70 @@
// in test/support/pages/Common.js
define(function (require) {
var registerSuite = require('intern!object');
var expect = require('intern/dojo/node!expect.js');
var Promise = require('bluebird');
// the page object is created as a constructor
// so we can provide the remote Command object
// at runtime
function Common(remote) {
this.remote = remote;
}
var defaultTimeout = 5000;
Common.prototype = {
constructor: Common,
tryForTime: function tryForTime(timeout, block) {
var self = this;
var start = Date.now();
var lastTry = 0;
function attempt() {
lastTry = Date.now();
if (lastTry - start > timeout) {
throw new Error('timeout');
}
return Promise.try(block).catch(function (err) {
self.log('failed with "' + err.message + '"');
self.log('trying again in 1/2 second');
return Promise.delay(500).then(attempt);
});
}
return Promise.try(attempt);
},
log: function log(logString) {
console.log(Date.now() + ' : ' + logString);
},
sleep: function sleep(sleepMilliseconds) {
var self = this;
self.log('... sleep(' + sleepMilliseconds + ') start');
return this.remote
.setFindTimeout(sleepMilliseconds)
.findByCssSelector('youWillNeverFindThis')
.then(function () {
self.log('Nobody should ever see this');
return;
})
.catch(function () {
self.log('... sleep(' + sleepMilliseconds + ') end');
return;
});
}
// …additional page interaction tasks…
};
return Common;
});

View file

@ -1,5 +1,6 @@
// in test/support/pages/HeaderPage.js
define(function (require) {
// the page object is created as a constructor
// so we can provide the remote Command object
// at runtime
@ -7,44 +8,42 @@ define(function (require) {
this.remote = remote;
}
var defaultTimeout = 5000;
HeaderPage.prototype = {
constructor: HeaderPage,
clickDiscover: function () {
clickDiscover: function clickDiscover() {
return this.remote
.setFindTimeout(5000)
.setFindTimeout(defaultTimeout)
.findByCssSelector('a[href*=\'discover\']')
.then(function (tab) {
return tab.click();
});
},
clickVisualize: function () {
clickVisualize: function clickVisualize() {
return this.remote
.setFindTimeout(5000)
.setFindTimeout(defaultTimeout)
.findByCssSelector('a[href*=\'visualize\']')
.then(function (tab) {
return tab.click();
});
},
clickDashboard: function () {
clickDashboard: function clickDashboard() {
return this.remote
.setFindTimeout(5000)
.setFindTimeout(defaultTimeout)
.findByCssSelector('a[href*=\'dashboard\']')
.then(function (tab) {
return tab.click();
});
},
clickSettings: function () {
clickSettings: function clickSettings() {
return this.remote
.setFindTimeout(5000)
.setFindTimeout(defaultTimeout)
.findByCssSelector('a[href*=\'settings\']')
.then(function (tab) {
return tab.click();
});
},
log: function (logString) {
console.log(Date.now() + ' : ' + logString);
}
};

View file

@ -4,40 +4,44 @@ define(function (require) {
// so we can provide the remote Command object
// at runtime
var Common = require('./Common');
var defaultTimeout = 5000;
var common;
function SettingsPage(remote) {
this.remote = remote;
common = new Common(this.remote);
}
SettingsPage.prototype = {
constructor: SettingsPage,
getTimeBasedEventsCheckbox: function () {
getTimeBasedEventsCheckbox: function getTimeBasedEventsCheckbox() {
return this.remote
.setFindTimeout(defaultTimeout)
.findByCssSelector('input[ng-model="index.isTimeBased"]');
},
getNameIsPatternCheckbox: function () {
getNameIsPatternCheckbox: function getNameIsPatternCheckbox() {
return this.remote
.setFindTimeout(defaultTimeout / 2) // fail faster since we're sometimes checking that it doesn't exist
.findByCssSelector('input[ng-model="index.nameIsPattern"]');
},
getIndexPatternField: function () {
getIndexPatternField: function getIndexPatternField() {
return this.remote
.setFindTimeout(defaultTimeout)
.findByCssSelector('[ng-model="index.name"]');
},
getTimeFieldNameField: function () {
getTimeFieldNameField: function getTimeFieldNameField() {
return this.remote
.setFindTimeout(defaultTimeout)
.findByCssSelector('select[ng-model="index.timeField"]');
},
selectTimeFieldOption: function (selection) {
selectTimeFieldOption: function selectTimeFieldOption(selection) {
var self = this;
return this
.getTimeFieldNameField().click()
@ -51,72 +55,72 @@ define(function (require) {
});
},
getTimeFieldOption: function (selection) {
getTimeFieldOption: function getTimeFieldOption(selection) {
return this.remote
.setFindTimeout(defaultTimeout * 2)
.findByCssSelector('option[label="' + selection + '"]')
.click();
},
getCreateButton: function () {
getCreateButton: function getCreateButton() {
return this.remote
.setFindTimeout(defaultTimeout)
.findByCssSelector('.btn');
},
clickCreateButton: function () {
clickCreateButton: function clickCreateButton() {
return this.remote
.setFindTimeout(defaultTimeout)
.findByCssSelector('.btn').click();
},
clickDefaultIndexButton: function () {
clickDefaultIndexButton: function clickDefaultIndexButton() {
return this.remote
.setFindTimeout(defaultTimeout)
.findByCssSelector('button[tooltip="Set as default index"')
.click();
},
clickDeletePattern: function () {
clickDeletePattern: function clickDeletePattern() {
return this.remote
.setFindTimeout(defaultTimeout)
.findByCssSelector('button[tooltip="Remove index pattern"')
.click();
},
getIndexPageHeading: function () {
getIndexPageHeading: function getIndexPageHeading() {
return this.remote
.setFindTimeout(defaultTimeout)
.findByCssSelector('h1.title.ng-binding.ng-isolate-scope');
},
getConfigureHeader: function () {
getConfigureHeader: function getConfigureHeader() {
return this.remote
.setFindTimeout(defaultTimeout)
.findByCssSelector('h1');
},
getTableHeader: function () {
getTableHeader: function getTableHeader() {
return this.remote
.setFindTimeout(defaultTimeout)
.findAllByCssSelector('table.table.table-condensed thead tr th');
},
sortBy: function (columnName) {
// console.log('sorting by ' + columnName);
sortBy: function sortBy(columnName) {
// common.log('sorting by ' + columnName);
return this.remote
.setFindTimeout(defaultTimeout)
.findAllByCssSelector('table.table.table-condensed thead tr th span')
.then(function (chartTypes) {
// console.log('found bucket types ' + chartTypes.length);
// common.log('found bucket types ' + chartTypes.length);
function getChartType(chart) {
return chart
.getVisibleText()
.then(function (chartString) {
//console.log(chartString);
//common.log(chartString);
if (chartString === columnName) {
// console.log('sorting by ' + columnName);
// common.log('sorting by ' + columnName);
return chart
.click();
}
@ -127,7 +131,7 @@ define(function (require) {
});
},
getTableRow: function (rowNumber, colNumber) {
getTableRow: function getTableRow(rowNumber, colNumber) {
return this.remote
.setFindTimeout(defaultTimeout)
// passing in zero-based index, but adding 1 for css 1-based indexes
@ -137,7 +141,7 @@ define(function (require) {
);
},
getFieldsTabCount: function () {
getFieldsTabCount: function getFieldsTabCount() {
return this.remote
.setFindTimeout(defaultTimeout)
// passing in zero-based index, but adding 1 for css 1-based indexes
@ -152,13 +156,13 @@ define(function (require) {
});
},
getPageSize: function () {
getPageSize: function getPageSize() {
var selectedItemLabel = '';
return this.remote
.setFindTimeout(defaultTimeout)
.findAllByCssSelector('select.ng-pristine.ng-valid.ng-untouched option')
.then(function (chartTypes) {
//console.log('found selection options ' + chartTypes.length);
//common.log('found selection options ' + chartTypes.length);
function getChartType(chart) {
var thisChart = chart;
@ -166,11 +170,11 @@ define(function (require) {
.isSelected()
.then(function (isSelected) {
if (isSelected === true) {
//console.log('Found selected option ');
//common.log('Found selected option ');
return thisChart
.getProperty('label')
.then(function (theLabel) {
// console.log('Page size = ' + theLabel);
// common.log('Page size = ' + theLabel);
selectedItemLabel = theLabel;
});
}
@ -180,18 +184,18 @@ define(function (require) {
return Promise.all(getChartTypesPromises);
})
.then(function () {
//console.log('returning types array here? ' + types);
//common.log('returning types array here? ' + types);
return selectedItemLabel;
});
},
getPageFieldCount: function () {
getPageFieldCount: function getPageFieldCount() {
return this.remote
.setFindTimeout(defaultTimeout)
.findAllByCssSelector('div.agg-table-paginated table.table.table-condensed tbody tr td.ng-scope:nth-child(1) span.ng-binding');
},
goToPage: function (pageNum) {
goToPage: function goToPage(pageNum) {
return this.remote
.setFindTimeout(defaultTimeout)
.findByCssSelector('ul.pagination-other-pages-list.pagination-sm.ng-scope li.ng-scope:nth-child(' +
@ -202,7 +206,7 @@ define(function (require) {
});
},
openControlsRow: function (row) {
openControlsRow: function openControlsRow(row) {
return this.remote
.setFindTimeout(defaultTimeout)
.findByCssSelector('table.table.table-condensed tbody tr:nth-child(' +
@ -213,7 +217,7 @@ define(function (require) {
});
},
openControlsByName: function (name) {
openControlsByName: function openControlsByName(name) {
return this.remote
.setFindTimeout(defaultTimeout * 2)
// .findByCssSelector('div.actions a.btn.btn-xs.btn-default[href="#/settings/indices/logstash-*/field/' + name + '"]')
@ -223,7 +227,7 @@ define(function (require) {
});
},
increasePopularity: function () {
increasePopularity: function increasePopularity() {
return this.remote
.setFindTimeout(defaultTimeout)
.findByCssSelector('button.btn.btn-default[aria-label="Plus"]')
@ -232,7 +236,7 @@ define(function (require) {
});
},
getPopularity: function () {
getPopularity: function getPopularity() {
return this.remote
.setFindTimeout(defaultTimeout)
.findByCssSelector('input.form-control.ng-pristine.ng-valid.ng-untouched.ng-valid-number')
@ -242,7 +246,7 @@ define(function (require) {
});
},
controlChangeCancel: function () {
controlChangeCancel: function controlChangeCancel() {
return this.remote
.setFindTimeout(defaultTimeout)
.findByCssSelector('button.btn.btn-primary[aria-label="Cancel"]')
@ -251,7 +255,7 @@ define(function (require) {
});
},
controlChangeSave: function () {
controlChangeSave: function controlChangeSave() {
return this.remote
.setFindTimeout(defaultTimeout)
.findByCssSelector('button.btn.btn-success.ng-binding[aria-label="Update Field"]')
@ -260,7 +264,7 @@ define(function (require) {
});
},
setPageSize: function (size) {
setPageSize: function setPageSize(size) {
return this.remote
.setFindTimeout(defaultTimeout)
.findByCssSelector('form.form-inline.pagination-size.ng-scope.ng-pristine.ng-valid div.form-group option[label="' + size + '"]')