mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 01:38:56 -04:00
Backport PR #7502
--------- **Commit 1:** Switch from Firefox to Chrome * Original sha:677a6c1d3f
* Authored by LeeDr <lee.drengenberg@elastic.co> on 2016-06-17T22:32:15Z **Commit 2:** fix chromedriver.path * Original sha:589cb71cbb
* Authored by LeeDr <lee.drengenberg@elastic.co> on 2016-06-20T14:25:22Z **Commit 3:** More selenium cleanup * Original sha:056294b7e9
* Authored by LeeDr <lee.drengenberg@elastic.co> on 2016-06-20T15:23:29Z **Commit 4:** Put task intern:dev back in! * Original sha:b85d919f68
* Authored by LeeDr <lee.drengenberg@elastic.co> on 2016-06-20T15:38:18Z **Commit 5:** temporary screenshots fix * Original sha:8a9178ca0d
* Authored by LeeDr <lee.drengenberg@elastic.co> on 2016-06-20T16:11:53Z **Commit 6:** Add screenshots dir * Original sha:929f30c8cc
* Authored by LeeDr <lee.drengenberg@elastic.co> on 2016-06-20T16:26:07Z **Commit 7:** Add getSpinnerDone on clickNewSearch to fix failures * Original sha:dfacedb27b
* Authored by LeeDr <lee.drengenberg@elastic.co> on 2016-06-20T16:54:48Z **Commit 8:** Backport screenshots 'session' and 'failure' folders * Original sha:fe9f34cb68
* Authored by LeeDr <lee.drengenberg@elastic.co> on 2016-06-20T18:04:56Z **Commit 9:** gitignore *.png in failures and session * Original sha:06d70e6a63
* Authored by LeeDr <lee.drengenberg@elastic.co> on 2016-06-20T20:53:26Z **Commit 10:** Update .gitignore * Original sha:603f5035ac
* Authored by Lee Drengenberg <lee.drengenberg@elastic.co> on 2016-06-20T21:21:55Z * Committed by GitHub <noreply@github.com> on 2016-06-20T21:21:55Z
This commit is contained in:
parent
30a415d46c
commit
065cd11fc0
15 changed files with 72 additions and 138 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -11,7 +11,8 @@ target
|
|||
.idea
|
||||
*.iml
|
||||
*.log
|
||||
/test/output
|
||||
/test/screenshots/failure/*.png
|
||||
/test/screenshots/session/*.png
|
||||
/esvm
|
||||
.htpasswd
|
||||
.eslintcache
|
||||
|
|
|
@ -111,26 +111,18 @@ The standard `npm run test` task runs several sub tasks and can take several min
|
|||
|
||||
#### Running tests using npm task:
|
||||
|
||||
*The Selenium server that is started currently only runs the tests in Firefox*
|
||||
*The ChromeDriver that is started currently only runs the tests in Chrome browser*
|
||||
|
||||
To runt the functional UI tests, execute the following command:
|
||||
To run the functional UI tests, execute the following command:
|
||||
|
||||
`npm run test:ui`
|
||||
|
||||
The task above takes a little time to start the servers. You can also start the servers and leave them running, and then run the tests separately:
|
||||
|
||||
`npm run test:ui:server` will start the server required to run the selenium tests, leave this open
|
||||
`npm run test:ui:server` will start the server required to run the UI tests, leave this open
|
||||
|
||||
`npm run test:ui:runner` will run the frontend tests and close when complete
|
||||
|
||||
#### Running tests locally with your existing (and already running) ElasticSearch, Kibana, and Selenium Server:
|
||||
|
||||
Set your es and kibana ports in `test/intern.js` to 9220 and 5620, respectively. You can configure your Selenium server to run the tests on Chrome,IE, or other browsers here.
|
||||
|
||||
Once you've got the services running, execute the following:
|
||||
|
||||
`npm run test:ui:runner`
|
||||
|
||||
#### General notes:
|
||||
|
||||
- Using Page Objects pattern (https://theintern.github.io/intern/#writing-functional-test)
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
"Court Ewing <court@elastic.co>",
|
||||
"Joe Fleming <joe.fleming@elastic.co>",
|
||||
"Khalah Jones-Golden <khalah.jones@elastic.co>",
|
||||
"Lee Drengenberg <lee.drengenberg@elastic.co>",
|
||||
"Lukas Olson <lukas.olson@elastic.co>",
|
||||
"Juan Thomassie <juan.thomassie@elastic.co>",
|
||||
"Shelby Sturgis <shelby@elastic.co>",
|
||||
|
@ -142,6 +143,7 @@
|
|||
"auto-release-sinon": "1.0.3",
|
||||
"babel-eslint": "4.1.7",
|
||||
"chokidar": "1.0.5",
|
||||
"chromedriver": "2.21.2",
|
||||
"eslint": "1.5.1",
|
||||
"eslint-plugin-mocha": "1.0.0",
|
||||
"expect.js": "0.3.1",
|
||||
|
@ -160,7 +162,7 @@
|
|||
"gruntify-eslint": "1.0.1",
|
||||
"html-entities": "1.1.3",
|
||||
"husky": "0.8.1",
|
||||
"intern": "3.0.1",
|
||||
"intern": "3.2.3",
|
||||
"istanbul-instrumenter-loader": "0.1.3",
|
||||
"karma": "0.13.9",
|
||||
"karma-chrome-launcher": "0.2.0",
|
||||
|
|
|
@ -1,15 +0,0 @@
|
|||
var path = require('path');
|
||||
|
||||
|
||||
module.exports = function (grunt) {
|
||||
return {
|
||||
options: {
|
||||
selenium: {
|
||||
filename: 'selenium-server-standalone-2.53.0.jar',
|
||||
server: 'https://selenium-release.storage.googleapis.com/2.53/',
|
||||
md5: '774efe2d84987fb679f2dea038c2fa32',
|
||||
directory: path.join(grunt.config.get('root'), 'selenium')
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
|
@ -5,6 +5,7 @@ module.exports = function (grunt) {
|
|||
let root = p => resolve(__dirname, '../../', p);
|
||||
let binScript = /^win/.test(platform) ? '.\\bin\\kibana.bat' : './bin/kibana';
|
||||
let uiConfig = require(root('test/serverConfig'));
|
||||
let chromedriver = require('chromedriver');
|
||||
|
||||
return {
|
||||
testServer: {
|
||||
|
@ -78,35 +79,31 @@ module.exports = function (grunt) {
|
|||
]
|
||||
},
|
||||
|
||||
seleniumServer: {
|
||||
chromeDriver: {
|
||||
options: {
|
||||
wait: false,
|
||||
ready: /Selenium Server is up and running/,
|
||||
quiet: true,
|
||||
failOnError: false
|
||||
},
|
||||
cmd: 'java',
|
||||
args: [
|
||||
'-jar',
|
||||
'selenium/selenium-server-standalone-2.53.0.jar',
|
||||
'-port',
|
||||
uiConfig.servers.webdriver.port
|
||||
]
|
||||
},
|
||||
|
||||
devSeleniumServer: {
|
||||
options: {
|
||||
wait: false,
|
||||
ready: /Selenium Server is up and running/,
|
||||
ready: /Starting ChromeDriver/,
|
||||
quiet: false,
|
||||
failOnError: false
|
||||
},
|
||||
cmd: 'java',
|
||||
cmd: chromedriver.path,
|
||||
args: [
|
||||
'-jar',
|
||||
'selenium/selenium-server-standalone-2.53.0.jar',
|
||||
'-port',
|
||||
uiConfig.servers.webdriver.port
|
||||
`--port=${uiConfig.servers.webdriver.port}`,
|
||||
'--url-base=wd/hub'
|
||||
]
|
||||
},
|
||||
|
||||
devChromeDriver: {
|
||||
options: {
|
||||
wait: false,
|
||||
ready: /Starting ChromeDriver/,
|
||||
quiet: false,
|
||||
failOnError: false
|
||||
},
|
||||
cmd: chromedriver.path,
|
||||
args: [
|
||||
`--port=${uiConfig.servers.webdriver.port}`,
|
||||
'--url-base=wd/hub'
|
||||
]
|
||||
},
|
||||
|
||||
|
|
|
@ -1,60 +0,0 @@
|
|||
var _ = require('lodash');
|
||||
var request = require('request');
|
||||
var fs = require('fs');
|
||||
var path = require('path');
|
||||
var colors = require('ansicolors');
|
||||
var crypto = require('crypto');
|
||||
var {spawn} = require('child_process');
|
||||
|
||||
module.exports = function (grunt) {
|
||||
grunt.registerTask('downloadSelenium', 'Download selenium standalone', function (keepalive) {
|
||||
const done = this.async();
|
||||
const config = this.options();
|
||||
|
||||
const SELENIUM_FILE_PATH = path.join(config.selenium.directory, config.selenium.filename);
|
||||
const SELENIUM_DOWNLOAD_URL = config.selenium.server + config.selenium.filename;
|
||||
|
||||
function validateDownload(path, expectedHash, success) {
|
||||
grunt.log.write('Validating hash...');
|
||||
fs.readFile(path, function checkHash(err, data) {
|
||||
if (err) grunt.fail.warn(err);
|
||||
|
||||
const calculatedHash = crypto.createHash('md5').update(data).digest('hex');
|
||||
if (calculatedHash !== expectedHash) return grunt.fail.warn('Selenium download has an invalid hash');
|
||||
|
||||
grunt.log.writeln('done');
|
||||
success();
|
||||
});
|
||||
}
|
||||
|
||||
function downloadSelenium(success) {
|
||||
grunt.log.write(`Downloading ${SELENIUM_DOWNLOAD_URL}...`);
|
||||
request.get(SELENIUM_DOWNLOAD_URL)
|
||||
.pipe(fs.createWriteStream(SELENIUM_FILE_PATH))
|
||||
.on('error', function downloadError(err) {
|
||||
grunt.fail.warn(err);
|
||||
})
|
||||
.on('finish', function downloadFinish() {
|
||||
grunt.log.writeln('done');
|
||||
validateDownload(SELENIUM_FILE_PATH, config.selenium.md5, success);
|
||||
});
|
||||
}
|
||||
|
||||
function start() {
|
||||
try {
|
||||
fs.mkdirSync(config.selenium.directory);
|
||||
} catch (err) {
|
||||
if (err && err.code !== 'EEXIST') grunt.fail.warn(err);
|
||||
}
|
||||
|
||||
if (fs.existsSync(SELENIUM_FILE_PATH)) {
|
||||
validateDownload(SELENIUM_FILE_PATH, config.selenium.md5, done);
|
||||
} else {
|
||||
downloadSelenium(done);
|
||||
}
|
||||
}
|
||||
|
||||
start();
|
||||
|
||||
});
|
||||
};
|
|
@ -18,19 +18,17 @@ module.exports = function (grunt) {
|
|||
grunt.registerTask('test:ui', [
|
||||
'esvm:ui',
|
||||
'run:testUIServer',
|
||||
'downloadSelenium',
|
||||
'run:seleniumServer',
|
||||
'run:chromeDriver',
|
||||
'intern:dev',
|
||||
'esvm_shutdown:ui',
|
||||
'stop:seleniumServer',
|
||||
'stop:chromeDriver',
|
||||
'stop:testUIServer'
|
||||
]);
|
||||
|
||||
grunt.registerTask('test:ui:server', [
|
||||
'esvm:ui',
|
||||
'run:testUIServer',
|
||||
'downloadSelenium',
|
||||
'run:devSeleniumServer:keepalive'
|
||||
'run:devChromeDriver:keepalive'
|
||||
]);
|
||||
|
||||
grunt.registerTask('test:ui:runner', [
|
||||
|
|
|
@ -74,10 +74,10 @@ define(function (require) {
|
|||
var expectedUrl = baseUrl
|
||||
+ '/app/kibana?_t=1453775307251#'
|
||||
+ '/discover?_g=(refreshInterval:(display:Off,pause:!f,value:0),time'
|
||||
+ ':(from:%272015-09-19T06:31:44.000Z%27,mode:absolute,to:%272015-09'
|
||||
+ '-23T18:31:44.000Z%27))&_a=(columns:!(_source),index:%27logstash-'
|
||||
+ '*%27,interval:auto,query:(query_string:(analyze_wildcard:!t,query'
|
||||
+ ':%27*%27)),sort:!(%27@timestamp%27,desc))';
|
||||
+ ':(from:\'2015-09-19T06:31:44.000Z\',mode:absolute,to:\'2015-09'
|
||||
+ '-23T18:31:44.000Z\'))&_a=(columns:!(_source),index:\'logstash-'
|
||||
+ '*\',interval:auto,query:(query_string:(analyze_wildcard:!t,query'
|
||||
+ ':\'*\')),sort:!(\'@timestamp\',desc))';
|
||||
return discoverPage.getSharedUrl()
|
||||
.then(function (actualUrl) {
|
||||
// strip the timestamp out of each URL
|
||||
|
|
|
@ -5,11 +5,10 @@ define(function (require) {
|
|||
return _.assign({
|
||||
debug: true,
|
||||
capabilities: {
|
||||
'selenium-version': '2.53.0',
|
||||
'idle-timeout': 99
|
||||
},
|
||||
environments: [{
|
||||
browserName: 'firefox'
|
||||
browserName: 'chrome'
|
||||
}],
|
||||
tunnelOptions: serverConfig.servers.webdriver,
|
||||
functionalSuites: [
|
||||
|
|
0
test/screenshots/.empty
Normal file
0
test/screenshots/.empty
Normal file
0
test/screenshots/failure/.empty
Normal file
0
test/screenshots/failure/.empty
Normal file
0
test/screenshots/session/.empty
Normal file
0
test/screenshots/session/.empty
Normal file
|
@ -57,11 +57,8 @@ define(function (require) {
|
|||
|
||||
navigateToApp: function (appName, testStatusPage) {
|
||||
var self = this;
|
||||
// navUrl includes user:password@ for use with Shield
|
||||
// appUrl excludes user:password@ to match what getCurrentUrl returns
|
||||
var navUrl = getUrl(config.servers.kibana, config.apps[appName]);
|
||||
var appUrl = getUrl.noAuth(config.servers.kibana, config.apps[appName]);
|
||||
self.debug('navigating to ' + appName + ' url: ' + navUrl);
|
||||
self.debug('navigating to ' + appName + ' url: ' + appUrl);
|
||||
|
||||
var doNavigation = function (url) {
|
||||
return self.tryForTime(defaultTimeout, function () {
|
||||
|
@ -106,7 +103,7 @@ define(function (require) {
|
|||
});
|
||||
};
|
||||
|
||||
return doNavigation(navUrl)
|
||||
return doNavigation(appUrl)
|
||||
.then(function (currentUrl) {
|
||||
var lastUrl = currentUrl;
|
||||
return self.tryForTime(defaultTimeout, function () {
|
||||
|
@ -229,24 +226,26 @@ define(function (require) {
|
|||
|
||||
return function (reason) {
|
||||
var now = Date.now();
|
||||
var filename = ['failure', now, testName].join('_') + '.png';
|
||||
var fileName = ['failure', now, testName].join('_') + '.png';
|
||||
|
||||
return self.saveScreenshot(filename)
|
||||
return self.saveScreenshot(fileName, true)
|
||||
.finally(function () {
|
||||
throw new Error(reason);
|
||||
});
|
||||
};
|
||||
},
|
||||
|
||||
saveScreenshot: function saveScreenshot(filename) {
|
||||
saveScreenshot: function saveScreenshot(fileName, isFailure) {
|
||||
var self = this;
|
||||
var outDir = path.resolve('test', 'output');
|
||||
var outDir = path.resolve('test', 'screenshots');
|
||||
var directoryName = isFailure ? 'failure' : 'session';
|
||||
var directoryPath = path.resolve('test', 'screenshots', directoryName);
|
||||
var filePath = path.resolve(directoryPath, fileName);
|
||||
self.debug('Taking screenshot "' + filePath + '"');
|
||||
|
||||
return self.remote.takeScreenshot()
|
||||
.then(function writeScreenshot(data) {
|
||||
var filepath = path.resolve(outDir, filename);
|
||||
self.debug('Taking screenshot "' + filepath + '"');
|
||||
fs.writeFileSync(filepath, data);
|
||||
fs.writeFileSync(filePath, data);
|
||||
})
|
||||
.catch(function (err) {
|
||||
self.log('SCREENSHOT FAILED: ' + err);
|
||||
|
|
|
@ -3,13 +3,16 @@ define(function (require) {
|
|||
var config = require('intern').config;
|
||||
var Promise = require('bluebird');
|
||||
var Common = require('./common');
|
||||
var HeaderPage = require('./header_page');
|
||||
|
||||
var defaultTimeout = config.timeouts.default;
|
||||
var common;
|
||||
var headerPage;
|
||||
|
||||
function settingsPage(remote) {
|
||||
this.remote = remote;
|
||||
common = new Common(this.remote);
|
||||
headerPage = new HeaderPage(this.remote);
|
||||
}
|
||||
|
||||
settingsPage.prototype = {
|
||||
|
@ -238,6 +241,9 @@ define(function (require) {
|
|||
)
|
||||
.then(function (page) {
|
||||
return page.click();
|
||||
})
|
||||
.then(function () {
|
||||
return headerPage.getSpinnerDone();
|
||||
});
|
||||
},
|
||||
|
||||
|
|
|
@ -3,13 +3,16 @@ define(function (require) {
|
|||
var config = require('intern').config;
|
||||
var registerSuite = require('intern!object');
|
||||
var Common = require('./common');
|
||||
var HeaderPage = require('./header_page');
|
||||
|
||||
var defaultTimeout = config.timeouts.default;
|
||||
var common;
|
||||
var headerPage;
|
||||
|
||||
function VisualizePage(remote) {
|
||||
this.remote = remote;
|
||||
common = new Common(this.remote);
|
||||
headerPage = new HeaderPage(this.remote);
|
||||
}
|
||||
|
||||
VisualizePage.prototype = {
|
||||
|
@ -122,7 +125,10 @@ define(function (require) {
|
|||
return this.remote
|
||||
.setFindTimeout(defaultTimeout * 2)
|
||||
.findByClassName('kbn-timepicker-go')
|
||||
.click();
|
||||
.click()
|
||||
.then(function () {
|
||||
return headerPage.getSpinnerDone();
|
||||
});
|
||||
},
|
||||
|
||||
collapseChart: function collapseChart() {
|
||||
|
@ -151,7 +157,10 @@ define(function (require) {
|
|||
return this.remote
|
||||
.setFindTimeout(defaultTimeout)
|
||||
.findByCssSelector('li[ng-click="stepTwoMode=\'new\'"]')
|
||||
.click();
|
||||
.click()
|
||||
.then(function () {
|
||||
return headerPage.getSpinnerDone();
|
||||
});
|
||||
},
|
||||
|
||||
setValue: function setValue(newValue) {
|
||||
|
@ -178,7 +187,10 @@ define(function (require) {
|
|||
return this.remote
|
||||
.setFindTimeout(defaultTimeout)
|
||||
.findByCssSelector('li[ng-click="stepTwoMode=\'saved\'"]')
|
||||
.click();
|
||||
.click()
|
||||
.then(function () {
|
||||
return headerPage.getSpinnerDone();
|
||||
});
|
||||
},
|
||||
|
||||
selectSearch: function selectSearch(searchName) {
|
||||
|
@ -282,7 +294,10 @@ define(function (require) {
|
|||
return this.remote
|
||||
.setFindTimeout(defaultTimeout)
|
||||
.findByCssSelector('.btn-success')
|
||||
.click();
|
||||
.click()
|
||||
.then(function () {
|
||||
return headerPage.getSpinnerDone();
|
||||
});
|
||||
},
|
||||
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue