mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 17:59:23 -04:00
Support Cloud Kibana testing
This commit is contained in:
parent
f59762e440
commit
c877b0d72a
11 changed files with 119 additions and 49 deletions
|
@ -258,6 +258,24 @@ To execute the front-end browser tests, enter the following. This requires the s
|
||||||
npm run test:ui:runner
|
npm run test:ui:runner
|
||||||
```
|
```
|
||||||
|
|
||||||
|
To run these browser tests against against some other Elasticsearch and Kibana instance you can set these environment variables and then run the test runner.
|
||||||
|
Here's an example to run against an Elastic Cloud instance (note that you should run the same branch of tests as the version of Kibana you're testing);
|
||||||
|
|
||||||
|
```bash
|
||||||
|
export TEST_KIBANA_PROTOCOL=https
|
||||||
|
export TEST_KIBANA_HOSTNAME=9249d04b1186b3e7bbe11ea60df4f963.us-east-1.aws.found.io
|
||||||
|
export TEST_KIBANA_PORT=443
|
||||||
|
export TEST_KIBANA_USER=elastic
|
||||||
|
export TEST_KIBANA_PASS=<your password here>
|
||||||
|
|
||||||
|
export TEST_ES_PROTOCOL=http
|
||||||
|
export TEST_ES_HOSTNAME=aaa5d22032d76805fcce724ed9d9f5a2.us-east-1.aws.found.io
|
||||||
|
export TEST_ES_PORT=9200
|
||||||
|
export TEST_ES_USER=elastic
|
||||||
|
export TEST_ES_PASS=<your password here>
|
||||||
|
npm run test:ui:runner
|
||||||
|
```
|
||||||
|
|
||||||
##### Browser Automation Notes
|
##### Browser Automation Notes
|
||||||
|
|
||||||
- Using Page Objects pattern (https://theintern.github.io/intern/#writing-functional-test)
|
- Using Page Objects pattern (https://theintern.github.io/intern/#writing-functional-test)
|
||||||
|
|
|
@ -62,12 +62,12 @@ module.exports = function (grunt) {
|
||||||
|
|
||||||
grunt.registerTask('test:ui:server', [
|
grunt.registerTask('test:ui:server', [
|
||||||
'esvm:ui',
|
'esvm:ui',
|
||||||
'run:testUIDevServer',
|
'run:testUIDevServer:keepalive'
|
||||||
'run:devChromeDriver:keepalive'
|
|
||||||
]);
|
]);
|
||||||
|
|
||||||
grunt.registerTask('test:ui:runner', [
|
grunt.registerTask('test:ui:runner', [
|
||||||
'clean:screenshots',
|
'clean:screenshots',
|
||||||
|
'run:devChromeDriver',
|
||||||
'intern:dev'
|
'intern:dev'
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
|
|
@ -20,6 +20,11 @@ bdd.describe('shared links', function describeIndexTests() {
|
||||||
|
|
||||||
bdd.before(function () {
|
bdd.before(function () {
|
||||||
baseUrl = PageObjects.common.getHostPort();
|
baseUrl = PageObjects.common.getHostPort();
|
||||||
|
PageObjects.common.debug('baseUrl = ' + baseUrl);
|
||||||
|
// browsers don't show the ':port' if it's 80 or 443 so we have to
|
||||||
|
// remove that part so we can get a match in the tests.
|
||||||
|
baseUrl = baseUrl.replace(':80','').replace(':443','');
|
||||||
|
PageObjects.common.debug('New baseUrl = ' + baseUrl);
|
||||||
|
|
||||||
var fromTime = '2015-09-19 06:31:44.000';
|
var fromTime = '2015-09-19 06:31:44.000';
|
||||||
var toTime = '2015-09-23 18:31:44.000';
|
var toTime = '2015-09-23 18:31:44.000';
|
||||||
|
|
|
@ -77,11 +77,13 @@ bdd.describe('visualize app', function describeIndexTests() {
|
||||||
'8,000 2,863', '10,000 147', '12,000 148', '14,000 129', '16,000 161', '18,000 137'
|
'8,000 2,863', '10,000 147', '12,000 148', '14,000 129', '16,000 161', '18,000 137'
|
||||||
];
|
];
|
||||||
|
|
||||||
return PageObjects.visualize.getDataTableData()
|
return PageObjects.common.try(function () {
|
||||||
.then(function showData(data) {
|
return PageObjects.visualize.getDataTableData()
|
||||||
PageObjects.common.debug(data.split('\n'));
|
.then(function showData(data) {
|
||||||
PageObjects.common.saveScreenshot('Visualize-data-table');
|
PageObjects.common.debug(data.split('\n'));
|
||||||
expect(data.split('\n')).to.eql(expectedChartData);
|
PageObjects.common.saveScreenshot('Visualize-data-table');
|
||||||
|
expect(data.split('\n')).to.eql(expectedChartData);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -29,6 +29,7 @@ define(function (require) {
|
||||||
});
|
});
|
||||||
|
|
||||||
const apps = [
|
const apps = [
|
||||||
|
'intern/dojo/node!./apps/xpack',
|
||||||
'intern/dojo/node!./apps/discover',
|
'intern/dojo/node!./apps/discover',
|
||||||
'intern/dojo/node!./apps/management',
|
'intern/dojo/node!./apps/management',
|
||||||
'intern/dojo/node!./apps/visualize',
|
'intern/dojo/node!./apps/visualize',
|
||||||
|
|
|
@ -5,21 +5,25 @@ var kibanaURL = '/app/kibana';
|
||||||
module.exports = {
|
module.exports = {
|
||||||
servers: {
|
servers: {
|
||||||
webdriver: {
|
webdriver: {
|
||||||
protocol: process.env.TEST_UI_WEBDRIVER_PROTOCOL || 'http',
|
protocol: process.env.TEST_WEBDRIVER_PROTOCOL || 'http',
|
||||||
hostname: process.env.TEST_UI_WEBDRIVER_HOSTNAME || 'localhost',
|
hostname: process.env.TEST_WEBDRIVER_HOSTNAME || 'localhost',
|
||||||
port: parseInt(process.env.TEST_UI_WEBDRIVER_PORT, 10) || 4444
|
port: parseInt(process.env.TEST_WEBDRIVER_PORT, 10) || 4444
|
||||||
},
|
},
|
||||||
kibana: {
|
kibana: {
|
||||||
protocol: process.env.TEST_UI_KIBANA_PROTOCOL || 'http',
|
protocol: process.env.TEST_KIBANA_PROTOCOL || 'http',
|
||||||
hostname: process.env.TEST_UI_KIBANA_HOSTNAME || 'localhost',
|
hostname: process.env.TEST_KIBANA_HOSTNAME || 'localhost',
|
||||||
port: parseInt(process.env.TEST_UI_KIBANA_PORT, 10) || 5620,
|
port: parseInt(process.env.TEST_KIBANA_PORT, 10) || 5620,
|
||||||
auth: shield.kibanaUser.username + ':' + shield.kibanaUser.password
|
auth: shield.kibanaUser.username + ':' + shield.kibanaUser.password,
|
||||||
|
username: shield.kibanaUser.username,
|
||||||
|
password: shield.kibanaUser.password
|
||||||
},
|
},
|
||||||
elasticsearch: {
|
elasticsearch: {
|
||||||
protocol: process.env.TEST_UI_ES_PROTOCOL || 'http',
|
protocol: process.env.TEST_ES_PROTOCOL || 'http',
|
||||||
hostname: process.env.TEST_UI_ES_HOSTNAME || 'localhost',
|
hostname: process.env.TEST_ES_HOSTNAME || 'localhost',
|
||||||
port: parseInt(process.env.TEST_UI_ES_PORT, 10) || 9220,
|
port: parseInt(process.env.TEST_ES_PORT, 10) || 9220,
|
||||||
auth: shield.admin.username + ':' + shield.admin.password
|
auth: shield.admin.username + ':' + shield.admin.password,
|
||||||
|
username: shield.admin.username,
|
||||||
|
password: shield.admin.password
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
apps: {
|
apps: {
|
||||||
|
|
|
@ -1,16 +1,16 @@
|
||||||
const env = process.env;
|
const env = process.env;
|
||||||
|
|
||||||
exports.kibanaUser = {
|
exports.kibanaUser = {
|
||||||
username: env.SHIELD_KIBANA_USER || 'user',
|
username: env.TEST_KIBANA_USER || 'elastic',
|
||||||
password: env.SHIELD_KIBANA_USER_PASS || 'notsecure'
|
password: env.TEST_KIBANA_PASS || 'changeme'
|
||||||
};
|
};
|
||||||
|
|
||||||
exports.kibanaServer = {
|
exports.kibanaServer = {
|
||||||
username: env.SHIELD_KIBANA_SERVER || 'kibana',
|
username: env.TEST_KIBANA_SERVER_USER || 'elastic',
|
||||||
password: env.SHIELD_KIBANA_SERVER_PASS || 'notsecure'
|
password: env.TEST_KIBANA_SERVER_PASS || 'changeme'
|
||||||
};
|
};
|
||||||
|
|
||||||
exports.admin = {
|
exports.admin = {
|
||||||
username: env.SHIELD_ADMIN || 'admin',
|
username: env.TEST_ES_USER || 'elastic',
|
||||||
password: env.SHIELD_ADMIN_PASS || 'notsecure'
|
password: env.TEST_ES_PASS || 'changeme'
|
||||||
};
|
};
|
||||||
|
|
|
@ -25,6 +25,8 @@ import {
|
||||||
esClient
|
esClient
|
||||||
} from '../index';
|
} from '../index';
|
||||||
|
|
||||||
|
import PageObjects from './index';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
Log,
|
Log,
|
||||||
Try
|
Try
|
||||||
|
@ -114,31 +116,23 @@ export default class Common {
|
||||||
if (testStatusPage !== false) {
|
if (testStatusPage !== false) {
|
||||||
self.debug('self.checkForKibanaApp()');
|
self.debug('self.checkForKibanaApp()');
|
||||||
return self.checkForKibanaApp()
|
return self.checkForKibanaApp()
|
||||||
.then(function (kibanaLoaded) {
|
.then(function (kibanaApp) {
|
||||||
self.debug('kibanaLoaded = ' + kibanaLoaded);
|
self.debug('kibanaApp = ' + kibanaApp);
|
||||||
if (!kibanaLoaded) {
|
if (kibanaApp === 'login') {
|
||||||
var msg = 'Kibana is not loaded, retrying';
|
self.debug('Found loginPage username = '
|
||||||
self.debug(msg);
|
+ config.servers.kibana.username
|
||||||
throw new Error(msg);
|
+ 'password = ' + config.servers.kibana.password);
|
||||||
|
return PageObjects.shield.login(config.servers.kibana.username,
|
||||||
|
config.servers.kibana.password)
|
||||||
|
.then(function () {
|
||||||
|
return self.remote.getCurrentUrl();
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
return self.remote.getCurrentUrl();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
|
||||||
})
|
|
||||||
.then(function () {
|
|
||||||
return self.remote.getCurrentUrl();
|
|
||||||
})
|
|
||||||
.then(function (currentUrl) {
|
|
||||||
var loginPage = new RegExp('login').test(currentUrl);
|
|
||||||
if (loginPage) {
|
|
||||||
self.debug('Found loginPage = ' + loginPage + ', username = '
|
|
||||||
+ config.servers.kibana.shield.username);
|
|
||||||
return shieldPage.login(config.servers.kibana.shield.username,
|
|
||||||
config.servers.kibana.shield.password)
|
|
||||||
.then(function () {
|
|
||||||
return self.remote.getCurrentUrl();
|
|
||||||
});
|
|
||||||
} else {
|
} else {
|
||||||
return currentUrl;
|
return self.remote.getCurrentUrl();
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.then(function (currentUrl) {
|
.then(function (currentUrl) {
|
||||||
|
@ -154,7 +148,11 @@ export default class Common {
|
||||||
// Navigating to Settings when there is a default index pattern has a URL length of 196
|
// Navigating to Settings when there is a default index pattern has a URL length of 196
|
||||||
// (from debug output). Some other tabs may also be long. But a rather simple configured
|
// (from debug output). Some other tabs may also be long. But a rather simple configured
|
||||||
// visualization is about 1000 chars long. So at least we catch that case.
|
// visualization is about 1000 chars long. So at least we catch that case.
|
||||||
var navSuccessful = new RegExp(appUrl + '.{0,' + maxAdditionalLengthOnNavUrl + '}$')
|
|
||||||
|
// Browsers don't show the ':port' if it's 80 or 443 so we have to
|
||||||
|
// remove that part so we can get a match in the tests.
|
||||||
|
var navSuccessful = new RegExp(appUrl.replace(':80','').replace(':443','')
|
||||||
|
+ '.{0,' + maxAdditionalLengthOnNavUrl + '}$')
|
||||||
.test(currentUrl);
|
.test(currentUrl);
|
||||||
|
|
||||||
if (!navSuccessful) {
|
if (!navSuccessful) {
|
||||||
|
@ -236,7 +234,7 @@ export default class Common {
|
||||||
.then(function (app) {
|
.then(function (app) {
|
||||||
var appId = app.id;
|
var appId = app.id;
|
||||||
self.debug('current application: ' + appId);
|
self.debug('current application: ' + appId);
|
||||||
return appId === 'kibana';
|
return appId;
|
||||||
})
|
})
|
||||||
.catch(function (err) {
|
.catch(function (err) {
|
||||||
self.debug('kibana check failed');
|
self.debug('kibana check failed');
|
||||||
|
|
|
@ -47,7 +47,7 @@ export default class HeaderPage {
|
||||||
}
|
}
|
||||||
|
|
||||||
isTimepickerOpen() {
|
isTimepickerOpen() {
|
||||||
return this.remote.setFindTimeout(defaultFindTimeout)
|
return this.remote.setFindTimeout(2000)
|
||||||
.findDisplayedByCssSelector('.kbn-timepicker')
|
.findDisplayedByCssSelector('.kbn-timepicker')
|
||||||
.then(() => true)
|
.then(() => true)
|
||||||
.catch(() => false);
|
.catch(() => false);
|
||||||
|
|
|
@ -7,6 +7,7 @@ import HeaderPage from './header_page';
|
||||||
import SettingsPage from './settings_page';
|
import SettingsPage from './settings_page';
|
||||||
import ShieldPage from './shield_page';
|
import ShieldPage from './shield_page';
|
||||||
import VisualizePage from './visualize_page';
|
import VisualizePage from './visualize_page';
|
||||||
|
import MonitoringPage from './monitoring_page';
|
||||||
|
|
||||||
const common = new Common();
|
const common = new Common();
|
||||||
const consolePage = new ConsolePage();
|
const consolePage = new ConsolePage();
|
||||||
|
@ -16,6 +17,7 @@ const headerPage = new HeaderPage();
|
||||||
const settingsPage = new SettingsPage();
|
const settingsPage = new SettingsPage();
|
||||||
const shieldPage = new ShieldPage();
|
const shieldPage = new ShieldPage();
|
||||||
const visualizePage = new VisualizePage();
|
const visualizePage = new VisualizePage();
|
||||||
|
const monitoringPage = new MonitoringPage();
|
||||||
|
|
||||||
class PageObjects {
|
class PageObjects {
|
||||||
|
|
||||||
|
@ -35,6 +37,7 @@ class PageObjects {
|
||||||
settingsPage.init(remote);
|
settingsPage.init(remote);
|
||||||
shieldPage.init(remote);
|
shieldPage.init(remote);
|
||||||
visualizePage.init(remote);
|
visualizePage.init(remote);
|
||||||
|
monitoringPage.init(remote);
|
||||||
}
|
}
|
||||||
|
|
||||||
assertInitialized() {
|
assertInitialized() {
|
||||||
|
@ -76,6 +79,10 @@ class PageObjects {
|
||||||
return this.assertInitialized() && visualizePage;
|
return this.assertInitialized() && visualizePage;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get monitoring() {
|
||||||
|
return this.assertInitialized() && monitoringPage;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default new PageObjects();
|
export default new PageObjects();
|
||||||
|
|
35
test/support/page_objects/monitoring_page.js
Normal file
35
test/support/page_objects/monitoring_page.js
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
|
||||||
|
import {
|
||||||
|
defaultFindTimeout,
|
||||||
|
} from '../';
|
||||||
|
|
||||||
|
export default class MonitoringPage {
|
||||||
|
|
||||||
|
init(remote) {
|
||||||
|
this.remote = remote;
|
||||||
|
this.findTimeout = this.remote.setFindTimeout(defaultFindTimeout);
|
||||||
|
}
|
||||||
|
|
||||||
|
getWelcome() {
|
||||||
|
return this.findTimeout
|
||||||
|
.findDisplayedByCssSelector('render-directive')
|
||||||
|
.getVisibleText();
|
||||||
|
}
|
||||||
|
|
||||||
|
dismissWelcome() {
|
||||||
|
return this.remote.setFindTimeout(3000)
|
||||||
|
.findDisplayedByCssSelector('button.btn-banner')
|
||||||
|
.click();
|
||||||
|
}
|
||||||
|
|
||||||
|
getToasterContents() {
|
||||||
|
return this.findTimeout
|
||||||
|
.findByCssSelector('div.toaster-container.ng-isolate-scope')
|
||||||
|
.getVisibleText();
|
||||||
|
}
|
||||||
|
|
||||||
|
clickOptOut() {
|
||||||
|
return this.findTimeout.findByLinkText('Opt out here').click();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue