diff --git a/packages/kbn-eslint-import-resolver-kibana/lib/get_kibana_path.js b/packages/kbn-eslint-import-resolver-kibana/lib/get_kibana_path.js index d779b3a542e6..93c0f907d628 100755 --- a/packages/kbn-eslint-import-resolver-kibana/lib/get_kibana_path.js +++ b/packages/kbn-eslint-import-resolver-kibana/lib/get_kibana_path.js @@ -21,7 +21,7 @@ const { resolve } = require('path'); const { debug } = require('./debug'); -const DEFAULT_PLUGIN_PATH = '../../kibana'; +const DEFAULT_PLUGIN_PATH = '../..'; /* * Resolves the path to Kibana, either from default setting or config diff --git a/packages/kbn-plugin-generator/integration_tests/generate_plugin.test.js b/packages/kbn-plugin-generator/integration_tests/generate_plugin.test.js new file mode 100644 index 000000000000..220fce8b9337 --- /dev/null +++ b/packages/kbn-plugin-generator/integration_tests/generate_plugin.test.js @@ -0,0 +1,157 @@ +/* + * 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 no-restricted-syntax */ +import { spawn } from 'child_process'; +import { resolve } from 'path'; +import util from 'util'; +import { stat } from 'fs'; +import { snakeCase } from 'lodash'; +import del from 'del'; +import { withProcRunner, ToolingLog } from '@kbn/dev-utils'; +import { createEsTestCluster } from '@kbn/test'; +import execa from 'execa'; + +const statP = util.promisify(stat); +const ROOT_DIR = resolve(__dirname, '../../../'); +const oneMinute = 60000; + +describe(`running the plugin-generator via 'node scripts/generate_plugin.js plugin-name' with default config`, () => { + const pluginName = 'ispec-plugin'; + const snakeCased = snakeCase(pluginName); + const generatedPath = resolve(ROOT_DIR, `plugins/${snakeCased}`); + const collect = xs => data => xs.push(data + ''); // Coerce from Buffer to String + + beforeAll(() => { + jest.setTimeout(oneMinute * 10); + }); + + beforeAll(done => { + const create = spawn(process.execPath, ['scripts/generate_plugin.js', pluginName], { + cwd: ROOT_DIR, + }); + create.stdout.on('data', function selectDefaults() { + create.stdin.write('\n'); // Generate a plugin with default options. + }); + create.on('close', done); + }); + + afterAll(() => { + del.sync(generatedPath, { force: true }); + }); + + it(`should succeed on creating a plugin in a directory named 'plugins/${snakeCased}`, async () => { + const stats = await statP(generatedPath); + expect(stats.isDirectory()).toBe(true); + }); + + describe(`then running`, () => { + it(`'yarn test:browser' should exit 0`, async () => { + await execa('yarn', ['test:browser'], { cwd: generatedPath }); + }); + + it(`'yarn test:server' should exit 0`, async () => { + await execa('yarn', ['test:server'], { cwd: generatedPath }); + }); + + it(`'yarn build' should exit 0`, async () => { + await execa('yarn', ['build'], { cwd: generatedPath }); + }); + + it(`'yarn start' should result in the spec plugin being initialized on kibana's stdout`, async () => { + const log = new ToolingLog(); + const es = createEsTestCluster({ license: 'basic', log }); + await es.start(); + await withProcRunner(log, async proc => { + await proc.run('kibana', { + cmd: 'yarn', + args: ['start', '--optimize.enabled=false', '--logging.json=false'], + cwd: generatedPath, + wait: /ispec_plugin.+Status changed from uninitialized to green - Ready/, + }); + await proc.stop('kibana'); + }); + await es.stop(); + }); + + it(`'yarn preinstall' should exit 0`, async () => { + await execa('yarn', ['preinstall'], { cwd: generatedPath }); + }); + + it(`'yarn lint' should exit 0`, async () => { + await execa('yarn', ['lint'], { cwd: generatedPath }); + }); + + it(`'yarn kbn --help' should print out the kbn help msg`, done => { + const helpMsg = ` +usage: kbn [] + +By default commands are run for Kibana itself, all packages in the 'packages/' +folder and for all plugins in './plugins' and '../kibana-extra'. + +Available commands: + + bootstrap - Install dependencies and crosslink projects + clean - Remove the node_modules and target directories from all projects. + run - Run script defined in package.json in each package that contains that script. + watch - Runs \`kbn:watch\` script for every project. + +Global options: + + -e, --exclude Exclude specified project. Can be specified multiple times to exclude multiple projects, e.g. '-e kibana -e @kbn/pm'. + -i, --include Include only specified projects. If left unspecified, it defaults to including all projects. + --oss Do not include the x-pack when running command. + --skip-kibana-plugins Filter all plugins in ./plugins and ../kibana-extra when running command. +`; + const outData = []; + const kbnHelp = spawn('yarn', ['kbn', '--help'], { cwd: generatedPath }); + kbnHelp.stdout.on('data', collect(outData)); + kbnHelp.on('close', () => { + expect(outData.join('\n')).toContain(helpMsg); + done(); + }); + }); + + it(`'yarn es --help' should print out the es help msg`, done => { + const helpMsg = ` +usage: es [] + +Assists with running Elasticsearch for Kibana development + +Available commands: + + snapshot - Downloads and run from a nightly snapshot + source - Build and run from source + archive - Install and run from an Elasticsearch tar + build_snapshots - Build and collect ES snapshots + +Global options: + + --help +`; + const outData = []; + const kbnHelp = spawn('yarn', ['es', '--help'], { cwd: generatedPath }); + kbnHelp.stdout.on('data', collect(outData)); + kbnHelp.on('close', () => { + expect(outData.join('\n')).toContain(helpMsg); + done(); + }); + }); + }); +}); diff --git a/packages/kbn-plugin-generator/sao_template/sao.js b/packages/kbn-plugin-generator/sao_template/sao.js index 874735593d44..3eb88f53190a 100755 --- a/packages/kbn-plugin-generator/sao_template/sao.js +++ b/packages/kbn-plugin-generator/sao_template/sao.js @@ -80,7 +80,7 @@ module.exports = function({ name }) { }, move: { gitignore: '.gitignore', - eslintrc: '.eslintrc', + 'eslintrc.js': '.eslintrc.js', 'package_template.json': 'package.json', }, data: answers => diff --git a/packages/kbn-plugin-generator/sao_template/sao.test.js b/packages/kbn-plugin-generator/sao_template/sao.test.js index 77c9b4533b9c..80149c008dad 100755 --- a/packages/kbn-plugin-generator/sao_template/sao.test.js +++ b/packages/kbn-plugin-generator/sao_template/sao.test.js @@ -198,6 +198,6 @@ describe('plugin generator sao integration', () => { it('includes dotfiles', async () => { const res = await sao.mockPrompt(template); expect(res.files['.gitignore']).toBeTruthy(); - expect(res.files['.eslintrc']).toBeTruthy(); + expect(res.files['.eslintrc.js']).toBeTruthy(); }); }); diff --git a/packages/kbn-plugin-generator/sao_template/template/.i18nrc.json b/packages/kbn-plugin-generator/sao_template/template/.i18nrc.json index edcca37a248f..1a8aea885387 100644 --- a/packages/kbn-plugin-generator/sao_template/template/.i18nrc.json +++ b/packages/kbn-plugin-generator/sao_template/template/.i18nrc.json @@ -1,5 +1,9 @@ { "paths": { "<%= camelCase(name) %>": "./" - } + }, + "translations": [ + "translations/zh-CN.json" + ] } + diff --git a/packages/kbn-plugin-generator/sao_template/template/eslintrc b/packages/kbn-plugin-generator/sao_template/template/eslintrc deleted file mode 100755 index e54900aa3024..000000000000 --- a/packages/kbn-plugin-generator/sao_template/template/eslintrc +++ /dev/null @@ -1,7 +0,0 @@ ---- -extends: "@elastic/kibana" - -settings: - import/resolver: - '@elastic/eslint-import-resolver-kibana': - rootPackageName: '<%= snakeCase(name) %>' diff --git a/packages/kbn-plugin-generator/sao_template/template/eslintrc.js b/packages/kbn-plugin-generator/sao_template/template/eslintrc.js new file mode 100755 index 000000000000..e1dfadc212b7 --- /dev/null +++ b/packages/kbn-plugin-generator/sao_template/template/eslintrc.js @@ -0,0 +1,24 @@ +module.exports = { + root: true, + extends: ['@elastic/eslint-config-kibana', 'plugin:@elastic/eui/recommended'], + settings: { + 'import/resolver': { + '@kbn/eslint-import-resolver-kibana': { + rootPackageName: '<%= snakeCase(name) %>', + }, + }, + }, + overrides: [ + { + files: ['**/public/**/*'], + settings: { + 'import/resolver': { + '@kbn/eslint-import-resolver-kibana': { + forceNode: false, + rootPackageName: '<%= snakeCase(name) %>', + }, + }, + }, + }, + ] +}; diff --git a/packages/kbn-plugin-generator/sao_template/template/index.js b/packages/kbn-plugin-generator/sao_template/template/index.js index 40ed14af52c6..0a3e16cf71e4 100755 --- a/packages/kbn-plugin-generator/sao_template/template/index.js +++ b/packages/kbn-plugin-generator/sao_template/template/index.js @@ -43,39 +43,39 @@ export default function (kibana) { init(server, options) { // eslint-disable-line no-unused-vars <%_ if (generateApp) { -%> - const xpackMainPlugin = server.plugins.xpack_main; - if (xpackMainPlugin) { - const featureId = '<%= snakeCase(name) %>'; + const xpackMainPlugin = server.plugins.xpack_main; + if (xpackMainPlugin) { + const featureId = '<%= snakeCase(name) %>'; - xpackMainPlugin.registerFeature({ - id: featureId, - name: i18n.translate('<%= camelCase(name) %>.featureRegistry.featureName', { - defaultMessage: '<%= name %>', - }), - navLinkId: featureId, - icon: 'questionInCircle', - app: [featureId, 'kibana'], - catalogue: [], - privileges: { - all: { - api: [], - savedObject: { - all: [], - read: [], - }, - ui: ['show'], - }, - read: { - api: [], - savedObject: { - all: [], - read: [], - }, - ui: ['show'], + xpackMainPlugin.registerFeature({ + id: featureId, + name: i18n.translate('<%= camelCase(name) %>.featureRegistry.featureName', { + defaultMessage: '<%= name %>', + }), + navLinkId: featureId, + icon: 'questionInCircle', + app: [featureId, 'kibana'], + catalogue: [], + privileges: { + all: { + api: [], + savedObject: { + all: [], + read: [], }, + ui: ['show'], }, - }); - } + read: { + api: [], + savedObject: { + all: [], + read: [], + }, + ui: ['show'], + }, + }, + }); + } <%_ } -%> <%_ if (generateApi) { -%> diff --git a/packages/kbn-plugin-generator/sao_template/template/public/components/main/index.js b/packages/kbn-plugin-generator/sao_template/template/public/components/main/index.js index b8dd6dff2e53..68710baa1bee 100644 --- a/packages/kbn-plugin-generator/sao_template/template/public/components/main/index.js +++ b/packages/kbn-plugin-generator/sao_template/template/public/components/main/index.js @@ -1 +1 @@ -export { Main } from './main'; \ No newline at end of file +export { Main } from './main'; diff --git a/scripts/jest_integration.js b/scripts/jest_integration.js index 5eafcca2176c..7da1436f5583 100755 --- a/scripts/jest_integration.js +++ b/scripts/jest_integration.js @@ -31,6 +31,7 @@ var resolve = require('path').resolve; process.argv.push('--config', resolve(__dirname, '../src/dev/jest/config.integration.js')); +process.argv.push('--runInBand'); require('../src/setup_node_env'); require('../src/dev/jest/cli'); diff --git a/src/dev/jest/setup/after_env.integration.js b/src/dev/jest/setup/after_env.integration.js index 7a2e7b8ab31c..21a9545c7cf7 100644 --- a/src/dev/jest/setup/after_env.integration.js +++ b/src/dev/jest/setup/after_env.integration.js @@ -20,6 +20,6 @@ /* eslint-env jest */ /** - * Set the default timeout for the integration test suite to 30 seconds + * Set the default timeout for the integration test suite to 10 minutes */ -jest.setTimeout(30 * 1000); +jest.setTimeout(10 * 60 * 1000); diff --git a/src/legacy/core_plugins/tests_bundle/index.js b/src/legacy/core_plugins/tests_bundle/index.js index ae14438119da..803fe1d220f4 100644 --- a/src/legacy/core_plugins/tests_bundle/index.js +++ b/src/legacy/core_plugins/tests_bundle/index.js @@ -52,17 +52,13 @@ export default (kibana) => { } } = kbnServer; - const testGlobs = [ - 'src/legacy/ui/public/**/*.js', - '!src/legacy/ui/public/flot-charts/**/*', - ]; + const testGlobs = []; + const testingPluginIds = config.get('tests_bundle.pluginId'); if (testingPluginIds) { - testGlobs.push('!src/legacy/ui/public/**/__tests__/**/*'); testingPluginIds.split(',').forEach((pluginId) => { - const plugin = plugins - .find(plugin => plugin.id === pluginId); + const plugin = plugins.find(plugin => plugin.id === pluginId); if (!plugin) { throw new Error('Invalid testingPluginId :: unknown plugin ' + pluginId); @@ -78,6 +74,8 @@ export default (kibana) => { 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());