From 5f2f07315e68deb93827ed1e544d914894f2a2f3 Mon Sep 17 00:00:00 2001 From: Eli Perelman Date: Thu, 16 Jan 2020 13:01:16 -0600 Subject: [PATCH] Generate legacy vars when rendering all applications (#54768) (#55082) * Generate legacy vars when rendering all applications * Move rendering functional tests and add user settings tests * Make rendering integration tests more robust, get data from page * Address review nits, fix CI failures * Remove extraneous file * Fix type error --- ...in-server.iscopedrenderingclient.render.md | 4 +- src/core/server/index.ts | 2 +- src/core/server/legacy/legacy_internals.ts | 14 +- src/core/server/legacy/legacy_service.ts | 9 +- src/core/server/legacy/types.ts | 8 +- .../server/rendering/rendering_service.tsx | 4 +- src/core/server/rendering/types.ts | 14 +- src/core/server/server.api.md | 20 ++- src/core/server/server.ts | 6 +- src/plugins/testbed/server/index.ts | 24 ---- test/api_integration/apis/core/index.js | 5 - .../plugins/rendering_plugin/kibana.json | 8 ++ .../plugins/rendering_plugin/package.json | 17 +++ .../plugins/rendering_plugin/public/index.ts | 23 ++++ .../rendering_plugin/public/plugin.tsx | 41 ++++++ .../plugins/rendering_plugin/server/index.ts | 22 +++ .../plugins/rendering_plugin/server/plugin.ts | 63 +++++++++ .../plugins/rendering_plugin/tsconfig.json | 15 +++ .../test_suites/core_plugins/applications.ts | 4 +- .../test_suites/core_plugins/index.ts | 1 + .../test_suites/core_plugins/rendering.ts | 127 ++++++++++++++++++ .../core_plugins/server_plugins.ts | 10 -- 22 files changed, 368 insertions(+), 73 deletions(-) create mode 100644 test/plugin_functional/plugins/rendering_plugin/kibana.json create mode 100644 test/plugin_functional/plugins/rendering_plugin/package.json create mode 100644 test/plugin_functional/plugins/rendering_plugin/public/index.ts create mode 100644 test/plugin_functional/plugins/rendering_plugin/public/plugin.tsx create mode 100644 test/plugin_functional/plugins/rendering_plugin/server/index.ts create mode 100644 test/plugin_functional/plugins/rendering_plugin/server/plugin.ts create mode 100644 test/plugin_functional/plugins/rendering_plugin/tsconfig.json create mode 100644 test/plugin_functional/test_suites/core_plugins/rendering.ts diff --git a/docs/development/core/server/kibana-plugin-server.iscopedrenderingclient.render.md b/docs/development/core/server/kibana-plugin-server.iscopedrenderingclient.render.md index 1bc78dd84571d..42cbc59c536a6 100644 --- a/docs/development/core/server/kibana-plugin-server.iscopedrenderingclient.render.md +++ b/docs/development/core/server/kibana-plugin-server.iscopedrenderingclient.render.md @@ -9,14 +9,14 @@ Generate a `KibanaResponse` which renders an HTML page bootstrapped with the `co Signature: ```typescript -render(options?: IRenderOptions): Promise; +render(options?: Pick): Promise; ``` ## Parameters | Parameter | Type | Description | | --- | --- | --- | -| options | IRenderOptions | | +| options | Pick<IRenderOptions, 'includeUserSettings'> | | Returns: diff --git a/src/core/server/index.ts b/src/core/server/index.ts index eccf3985fc495..8f39cc33cae79 100644 --- a/src/core/server/index.ts +++ b/src/core/server/index.ts @@ -152,7 +152,7 @@ export { SessionCookieValidationResult, SessionStorageFactory, } from './http'; -export { RenderingServiceSetup, IRenderOptions, LegacyRenderOptions } from './rendering'; +export { RenderingServiceSetup, IRenderOptions } from './rendering'; export { Logger, LoggerFactory, LogMeta, LogRecord, LogLevel } from './logging'; export { diff --git a/src/core/server/legacy/legacy_internals.ts b/src/core/server/legacy/legacy_internals.ts index 3bf54e5f75dce..628ca4ed12f6b 100644 --- a/src/core/server/legacy/legacy_internals.ts +++ b/src/core/server/legacy/legacy_internals.ts @@ -19,7 +19,8 @@ import { Server } from 'hapi'; -import { LegacyRequest } from '../http'; +import { KibanaRequest, LegacyRequest } from '../http'; +import { ensureRawRequest } from '../http/router'; import { mergeVars } from './merge_vars'; import { ILegacyInternals, LegacyVars, VarsInjector, LegacyConfig, LegacyUiExports } from './types'; @@ -51,11 +52,12 @@ export class LegacyInternals implements ILegacyInternals { )); } - private replaceVars(vars: LegacyVars, request: LegacyRequest) { + private replaceVars(vars: LegacyVars, request: KibanaRequest | LegacyRequest) { const { injectedVarsReplacers = [] } = this.uiExports; return injectedVarsReplacers.reduce( - async (injected, replacer) => replacer(await injected, request, this.server), + async (injected, replacer) => + replacer(await injected, ensureRawRequest(request), this.server), Promise.resolve(vars) ); } @@ -78,7 +80,11 @@ export class LegacyInternals implements ILegacyInternals { ); } - public async getVars(id: string, request: LegacyRequest, injected: LegacyVars = {}) { + public async getVars( + id: string, + request: KibanaRequest | LegacyRequest, + injected: LegacyVars = {} + ) { return this.replaceVars( mergeVars(this.defaultVars, await this.getInjectedUiAppVars(id), injected), request diff --git a/src/core/server/legacy/legacy_service.ts b/src/core/server/legacy/legacy_service.ts index 7a03cefc38c1a..ffcbf1662ee85 100644 --- a/src/core/server/legacy/legacy_service.ts +++ b/src/core/server/legacy/legacy_service.ts @@ -31,6 +31,7 @@ import { PathConfigType } from '../path'; import { findLegacyPluginSpecs } from './plugins'; import { convertLegacyDeprecationProvider } from './config'; import { + ILegacyInternals, LegacyServiceSetupDeps, LegacyServiceStartDeps, LegacyPlugins, @@ -82,6 +83,7 @@ export class LegacyService implements CoreService { private legacyRawConfig?: LegacyConfig; private legacyPlugins?: LegacyPlugins; private settings?: LegacyVars; + public legacyInternals?: ILegacyInternals; constructor(private readonly coreContext: CoreContext) { const { logger, configService } = coreContext; @@ -183,6 +185,11 @@ export class LegacyService implements CoreService { // propagate the instance uuid to the legacy config, as it was the legacy way to access it. this.legacyRawConfig!.set('server.uuid', setupDeps.core.uuid.getInstanceUuid()); this.setupDeps = setupDeps; + this.legacyInternals = new LegacyInternals( + this.legacyPlugins.uiExports, + this.legacyRawConfig!, + setupDeps.core.http.server + ); } public async start(startDeps: LegacyServiceStartDeps) { @@ -317,7 +324,7 @@ export class LegacyService implements CoreService { rendering: setupDeps.core.rendering, uiSettings: setupDeps.core.uiSettings, savedObjectsClientProvider: startDeps.core.savedObjects.clientProvider, - legacy: new LegacyInternals(legacyPlugins.uiExports, config, setupDeps.core.http.server), + legacy: this.legacyInternals, }, logger: this.coreContext.logger, }, diff --git a/src/core/server/legacy/types.ts b/src/core/server/legacy/types.ts index 6ec893be9b310..40b8244a31890 100644 --- a/src/core/server/legacy/types.ts +++ b/src/core/server/legacy/types.ts @@ -20,7 +20,7 @@ import { Server } from 'hapi'; import { ChromeNavLink } from '../../public'; -import { LegacyRequest } from '../http'; +import { KibanaRequest, LegacyRequest } from '../http'; import { InternalCoreSetup, InternalCoreStart } from '../internal_types'; import { PluginsServiceSetup, PluginsServiceStart } from '../plugins'; import { RenderingServiceSetup } from '../rendering'; @@ -198,7 +198,11 @@ export interface ILegacyInternals { /** * Get the metadata vars for a particular plugin */ - getVars(id: string, request: LegacyRequest, injected?: LegacyVars): Promise; + getVars( + id: string, + request: KibanaRequest | LegacyRequest, + injected?: LegacyVars + ): Promise; } /** diff --git a/src/core/server/rendering/rendering_service.tsx b/src/core/server/rendering/rendering_service.tsx index 41810c6a10655..11d1fb271c81d 100644 --- a/src/core/server/rendering/rendering_service.tsx +++ b/src/core/server/rendering/rendering_service.tsx @@ -27,10 +27,10 @@ import { CoreService } from '../../types'; import { CoreContext } from '../core_context'; import { Template } from './views'; import { + IRenderOptions, RenderingSetupDeps, RenderingServiceSetup, RenderingMetadata, - LegacyRenderOptions, } from './types'; /** @internal */ @@ -56,7 +56,7 @@ export class RenderingService implements CoreService { app = { getId: () => 'core' }, includeUserSettings = true, vars = {}, - }: LegacyRenderOptions = {} + }: IRenderOptions = {} ) => { const { env } = this.coreContext; const basePath = http.basePath.get(request); diff --git a/src/core/server/rendering/types.ts b/src/core/server/rendering/types.ts index 31b326bab6c78..3f9f6ff294909 100644 --- a/src/core/server/rendering/types.ts +++ b/src/core/server/rendering/types.ts @@ -84,21 +84,19 @@ export interface IRenderOptions { * `true` by default. */ includeUserSettings?: boolean; -} -/** - * @internal - * @deprecated for legacy use only, remove with ui_render_mixin - */ -export interface LegacyRenderOptions extends IRenderOptions { /** * Render the bootstrapped HTML content for an optional legacy application. * Defaults to `core`. + * @deprecated for legacy use only, remove with ui_render_mixin + * @internal */ app?: { getId(): string }; /** * Inject custom vars into the page metadata. + * @deprecated for legacy use only, remove with ui_render_mixin + * @internal */ vars?: Record; } @@ -123,7 +121,7 @@ export interface IScopedRenderingClient { * ); * ``` */ - render(options?: IRenderOptions): Promise; + render(options?: Pick): Promise; } /** @internal */ @@ -140,6 +138,6 @@ export interface RenderingServiceSetup { render( request: R, uiSettings: IUiSettingsClient, - options?: R extends LegacyRequest ? LegacyRenderOptions : IRenderOptions + options?: IRenderOptions ): Promise; } diff --git a/src/core/server/server.api.md b/src/core/server/server.api.md index 7f3a960571012..13b5c6f277e8c 100644 --- a/src/core/server/server.api.md +++ b/src/core/server/server.api.md @@ -803,7 +803,13 @@ export interface IndexSettingsDeprecationInfo { // @public (undocumented) export interface IRenderOptions { + // @internal @deprecated + app?: { + getId(): string; + }; includeUserSettings?: boolean; + // @internal @deprecated + vars?: Record; } // @public @@ -832,7 +838,7 @@ export type IScopedClusterClient = Pick; + render(options?: Pick): Promise; } // @public @@ -932,21 +938,13 @@ export class LegacyInternals implements ILegacyInternals { // (undocumented) getInjectedUiAppVars(id: string): Promise>; // (undocumented) - getVars(id: string, request: LegacyRequest, injected?: LegacyVars): Promise>; + getVars(id: string, request: KibanaRequest | LegacyRequest, injected?: LegacyVars): Promise>; // Warning: (ae-forgotten-export) The symbol "VarsInjector" needs to be exported by the entry point index.d.ts // // (undocumented) injectUiAppVars(id: string, injector: VarsInjector): void; } -// @internal @deprecated (undocumented) -export interface LegacyRenderOptions extends IRenderOptions { - app?: { - getId(): string; - }; - vars?: Record; -} - // @public @deprecated (undocumented) export interface LegacyRequest extends Request { } @@ -1233,7 +1231,7 @@ export type RedirectResponseOptions = HttpResponseOptions & { // @internal (undocumented) export interface RenderingServiceSetup { - render(request: R, uiSettings: IUiSettingsClient, options?: R extends LegacyRequest ? LegacyRenderOptions : IRenderOptions): Promise; + render(request: R, uiSettings: IUiSettingsClient, options?: IRenderOptions): Promise; } // @public diff --git a/src/core/server/server.ts b/src/core/server/server.ts index 7c3f9f249db13..89a5bdc4802fd 100644 --- a/src/core/server/server.ts +++ b/src/core/server/server.ts @@ -220,7 +220,11 @@ export class Server { return { rendering: { - render: rendering.render.bind(rendering, req, uiSettingsClient), + render: async (options = {}) => + rendering.render(req, uiSettingsClient, { + ...options, + vars: await this.legacy.legacyInternals!.getVars('core', req), + }), }, savedObjects: { client: savedObjectsClient, diff --git a/src/plugins/testbed/server/index.ts b/src/plugins/testbed/server/index.ts index 4873fe0926472..96d5612508a96 100644 --- a/src/plugins/testbed/server/index.ts +++ b/src/plugins/testbed/server/index.ts @@ -23,7 +23,6 @@ import { schema, TypeOf } from '@kbn/config-schema'; import { CoreSetup, CoreStart, - LegacyRenderOptions, Logger, PluginInitializerContext, PluginConfigDescriptor, @@ -78,29 +77,6 @@ class Plugin { } ); - router.get( - { - path: '/requestcontext/render/{id}', - validate: { - params: schema.object({ - id: schema.maybe(schema.string()), - }), - }, - }, - async (context, req, res) => { - const { id } = req.params; - const options: Partial = { app: { getId: () => id! } }; - const body = await context.core.rendering.render(options); - - return res.ok({ - body, - headers: { - 'content-securty-policy': core.http.csp.header, - }, - }); - } - ); - return { data$: this.initializerContext.config.create().pipe( map(configValue => { diff --git a/test/api_integration/apis/core/index.js b/test/api_integration/apis/core/index.js index 766faf067e4ac..be1ecf9b9c497 100644 --- a/test/api_integration/apis/core/index.js +++ b/test/api_integration/apis/core/index.js @@ -33,11 +33,6 @@ export default function({ getService }) { 200, 'SavedObjects client: {"page":1,"per_page":20,"total":0,"saved_objects":[]}' )); - - it('provides access to application rendering client', async () => { - await supertest.get('/requestcontext/render/core').expect(200, /app:core/); - await supertest.get('/requestcontext/render/testbed').expect(200, /app:testbed/); - }); }); describe('compression', () => { diff --git a/test/plugin_functional/plugins/rendering_plugin/kibana.json b/test/plugin_functional/plugins/rendering_plugin/kibana.json new file mode 100644 index 0000000000000..886eca2bdde1d --- /dev/null +++ b/test/plugin_functional/plugins/rendering_plugin/kibana.json @@ -0,0 +1,8 @@ +{ + "id": "rendering_plugin", + "version": "0.0.1", + "kibanaVersion": "kibana", + "configPath": ["rendering_plugin"], + "server": true, + "ui": true +} diff --git a/test/plugin_functional/plugins/rendering_plugin/package.json b/test/plugin_functional/plugins/rendering_plugin/package.json new file mode 100644 index 0000000000000..9ab6eccbe31be --- /dev/null +++ b/test/plugin_functional/plugins/rendering_plugin/package.json @@ -0,0 +1,17 @@ +{ + "name": "rendering_plugin", + "version": "1.0.0", + "main": "target/test/plugin_functional/plugins/rendering_plugin", + "kibana": { + "version": "kibana", + "templateVersion": "1.0.0" + }, + "license": "Apache-2.0", + "scripts": { + "kbn": "node ../../../../scripts/kbn.js", + "build": "rm -rf './target' && tsc" + }, + "devDependencies": { + "typescript": "3.5.3" + } +} diff --git a/test/plugin_functional/plugins/rendering_plugin/public/index.ts b/test/plugin_functional/plugins/rendering_plugin/public/index.ts new file mode 100644 index 0000000000000..c32f3c03e8c63 --- /dev/null +++ b/test/plugin_functional/plugins/rendering_plugin/public/index.ts @@ -0,0 +1,23 @@ +/* + * 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 { PluginInitializer } from 'kibana/public'; +import { RenderingPlugin } from './plugin'; + +export const plugin: PluginInitializer = () => new RenderingPlugin(); diff --git a/test/plugin_functional/plugins/rendering_plugin/public/plugin.tsx b/test/plugin_functional/plugins/rendering_plugin/public/plugin.tsx new file mode 100644 index 0000000000000..6e80b56953ca0 --- /dev/null +++ b/test/plugin_functional/plugins/rendering_plugin/public/plugin.tsx @@ -0,0 +1,41 @@ +/* + * 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 React from 'react'; +import { render, unmountComponentAtNode } from 'react-dom'; +import { Plugin, CoreSetup } from 'kibana/public'; + +export class RenderingPlugin implements Plugin { + public setup(core: CoreSetup) { + core.application.register({ + id: 'rendering', + title: 'Rendering', + appRoute: '/render', + async mount(context, { element }) { + render(

rendering service

, element); + + return () => unmountComponentAtNode(element); + }, + }); + } + + public start() {} + + public stop() {} +} diff --git a/test/plugin_functional/plugins/rendering_plugin/server/index.ts b/test/plugin_functional/plugins/rendering_plugin/server/index.ts new file mode 100644 index 0000000000000..90ffdebb29f29 --- /dev/null +++ b/test/plugin_functional/plugins/rendering_plugin/server/index.ts @@ -0,0 +1,22 @@ +/* + * 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 { RenderingPlugin } from './plugin'; + +export const plugin = () => new RenderingPlugin(); diff --git a/test/plugin_functional/plugins/rendering_plugin/server/plugin.ts b/test/plugin_functional/plugins/rendering_plugin/server/plugin.ts new file mode 100644 index 0000000000000..fad19728b7514 --- /dev/null +++ b/test/plugin_functional/plugins/rendering_plugin/server/plugin.ts @@ -0,0 +1,63 @@ +/* + * 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 { Plugin, CoreSetup, IRenderOptions } from 'kibana/server'; + +import { schema } from '@kbn/config-schema'; + +export class RenderingPlugin implements Plugin { + public setup(core: CoreSetup) { + const router = core.http.createRouter(); + + router.get( + { + path: '/render/{id}', + validate: { + query: schema.object( + { + includeUserSettings: schema.boolean({ defaultValue: true }), + }, + { allowUnknowns: true } + ), + params: schema.object({ + id: schema.maybe(schema.string()), + }), + }, + }, + async (context, req, res) => { + const { id } = req.params; + const { includeUserSettings } = req.query; + const app = { getId: () => id! }; + const options: Partial = { app, includeUserSettings }; + const body = await context.core.rendering.render(options); + + return res.ok({ + body, + headers: { + 'content-security-policy': core.http.csp.header, + }, + }); + } + ); + } + + public start() {} + + public stop() {} +} diff --git a/test/plugin_functional/plugins/rendering_plugin/tsconfig.json b/test/plugin_functional/plugins/rendering_plugin/tsconfig.json new file mode 100644 index 0000000000000..1ba21f11b7de2 --- /dev/null +++ b/test/plugin_functional/plugins/rendering_plugin/tsconfig.json @@ -0,0 +1,15 @@ +{ + "extends": "../../../../tsconfig.json", + "compilerOptions": { + "outDir": "./target", + "skipLibCheck": true + }, + "include": [ + "index.ts", + "public/**/*.ts", + "public/**/*.tsx", + "server/**/*.ts", + "../../../../typings/**/*", + ], + "exclude": [] +} diff --git a/test/plugin_functional/test_suites/core_plugins/applications.ts b/test/plugin_functional/test_suites/core_plugins/applications.ts index 231458fad155b..f50d460532556 100644 --- a/test/plugin_functional/test_suites/core_plugins/applications.ts +++ b/test/plugin_functional/test_suites/core_plugins/applications.ts @@ -121,13 +121,13 @@ export default function({ getService, getPageObjects }: PluginFunctionalProvider expect(wrapperWidth).to.be.below(windowWidth); }); - it.skip('can navigate from NP apps to legacy apps', async () => { + it('can navigate from NP apps to legacy apps', async () => { await appsMenu.clickLink('Management'); await loadingScreenShown(); await testSubjects.existOrFail('managementNav'); }); - it.skip('can navigate from legacy apps to NP apps', async () => { + it('can navigate from legacy apps to NP apps', async () => { await appsMenu.clickLink('Foo'); await loadingScreenShown(); await testSubjects.existOrFail('fooAppHome'); diff --git a/test/plugin_functional/test_suites/core_plugins/index.ts b/test/plugin_functional/test_suites/core_plugins/index.ts index d66e2e7dc5da7..d57ad11ea004e 100644 --- a/test/plugin_functional/test_suites/core_plugins/index.ts +++ b/test/plugin_functional/test_suites/core_plugins/index.ts @@ -29,5 +29,6 @@ export default function({ loadTestFile }: PluginFunctionalProviderContext) { loadTestFile(require.resolve('./top_nav')); loadTestFile(require.resolve('./application_leave_confirm')); loadTestFile(require.resolve('./application_status')); + loadTestFile(require.resolve('./rendering')); }); } diff --git a/test/plugin_functional/test_suites/core_plugins/rendering.ts b/test/plugin_functional/test_suites/core_plugins/rendering.ts new file mode 100644 index 0000000000000..d0025c82a7ba5 --- /dev/null +++ b/test/plugin_functional/test_suites/core_plugins/rendering.ts @@ -0,0 +1,127 @@ +/* + * 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 expect from '@kbn/expect'; + +import '../../plugins/core_provider_plugin/types'; +import { PluginFunctionalProviderContext } from '../../services'; + +// eslint-disable-next-line import/no-default-export +export default function({ getService, getPageObjects }: PluginFunctionalProviderContext) { + const PageObjects = getPageObjects(['common']); + const browser = getService('browser'); + const find = getService('find'); + const testSubjects = getService('testSubjects'); + + function navigate(path: string) { + return browser.get(`${PageObjects.common.getHostPort()}${path}`); + } + + function getLegacyMode() { + return browser.execute(() => { + return JSON.parse(document.querySelector('kbn-injected-metadata')!.getAttribute('data')!) + .legacyMode; + }); + } + + function getUserSettings() { + return browser.execute(() => { + return JSON.parse(document.querySelector('kbn-injected-metadata')!.getAttribute('data')!) + .legacyMetadata.uiSettings.user; + }); + } + + async function init() { + const loading = await testSubjects.find('kbnLoadingMessage', 5000); + + return () => find.waitForElementStale(loading); + } + + describe('rendering service', () => { + it('renders "core" application', async () => { + await navigate('/render/core'); + + const [loaded, legacyMode, userSettings] = await Promise.all([ + init(), + getLegacyMode(), + getUserSettings(), + ]); + + expect(legacyMode).to.be(false); + expect(userSettings).to.not.be.empty(); + + await loaded(); + + expect(await testSubjects.exists('renderingHeader')).to.be(true); + }); + + it('renders "core" application without user settings', async () => { + await navigate('/render/core?includeUserSettings=false'); + + const [loaded, legacyMode, userSettings] = await Promise.all([ + init(), + getLegacyMode(), + getUserSettings(), + ]); + + expect(legacyMode).to.be(false); + expect(userSettings).to.be.empty(); + + await loaded(); + + expect(await testSubjects.exists('renderingHeader')).to.be(true); + }); + + it('renders "legacy" application', async () => { + await navigate('/render/core_plugin_legacy'); + + const [loaded, legacyMode, userSettings] = await Promise.all([ + init(), + getLegacyMode(), + getUserSettings(), + ]); + + expect(legacyMode).to.be(true); + expect(userSettings).to.not.be.empty(); + + await loaded(); + + expect(await testSubjects.exists('coreLegacyCompatH1')).to.be(true); + expect(await testSubjects.exists('renderingHeader')).to.be(false); + }); + + it('renders "legacy" application without user settings', async () => { + await navigate('/render/core_plugin_legacy?includeUserSettings=false'); + + const [loaded, legacyMode, userSettings] = await Promise.all([ + init(), + getLegacyMode(), + getUserSettings(), + ]); + + expect(legacyMode).to.be(true); + expect(userSettings).to.be.empty(); + + await loaded(); + + expect(await testSubjects.exists('coreLegacyCompatH1')).to.be(true); + expect(await testSubjects.exists('renderingHeader')).to.be(false); + }); + }); +} diff --git a/test/plugin_functional/test_suites/core_plugins/server_plugins.ts b/test/plugin_functional/test_suites/core_plugins/server_plugins.ts index 3f89036fc2b65..eb232b1458991 100644 --- a/test/plugin_functional/test_suites/core_plugins/server_plugins.ts +++ b/test/plugin_functional/test_suites/core_plugins/server_plugins.ts @@ -54,15 +54,5 @@ export default function({ getService }: PluginFunctionalProviderContext) { statusCode: 400, }); }); - - it('renders core application explicitly', async () => { - await supertest.get('/requestcontext/render/core').expect(200, /app:core/); - }); - - it('renders legacy application', async () => { - await supertest - .get('/requestcontext/render/core_plugin_legacy') - .expect(200, /app:core_plugin_legacy/); - }); }); }