Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,24 @@ To execute the front-end browser tests, enter the following. This requires the s
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

- Using Page Objects pattern (https://theintern.github.io/intern/#writing-functional-test)
Expand Down
4 changes: 2 additions & 2 deletions tasks/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -62,12 +62,12 @@ module.exports = function (grunt) {

grunt.registerTask('test:ui:server', [
'esvm:ui',
'run:testUIDevServer',
'run:devChromeDriver:keepalive'
'run:testUIDevServer:keepalive'
]);

grunt.registerTask('test:ui:runner', [
'clean:screenshots',
'run:devChromeDriver',
'intern:dev'
]);

Expand Down
5 changes: 5 additions & 0 deletions test/functional/apps/discover/_shared_links.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,11 @@ bdd.describe('shared links', function describeIndexTests() {

bdd.before(function () {
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 toTime = '2015-09-23 18:31:44.000';
Expand Down
12 changes: 7 additions & 5 deletions test/functional/apps/visualize/_data_table.js
Original file line number Diff line number Diff line change
Expand Up @@ -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'
];

return PageObjects.visualize.getDataTableData()
.then(function showData(data) {
PageObjects.common.debug(data.split('\n'));
PageObjects.common.saveScreenshot('Visualize-data-table');
expect(data.split('\n')).to.eql(expectedChartData);
return PageObjects.common.try(function () {
return PageObjects.visualize.getDataTableData()
.then(function showData(data) {
PageObjects.common.debug(data.split('\n'));
PageObjects.common.saveScreenshot('Visualize-data-table');
expect(data.split('\n')).to.eql(expectedChartData);
});
});
});

Expand Down
36 changes: 36 additions & 0 deletions test/functional/apps/xpack/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import {
bdd,
remote,
defaultTimeout
} from '../../../support';

import PageObjects from '../../../support/page_objects';

bdd.describe('dismiss x-pack', function () {
this.timeout = defaultTimeout;

// Putting everything here in 'before' so it doesn't count as a test
// since x-pack may or may not be installed. We just want the banner closed.
bdd.before(function () {
PageObjects.common.debug('check for X-Pack welcome, opt-out, and dismiss it');
// find class toaster and see if there's any list items in it?
return PageObjects.settings.navigateTo()
.then(() => {
return PageObjects.monitoring.getToasterContents();
})
.then((contents) => {
// Welcome to X-Pack!
// Sharing your cluster statistics with us helps us improve. Your data is never shared with anyone. Not interested? Opt out here.
// Dismiss
PageObjects.common.debug('Toast banner contents = ' + contents);
if (contents.includes('X-Pack')) {
return PageObjects.monitoring.clickOptOut()
.then(() => {
return PageObjects.monitoring.dismissWelcome();
});
}
});

});

});
1 change: 1 addition & 0 deletions test/functional/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ define(function (require) {
});

const apps = [
'intern/dojo/node!./apps/xpack',
'intern/dojo/node!./apps/discover',
'intern/dojo/node!./apps/management',
'intern/dojo/node!./apps/visualize',
Expand Down
26 changes: 15 additions & 11 deletions test/server_config.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,25 @@ var kibanaURL = '/app/kibana';
module.exports = {
servers: {
webdriver: {
protocol: process.env.TEST_UI_WEBDRIVER_PROTOCOL || 'http',
hostname: process.env.TEST_UI_WEBDRIVER_HOSTNAME || 'localhost',
port: parseInt(process.env.TEST_UI_WEBDRIVER_PORT, 10) || 4444
protocol: process.env.TEST_WEBDRIVER_PROTOCOL || 'http',
hostname: process.env.TEST_WEBDRIVER_HOSTNAME || 'localhost',
port: parseInt(process.env.TEST_WEBDRIVER_PORT, 10) || 4444
},
kibana: {
protocol: process.env.TEST_UI_KIBANA_PROTOCOL || 'http',
hostname: process.env.TEST_UI_KIBANA_HOSTNAME || 'localhost',
port: parseInt(process.env.TEST_UI_KIBANA_PORT, 10) || 5620,
auth: shield.kibanaUser.username + ':' + shield.kibanaUser.password
protocol: process.env.TEST_KIBANA_PROTOCOL || 'http',
hostname: process.env.TEST_KIBANA_HOSTNAME || 'localhost',
port: parseInt(process.env.TEST_KIBANA_PORT, 10) || 5620,
auth: shield.kibanaUser.username + ':' + shield.kibanaUser.password,
username: shield.kibanaUser.username,
password: shield.kibanaUser.password
},
elasticsearch: {
protocol: process.env.TEST_UI_ES_PROTOCOL || 'http',
hostname: process.env.TEST_UI_ES_HOSTNAME || 'localhost',
port: parseInt(process.env.TEST_UI_ES_PORT, 10) || 9220,
auth: shield.admin.username + ':' + shield.admin.password
protocol: process.env.TEST_ES_PROTOCOL || 'http',
hostname: process.env.TEST_ES_HOSTNAME || 'localhost',
port: parseInt(process.env.TEST_ES_PORT, 10) || 9220,
auth: shield.admin.username + ':' + shield.admin.password,
username: shield.admin.username,
password: shield.admin.password
}
},
apps: {
Expand Down
12 changes: 6 additions & 6 deletions test/shield.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
const env = process.env;

exports.kibanaUser = {
username: env.SHIELD_KIBANA_USER || 'user',
password: env.SHIELD_KIBANA_USER_PASS || 'notsecure'
username: env.TEST_KIBANA_USER || 'elastic',
password: env.TEST_KIBANA_PASS || 'changeme'
};

exports.kibanaServer = {
username: env.SHIELD_KIBANA_SERVER || 'kibana',
password: env.SHIELD_KIBANA_SERVER_PASS || 'notsecure'
username: env.TEST_KIBANA_SERVER_USER || 'kibana',
password: env.TEST_KIBANA_SERVER_PASS || 'changeme'
};

exports.admin = {
username: env.SHIELD_ADMIN || 'admin',
password: env.SHIELD_ADMIN_PASS || 'notsecure'
username: env.TEST_ES_USER || 'elastic',
password: env.TEST_ES_PASS || 'changeme'
};
16 changes: 11 additions & 5 deletions test/support/page_objects/common.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ import {
esClient
} from '../index';

import PageObjects from './index';

import {
Log,
Try
Expand Down Expand Up @@ -116,10 +118,10 @@ export default class Common {
.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)
self.debug('Found loginPage username = '
+ config.servers.kibana.username);
return PageObjects.shield.login(config.servers.kibana.username,
config.servers.kibana.password)
.then(function () {
return self.remote.getCurrentUrl();
});
Expand All @@ -140,7 +142,11 @@ export default class Common {
// 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
// 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);

if (!navSuccessful) {
Expand Down
2 changes: 1 addition & 1 deletion test/support/page_objects/header_page.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ export default class HeaderPage {
}

isTimepickerOpen() {
return this.remote.setFindTimeout(defaultFindTimeout)
return this.remote.setFindTimeout(2000)
.findDisplayedByCssSelector('.kbn-timepicker')
.then(() => true)
.catch(() => false);
Expand Down
7 changes: 7 additions & 0 deletions test/support/page_objects/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import HeaderPage from './header_page';
import SettingsPage from './settings_page';
import ShieldPage from './shield_page';
import VisualizePage from './visualize_page';
import MonitoringPage from './monitoring_page';

const common = new Common();
const consolePage = new ConsolePage();
Expand All @@ -16,6 +17,7 @@ const headerPage = new HeaderPage();
const settingsPage = new SettingsPage();
const shieldPage = new ShieldPage();
const visualizePage = new VisualizePage();
const monitoringPage = new MonitoringPage();

class PageObjects {

Expand All @@ -35,6 +37,7 @@ class PageObjects {
settingsPage.init(remote);
shieldPage.init(remote);
visualizePage.init(remote);
monitoringPage.init(remote);
}

assertInitialized() {
Expand Down Expand Up @@ -76,6 +79,10 @@ class PageObjects {
return this.assertInitialized() && visualizePage;
}

get monitoring() {
return this.assertInitialized() && monitoringPage;
}

}

export default new PageObjects();
35 changes: 35 additions & 0 deletions test/support/page_objects/monitoring_page.js
Original file line number Diff line number Diff line change
@@ -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();
}

}