From c87aec3daecfbb7f974c110cd89bc185fbacd380 Mon Sep 17 00:00:00 2001 From: spalger Date: Tue, 12 Jan 2016 16:23:32 -0700 Subject: [PATCH 01/27] [mocha] move setup work into module with https://github.com/elastic/kibana/pull/5553 we added command line flags the told mocha it was supposed to use babel. This changes the strategy here and instead uses mocha's -r option (and it's mocha.opts file to specify it). This means that using mocha directly from the command line still works, and that we have a place where we can do other setup work. --- package.json | 4 ++-- tasks/config/simplemocha.js | 8 ++++++++ test/mocha.opts | 1 + test/mocha_setup.js | 1 + 4 files changed, 12 insertions(+), 2 deletions(-) create mode 100644 test/mocha.opts create mode 100644 test/mocha_setup.js diff --git a/package.json b/package.json index ff6ed171995f..937f1f2ebca1 100644 --- a/package.json +++ b/package.json @@ -55,8 +55,8 @@ "elasticsearch": "grunt esvm:dev:keepalive", "lint": "grunt eslint:source", "lintroller": "grunt eslint:fixSource", - "mocha": "mocha --compilers js:babel/register", - "mocha:debug": "mocha --debug-brk --compilers js:babel/register" + "mocha": "mocha", + "mocha:debug": "mocha --debug-brk" }, "repository": { "type": "git", diff --git a/tasks/config/simplemocha.js b/tasks/config/simplemocha.js index 3aacde1f64e2..c2b78a9c6b55 100644 --- a/tasks/config/simplemocha.js +++ b/tasks/config/simplemocha.js @@ -1,3 +1,11 @@ +var wrap = require('lodash').wrap; +var Mocha = require('mocha'); + +Mocha.prototype.run = wrap(Mocha.prototype.run, function (orig) { + require('../../test/mocha_setup'); + orig.call(this); +}); + module.exports = { options: { timeout: 10000, diff --git a/test/mocha.opts b/test/mocha.opts new file mode 100644 index 000000000000..40030a7420e8 --- /dev/null +++ b/test/mocha.opts @@ -0,0 +1 @@ +-r test/mocha_setup.js diff --git a/test/mocha_setup.js b/test/mocha_setup.js new file mode 100644 index 000000000000..03d0880b8862 --- /dev/null +++ b/test/mocha_setup.js @@ -0,0 +1 @@ +require('babel/register')(require('../src/optimize/babelOptions').node); From 680bf2102c7a46892923cc9db4da5429caff4ad0 Mon Sep 17 00:00:00 2001 From: spalger Date: Tue, 12 Jan 2016 16:28:49 -0700 Subject: [PATCH 02/27] [mocha] setup auto-release-sinon for server tests --- test/mocha_setup.js | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/test/mocha_setup.js b/test/mocha_setup.js index 03d0880b8862..ef355605341a 100644 --- a/test/mocha_setup.js +++ b/test/mocha_setup.js @@ -1 +1,31 @@ +var sinon = require('sinon'); +var autoRelease = require('auto-release-sinon'); + require('babel/register')(require('../src/optimize/babelOptions').node); + +var queuedAfterEachArgs = []; +Object.defineProperty(global, 'afterEach', { + configurable: true, + get() { return undefined; }, + set(afterEach) { + Object.defineProperty(global, 'afterEach', { + configurable: true, + writable: true, + value: afterEach + }); + + queuedAfterEachArgs.forEach(function (args) { + afterEach.apply(null, args); + }); + + return global.afterEach; + } +}); + +autoRelease.setupAutoRelease(sinon, function () { + if (!global.afterEach) { + queuedAfterEachArgs.push(Array.prototype.slice.call(arguments)); + } else { + global.afterEach.apply(this, arguments); + } +}); From 7b15ee05d1df291d316c22fff16f858f6eb0a28a Mon Sep 17 00:00:00 2001 From: spalger Date: Wed, 13 Jan 2016 16:50:55 -0700 Subject: [PATCH 03/27] [mochaSetup] added notes to explain the purpose for the workarounds in place --- tasks/config/simplemocha.js | 2 ++ test/mocha_setup.js | 10 ++++++++++ 2 files changed, 12 insertions(+) diff --git a/tasks/config/simplemocha.js b/tasks/config/simplemocha.js index c2b78a9c6b55..2016b2d93bbd 100644 --- a/tasks/config/simplemocha.js +++ b/tasks/config/simplemocha.js @@ -1,6 +1,8 @@ var wrap = require('lodash').wrap; var Mocha = require('mocha'); +// work around simplemocha's lack of a "--require" option. +// see https://github.com/yaymukund/grunt-simple-mocha/issues/50 for feature request. Mocha.prototype.run = wrap(Mocha.prototype.run, function (orig) { require('../../test/mocha_setup'); orig.call(this); diff --git a/test/mocha_setup.js b/test/mocha_setup.js index ef355605341a..8404ab88be2f 100644 --- a/test/mocha_setup.js +++ b/test/mocha_setup.js @@ -3,6 +3,16 @@ var autoRelease = require('auto-release-sinon'); require('babel/register')(require('../src/optimize/babelOptions').node); +// hook into the global afterEach variable to allow autoReleaseSinon to register +// an afterEach handler before mocha has exposed itself to the test files. +// +// This works by telling autoReleaseSinon to use a fake "afterEach" function. +// Rather than actually record an afterEach handler the function tracks all of +// the calls it received and queues them up in queuedAfterEachArgs. +// +// The global "afterEach" variable is also tracked, and once it is assigned by mocha +// the variable global is reconfigured to point directly to the new value (from mocha) +// and all of the queued invocations are executed. var queuedAfterEachArgs = []; Object.defineProperty(global, 'afterEach', { configurable: true, From d3fd053d0affacbaef6834b057eb6c596586ac14 Mon Sep 17 00:00:00 2001 From: spalger Date: Wed, 13 Jan 2016 16:51:29 -0700 Subject: [PATCH 04/27] [mochaOpts] use full option name --- test/mocha.opts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/mocha.opts b/test/mocha.opts index 40030a7420e8..72451b6e7f81 100644 --- a/test/mocha.opts +++ b/test/mocha.opts @@ -1 +1 @@ --r test/mocha_setup.js +--require test/mocha_setup.js From 777362569053615d851a09737d551a6bd2e8c307 Mon Sep 17 00:00:00 2001 From: spalger Date: Thu, 14 Jan 2016 10:32:28 -0700 Subject: [PATCH 05/27] [simplemocha] always perform mocha setup if grunt task is loaded --- tasks/config/simplemocha.js | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/tasks/config/simplemocha.js b/tasks/config/simplemocha.js index 2016b2d93bbd..80bbadd43335 100644 --- a/tasks/config/simplemocha.js +++ b/tasks/config/simplemocha.js @@ -1,12 +1,4 @@ -var wrap = require('lodash').wrap; -var Mocha = require('mocha'); - -// work around simplemocha's lack of a "--require" option. -// see https://github.com/yaymukund/grunt-simple-mocha/issues/50 for feature request. -Mocha.prototype.run = wrap(Mocha.prototype.run, function (orig) { - require('../../test/mocha_setup'); - orig.call(this); -}); +require('../../test/mocha_setup'); module.exports = { options: { From 24749258dbc92f32722a1a1158bbd09d0f01d3a5 Mon Sep 17 00:00:00 2001 From: Jonathan Budzenski Date: Wed, 20 Jan 2016 12:04:15 -0600 Subject: [PATCH 06/27] [build] Create os packages on jenkins --- tasks/build/index.js | 56 +++++++++++++++++++++++--------------------- tasks/jenkins.js | 3 ++- 2 files changed, 31 insertions(+), 28 deletions(-) diff --git a/tasks/build/index.js b/tasks/build/index.js index 22341871639d..f136f89179ea 100644 --- a/tasks/build/index.js +++ b/tasks/build/index.js @@ -1,31 +1,33 @@ module.exports = function (grunt) { let { flatten } = require('lodash'); - grunt.registerTask('build', flatten([ - '_build:getProps', - 'clean:build', - 'clean:target', - '_build:downloadNodeBuilds:start', - 'copy:devSource', - 'babel:build', - '_build:babelOptions', - '_build:installedPlugins', - '_build:packageJson', - '_build:readme', - '_build:installNpmDeps', - '_build:removePkgJsonDeps', - 'clean:testsFromModules', - 'clean:deepModuleBins', - 'clean:deepModules', - 'run:optimizeBuild', - 'stop:optimizeBuild', - '_build:downloadNodeBuilds:finish', - '_build:versionedLinks', - '_build:archives', - !grunt.option('os-packages') ? [] : [ - '_build:pleaseRun', - '_build:osPackages', - ], - '_build:shasums' - ])); + grunt.registerTask('build', 'Build packages', function (arg) { + grunt.task.run(flatten([ + '_build:getProps', + 'clean:build', + 'clean:target', + '_build:downloadNodeBuilds:start', + 'copy:devSource', + 'babel:build', + '_build:babelOptions', + '_build:installedPlugins', + '_build:packageJson', + '_build:readme', + '_build:installNpmDeps', + '_build:removePkgJsonDeps', + 'clean:testsFromModules', + 'clean:deepModuleBins', + 'clean:deepModules', + 'run:optimizeBuild', + 'stop:optimizeBuild', + '_build:downloadNodeBuilds:finish', + '_build:versionedLinks', + '_build:archives', + (grunt.option('os-packages') || arg === 'ospackages') ? [ + '_build:pleaseRun', + '_build:osPackages', + ] : [], + '_build:shasums' + ])); + }); }; diff --git a/tasks/jenkins.js b/tasks/jenkins.js index f043e92d0cc7..c76028a1e41e 100644 --- a/tasks/jenkins.js +++ b/tasks/jenkins.js @@ -3,7 +3,8 @@ module.exports = function (grunt) { grunt.registerTask('jenkins', 'Jenkins build script', compact([ 'test', - process.env.JOB_NAME === 'kibana_core' ? 'build' : null + // process.env.JOB_NAME === 'kibana_core' ? 'build' : null + 'build:ospackages' ])); }; From 4f827c83fac7482ae188bf320264eeb0fa1d6a96 Mon Sep 17 00:00:00 2001 From: Jonathan Budzenski Date: Wed, 20 Jan 2016 12:21:35 -0600 Subject: [PATCH 07/27] [build] Only build on core --- tasks/jenkins.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tasks/jenkins.js b/tasks/jenkins.js index c76028a1e41e..e3d3d9c3cc06 100644 --- a/tasks/jenkins.js +++ b/tasks/jenkins.js @@ -3,8 +3,7 @@ module.exports = function (grunt) { grunt.registerTask('jenkins', 'Jenkins build script', compact([ 'test', - // process.env.JOB_NAME === 'kibana_core' ? 'build' : null - 'build:ospackages' + process.env.JOB_NAME === 'kibana_core' ? 'build:ospackages' : null ])); }; From 82d993adff278a632e4cb9f52307af7a8ba474bb Mon Sep 17 00:00:00 2001 From: LeeDr Date: Mon, 25 Jan 2016 20:39:27 -0600 Subject: [PATCH 08/27] Add 5 tests for Discover shared links --- test/functional/apps/discover/_discover.js | 2 +- .../functional/apps/discover/_shared_links.js | 143 ++++++++++++++++++ test/functional/apps/discover/index.js | 3 + test/support/pages/Common.js | 4 + test/support/pages/DiscoverPage.js | 36 +++++ test/utils/getUrl.js | 10 +- 6 files changed, 196 insertions(+), 2 deletions(-) create mode 100644 test/functional/apps/discover/_shared_links.js diff --git a/test/functional/apps/discover/_discover.js b/test/functional/apps/discover/_discover.js index eced6ad88137..b0cf63a0748d 100644 --- a/test/functional/apps/discover/_discover.js +++ b/test/functional/apps/discover/_discover.js @@ -272,7 +272,7 @@ define(function (require) { var hasFailure = false; for (var y = 0; y < expectedBarChartData.length; y++) { stringResults += y + ': expected = ' + expectedBarChartData[y] + ', actual = ' + paths[y] + - ', Pass = ' + (Math.abs(expectedBarChartData[y] - paths[y]) < barHeightTolerance); + ', Pass = ' + (Math.abs(expectedBarChartData[y] - paths[y]) < barHeightTolerance) + '\n'; if ((Math.abs(expectedBarChartData[y] - paths[y]) > barHeightTolerance)) { hasFailure = true; }; diff --git a/test/functional/apps/discover/_shared_links.js b/test/functional/apps/discover/_shared_links.js new file mode 100644 index 000000000000..7b032e1d4dad --- /dev/null +++ b/test/functional/apps/discover/_shared_links.js @@ -0,0 +1,143 @@ +define(function (require) { + var Common = require('../../../support/pages/Common'); + var HeaderPage = require('../../../support/pages/HeaderPage'); + var SettingsPage = require('../../../support/pages/settings_page'); + var DiscoverPage = require('../../../support/pages/DiscoverPage'); + var expect = require('intern/dojo/node!expect.js'); + + return function (bdd, scenarioManager) { + bdd.describe('shared links', function describeIndexTests() { + var common; + var headerPage; + var settingsPage; + var discoverPage; + var baseUrl; + + bdd.before(function () { + common = new Common(this.remote); + headerPage = new HeaderPage(this.remote); + settingsPage = new SettingsPage(this.remote); + discoverPage = new DiscoverPage(this.remote); + + baseUrl = common.getHostPort(); + // baseUrl = 'http://localhost:5620'; + + var fromTime = '2015-09-19 06:31:44.000'; + var toTime = '2015-09-23 18:31:44.000'; + + // start each test with an empty kibana index + return scenarioManager.reload('emptyKibana') + // and load a set of makelogs data + .then(function loadIfEmptyMakelogs() { + return scenarioManager.loadIfEmpty('logstashFunctional'); + }) + .then(function (navigateTo) { + common.debug('navigateTo'); + return settingsPage.navigateTo(); + }) + .then(function () { + common.debug('createIndexPattern'); + return settingsPage.createIndexPattern(); + }) + .then(function () { + common.debug('discover'); + return common.navigateToApp('discover'); + }) + .then(function () { + common.debug('setAbsoluteRange'); + return headerPage.setAbsoluteRange(fromTime, toTime); + }) + .catch(common.handleError(this)); + }); + + + bdd.describe('shared link', function () { + var queryName1 = 'Query # 1'; + var fromTimeString = 'September 19th 2015, 06:31:44.000'; + var toTimeString = 'September 23rd 2015, 18:31:44.000'; + + bdd.it('should show "Share a link" caption', function () { + var expectedCaption = 'Share a link'; + return discoverPage.clickShare() + .then(function () { + return discoverPage.getShareCaption(); + }) + .then(function (actualCaption) { + expect(actualCaption).to.be(expectedCaption); + }) + .catch(common.handleError(this)); + }); + + + bdd.it('should show the correct formatted URL', function () { + // this is a BAD URL which includes the nav bar + 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))'; + return discoverPage.getSharedUrl() + .then(function (actualUrl) { + // strip the timestamp out of each URL + expect(actualUrl.replace(/_t=\d{13}/,'_t=TIMESTAMP')) + + .to.be(expectedUrl.replace(/_t=\d{13}/,'_t=TIMESTAMP')); + }) + .catch(common.handleError(this)); + }); + + bdd.it('should show toast message for copy to clipboard', function () { + var expectedMsg = 'Share search: URL copied to clipboard.'; + return discoverPage.clickCopyToClipboard() + .then(function () { + return headerPage.getToastMessage(); + }) + .then(function (toastMessage) { + expect(toastMessage).to.be(expectedMsg); + }) + .then(function () { + return headerPage.waitForToastMessageGone(); + }) + .catch(common.handleError(this)); + }); + + // TODO: verify clipboard contents + + bdd.it('shorten URL button should produce a short URL', function () { + var re = new RegExp(baseUrl + '/goto/[0-9a-f]{32}$'); + return discoverPage.clickShortenUrl() + .then(function () { + return common.tryForTime(20 * 1000, function tryingForTime() { + return discoverPage.getShortenedUrl() + .then(function (actualUrl) { + expect(actualUrl).to.match(re); + }); + }); + }) + .catch(common.handleError(this)); + }); + + // NOTE: This test has to run immediately after the test above + // 'shorten URL button should produce a short URL' + bdd.it('should show toast message for copy to clipboard', function () { + var expectedMsg = 'Share search: URL copied to clipboard.'; + return discoverPage.clickCopyToClipboard() + .then(function () { + return headerPage.getToastMessage(); + }) + .then(function (toastMessage) { + expect(toastMessage).to.be(expectedMsg); + }) + .then(function () { + return headerPage.waitForToastMessageGone(); + }) + .catch(common.handleError(this)); + }); + + + }); + }); + }; +}); diff --git a/test/functional/apps/discover/index.js b/test/functional/apps/discover/index.js index eef3af445e9a..c7885133e7e8 100644 --- a/test/functional/apps/discover/index.js +++ b/test/functional/apps/discover/index.js @@ -5,6 +5,7 @@ define(function (require) { var ScenarioManager = require('intern/dojo/node!../../../fixtures/scenarioManager'); var discoverTest = require('./_discover'); var fieldData = require('./_field_data'); + var sharedLinks = require('./_shared_links'); bdd.describe('discover app', function () { var scenarioManager; @@ -25,5 +26,7 @@ define(function (require) { fieldData(bdd, scenarioManager); + sharedLinks(bdd, scenarioManager); + }); }); diff --git a/test/support/pages/Common.js b/test/support/pages/Common.js index 070f4e041c89..a48f06f3ecc5 100644 --- a/test/support/pages/Common.js +++ b/test/support/pages/Common.js @@ -51,6 +51,10 @@ define(function (require) { Common.prototype = { constructor: Common, + getHostPort: function getHostPort() { + return getUrl.baseUrl(config.servers.kibana); + }, + navigateToApp: function (appName, testStatusPage) { var self = this; // navUrl includes user:password@ for use with Shield diff --git a/test/support/pages/DiscoverPage.js b/test/support/pages/DiscoverPage.js index cbaa0073f43a..3dcf3f55fbf1 100644 --- a/test/support/pages/DiscoverPage.js +++ b/test/support/pages/DiscoverPage.js @@ -175,6 +175,42 @@ define(function (require) { return thisTime .findAllByCssSelector('mark') .getVisibleText(); + }, + + clickShare: function clickShare() { + return thisTime + .findByCssSelector('button[aria-label="Share Search"]') + .click(); + }, + + clickShortenUrl: function clickShortenUrl() { + return thisTime + .findByCssSelector('button.shorten-button') + .click(); + }, + + clickCopyToClipboard: function clickCopyToClipboard() { + return thisTime + .findByCssSelector('button.clipboard-button') + .click(); + }, + + getShareCaption: function getShareCaption() { + return thisTime + .findByCssSelector('div.form-group > label') + .getVisibleText(); + }, + + getSharedUrl: function getSharedUrl() { + return thisTime + .findByCssSelector('.url') + .getProperty('baseURI'); + }, + + getShortenedUrl: function getShortenedUrl() { + return thisTime + .findByCssSelector('.url') + .getProperty('value'); } }; diff --git a/test/utils/getUrl.js b/test/utils/getUrl.js index 5e69bb870716..3a1b172d7fbc 100644 --- a/test/utils/getUrl.js +++ b/test/utils/getUrl.js @@ -8,7 +8,8 @@ var url = require('url'); * { * protocol: 'http', * hostname: 'localhost', -* port: 9220 +* port: 9220, +* auth: shield.kibanaUser.username + ':' + shield.kibanaUser.password * } * @param {object} app The params to append * example: @@ -31,3 +32,10 @@ getUrl.noAuth = function getUrlNoAuth(config, app) { }); return getUrl(config, app); }; + +getUrl.baseUrl = function getBaseUrl(config) { + config = _.pick(config, function (val, param) { + return param !== 'auth' & param !== 'pathname' & param !== 'hash'; + }); + return url.format(config); +}; From 3ea248c3eebcecf2417fbcdf8aaf1e57d1ec3211 Mon Sep 17 00:00:00 2001 From: LeeDr Date: Mon, 25 Jan 2016 20:39:27 -0600 Subject: [PATCH 09/27] Add 5 tests for Discover shared links --- test/functional/apps/discover/_discover.js | 2 +- .../functional/apps/discover/_shared_links.js | 143 ++++++++++++++++++ test/functional/apps/discover/index.js | 3 + test/support/pages/Common.js | 4 + test/support/pages/DiscoverPage.js | 36 +++++ test/utils/getUrl.js | 10 +- 6 files changed, 196 insertions(+), 2 deletions(-) create mode 100644 test/functional/apps/discover/_shared_links.js diff --git a/test/functional/apps/discover/_discover.js b/test/functional/apps/discover/_discover.js index eced6ad88137..b0cf63a0748d 100644 --- a/test/functional/apps/discover/_discover.js +++ b/test/functional/apps/discover/_discover.js @@ -272,7 +272,7 @@ define(function (require) { var hasFailure = false; for (var y = 0; y < expectedBarChartData.length; y++) { stringResults += y + ': expected = ' + expectedBarChartData[y] + ', actual = ' + paths[y] + - ', Pass = ' + (Math.abs(expectedBarChartData[y] - paths[y]) < barHeightTolerance); + ', Pass = ' + (Math.abs(expectedBarChartData[y] - paths[y]) < barHeightTolerance) + '\n'; if ((Math.abs(expectedBarChartData[y] - paths[y]) > barHeightTolerance)) { hasFailure = true; }; diff --git a/test/functional/apps/discover/_shared_links.js b/test/functional/apps/discover/_shared_links.js new file mode 100644 index 000000000000..7b032e1d4dad --- /dev/null +++ b/test/functional/apps/discover/_shared_links.js @@ -0,0 +1,143 @@ +define(function (require) { + var Common = require('../../../support/pages/Common'); + var HeaderPage = require('../../../support/pages/HeaderPage'); + var SettingsPage = require('../../../support/pages/settings_page'); + var DiscoverPage = require('../../../support/pages/DiscoverPage'); + var expect = require('intern/dojo/node!expect.js'); + + return function (bdd, scenarioManager) { + bdd.describe('shared links', function describeIndexTests() { + var common; + var headerPage; + var settingsPage; + var discoverPage; + var baseUrl; + + bdd.before(function () { + common = new Common(this.remote); + headerPage = new HeaderPage(this.remote); + settingsPage = new SettingsPage(this.remote); + discoverPage = new DiscoverPage(this.remote); + + baseUrl = common.getHostPort(); + // baseUrl = 'http://localhost:5620'; + + var fromTime = '2015-09-19 06:31:44.000'; + var toTime = '2015-09-23 18:31:44.000'; + + // start each test with an empty kibana index + return scenarioManager.reload('emptyKibana') + // and load a set of makelogs data + .then(function loadIfEmptyMakelogs() { + return scenarioManager.loadIfEmpty('logstashFunctional'); + }) + .then(function (navigateTo) { + common.debug('navigateTo'); + return settingsPage.navigateTo(); + }) + .then(function () { + common.debug('createIndexPattern'); + return settingsPage.createIndexPattern(); + }) + .then(function () { + common.debug('discover'); + return common.navigateToApp('discover'); + }) + .then(function () { + common.debug('setAbsoluteRange'); + return headerPage.setAbsoluteRange(fromTime, toTime); + }) + .catch(common.handleError(this)); + }); + + + bdd.describe('shared link', function () { + var queryName1 = 'Query # 1'; + var fromTimeString = 'September 19th 2015, 06:31:44.000'; + var toTimeString = 'September 23rd 2015, 18:31:44.000'; + + bdd.it('should show "Share a link" caption', function () { + var expectedCaption = 'Share a link'; + return discoverPage.clickShare() + .then(function () { + return discoverPage.getShareCaption(); + }) + .then(function (actualCaption) { + expect(actualCaption).to.be(expectedCaption); + }) + .catch(common.handleError(this)); + }); + + + bdd.it('should show the correct formatted URL', function () { + // this is a BAD URL which includes the nav bar + 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))'; + return discoverPage.getSharedUrl() + .then(function (actualUrl) { + // strip the timestamp out of each URL + expect(actualUrl.replace(/_t=\d{13}/,'_t=TIMESTAMP')) + + .to.be(expectedUrl.replace(/_t=\d{13}/,'_t=TIMESTAMP')); + }) + .catch(common.handleError(this)); + }); + + bdd.it('should show toast message for copy to clipboard', function () { + var expectedMsg = 'Share search: URL copied to clipboard.'; + return discoverPage.clickCopyToClipboard() + .then(function () { + return headerPage.getToastMessage(); + }) + .then(function (toastMessage) { + expect(toastMessage).to.be(expectedMsg); + }) + .then(function () { + return headerPage.waitForToastMessageGone(); + }) + .catch(common.handleError(this)); + }); + + // TODO: verify clipboard contents + + bdd.it('shorten URL button should produce a short URL', function () { + var re = new RegExp(baseUrl + '/goto/[0-9a-f]{32}$'); + return discoverPage.clickShortenUrl() + .then(function () { + return common.tryForTime(20 * 1000, function tryingForTime() { + return discoverPage.getShortenedUrl() + .then(function (actualUrl) { + expect(actualUrl).to.match(re); + }); + }); + }) + .catch(common.handleError(this)); + }); + + // NOTE: This test has to run immediately after the test above + // 'shorten URL button should produce a short URL' + bdd.it('should show toast message for copy to clipboard', function () { + var expectedMsg = 'Share search: URL copied to clipboard.'; + return discoverPage.clickCopyToClipboard() + .then(function () { + return headerPage.getToastMessage(); + }) + .then(function (toastMessage) { + expect(toastMessage).to.be(expectedMsg); + }) + .then(function () { + return headerPage.waitForToastMessageGone(); + }) + .catch(common.handleError(this)); + }); + + + }); + }); + }; +}); diff --git a/test/functional/apps/discover/index.js b/test/functional/apps/discover/index.js index eef3af445e9a..c7885133e7e8 100644 --- a/test/functional/apps/discover/index.js +++ b/test/functional/apps/discover/index.js @@ -5,6 +5,7 @@ define(function (require) { var ScenarioManager = require('intern/dojo/node!../../../fixtures/scenarioManager'); var discoverTest = require('./_discover'); var fieldData = require('./_field_data'); + var sharedLinks = require('./_shared_links'); bdd.describe('discover app', function () { var scenarioManager; @@ -25,5 +26,7 @@ define(function (require) { fieldData(bdd, scenarioManager); + sharedLinks(bdd, scenarioManager); + }); }); diff --git a/test/support/pages/Common.js b/test/support/pages/Common.js index 070f4e041c89..a48f06f3ecc5 100644 --- a/test/support/pages/Common.js +++ b/test/support/pages/Common.js @@ -51,6 +51,10 @@ define(function (require) { Common.prototype = { constructor: Common, + getHostPort: function getHostPort() { + return getUrl.baseUrl(config.servers.kibana); + }, + navigateToApp: function (appName, testStatusPage) { var self = this; // navUrl includes user:password@ for use with Shield diff --git a/test/support/pages/DiscoverPage.js b/test/support/pages/DiscoverPage.js index cbaa0073f43a..3dcf3f55fbf1 100644 --- a/test/support/pages/DiscoverPage.js +++ b/test/support/pages/DiscoverPage.js @@ -175,6 +175,42 @@ define(function (require) { return thisTime .findAllByCssSelector('mark') .getVisibleText(); + }, + + clickShare: function clickShare() { + return thisTime + .findByCssSelector('button[aria-label="Share Search"]') + .click(); + }, + + clickShortenUrl: function clickShortenUrl() { + return thisTime + .findByCssSelector('button.shorten-button') + .click(); + }, + + clickCopyToClipboard: function clickCopyToClipboard() { + return thisTime + .findByCssSelector('button.clipboard-button') + .click(); + }, + + getShareCaption: function getShareCaption() { + return thisTime + .findByCssSelector('div.form-group > label') + .getVisibleText(); + }, + + getSharedUrl: function getSharedUrl() { + return thisTime + .findByCssSelector('.url') + .getProperty('baseURI'); + }, + + getShortenedUrl: function getShortenedUrl() { + return thisTime + .findByCssSelector('.url') + .getProperty('value'); } }; diff --git a/test/utils/getUrl.js b/test/utils/getUrl.js index 5e69bb870716..3a1b172d7fbc 100644 --- a/test/utils/getUrl.js +++ b/test/utils/getUrl.js @@ -8,7 +8,8 @@ var url = require('url'); * { * protocol: 'http', * hostname: 'localhost', -* port: 9220 +* port: 9220, +* auth: shield.kibanaUser.username + ':' + shield.kibanaUser.password * } * @param {object} app The params to append * example: @@ -31,3 +32,10 @@ getUrl.noAuth = function getUrlNoAuth(config, app) { }); return getUrl(config, app); }; + +getUrl.baseUrl = function getBaseUrl(config) { + config = _.pick(config, function (val, param) { + return param !== 'auth' & param !== 'pathname' & param !== 'hash'; + }); + return url.format(config); +}; From 5073aa520c11e8d498697fbcfc20a4a7571c52fc Mon Sep 17 00:00:00 2001 From: LeeDr Date: Tue, 26 Jan 2016 12:30:09 -0600 Subject: [PATCH 10/27] Share expectedToastMessage variable between tests, and comment about Firefox version changes message. --- test/functional/apps/discover/_shared_links.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/functional/apps/discover/_shared_links.js b/test/functional/apps/discover/_shared_links.js index 7b032e1d4dad..4d04b2b67fb8 100644 --- a/test/functional/apps/discover/_shared_links.js +++ b/test/functional/apps/discover/_shared_links.js @@ -12,6 +12,8 @@ define(function (require) { var settingsPage; var discoverPage; var baseUrl; + // var expectedToastMessage = 'Share search: URL selected. Press Ctrl+C to copy.'; pre-Firefox 41 + var expectedToastMessage = 'Share search: URL copied to clipboard.'; bdd.before(function () { common = new Common(this.remote); @@ -89,13 +91,12 @@ define(function (require) { }); bdd.it('should show toast message for copy to clipboard', function () { - var expectedMsg = 'Share search: URL copied to clipboard.'; return discoverPage.clickCopyToClipboard() .then(function () { return headerPage.getToastMessage(); }) .then(function (toastMessage) { - expect(toastMessage).to.be(expectedMsg); + expect(toastMessage).to.be(expectedToastMessage); }) .then(function () { return headerPage.waitForToastMessageGone(); @@ -122,13 +123,12 @@ define(function (require) { // NOTE: This test has to run immediately after the test above // 'shorten URL button should produce a short URL' bdd.it('should show toast message for copy to clipboard', function () { - var expectedMsg = 'Share search: URL copied to clipboard.'; return discoverPage.clickCopyToClipboard() .then(function () { return headerPage.getToastMessage(); }) .then(function (toastMessage) { - expect(toastMessage).to.be(expectedMsg); + expect(toastMessage).to.be(expectedToastMessage); }) .then(function () { return headerPage.waitForToastMessageGone(); From 78d004be2a7e5fe1e6cb3e38374a7267f4a7ff58 Mon Sep 17 00:00:00 2001 From: michaelcheng429 Date: Tue, 26 Jan 2016 14:49:45 -0600 Subject: [PATCH 11/27] minor copy improvements (typos) --- .../components/field_chooser/discover_field.js | 4 ++-- .../settings/sections/advanced/advanced_row.html | 12 ++++++------ .../settings/sections/advanced/advanced_row.js | 8 ++++---- .../public/settings/sections/indices/index.html | 2 +- .../kibana/public/settings/sections/indices/index.js | 4 ++-- src/ui/public/state_management/state.js | 6 +++--- src/ui/public/time_buckets/time_buckets.js | 4 ++-- 7 files changed, 20 insertions(+), 20 deletions(-) diff --git a/src/plugins/kibana/public/discover/components/field_chooser/discover_field.js b/src/plugins/kibana/public/discover/components/field_chooser/discover_field.js index 1f9bf7b62235..2411e915e149 100644 --- a/src/plugins/kibana/public/discover/components/field_chooser/discover_field.js +++ b/src/plugins/kibana/public/discover/components/field_chooser/discover_field.js @@ -60,11 +60,11 @@ define(function (require) { }; $scope.toggleDisplay = function (field) { - // inheritted param to fieldChooser + // This is inherited from fieldChooser $scope.toggle(field.name); if (field.display) $scope.increaseFieldCounter(field); - // we are now displaying the field, kill it's details + // we are now displaying the field, kill its details if (field.details) { $scope.toggleDetails(field); } diff --git a/src/plugins/kibana/public/settings/sections/advanced/advanced_row.html b/src/plugins/kibana/public/settings/sections/advanced/advanced_row.html index 1bd6edaac644..4b57f3304114 100644 --- a/src/plugins/kibana/public/settings/sections/advanced/advanced_row.html +++ b/src/plugins/kibana/public/settings/sections/advanced/advanced_row.html @@ -16,7 +16,7 @@
@@ -65,7 +65,7 @@
- + {{conf.value || conf.defVal}} {{(conf.value || conf.defVal).join(', ')}} {{conf.value === undefined ? conf.defVal : conf.value}} @@ -74,7 +74,7 @@