[7.x] Remove karma (#73126) (#73328)

Co-authored-by: spalger <spalger@users.noreply.github.com>
Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>
This commit is contained in:
Spencer 2020-07-28 10:19:26 -07:00 committed by GitHub
parent 104234204a
commit 60ec901f64
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
54 changed files with 76 additions and 2267 deletions

View file

@ -26,8 +26,6 @@ root)
|Functional
|`test/*integration/**/config.js` `test/*functional/**/config.js` `test/accessibility/config.js`
|`yarn test:ftr:server --config test/[directory]/config.js``yarn test:ftr:runner --config test/[directory]/config.js --grep=regexp`
|Karma |`src/**/public/__tests__/*.js` |`yarn test:karma:debug`
|===
For X-Pack tests located in `x-pack/` see

View file

@ -95,38 +95,6 @@ to proceed in this mode.
node scripts/mocha --debug <file>
----
With `yarn test:karma`, you can run only the browser tests. Coverage
reports are available for browser tests by running
`yarn test:coverage`. You can find the results under the `coverage/`
directory that will be created upon completion.
[source,bash]
----
yarn test:karma
----
Using `yarn test:karma:debug` initializes an environment for debugging
the browser tests. Includes an dedicated instance of the {kib} server
for building the test bundle, and a karma server. When running this task
the build is optimized for the first time and then a karma-owned
instance of the browser is opened. Click the "`debug`" button to open a
new tab that executes the unit tests.
[source,bash]
----
yarn test:karma:debug
----
In the screenshot below, youll notice the URL is
`localhost:9876/debug.html`. You can append a `grep` query parameter
to this URL and set it to a string value which will be used to exclude
tests which dont match. For example, if you changed the URL to
`localhost:9876/debug.html?query=my test` and then refreshed the
browser, youd only see tests run which contain "`my test`" in the test
description.
image:http://i.imgur.com/DwHxgfq.png[Browser test debugging]
[discrete]
=== Unit Testing Plugins
@ -141,5 +109,4 @@ command from your plugin:
[source,bash]
----
yarn test:mocha
yarn test:karma:debug # remove the debug flag to run them once and close
----

View file

@ -41,8 +41,6 @@
"kbn": "node scripts/kbn",
"es": "node scripts/es",
"test": "grunt test",
"test:karma": "grunt test:karma",
"test:karma:debug": "grunt test:karmaDebug",
"test:jest": "node scripts/jest",
"test:jest_integration": "node scripts/jest_integration",
"test:mocha": "node scripts/mocha",
@ -442,7 +440,6 @@
"grunt-available-tasks": "^0.6.3",
"grunt-cli": "^1.2.0",
"grunt-contrib-watch": "^1.1.0",
"grunt-karma": "^3.0.2",
"grunt-peg": "^2.0.1",
"grunt-run": "0.8.1",
"gulp-babel": "^8.0.0",
@ -460,14 +457,6 @@
"jest-raw-loader": "^1.0.1",
"jimp": "^0.9.6",
"json5": "^1.0.1",
"karma": "5.0.2",
"karma-chrome-launcher": "2.2.0",
"karma-coverage": "1.1.2",
"karma-firefox-launcher": "1.1.0",
"karma-ie-launcher": "1.0.0",
"karma-junit-reporter": "1.2.0",
"karma-mocha": "2.0.0",
"karma-safari-launcher": "1.0.0",
"license-checker": "^16.0.0",
"listr": "^0.14.1",
"load-grunt-config": "^3.0.1",

View file

@ -28,13 +28,9 @@ exports.getWebpackConfig = function (kibanaPath, projectRoot, config) {
const alias = {
// Kibana defaults https://github.com/elastic/kibana/blob/6998f074542e8c7b32955db159d15661aca253d7/src/legacy/ui/ui_bundler_env.js#L30-L36
ui: fromKibana('src/legacy/ui/public'),
test_harness: fromKibana('src/test_harness/public'),
// Dev defaults for test bundle https://github.com/elastic/kibana/blob/6998f074542e8c7b32955db159d15661aca253d7/src/core_plugins/tests_bundle/index.js#L73-L78
ng_mock$: fromKibana('src/test_utils/public/ng_mock'),
'angular-mocks$': fromKibana(
'src/legacy/core_plugins/tests_bundle/webpackShims/angular-mocks.js'
),
fixtures: fromKibana('src/fixtures'),
test_utils: fromKibana('src/test_utils/public'),
};

View file

@ -71,10 +71,6 @@ Generated plugins receive a handful of scripts that can be used during developme
Build a distributable archive of your plugin.
- `yarn test:karma`
Run the browser tests in a real web browser.
- `yarn test:mocha`
Run the server tests using mocha.

View file

@ -30,7 +30,6 @@ $ plugin-helpers help
start Start kibana and have it include this plugin
build [options] [files...] Build a distributable archive
test Run the server and browser tests
test:karma [options] Run the browser tests in a real web browser
test:mocha [files...] Run the server tests using mocha
Options:

View file

@ -62,25 +62,6 @@ program
}))
);
program
.command('test')
.description('Run the server and browser tests')
.on('--help', docs('test/all'))
.action(createCommanderAction('testAll'));
program
.command('test:karma')
.description('Run the browser tests in a real web browser')
.option('--dev', 'Enable dev mode, keeps the test server running')
.option('-p, --plugins <plugin-ids>', "Manually specify which plugins' test bundles to run")
.on('--help', docs('test/karma'))
.action(
createCommanderAction('testKarma', (command) => ({
dev: Boolean(command.dev),
plugins: command.plugins,
}))
);
program
.command('test:mocha [files...]')
.description('Run the server tests using mocha')

View file

@ -19,23 +19,17 @@
import { buildTask } from '../tasks/build';
import { startTask } from '../tasks/start';
import { testAllTask } from '../tasks/test/all';
import { testKarmaTask } from '../tasks/test/karma';
import { testMochaTask } from '../tasks/test/mocha';
// define a tasks interface that we can extend in the tests
export interface Tasks {
build: typeof buildTask;
start: typeof startTask;
testAll: typeof testAllTask;
testKarma: typeof testKarmaTask;
testMocha: typeof testMochaTask;
}
export const tasks: Tasks = {
build: buildTask,
start: startTask,
testAll: testAllTask,
testKarma: testKarmaTask,
testMocha: testMochaTask,
};

View file

@ -1,3 +0,0 @@
Runs both the mocha and karma tests, in that order.
This is just a simple caller to both `test/mocha` and `test/karma`

View file

@ -1,20 +0,0 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
export * from './test_all_task';

View file

@ -1,25 +0,0 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { TaskContext } from '../../../lib';
export function testAllTask({ run }: TaskContext) {
run('testMocha');
run('testKarma');
}

View file

@ -1,60 +0,0 @@
writing tests
=============
Browser tests are written just like server tests, they are just executed differently.
- place tests near the code they test, in `__tests__` directories throughout
the public directory
- Use the same bdd-style `describe()` and `it()`
api to define the suites and cases of your tests.
```js
describe('some portion of your code', function () {
it('should do this thing', function () {
expect(true).to.be(false);
});
});
```
starting the test runner
========================
Under the covers this command uses the `test:karma` task from kibana. This will execute
your tasks once and exit when complete.
When run with the `--dev` option, the command uses the `test:karma:debug` task from kibana.
This task sets-up a test runner that will watch your code for changes and rebuild your
tests when necessary. You access the test runner through a browser that it starts itself
(via Karma).
If your plugin consists of a number of internal plugins, you may wish to keep the tests
isolated to a specific plugin or plugins, instead of executing all of the tests. To do this,
use `--plugins` and passing the plugins you would like to test. Multiple plugins can be
specified by separating them with commas.
running the tests
=================
Once the test runner has started you a new browser window should be opened and you should
see a message saying "connected". Next to that is a "DEBUG" button. This button will open
an interactive version of your tests that you can refresh, inspects, and otherwise debug
while you write your tests.
focus on the task at hand
=========================
To limit the tests that run you can either:
1. use the ?grep= query string to filter the test cases/suites by name
2. Click the suite title or (play) button next to test output
3. Add `.only` to your `describe()` or `it()` calls:
```js
describe.only('suite name', function () {
// ...
});
```

View file

@ -1,20 +0,0 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
export * from './test_karma_task';

View file

@ -1,42 +0,0 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { execFileSync } from 'child_process';
import { TaskContext } from '../../../lib';
import { winCmd } from '../../../lib/win_cmd';
export function testKarmaTask({ plugin, options }: TaskContext) {
options = options || {};
const kbnServerArgs = ['--kbnServer.plugin-path=' + plugin.root];
if (options.plugins) {
kbnServerArgs.push('--kbnServer.tests_bundle.pluginId=' + options.plugins);
} else {
kbnServerArgs.push('--kbnServer.tests_bundle.pluginId=' + plugin.id);
}
const task = options.dev ? 'test:karma:debug' : 'test:karma';
const args = [task].concat(kbnServerArgs);
execFileSync(winCmd('yarn'), args, {
cwd: plugin.kibanaRoot,
stdio: ['ignore', 1, 2],
});
}

View file

@ -21,6 +21,5 @@ const Fs = jest.requireActual('fs');
export const FTR_REPORT = Fs.readFileSync(require.resolve('./ftr_report.xml'), 'utf8');
export const JEST_REPORT = Fs.readFileSync(require.resolve('./jest_report.xml'), 'utf8');
export const KARMA_REPORT = Fs.readFileSync(require.resolve('./karma_report.xml'), 'utf8');
export const MOCHA_REPORT = Fs.readFileSync(require.resolve('./mocha_report.xml'), 'utf8');
export const CYPRESS_REPORT = Fs.readFileSync(require.resolve('./cypress_report.xml'), 'utf8');

View file

@ -1,33 +0,0 @@
<?xml version="1.0"?>
<testsuite name="Chrome 75.0.3770 (Mac OS X 10.14.5)" package="" timestamp="2019-07-02T19:53:21" id="0" hostname="spalger.lan" tests="648" errors="0" failures="4" time="1.759">
<properties>
<property name="browser.fullName" value="Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36"/>
</properties>
<testcase name="collectBranch() should return an array with bucket objects" time="0.014" classname="Browser Unit Tests.collectBranch()"/>
<testcase name="Vis-Editor-Agg-Params plugin directive should hide custom label parameter" time="0" classname="Browser Unit Tests.Vis-Editor-Agg-Params plugin directive">
<skipped/>
</testcase>
<testcase name="CoordinateMapsVisualizationTest CoordinateMapsVisualization - basics should initialize OK" time="0.265" classname="Browser Unit Tests.CoordinateMapsVisualizationTest">
<failure type="">Error: expected 7069 to be below 64
at Assertion.__kbnBundles__.tests../packages/kbn-expect/expect.js.Assertion.assert (http://localhost:5610/bundles/tests.bundle.js?shards=4&amp;shard_num=1:13671:11)
at Assertion.__kbnBundles__.tests../packages/kbn-expect/expect.js.Assertion.lessThan.Assertion.below (http://localhost:5610/bundles/tests.bundle.js?shards=4&amp;shard_num=1:13891:8)
at Function.lessThan (http://localhost:5610/bundles/tests.bundle.js?shards=4&amp;shard_num=1:14078:15)
at _callee3$ (http://localhost:5610/bundles/tests.bundle.js?shards=4&amp;shard_num=1:158985:60)
at tryCatch (webpack://%5Bname%5D/./node_modules/regenerator-runtime/runtime.js?:62:40)
at Generator.invoke [as _invoke] (webpack://%5Bname%5D/./node_modules/regenerator-runtime/runtime.js?:288:22)
at Generator.prototype.&lt;computed&gt; [as next] (webpack://%5Bname%5D/./node_modules/regenerator-runtime/runtime.js?:114:21)
at asyncGeneratorStep (http://localhost:5610/bundles/tests.bundle.js?shards=4&amp;shard_num=1:158772:103)
at _next (http://localhost:5610/bundles/tests.bundle.js?shards=4&amp;shard_num=1:158774:194)
</failure>
</testcase>
<testcase name="CoordinateMapsVisualizationTest CoordinateMapsVisualization - basics should toggle to Heatmap OK" time="0.055" classname="Browser Unit Tests.CoordinateMapsVisualizationTest"/>
<testcase name="VegaParser._parseSchema should warn on vega-lite version too new to be supported" time="0.001" classname="Browser Unit Tests.VegaParser·_parseSchema"/>
<system-out>
<![CDATA[Chrome 75.0.3770 (Mac OS X 10.14.5) LOG: 'ready to load tests for shard 1 of 4'
,Chrome 75.0.3770 (Mac OS X 10.14.5) WARN: 'Unmatched GET to http://localhost:9876/api/interpreter/fns'
...
]]>
</system-out>
<system-err/>
</testsuite>

View file

@ -39,13 +39,7 @@ jest.mock('fs', () => {
};
});
import {
FTR_REPORT,
JEST_REPORT,
MOCHA_REPORT,
KARMA_REPORT,
CYPRESS_REPORT,
} from './__fixtures__';
import { FTR_REPORT, JEST_REPORT, MOCHA_REPORT, CYPRESS_REPORT } from './__fixtures__';
import { parseTestReport } from './test_report';
import { addMessagesToReport } from './add_messages_to_report';
@ -338,79 +332,3 @@ it('rewrites cypress reports with minimal changes', async () => {
`);
});
it('rewrites karma reports with minimal changes', async () => {
const xml = await addMessagesToReport({
report: await parseTestReport(KARMA_REPORT),
messages: [
{
name:
'CoordinateMapsVisualizationTest CoordinateMapsVisualization - basics should initialize OK',
classname: 'Browser Unit Tests.CoordinateMapsVisualizationTest',
message: 'foo bar',
},
],
log,
reportPath: Path.resolve(__dirname, './__fixtures__/karma_report.xml'),
});
expect(createPatch('karma.xml', KARMA_REPORT, xml, { context: 0 })).toMatchInlineSnapshot(`
Index: karma.xml
===================================================================
--- karma.xml [object Object]
+++ karma.xml
@@ -1,5 +1,5 @@
-?xml version="1.0"?
+?xml version="1.0" encoding="utf-8"?
testsuite name="Chrome 75.0.3770 (Mac OS X 10.14.5)" package="" timestamp="2019-07-02T19:53:21" id="0" hostname="spalger.lan" tests="648" errors="0" failures="4" time="1.759"
properties
property name="browser.fullName" value="Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36"/
/properties
@@ -7,27 +7,31 @@
testcase name="Vis-Editor-Agg-Params plugin directive should hide custom label parameter" time="0" classname="Browser Unit Tests.Vis-Editor-Agg-Params plugin directive"
skipped/
/testcase
testcase name="CoordinateMapsVisualizationTest CoordinateMapsVisualization - basics should initialize OK" time="0.265" classname="Browser Unit Tests.CoordinateMapsVisualizationTest"
- failure type=""Error: expected 7069 to be below 64
- at Assertion.__kbnBundles__.tests../packages/kbn-expect/expect.js.Assertion.assert (http://localhost:5610/bundles/tests.bundle.js?shards=4&amp;shard_num=1:13671:11)
- at Assertion.__kbnBundles__.tests../packages/kbn-expect/expect.js.Assertion.lessThan.Assertion.below (http://localhost:5610/bundles/tests.bundle.js?shards=4&amp;shard_num=1:13891:8)
- at Function.lessThan (http://localhost:5610/bundles/tests.bundle.js?shards=4&amp;shard_num=1:14078:15)
- at _callee3$ (http://localhost:5610/bundles/tests.bundle.js?shards=4&amp;shard_num=1:158985:60)
+ failure type=""![CDATA[Error: expected 7069 to be below 64
+ at Assertion.__kbnBundles__.tests../packages/kbn-expect/expect.js.Assertion.assert (http://localhost:5610/bundles/tests.bundle.js?shards=4&shard_num=1:13671:11)
+ at Assertion.__kbnBundles__.tests../packages/kbn-expect/expect.js.Assertion.lessThan.Assertion.below (http://localhost:5610/bundles/tests.bundle.js?shards=4&shard_num=1:13891:8)
+ at Function.lessThan (http://localhost:5610/bundles/tests.bundle.js?shards=4&shard_num=1:14078:15)
+ at _callee3$ (http://localhost:5610/bundles/tests.bundle.js?shards=4&shard_num=1:158985:60)
at tryCatch (webpack://%5Bname%5D/./node_modules/regenerator-runtime/runtime.js?:62:40)
at Generator.invoke [as _invoke] (webpack://%5Bname%5D/./node_modules/regenerator-runtime/runtime.js?:288:22)
- at Generator.prototype.&lt;computed&gt; [as next] (webpack://%5Bname%5D/./node_modules/regenerator-runtime/runtime.js?:114:21)
- at asyncGeneratorStep (http://localhost:5610/bundles/tests.bundle.js?shards=4&amp;shard_num=1:158772:103)
- at _next (http://localhost:5610/bundles/tests.bundle.js?shards=4&amp;shard_num=1:158774:194)
-/failure
+ at Generator.prototype.computed [as next] (webpack://%5Bname%5D/./node_modules/regenerator-runtime/runtime.js?:114:21)
+ at asyncGeneratorStep (http://localhost:5610/bundles/tests.bundle.js?shards=4&shard_num=1:158772:103)
+ at _next (http://localhost:5610/bundles/tests.bundle.js?shards=4&shard_num=1:158774:194)
+]]/failure
+ system-outFailed Tests Reporter:
+ - foo bar
+
+/system-out
/testcase
testcase name="CoordinateMapsVisualizationTest CoordinateMapsVisualization - basics should toggle to Heatmap OK" time="0.055" classname="Browser Unit Tests.CoordinateMapsVisualizationTest"/
testcase name="VegaParser._parseSchema should warn on vega-lite version too new to be supported" time="0.001" classname="Browser Unit Tests.VegaParser·_parseSchema"/
system-out
- ![CDATA[Chrome 75.0.3770 (Mac OS X 10.14.5) LOG: 'ready to load tests for shard 1 of 4'
+ Chrome 75.0.3770 (Mac OS X 10.14.5) LOG: 'ready to load tests for shard 1 of 4'
,Chrome 75.0.3770 (Mac OS X 10.14.5) WARN: 'Unmatched GET to http://localhost:9876/api/interpreter/fns'
...
-]]
+
/system-out
system-err/
-/testsuite
+/testsuite
\\ No newline at end of file
`);
});

View file

@ -19,7 +19,7 @@
import { getFailures } from './get_failures';
import { parseTestReport } from './test_report';
import { FTR_REPORT, JEST_REPORT, KARMA_REPORT, MOCHA_REPORT } from './__fixtures__';
import { FTR_REPORT, JEST_REPORT, MOCHA_REPORT } from './__fixtures__';
it('discovers failures in ftr report', async () => {
const failures = getFailures(await parseTestReport(FTR_REPORT));
@ -85,31 +85,6 @@ it('discovers failures in jest report', async () => {
`);
});
it('discovers failures in karma report', async () => {
const failures = getFailures(await parseTestReport(KARMA_REPORT));
expect(failures).toMatchInlineSnapshot(`
Array [
Object {
"classname": "Browser Unit Tests.CoordinateMapsVisualizationTest",
"failure": "Error: expected 7069 to be below 64
at Assertion.__kbnBundles__.tests../packages/kbn-expect/expect.js.Assertion.assert (http://localhost:5610/bundles/tests.bundle.js?shards=4&shard_num=1:13671:11)
at Assertion.__kbnBundles__.tests../packages/kbn-expect/expect.js.Assertion.lessThan.Assertion.below (http://localhost:5610/bundles/tests.bundle.js?shards=4&shard_num=1:13891:8)
at Function.lessThan (http://localhost:5610/bundles/tests.bundle.js?shards=4&shard_num=1:14078:15)
at _callee3$ (http://localhost:5610/bundles/tests.bundle.js?shards=4&shard_num=1:158985:60)
at tryCatch (webpack://%5Bname%5D/./node_modules/regenerator-runtime/runtime.js?:62:40)
at Generator.invoke [as _invoke] (webpack://%5Bname%5D/./node_modules/regenerator-runtime/runtime.js?:288:22)
at Generator.prototype.<computed> [as next] (webpack://%5Bname%5D/./node_modules/regenerator-runtime/runtime.js?:114:21)
at asyncGeneratorStep (http://localhost:5610/bundles/tests.bundle.js?shards=4&shard_num=1:158772:103)
at _next (http://localhost:5610/bundles/tests.bundle.js?shards=4&shard_num=1:158774:194)
",
"likelyIrrelevant": false,
"name": "CoordinateMapsVisualizationTest CoordinateMapsVisualization - basics should initialize OK",
"time": "0.265",
},
]
`);
});
it('discovers failures in mocha report', async () => {
const failures = getFailures(await parseTestReport(MOCHA_REPORT));
expect(failures).toMatchInlineSnapshot(`

View file

@ -19,7 +19,7 @@
import { getReportMessageIter } from './report_metadata';
import { parseTestReport } from './test_report';
import { FTR_REPORT, JEST_REPORT, KARMA_REPORT, MOCHA_REPORT } from './__fixtures__';
import { FTR_REPORT, JEST_REPORT, MOCHA_REPORT } from './__fixtures__';
it('reads messages and screenshots from metadata-json properties', async () => {
const ftrReport = await parseTestReport(FTR_REPORT);
@ -43,7 +43,4 @@ it('reads messages and screenshots from metadata-json properties', async () => {
const mochaReport = await parseTestReport(MOCHA_REPORT);
expect(Array.from(getReportMessageIter(mochaReport))).toMatchInlineSnapshot(`Array []`);
const karmaReport = await parseTestReport(KARMA_REPORT);
expect(Array.from(getReportMessageIter(karmaReport))).toMatchInlineSnapshot(`Array []`);
});

View file

@ -24,7 +24,7 @@ const globals: any = typeof window === 'undefined' ? {} : window;
export type Theme = typeof LightTheme;
// in the Kibana app we can rely on this global being defined, but in
// some cases (like jest, or karma tests) the global is undefined
// some cases (like jest) the global is undefined
export const tag: string = globals.__kbnThemeTag__ || 'v7light';
export const version = tag.startsWith('v7') ? 7 : 8;
export const darkMode = tag.endsWith('dark');

View file

@ -1613,14 +1613,6 @@ If others are consuming your plugin's new platform contracts via the `ui/new_pla
> Note: The `ui/new_platform` mock is only designed for use by old Jest tests. If you are writing new tests, you should structure your code and tests such that you don't need this mock. Instead, you should import the `core` mock directly and instantiate it.
#### What about karma tests?
While our plan is to only provide first-class mocks for Jest tests, there are many legacy karma tests that cannot be quickly or easily converted to Jest -- particularly those which are still relying on mocking Angular services via `ngMock`.
For these tests, we are maintaining a separate set of mocks. Files with a `.karma_mock.{js|ts|tsx}` extension will be loaded _globally_ before karma tests are run.
It is important to note that this behavior is different from `jest.mock('ui/new_platform')`, which only mocks tests on an individual basis. If you encounter any failures in karma tests as a result of new platform migration efforts, you may need to add a `.karma_mock.js` file for the affected services, or add to the existing karma mock we are maintaining in `ui/new_platform`.
### Provide Legacy Platform API to the New platform plugin
#### On the server side

View file

@ -56,7 +56,7 @@ interface BootstrapModule {
* The LegacyPlatformService is responsible for initializing
* the legacy platform by injecting parts of the new platform
* services into the legacy platform modules, like ui/modules,
* and then bootstrapping the ui/chrome or ui/test_harness to
* and then bootstrapping the ui/chrome or ~~ui/test_harness~~ to
* setup either the app or browser tests.
*/
export class LegacyPlatformService {

View file

@ -42,21 +42,7 @@ export const config = {
validate: match(validBasePathRegex, "must start with a slash, don't end with one"),
})
),
cors: schema.conditional(
schema.contextRef('dev'),
true,
schema.object(
{
origin: schema.arrayOf(schema.string()),
},
{
defaultValue: {
origin: ['*://localhost:9876'], // karma test server
},
}
),
schema.boolean({ defaultValue: false })
),
cors: schema.boolean({ defaultValue: false }),
customResponseHeaders: schema.recordOf(schema.string(), schema.any(), {
defaultValue: {},
}),

View file

@ -33,7 +33,6 @@ export const CopySource: Task = {
'!src/**/{__tests__,__snapshots__,__mocks__}/**',
'!src/test_utils/**',
'!src/fixtures/**',
'!src/legacy/core_plugins/tests_bundle/**',
'!src/legacy/core_plugins/console/public/tests/**',
'!src/cli/cluster/**',
'!src/cli/repl/**',

View file

@ -123,7 +123,6 @@ export const IGNORE_DIRECTORY_GLOBS = [
export const TEMPORARILY_IGNORED_PATHS = [
'src/legacy/core_plugins/console/public/src/directives/helpExample.txt',
'src/legacy/core_plugins/console/public/src/sense_editor/theme-sense-dark.js',
'src/legacy/core_plugins/tests_bundle/webpackShims/angular-mocks.js',
'src/legacy/core_plugins/tile_map/public/__tests__/scaledCircleMarkers.png',
'src/legacy/core_plugins/tile_map/public/__tests__/shadedCircleMarkers.png',
'src/legacy/core_plugins/tile_map/public/__tests__/shadedGeohashGrid.png',

View file

@ -1,64 +0,0 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
// eslint-disable-next-line @kbn/eslint/no-restricted-paths
import { fromRoot } from '../../../core/server/utils';
import { chain } from 'lodash';
import { resolve } from 'path';
import { fromNode } from 'bluebird';
import glob from 'glob-all';
const findSourceFiles = async (patterns, cwd = fromRoot('.')) => {
patterns = [].concat(patterns || []);
const matches = await fromNode((cb) => {
glob(
patterns,
{
cwd: cwd,
ignore: [
'node_modules/**/*',
'bower_components/**/*',
'**/_*.js',
'**/*.test.js',
'**/*.test.mocks.js',
'**/__mocks__/**/*',
],
symlinks: findSourceFiles.symlinks,
statCache: findSourceFiles.statCache,
realpathCache: findSourceFiles.realpathCache,
cache: findSourceFiles.cache,
},
cb
);
});
return chain(matches)
.flatten()
.uniq()
.map((match) => resolve(cwd, match))
.value();
};
findSourceFiles.symlinks = {};
findSourceFiles.statCache = {};
findSourceFiles.realpathCache = {};
findSourceFiles.cache = {};
export default findSourceFiles;

View file

@ -1,180 +0,0 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { createReadStream } from 'fs';
import { resolve } from 'path';
import globby from 'globby';
import MultiStream from 'multistream';
import webpackMerge from 'webpack-merge';
// eslint-disable-next-line @kbn/eslint/no-restricted-paths
import { fromRoot } from '../../../core/server/utils';
import { replacePlaceholder } from '../../../optimize/public_path_placeholder';
import findSourceFiles from './find_source_files';
import { createTestEntryTemplate } from './tests_entry_template';
export default (kibana) => {
return new kibana.Plugin({
config: (Joi) => {
return Joi.object({
enabled: Joi.boolean().default(true),
instrument: Joi.boolean().default(false),
pluginId: Joi.string(),
}).default();
},
uiExports: {
styleSheetPaths: resolve(__dirname, 'public/index.scss'),
async __bundleProvider__(kbnServer) {
const modules = new Set();
const {
config,
uiApps,
uiBundles,
plugins,
uiExports: { uiSettingDefaults = {} },
} = kbnServer;
const testGlobs = [];
const testingPluginIds = config.get('tests_bundle.pluginId');
if (testingPluginIds) {
testingPluginIds.split(',').forEach((pluginId) => {
const plugin = plugins.find((plugin) => plugin.id === pluginId);
if (!plugin) {
throw new Error('Invalid testingPluginId :: unknown plugin ' + pluginId);
}
// add the modules from all of this plugins apps
for (const app of uiApps) {
if (app.getPluginId() === pluginId) {
modules.add(app.getMainModuleId());
}
}
testGlobs.push(`${plugin.publicDir}/**/__tests__/**/*.js`);
});
} else {
// add all since we are not just focused on specific plugins
testGlobs.push('src/legacy/ui/public/**/*.js', '!src/legacy/ui/public/flot-charts/**/*');
// add the modules from all of the apps
for (const app of uiApps) {
modules.add(app.getMainModuleId());
}
for (const plugin of plugins) {
testGlobs.push(`${plugin.publicDir}/**/__tests__/**/*.js`);
}
}
const testFiles = await findSourceFiles(testGlobs);
for (const f of testFiles) modules.add(f);
if (config.get('tests_bundle.instrument')) {
uiBundles.addPostLoader({
test: /\.js$/,
exclude: /[\/\\](__tests__|node_modules|bower_components|webpackShims)[\/\\]/,
loader: 'istanbul-instrumenter-loader',
});
}
uiBundles.add({
id: 'tests',
modules: [...modules],
template: createTestEntryTemplate(uiSettingDefaults),
extendConfig(webpackConfig) {
const mergedConfig = webpackMerge(
{
resolve: {
extensions: ['.karma_mock.js', '.karma_mock.tsx', '.karma_mock.ts'],
},
node: {
fs: 'empty',
child_process: 'empty',
dns: 'empty',
net: 'empty',
tls: 'empty',
},
},
webpackConfig
);
/**
* [..] it removes the commons bundle creation from the webpack
* config when we're building the bundle for the browser tests. It
* shouldn't be created, and by default isn't, but something is
* triggering it in webpack which breaks the tests so if we just
* remove the optimization config it will never happen and the tests
* will keep working [..]
*
* TLDR: If you have any questions about this line, ask Spencer.
*/
delete mergedConfig.optimization.splitChunks.cacheGroups.commons;
return mergedConfig;
},
});
kbnServer.server.route({
method: 'GET',
path: '/test_bundle/built_css.css',
async handler(_, h) {
const cssFiles = await globby(
testingPluginIds
? testingPluginIds.split(',').map((id) => `built_assets/css/plugins/${id}/**/*.css`)
: `built_assets/css/**/*.css`,
{ cwd: fromRoot('.'), absolute: true }
);
const stream = replacePlaceholder(
new MultiStream(cssFiles.map((path) => createReadStream(path))),
'/built_assets/css/'
);
return h.response(stream).code(200).type('text/css');
},
});
// Sets global variables normally set by the bootstrap.js script
kbnServer.server.route({
path: '/test_bundle/karma/globals.js',
method: 'GET',
async handler(req, h) {
const basePath = config.get('server.basePath');
const file = `window.__kbnPublicPath__ = { 'kbn-ui-shared-deps': "${basePath}/bundles/kbn-ui-shared-deps/" };`;
return h.response(file).header('content-type', 'application/json');
},
});
},
__globalImportAliases__: {
ng_mock$: fromRoot('src/test_utils/public/ng_mock'),
'angular-mocks$': require.resolve('./webpackShims/angular-mocks'),
fixtures: fromRoot('src/fixtures'),
test_utils: fromRoot('src/test_utils/public'),
},
},
});
};

View file

@ -1,4 +0,0 @@
{
"name": "tests_bundle",
"version": "kibana"
}

View file

@ -1,4 +0,0 @@
// This file pulls some styles of NP plugins into the legacy test stylesheet
// so they are available for karma browser tests.
@import '../../../../plugins/vis_type_vislib/public/index';
@import '../../../../plugins/visualizations/public/index';

View file

@ -1,158 +0,0 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { Type } from '@kbn/config-schema';
import pkg from '../../../../package.json';
export const createTestEntryTemplate = (defaultUiSettings) => (bundle) => `
/**
* Test entry file
*
* This is programmatically created and updated, do not modify
*
* context: ${bundle.getContext()}
*
*/
import fetchMock from 'fetch-mock/es5/client';
import { CoreSystem } from '__kibanaCore__';
// Fake uiCapabilities returned to Core in browser tests
const uiCapabilities = {
navLinks: {
myLink: true,
notMyLink: true,
},
discover: {
showWriteControls: true
},
visualize: {
save: true
},
dashboard: {
showWriteControls: true
},
timelion: {
save: true
},
management: {
kibana: {
settings: true,
index_patterns: true,
objects: true
}
}
};
// Mock fetch for CoreSystem calls.
fetchMock.config.fallbackToNetwork = true;
fetchMock.post(/\\/api\\/core\\/capabilities/, {
status: 200,
body: JSON.stringify(uiCapabilities),
headers: { 'Content-Type': 'application/json' },
});
// render the core system in a element not attached to the document as the
// default children of the body in the browser tests are needed for mocha and
// other test components to work
const rootDomElement = document.createElement('div');
const coreSystem = new CoreSystem({
injectedMetadata: {
version: '1.2.3',
buildNumber: 1234,
legacyMode: true,
legacyMetadata: {
app: {
id: 'karma',
title: 'Karma',
},
nav: [],
version: '1.2.3',
buildNum: 1234,
devMode: true,
uiSettings: {
defaults: ${JSON.stringify(
defaultUiSettings,
(key, value) => {
if (value instanceof Type) return null;
return value;
},
2
)
.split('\n')
.join('\n ')},
user: {}
},
nav: []
},
csp: {
warnLegacyBrowsers: false,
},
capabilities: uiCapabilities,
uiPlugins: [],
vars: {
kbnIndex: '.kibana',
esShardTimeout: 1500,
esApiVersion: ${JSON.stringify(pkg.branch)},
esRequestTimeout: '300000',
tilemapsConfig: {
deprecated: {
isOverridden: false,
config: {
options: {
}
}
}
},
regionmapsConfig: {
layers: []
},
mapConfig: {
includeElasticMapsService: true,
emsFileApiUrl: 'https://vector-staging.maps.elastic.co',
emsTileApiUrl: 'https://tiles.maps.elastic.co',
},
vegaConfig: {
enabled: true,
enableExternalUrls: true
},
},
},
rootDomElement,
requireLegacyBootstrapModule: () => {
// wrapped in NODE_ENV check so the 'ui/test_harness' module
// is not included in the distributable
if (process.env.IS_KIBANA_DISTRIBUTABLE !== 'true') {
return require('ui/test_harness');
}
throw new Error('tests bundle is not available in the distributable');
},
requireNewPlatformShimModule: () => require('ui/new_platform'),
requireLegacyFiles: () => {
${bundle.getRequires().join('\n ')}
}
})
coreSystem
.setup()
.then(() => {
return coreSystem.start();
});
`;

View file

@ -1,21 +0,0 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
require('angular');
require('../../../../../node_modules/angular-mocks/angular-mocks.js');

View file

@ -1,2 +0,0 @@
rules:
no-console: 0

View file

@ -1,20 +0,0 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
export { bootstrap } from './test_harness';

View file

@ -1,22 +0,0 @@
/**
* This file is only for tests so it is it's own CSS
* to be imported directly by and only by this module.
*/
body#test-harness-body {
/**
now that tests include the kibana styles, we have
to override the body { display: flex; } rule as it
prevents the visualizations from properly testing
their sizing
*/
display: block;
}
body#test-harness-body #mocha-stats .progress {
/* bootstrap thinks it is the only one who will use ".progress" */
height: auto;
background-color: transparent;
overflow: auto;
border-radius: 0;
}

View file

@ -1,89 +0,0 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
// chrome expects to be loaded first, let it get its way
import chrome from '../chrome';
import { parse as parseUrl } from 'url';
import { Subject } from 'rxjs';
import sinon from 'sinon';
import { metadata } from '../metadata';
// eslint-disable-next-line @kbn/eslint/no-restricted-paths
import { UiSettingsClient } from '../../../../core/public/ui_settings';
import './test_harness.css';
import 'ng_mock';
import { setupTestSharding } from './test_sharding';
const { query } = parseUrl(window.location.href, true);
if (query && query.mocha) {
try {
window.mocha.setup(JSON.parse(query.mocha));
} catch (error) {
throw new Error(
`'?mocha=${query.mocha}' query string param provided but it could not be parsed as json`
);
}
}
setupTestSharding();
before(() => {
// prevent accidental ajax requests
sinon.useFakeXMLHttpRequest();
});
let stubUiSettings;
let done$;
function createStubUiSettings() {
if (stubUiSettings) {
done$.complete();
}
done$ = new Subject();
stubUiSettings = new UiSettingsClient({
api: {
async batchSet() {
return { settings: stubUiSettings.getAll() };
},
},
onUpdateError: () => {},
defaults: metadata.uiSettings.defaults,
initialSettings: {},
done$,
});
}
createStubUiSettings();
sinon.stub(chrome, 'getUiSettingsClient').callsFake(() => stubUiSettings);
afterEach(function () {
createStubUiSettings();
});
// Kick off mocha, called at the end of test entry files
export function bootstrap(targetDomElement) {
// allows test_harness.less to have higher priority selectors
targetDomElement.setAttribute('id', 'test-harness-body');
// load the hacks since we aren't actually bootstrapping the
// chrome, which is where the hacks would normally be loaded
require('uiExports/hacks');
chrome.setupAngular();
}

View file

@ -1,39 +0,0 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/**
* We don't have a lot of options for passing arguments to the page that karma
* creates, so we tack some query string params onto the test bundle script url.
*
* This function finds that url by looking for a script tag that has
* the "/tests.bundle.js" segment
*
* @return {string} url
*/
export function findTestBundleUrl() {
const scriptTags = document.querySelectorAll('script[src]');
const scriptUrls = [].map.call(scriptTags, (el) => el.getAttribute('src'));
const testBundleUrl = scriptUrls.find((url) => url.includes('/tests.bundle.js'));
if (!testBundleUrl) {
throw new Error("test bundle url couldn't be found");
}
return testBundleUrl;
}

View file

@ -1,47 +0,0 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import murmurHash3 from 'murmurhash3js';
// murmur hashes are 32bit unsigned integers
const MAX_HASH = Math.pow(2, 32);
/**
* Determine the shard number for a suite by hashing
* its name and placing it based on the hash
*
* @param {number} shardTotal - the total number of shards
* @param {string} suiteName - the suite name to hash
* @return {number} shardNum - 1-based shard number
*/
export function getShardNum(shardTotal, suiteName) {
const hashIntsPerShard = MAX_HASH / shardTotal;
const hashInt = murmurHash3.x86.hash32(suiteName);
// murmur3 produces 32bit integers, so we devide it by the number of chunks
// to determine which chunk the suite should fall in. +1 because the current
// chunk is 1-based
const shardNum = Math.floor(hashInt / hashIntsPerShard) + 1;
// It's not clear if hash32 can produce the MAX_HASH or not,
// but this just ensures that shard numbers don't go out of bounds
// and cause tests to be ignored unnecessarily
return Math.max(1, Math.min(shardNum, shardTotal));
}

View file

@ -1,45 +0,0 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { parse as parseUrl } from 'url';
/**
* This function extracts the relevant "shards" and "shard_num"
* params from the url.
*
* @param {string} testBundleUrl
* @return {object} params
* @property {number} params.shards - the total number of shards
* @property {number} params.shard_num - the current shard number, 1 based
*/
export function getShardingParamsFromUrl(url) {
const parsedUrl = parseUrl(url, true);
const parsedQuery = parsedUrl.query || {};
const params = {};
if (parsedQuery.shards) {
params.shards = parseInt(parsedQuery.shards, 10);
}
if (parsedQuery.shard_num) {
params.shard_num = parseInt(parsedQuery.shard_num, 10);
}
return params;
}

View file

@ -1,20 +0,0 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
export { setupTestSharding } from './setup_test_sharding';

View file

@ -1,69 +0,0 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { uniq, defaults } from 'lodash';
import { findTestBundleUrl } from './find_test_bundle_url';
import { getShardingParamsFromUrl } from './get_sharding_params_from_url';
import { setupTopLevelDescribeFilter } from './setup_top_level_describe_filter';
import { getShardNum } from './get_shard_num';
const DEFAULT_PARAMS = {
shards: 1,
shard_num: 1,
};
export function setupTestSharding() {
const pageUrl = window.location.href;
const bundleUrl = findTestBundleUrl();
// supports overriding params via the debug page
// url in dev mode
const params = defaults(
{},
getShardingParamsFromUrl(pageUrl),
getShardingParamsFromUrl(bundleUrl),
DEFAULT_PARAMS
);
const { shards: shardTotal, shard_num: shardNum } = params;
if (shardNum < 1 || shardNum > shardTotal) {
throw new TypeError(
`shard_num param of ${shardNum} must be greater 0 and less than the total, ${shardTotal}`
);
}
// track and log the number of ignored describe calls
const ignoredDescribeShards = [];
before(() => {
const ignoredCount = ignoredDescribeShards.length;
const ignoredFrom = uniq(ignoredDescribeShards).join(', ');
console.log(`Ignored ${ignoredCount} top-level suites from ${ignoredFrom}`);
});
// Filter top-level describe statements as they come
setupTopLevelDescribeFilter((describeName) => {
const describeShardNum = getShardNum(shardTotal, describeName);
if (describeShardNum === shardNum) return true;
// track shard numbers that we ignore
ignoredDescribeShards.push(describeShardNum);
});
console.log(`ready to load tests for shard ${shardNum} of ${shardTotal}`);
}

View file

@ -1,125 +0,0 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/**
* Intercept all calls to mocha.describe() and determine
* which calls make it through using a filter function.
*
* The filter function is also only called for top-level
* describe() calls; all describe calls nested within another
* are allowed based on the filter value for the parent
* describe
*
* ## example
*
* assume tests that look like this:
*
* ```js
* describe('section 1', () => {
* describe('item 1', () => {
*
* })
* })
* ```
*
* If the filter function returned true for "section 1" then "item 1"
* would automatically be defined. If it returned false for "section 1"
* then "section 1" would be ignored and "item 1" would never be defined
*
* @param {function} test - a function that takes the first argument
* passed to describe, the sections name, and
* returns true if the describe call should
* be delegated to mocha, any other value causes
* the describe call to be ignored
* @return {undefined}
*/
export function setupTopLevelDescribeFilter(test) {
const originalDescribe = window.describe;
if (!originalDescribe) {
throw new TypeError(
'window.describe must be defined by mocha before test sharding can be setup'
);
}
/**
* When describe is called it is likely to make additional, nested,
* calls to describe. We track how deeply nested we are at any time
* with a depth counter, `describeCallDepth`.
*
* Before delegating a describe call to mocha we increment
* that counter, and once mocha is done we decrement it.
*
* This way, we can check if `describeCallDepth > 0` at any time
* to know if we are already within a describe call.
*
* ```js
* // +1
* describe('section 1', () => {
* // describeCallDepth = 1
* // +1
* describe('item 1', () => {
* // describeCallDepth = 2
* })
* // -1
* })
* // -1
* // describeCallDepth = 0
* ```
*
* @type {Number}
*/
let describeCallDepth = 0;
const describeInterceptor = function (describeName, describeBody) {
const context = this;
const isTopLevelCall = describeCallDepth === 0;
const shouldIgnore = isTopLevelCall && Boolean(test(describeName)) === false;
if (shouldIgnore) return;
/**
* we wrap the delegation to mocha in a try/finally block
* to ensure that our describeCallDepth counter stays up
* to date even if the call throws an error.
*
* note that try/finally won't actually catch the error, it
* will continue to propagate up the call stack
*/
let result;
try {
describeCallDepth += 1;
result = originalDescribe.call(context, describeName, describeBody);
} finally {
describeCallDepth -= 1;
}
return result;
};
// to allow describe.only calls. we dont need interceptor as it will call describe internally
describeInterceptor.only = originalDescribe.only;
describeInterceptor.skip = originalDescribe.skip;
// ensure that window.describe isn't messed with by other code
Object.defineProperty(window, 'describe', {
configurable: false,
enumerable: true,
value: describeInterceptor,
});
}

View file

@ -30,7 +30,6 @@ export const UI_EXPORT_DEFAULTS = {
webpackAliases: {
ui: resolve(ROOT, 'src/legacy/ui/public'),
__kibanaCore__$: resolve(ROOT, 'src/core/public'),
test_harness: resolve(ROOT, 'src/test_harness/public'),
},
styleSheetPaths: ['light', 'dark'].map((theme) => ({

View file

@ -1,207 +0,0 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { dirname } from 'path';
import { times } from 'lodash';
import { makeJunitReportPath } from '@kbn/test';
import * as UiSharedDeps from '@kbn/ui-shared-deps';
const TOTAL_CI_SHARDS = 4;
const ROOT = dirname(require.resolve('../../package.json'));
const buildHash = String(Number.MAX_SAFE_INTEGER);
module.exports = function (grunt) {
function pickBrowser() {
if (grunt.option('browser')) {
return grunt.option('browser');
}
if (process.env.TEST_BROWSER_HEADLESS === '1') {
return 'Chrome_Headless';
}
return 'Chrome';
}
function pickReporters() {
// available reporters: https://npmjs.org/browse/keyword/karma-reporter
if (process.env.CI && process.env.DISABLE_JUNIT_REPORTER) {
return ['dots'];
}
if (process.env.CI) {
return ['dots', 'junit'];
}
return ['progress'];
}
function getKarmaFiles(shardNum) {
return [
'http://localhost:5610/test_bundle/built_css.css',
// Sets global variables normally set by the bootstrap.js script
'http://localhost:5610/test_bundle/karma/globals.js',
...UiSharedDeps.jsDepFilenames.map(
(chunkFilename) =>
`http://localhost:5610/${buildHash}/bundles/kbn-ui-shared-deps/${chunkFilename}`
),
`http://localhost:5610/${buildHash}/bundles/kbn-ui-shared-deps/${UiSharedDeps.jsFilename}`,
shardNum === undefined
? `http://localhost:5610/${buildHash}/bundles/tests.bundle.js`
: `http://localhost:5610/${buildHash}/bundles/tests.bundle.js?shards=${TOTAL_CI_SHARDS}&shard_num=${shardNum}`,
`http://localhost:5610/${buildHash}/bundles/kbn-ui-shared-deps/${UiSharedDeps.baseCssDistFilename}`,
// this causes tilemap tests to fail, probably because the eui styles haven't been
// included in the karma harness a long some time, if ever
// `http://localhost:5610/bundles/kbn-ui-shared-deps/${UiSharedDeps.lightCssDistFilename}`,
`http://localhost:5610/${buildHash}/bundles/tests.style.css`,
];
}
const config = {
options: {
// base path that will be used to resolve all patterns (eg. files, exclude)
basePath: '',
captureTimeout: 30000,
browserNoActivityTimeout: 120000,
frameworks: ['mocha'],
plugins: [
'karma-chrome-launcher',
'karma-coverage',
'karma-firefox-launcher',
'karma-ie-launcher',
'karma-junit-reporter',
'karma-mocha',
'karma-safari-launcher',
],
port: 9876,
colors: true,
logLevel: grunt.option('debug') || grunt.option('verbose') ? 'DEBUG' : 'INFO',
autoWatch: false,
browsers: [pickBrowser()],
customLaunchers: {
Chrome_Headless: {
base: 'Chrome',
flags: ['--headless', '--disable-gpu', '--remote-debugging-port=9222'],
},
},
reporters: pickReporters(),
junitReporter: {
outputFile: makeJunitReportPath(ROOT, 'karma'),
useBrowserName: false,
nameFormatter: (_, result) => [...result.suite, result.description].join(' '),
classNameFormatter: (_, result) => {
const rootSuite = result.suite[0] || result.description;
return `Browser Unit Tests.${rootSuite.replace(/\./g, '·')}`;
},
},
// list of files / patterns to load in the browser
files: getKarmaFiles(),
proxies: {
'/tests/': 'http://localhost:5610/tests/',
'/test_bundle/': 'http://localhost:5610/test_bundle/',
[`/${buildHash}/bundles/`]: `http://localhost:5610/${buildHash}/bundles/`,
},
client: {
mocha: {
reporter: 'html', // change Karma's debug.html to the mocha web reporter
timeout: 10000,
slow: 5000,
},
},
},
dev: { singleRun: false },
unit: { singleRun: true },
coverage: {
singleRun: true,
reporters: ['coverage'],
coverageReporter: {
reporters: [{ type: 'html', dir: 'coverage' }, { type: 'text-summary' }],
},
},
};
/**
* ------------------------------------------------------------
* CI sharding
* ------------------------------------------------------------
*
* Every test retains nearly all of the memory it causes to be allocated,
* which has started to kill the test browser as the size of the test suite
* increases. This is a deep-rooted problem that will take some serious
* work to fix.
*
* CI sharding is a short-term solution that splits the top-level describe
* calls into different "shards" and instructs karma to only run one shard
* at a time, reloading the browser in between each shard and forcing the
* memory from the previous shard to be released.
*
* ## how
*
* Rather than modify the bundling process to produce multiple testing
* bundles, top-level describe calls are sharded by their first argument,
* the suite name.
*
* The number of shards to create is controlled with the TOTAL_CI_SHARDS
* constant defined at the top of this file.
*
* ## controlling sharding
*
* To control sharding in a specific karma configuration, the total number
* of shards to create (?shards=X), and the current shard number
* (&shard_num=Y), are added to the testing bundle url and read by the
* test_harness/setup_test_sharding[1] module. This allows us to use a
* different number of shards in different scenarios (ie. running
* `yarn test:karma` runs the tests in a single shard, effectively
* disabling sharding)
*
* These same parameters can also be defined in the URL/query string of the
* karma debug page (started when you run `yarn test:karma:debug`).
*
* ## debugging
*
* It is *possible* that some tests will only pass if run after/with certain
* other suites. To debug this, make sure that your tests pass in isolation
* (by clicking the suite name on the karma debug page) and that it runs
* correctly in it's given shard (using the `?shards=X&shard_num=Y` query
* string params on the karma debug page). You can spot the shard number
* a test is running in by searching for the "ready to load tests for shard X"
* log message.
*
* [1]: src/legacy/ui/public/test_harness/test_sharding/setup_test_sharding.js
*/
times(TOTAL_CI_SHARDS, (i) => {
const n = i + 1;
config[`ciShard-${n}`] = {
singleRun: true,
options: {
files: getKarmaFiles(n),
},
};
});
return config;
};

View file

@ -17,7 +17,6 @@
* under the License.
*/
import { resolve } from 'path';
import { getFunctionalTestGroupRunConfigs } from '../function_test_groups';
const { version } = require('../../package.json');
@ -25,44 +24,7 @@ const KIBANA_INSTALL_DIR =
process.env.KIBANA_INSTALL_DIR ||
`./build/oss/kibana-${version}-SNAPSHOT-${process.platform}-x86_64`;
module.exports = function (grunt) {
function createKbnServerTask({ runBuild, flags = [] }) {
return {
options: {
wait: false,
ready: /http server running/,
quiet: false,
failOnError: false,
},
cmd: runBuild ? `./build/${runBuild}/bin/kibana` : process.execPath,
args: [
...(runBuild ? [] : [require.resolve('../../scripts/kibana'), '--oss']),
'--logging.json=false',
...flags,
// allow the user to override/inject flags by defining cli args starting with `--kbnServer.`
...grunt.option.flags().reduce(function (flags, flag) {
if (flag.startsWith('--kbnServer.')) {
flags.push(`--${flag.slice(12)}`);
}
return flags;
}, []),
],
};
}
const karmaTestServerFlags = [
'--env.name=development',
'--plugins.initialize=false',
'--optimize.bundleFilter=tests',
'--optimize.validateSyntaxOfNodeModules=false',
'--server.port=5610',
'--migrations.skip=true',
];
module.exports = function () {
const NODE = 'node';
const YARN = 'yarn';
const scriptWithGithubChecks = ({ title, options, cmd, args }) =>
@ -176,37 +138,6 @@ module.exports = function (grunt) {
],
}),
// used by the test:karma task
// runs the kibana server to serve the browser test bundle
karmaTestServer: createKbnServerTask({
flags: [...karmaTestServerFlags],
}),
browserSCSS: createKbnServerTask({
flags: [...karmaTestServerFlags, '--optimize', '--optimize.enabled=false'],
}),
// used by the test:coverage task
// runs the kibana server to serve the instrumented version of the browser test bundle
karmaTestCoverageServer: createKbnServerTask({
flags: [...karmaTestServerFlags, '--tests_bundle.instrument=true'],
}),
// used by the test:karma:debug task
// runs the kibana server to serve the browser test bundle, but listens for changes
// to the public/browser code and rebuilds the test bundle on changes
karmaTestDebugServer: createKbnServerTask({
flags: [
...karmaTestServerFlags,
'--dev',
'--no-dev-config',
'--no-watch',
'--no-base-path',
'--optimize.watchPort=5611',
'--optimize.watchPrebuild=true',
'--optimize.bundleDir=' + resolve(__dirname, '../../optimize/testdev'),
],
}),
verifyNotice: scriptWithGithubChecks({
title: 'Verify NOTICE.txt',
options: {
@ -324,7 +255,6 @@ module.exports = function (grunt) {
'test:jest_integration'
),
test_projects: gruntTaskWithGithubChecks('Project tests', 'test:projects'),
test_karma_ci: gruntTaskWithGithubChecks('Browser tests', 'test:karma-ci'),
...getFunctionalTestGroupRunConfigs({
kibanaInstallDir: KIBANA_INSTALL_DIR,

View file

@ -37,7 +37,6 @@ module.exports = function (grunt) {
'run:test_jest',
'run:test_jest_integration',
'run:test_projects',
'run:test_karma_ci',
'run:test_hardening',
'run:test_package_safer_lodash_set',
'run:apiIntegrationTests',

View file

@ -17,8 +17,6 @@
* under the License.
*/
import _, { keys } from 'lodash';
import { run } from '../utilities/visual_regression';
module.exports = function (grunt) {
@ -31,25 +29,6 @@ module.exports = function (grunt) {
}
);
grunt.registerTask('test:karma', [
'checkPlugins',
'run:browserSCSS',
'run:karmaTestServer',
'karma:unit',
]);
grunt.registerTask('test:karma-ci', () => {
const ciShardTasks = keys(grunt.config.get('karma'))
.filter((key) => key.startsWith('ciShard-'))
.map((key) => `karma:${key}`);
grunt.log.ok(`Running UI tests in ${ciShardTasks.length} shards`);
grunt.task.run(['run:browserSCSS']);
grunt.task.run(['run:karmaTestServer', ...ciShardTasks]);
});
grunt.registerTask('test:coverage', ['run:karmaTestCoverageServer', 'karma:coverage']);
grunt.registerTask('test:quick', [
'checkPlugins',
'run:mocha',
@ -57,18 +36,16 @@ module.exports = function (grunt) {
'test:jest',
'test:jest_integration',
'test:projects',
'test:karma',
'run:apiIntegrationTests',
]);
grunt.registerTask('test:karmaDebug', ['checkPlugins', 'run:karmaTestDebugServer', 'karma:dev']);
grunt.registerTask('test:mochaCoverage', ['run:mochaCoverage']);
grunt.registerTask('test', (subTask) => {
if (subTask) grunt.fail.fatal(`invalid task "test:${subTask}"`);
grunt.task.run(
_.compact([
[
!grunt.option('quick') && 'run:eslint',
!grunt.option('quick') && 'run:sasslint',
!grunt.option('quick') && 'run:checkTsProjects',
@ -78,7 +55,7 @@ module.exports = function (grunt) {
'run:checkFileCasing',
'run:licenses',
'test:quick',
])
].filter(Boolean)
);
});

View file

@ -2,9 +2,9 @@
source test/scripts/jenkins_test_setup.sh
echo " -> Running mocha tests"
cd "$XPACK_DIR"
checks-reporter-with-killswitch "X-Pack Karma Tests" yarn test:karma
echo " -> Building legacy styles for x-pack canvas storyshot tests"
cd "$KIBANA_DIR"
node scripts/build_sass
echo ""
echo ""

View file

@ -44,14 +44,6 @@ If you want to run tests only for a specific plugin (to save some time), you can
yarn test --plugins <plugin>[,<plugin>]* # where <plugin> is "reporting", etc.
```
#### Debugging browser tests
```
yarn test:karma:debug
```
Initializes an environment for debugging the browser tests. Includes an dedicated instance of the kibana server for building the test bundle, and a karma server. When running this task the build is optimized for the first time and then a karma-owned instance of the browser is opened. Click the "debug" button to open a new tab that executes the unit tests.
Run single tests by appending `grep` parameter to the end of the URL. For example `http://localhost:9876/debug.html?grep=ML%20-%20Explorer%20Controller` will only run tests with 'ML - Explorer Controller' in the describe block.
#### Running server unit tests
You can run mocha unit tests by running:

View file

@ -8,7 +8,6 @@ require('../src/setup_node_env');
const { buildTask } = require('./tasks/build');
const { devTask } = require('./tasks/dev');
const { testTask, testKarmaTask, testKarmaDebugTask } = require('./tasks/test');
const { downloadChromium } = require('./tasks/download_chromium');
// export the tasks that are runnable from the CLI
@ -16,7 +15,4 @@ module.exports = {
build: buildTask,
dev: devTask,
downloadChromium,
test: testTask,
'test:karma': testKarmaTask,
'test:karma:debug': testKarmaDebugTask,
};

View file

@ -11,8 +11,6 @@
"build": "gulp build",
"testonly": "echo 'Deprecated, use `yarn test`' && gulp test",
"test": "gulp test",
"test:karma:debug": "gulp test:karma:debug",
"test:karma": "gulp test:karma",
"test:jest": "node scripts/jest",
"test:mocha": "node scripts/mocha"
},

View file

@ -1,7 +0,0 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
require('./_helpers').runGulpTask('canvas:test:karma');

View file

@ -1,7 +0,0 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
require('./_helpers').runGulpTask('canvas:karma:debug');

View file

@ -1,33 +0,0 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
import * as pluginHelpers from '@kbn/plugin-helpers';
import gulp from 'gulp';
// @ts-ignore untyped, converted in a different location in master
import { createAutoJUnitReporter } from '../../src/dev/mocha';
import { getEnabledPlugins } from './helpers/flags';
export const testServerTask = async () => {
throw new Error('server mocha tests are now included in the `node scripts/mocha` script');
};
export const testKarmaTask = async () => {
const plugins = await getEnabledPlugins();
await pluginHelpers.run('testKarma', {
plugins: plugins.join(','),
});
};
export const testKarmaDebugTask = async () => {
const plugins = await getEnabledPlugins();
await pluginHelpers.run('testKarma', {
dev: true,
plugins: plugins.join(','),
});
};
export const testTask = gulp.series(testKarmaTask, testServerTask);

629
yarn.lock

File diff suppressed because it is too large Load diff