From affe64699e2bd23a50d9935fea472f83f29ef43a Mon Sep 17 00:00:00 2001 From: yaacov Date: Sun, 21 Jul 2019 16:29:19 +0300 Subject: [PATCH] Make integration tests a pakcage --- frontend/integration-tests/package.json | 14 +++++ frontend/integration-tests/protractor.conf.ts | 3 ++ .../integration-tests/tests/login.scenario.ts | 4 +- frontend/package.json | 6 +-- .../integration-tests/tests/demo.scenario.ts | 17 +++++++ .../packages/console-demo-plugin/package.json | 14 ++++- .../plugin-integration-tests.spec.ts | 51 +++++++++++++++++++ .../console-plugin-sdk/src/codegen/index.ts | 1 + .../src/codegen/plugin-integration-tests.ts | 42 +++++++++++++++ .../src/codegen/plugin-resolver.ts | 3 +- .../src/typings/extension.ts | 2 +- 11 files changed, 147 insertions(+), 10 deletions(-) create mode 100644 frontend/integration-tests/package.json create mode 100644 frontend/packages/console-demo-plugin/integration-tests/tests/demo.scenario.ts create mode 100644 frontend/packages/console-plugin-sdk/src/codegen/__tests__/plugin-integration-tests.spec.ts create mode 100644 frontend/packages/console-plugin-sdk/src/codegen/plugin-integration-tests.ts diff --git a/frontend/integration-tests/package.json b/frontend/integration-tests/package.json new file mode 100644 index 000000000000..9e284362ae4b --- /dev/null +++ b/frontend/integration-tests/package.json @@ -0,0 +1,14 @@ +{ + "name": "@console/integration-tests", + "version": "0.0.0-fixed", + "description": "Console integration tests", + "private": true, + "devDependencies": { + "protractor": "5.4.x", + "protractor-fail-fast": "3.x", + "protractor-jasmine2-screenshot-reporter": "0.5.x", + "js-yaml": "^3.13.1", + "lodash-es": "4.x", + "immutable": "3.x" + } +} diff --git a/frontend/integration-tests/protractor.conf.ts b/frontend/integration-tests/protractor.conf.ts index 3eb064599409..211104856257 100644 --- a/frontend/integration-tests/protractor.conf.ts +++ b/frontend/integration-tests/protractor.conf.ts @@ -7,6 +7,7 @@ import * as ConsoleReporter from 'jasmine-console-reporter'; import * as failFast from 'protractor-fail-fast'; import { createWriteStream } from 'fs'; import { format } from 'util'; +import { pluginsIntegrationTests } from '@console/plugin-sdk/src/codegen'; const tap = !!process.env.TAP; @@ -19,6 +20,7 @@ const junitReporter = new JUnitXmlReporter({ savePath: './gui_test_screenshots', const browserLogs: logging.Entry[] = []; const suite = (tests: string[]) => (!_.isNil(process.env.BRIDGE_KUBEADMIN_PASSWORD) ? ['tests/login.scenario.ts'] : []).concat(['tests/base.scenario.ts', ...tests]); +const pluginSuites = pluginsIntegrationTests(); export const config: Config = { framework: 'jasmine', @@ -87,6 +89,7 @@ export const config: Config = { return new Promise(resolve => htmlReporter.afterLaunch(resolve.bind(this, exitCode))); }, suites: { + ...pluginSuites, filter: suite([ 'tests/filter.scenario.ts', ]), diff --git a/frontend/integration-tests/tests/login.scenario.ts b/frontend/integration-tests/tests/login.scenario.ts index 75b725c1c6e9..8d465c09eb74 100644 --- a/frontend/integration-tests/tests/login.scenario.ts +++ b/frontend/integration-tests/tests/login.scenario.ts @@ -65,7 +65,7 @@ describe('Auth test', () => { it('logs out htpasswd user', async() => { await loginView.logout(); - expect(browser.getCurrentUrl()).toContain('oauth-openshift'); + expect(browser.getCurrentUrl()).toContain('openshift'); expect($('.login-pf').isPresent()).toBeTruthy(); }); @@ -79,7 +79,7 @@ describe('Auth test', () => { it('logs out kubeadmin user', async() => { await loginView.logout(); - expect(browser.getCurrentUrl()).toContain('oauth-openshift'); + expect(browser.getCurrentUrl()).toContain('openshift'); expect($('.login-pf').isPresent()).toBeTruthy(); // Log back in so that remaining tests can be run diff --git a/frontend/package.json b/frontend/package.json index 38f705918ad6..965fd28b84dd 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -5,7 +5,8 @@ "private": true, "workspaces": [ "packages/*", - "public" + "public", + "integration-tests" ], "scripts": { "clean": "rm -rf ./public/dist", @@ -165,9 +166,6 @@ "jest-cli": "21.x", "mini-css-extract-plugin": "0.4.x", "node-sass": "4.8.x", - "protractor": "5.4.x", - "protractor-fail-fast": "3.x", - "protractor-jasmine2-screenshot-reporter": "0.5.x", "read-pkg": "5.x", "redux-mock-store": "^1.5.3", "resolve-url-loader": "2.x", diff --git a/frontend/packages/console-demo-plugin/integration-tests/tests/demo.scenario.ts b/frontend/packages/console-demo-plugin/integration-tests/tests/demo.scenario.ts new file mode 100644 index 000000000000..b59103163b02 --- /dev/null +++ b/frontend/packages/console-demo-plugin/integration-tests/tests/demo.scenario.ts @@ -0,0 +1,17 @@ +import { browser, ExpectedConditions as until, $, $$ } from 'protractor'; +import { appHost, testName } from '@console/integration-tests/protractor.conf'; +import * as crudView from '@console/integration-tests/views/crud.view'; + +const BROWSER_TIMEOUT = 15000; + +describe('Demo integration test', () => { + it(`Test namespace ${testName}`, async () => { + // Use projects if OpenShift so non-admin users can run tests. + const resource = browser.params.openshift === 'true' ? 'projects' : 'namespaces'; + await browser.get(`${appHost}/k8s/cluster/${resource}`); + await crudView.isLoaded(); + const exists = await crudView.rowForName(testName).isPresent(); + + expect(browser.getCurrentUrl()).toContain(appHost); + }); +}); diff --git a/frontend/packages/console-demo-plugin/package.json b/frontend/packages/console-demo-plugin/package.json index bf37da7fd56e..d95cdf3d81ad 100644 --- a/frontend/packages/console-demo-plugin/package.json +++ b/frontend/packages/console-demo-plugin/package.json @@ -1,5 +1,5 @@ { - "name": "@console/demo-plugin", + "name": "@console/console-demo-plugin", "version": "0.0.0-fixed", "description": "Demo plugin for Console web application", "private": true, @@ -7,7 +7,17 @@ "@console/plugin-sdk": "0.0.0-fixed", "@console/shared": "0.0.0-fixed" }, + "devDependencies": { + "@console/integration-tests": "0.0.0-fixed" + }, "consolePlugin": { - "entry": "src/plugin.tsx" + "entry": "src/plugin.tsx", + "integrationTests": { + "demo": [ + "@console/integration-tests/tests/login.scenario.ts", + "@console/integration-tests/tests/base.scenario.ts", + "integration-tests/tests/demo.scenario.ts" + ] + } } } diff --git a/frontend/packages/console-plugin-sdk/src/codegen/__tests__/plugin-integration-tests.spec.ts b/frontend/packages/console-plugin-sdk/src/codegen/__tests__/plugin-integration-tests.spec.ts new file mode 100644 index 000000000000..d7d72ab4aab5 --- /dev/null +++ b/frontend/packages/console-plugin-sdk/src/codegen/__tests__/plugin-integration-tests.spec.ts @@ -0,0 +1,51 @@ +import { PluginPackage, Package, filterActivePluginPackages } from '../plugin-resolver'; +import { pluginsIntegrationTests } from '../plugin-integration-tests'; +import { templatePackage } from './plugin-resolver.spec'; + +describe('pluginsIntegrationTests', () => { + it('returns a map of short-plugin-name to a list of its integration tests.', () => { + const appPackage: Package = { + ...templatePackage, + name: 'app', + dependencies: { + '@console/bar-plugin': '1.2.3', + '@console/qux-plugin': '2.3.4', + }, + }; + + const pluginPackages: PluginPackage[] = [ + { + ...templatePackage, + name: '@console/bar-plugin', + version: '1.2.3', + consolePlugin: { + entry: 'plugin.ts', + integrationTests: { + bar: [ + '@console/integration-tests/tests/base.scenario.ts', + 'integration-tests/tests/index.scenario.ts', + ], + }, + }, + }, + { + ...templatePackage, + name: '@console/qux-plugin', + version: '2.3.4', + consolePlugin: { entry: 'plugin.ts' }, + }, + ]; + + const pluginFilter = () => filterActivePluginPackages(appPackage, pluginPackages); + + const monorepoRootDir = process.cwd(); + const expectedTests = { + bar: [ + 'tests/base.scenario.ts', + `${monorepoRootDir}/packages/bar-plugin/integration-tests/tests/index.scenario.ts`, + ], + }; + + expect(pluginsIntegrationTests(monorepoRootDir, pluginFilter)).toEqual(expectedTests); + }); +}); diff --git a/frontend/packages/console-plugin-sdk/src/codegen/index.ts b/frontend/packages/console-plugin-sdk/src/codegen/index.ts index fc704ab4b1a0..a68b86d32f5b 100644 --- a/frontend/packages/console-plugin-sdk/src/codegen/index.ts +++ b/frontend/packages/console-plugin-sdk/src/codegen/index.ts @@ -1,3 +1,4 @@ export { resolvePluginPackages } from './plugin-resolver'; +export { pluginsIntegrationTests } from './plugin-integration-tests'; export { loadActivePlugins, getActivePluginsModule } from './active-plugins'; export { printPluginStats } from './plugin-stats'; diff --git a/frontend/packages/console-plugin-sdk/src/codegen/plugin-integration-tests.ts b/frontend/packages/console-plugin-sdk/src/codegen/plugin-integration-tests.ts new file mode 100644 index 000000000000..fbd716ee33a7 --- /dev/null +++ b/frontend/packages/console-plugin-sdk/src/codegen/plugin-integration-tests.ts @@ -0,0 +1,42 @@ +import * as _ from 'lodash'; +import { + PluginPackage, + filterActivePluginPackages, + PluginPackageFilter, + resolvePluginPackages, +} from './plugin-resolver'; + +const CONSOLE_PLUGIN_PREFIX = '@console/'; +const CONSOLE_INEGRATION_TESTS_PREFIX = '@console/integration-tests/'; + +/** + * Return a map of short-plugin-name to a list of it's integration tests. + */ +export const pluginsIntegrationTests = ( + monorepoRootDir: string = process.cwd(), + pluginFilter: PluginPackageFilter = filterActivePluginPackages, +) => { + const shortName = (plugin: PluginPackage) => + plugin.name.startsWith(CONSOLE_PLUGIN_PREFIX) && plugin.name.slice(CONSOLE_PLUGIN_PREFIX.length); + + const integrationTests = (plugin: PluginPackage) => + plugin.consolePlugin.integrationTests && + _.transform( + plugin.consolePlugin.integrationTests, + (result, paths, testName) => + (result[testName] = _.map(paths, (path) => + path.startsWith(CONSOLE_INEGRATION_TESTS_PREFIX) + ? path.slice(CONSOLE_INEGRATION_TESTS_PREFIX.length) + : `${monorepoRootDir}/packages/${shortName(plugin)}/${path}`, + )), + {}, + ); + + const plugins = resolvePluginPackages(monorepoRootDir, pluginFilter); + const pluginTests = plugins.reduce( + (map, plugin) => Object.assign(map, integrationTests(plugin)), + {}, + ); + + return _.pickBy(pluginTests, (tests) => !!tests); +}; diff --git a/frontend/packages/console-plugin-sdk/src/codegen/plugin-resolver.ts b/frontend/packages/console-plugin-sdk/src/codegen/plugin-resolver.ts index 0c574ac3f19e..fb01a46f8e40 100644 --- a/frontend/packages/console-plugin-sdk/src/codegen/plugin-resolver.ts +++ b/frontend/packages/console-plugin-sdk/src/codegen/plugin-resolver.ts @@ -95,10 +95,11 @@ export type Package = readPkg.NormalizedPackageJson; export type PluginPackage = Package & { consolePlugin: { entry: string; + integrationTests?: Record; }; }; -type PluginPackageFilter = ( +export type PluginPackageFilter = ( appPackage: Package, pluginPackages: PluginPackage[], ) => PluginPackage[]; diff --git a/frontend/packages/console-plugin-sdk/src/typings/extension.ts b/frontend/packages/console-plugin-sdk/src/typings/extension.ts index 48af065e3c5a..e41ee9e74c43 100644 --- a/frontend/packages/console-plugin-sdk/src/typings/extension.ts +++ b/frontend/packages/console-plugin-sdk/src/typings/extension.ts @@ -27,7 +27,7 @@ export type Extension

= { * * ```json * { - * "name": "@console/demo-plugin", + * "name": "@console/console-demo-plugin", * "version": "0.0.0-fixed", * // scripts, dependencies, etc. * "consolePlugin": {