diff --git a/packages/kbn-optimizer/limits.yml b/packages/kbn-optimizer/limits.yml index 3a7c50feb38b7..f786d01232227 100644 --- a/packages/kbn-optimizer/limits.yml +++ b/packages/kbn-optimizer/limits.yml @@ -116,7 +116,6 @@ pageLoadAssetSize: dataViewManagement: 5000 reporting: 57003 visTypeHeatmap: 25340 - screenshotting: 17017 expressionGauge: 25000 controls: 34788 expressionPartitionVis: 26338 diff --git a/src/plugins/dashboard/public/application/hooks/use_dashboard_app_state.ts b/src/plugins/dashboard/public/application/hooks/use_dashboard_app_state.ts index 2ce1c87252d38..98b3d761f350e 100644 --- a/src/plugins/dashboard/public/application/hooks/use_dashboard_app_state.ts +++ b/src/plugins/dashboard/public/application/hooks/use_dashboard_app_state.ts @@ -185,7 +185,7 @@ export const useDashboardAppState = ({ // Backwards compatible way of detecting that we are taking a screenshot const legacyPrintLayoutDetected = screenshotModeService?.isScreenshotMode() && - screenshotModeService.getScreenshotLayout() === 'print'; + screenshotModeService.getScreenshotContext('layout') === 'print'; const initialDashboardState = { ...savedDashboardState, diff --git a/src/plugins/dashboard/public/services/screenshot_mode.ts b/src/plugins/dashboard/public/services/screenshot_mode.ts index 12ec1bca2207f..577aa3eab36b5 100644 --- a/src/plugins/dashboard/public/services/screenshot_mode.ts +++ b/src/plugins/dashboard/public/services/screenshot_mode.ts @@ -10,5 +10,3 @@ export type { ScreenshotModePluginStart, ScreenshotModePluginSetup, } from '../../../screenshot_mode/public'; - -export type { Layout } from '../../../screenshot_mode/common'; diff --git a/src/plugins/screenshot_mode/common/context.test.ts b/src/plugins/screenshot_mode/common/context.test.ts new file mode 100644 index 0000000000000..370ea27907295 --- /dev/null +++ b/src/plugins/screenshot_mode/common/context.test.ts @@ -0,0 +1,30 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { getScreenshotContext, setScreenshotContext } from './context'; + +describe('getScreenshotContext', () => { + it('should return a default value if there is no data', () => { + expect(getScreenshotContext('key', 'default')).toBe('default'); + }); +}); + +describe('setScreenshotContext', () => { + it('should store data in the context', () => { + setScreenshotContext('key', 'value'); + + expect(getScreenshotContext('key')).toBe('value'); + }); + + it('should not overwrite data on repetitive calls', () => { + setScreenshotContext('key1', 'value1'); + setScreenshotContext('key2', 'value2'); + + expect(getScreenshotContext('key1')).toBe('value1'); + }); +}); diff --git a/src/plugins/screenshot_mode/common/context.ts b/src/plugins/screenshot_mode/common/context.ts new file mode 100644 index 0000000000000..7f885baa175dd --- /dev/null +++ b/src/plugins/screenshot_mode/common/context.ts @@ -0,0 +1,53 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +// **PLEASE NOTE** +// The functionality in this file targets a browser environment AND is intended to be used both in public and server. +// For instance, reporting uses these functions when starting puppeteer to set the current browser into "screenshot" mode. + +type Context = Record; + +declare global { + interface Window { + __KBN_SCREENSHOT_CONTEXT__?: Context; + } +} + +/** + * Stores a value in the screenshotting context. + * @param key Context key to set. + * @param value Value to set. + */ +export function setScreenshotContext(key: string, value: T): void { + // Literal value to prevent adding an external reference + const KBN_SCREENSHOT_CONTEXT = '__KBN_SCREENSHOT_CONTEXT__'; + + if (!window[KBN_SCREENSHOT_CONTEXT]) { + Object.defineProperty(window, KBN_SCREENSHOT_CONTEXT, { + enumerable: true, + writable: true, + configurable: false, + value: {}, + }); + } + + window[KBN_SCREENSHOT_CONTEXT]![key] = value; +} + +/** + * Retrieves a value from the screenshotting context. + * @param key Context key to get. + * @param defaultValue Value to return if the key is not found. + * @return The value stored in the screenshotting context. + */ +export function getScreenshotContext(key: string, defaultValue?: T): T | undefined { + // Literal value to prevent adding an external reference + const KBN_SCREENSHOT_CONTEXT = '__KBN_SCREENSHOT_CONTEXT__'; + + return (window[KBN_SCREENSHOT_CONTEXT]?.[key] as T) ?? defaultValue; +} diff --git a/src/plugins/screenshot_mode/common/index.ts b/src/plugins/screenshot_mode/common/index.ts index 949691911fc27..46f120b1ec1a9 100644 --- a/src/plugins/screenshot_mode/common/index.ts +++ b/src/plugins/screenshot_mode/common/index.ts @@ -6,16 +6,11 @@ * Side Public License, v 1. */ +export { getScreenshotContext, setScreenshotContext } from './context'; export { getScreenshotMode, setScreenshotModeEnabled, setScreenshotModeDisabled, KBN_SCREENSHOT_MODE_ENABLED_KEY, - KBN_SCREENSHOT_MODE_LAYOUT_KEY, - setScreenshotLayout, - getScreenshotLayout, -} from './get_set_browser_screenshot_mode'; - -export type { Layout } from './get_set_browser_screenshot_mode'; - +} from './mode'; export { KBN_SCREENSHOT_MODE_HEADER } from './constants'; diff --git a/src/plugins/screenshot_mode/common/get_set_browser_screenshot_mode.ts b/src/plugins/screenshot_mode/common/mode.ts similarity index 73% rename from src/plugins/screenshot_mode/common/get_set_browser_screenshot_mode.ts rename to src/plugins/screenshot_mode/common/mode.ts index 850f70d2d002a..d4768ebff8308 100644 --- a/src/plugins/screenshot_mode/common/get_set_browser_screenshot_mode.ts +++ b/src/plugins/screenshot_mode/common/mode.ts @@ -12,6 +12,12 @@ export const KBN_SCREENSHOT_MODE_ENABLED_KEY = '__KBN_SCREENSHOT_MODE_ENABLED_KEY__'; +declare global { + interface Window { + [KBN_SCREENSHOT_MODE_ENABLED_KEY]?: boolean; + } +} + /** * This function is responsible for detecting whether we are currently in screenshot mode. * @@ -21,7 +27,7 @@ export const KBN_SCREENSHOT_MODE_ENABLED_KEY = '__KBN_SCREENSHOT_MODE_ENABLED_KE */ export const getScreenshotMode = (): boolean => { return ( - (window as unknown as Record)[KBN_SCREENSHOT_MODE_ENABLED_KEY] === true || + window[KBN_SCREENSHOT_MODE_ENABLED_KEY] === true || window.localStorage.getItem(KBN_SCREENSHOT_MODE_ENABLED_KEY) === 'true' ); }; @@ -61,31 +67,3 @@ export const setScreenshotModeDisabled = () => { } ); }; - -/** @deprecated */ -export const KBN_SCREENSHOT_MODE_LAYOUT_KEY = '__KBN_SCREENSHOT_MODE_LAYOUT_KEY__'; - -/** @deprecated */ -export type Layout = 'canvas' | 'preserve_layout' | 'print'; - -/** @deprecated */ -export const setScreenshotLayout = (value: Layout) => { - Object.defineProperty( - window, - '__KBN_SCREENSHOT_MODE_LAYOUT_KEY__', // Literal value to prevent adding an external reference - { - enumerable: true, - writable: true, - configurable: false, - value, - } - ); -}; - -/** @deprecated */ -export const getScreenshotLayout = (): undefined | Layout => { - return ( - (window as unknown as Record)[KBN_SCREENSHOT_MODE_LAYOUT_KEY] || - (window.localStorage.getItem(KBN_SCREENSHOT_MODE_LAYOUT_KEY) as Layout) - ); -}; diff --git a/src/plugins/screenshot_mode/public/mocks.ts b/src/plugins/screenshot_mode/public/mocks.ts index d7e69e9d89211..86ef4c3cf1a42 100644 --- a/src/plugins/screenshot_mode/public/mocks.ts +++ b/src/plugins/screenshot_mode/public/mocks.ts @@ -11,11 +11,11 @@ import type { ScreenshotModePluginSetup, ScreenshotModePluginStart } from './typ export const screenshotModePluginMock = { createSetupContract: (): DeeplyMockedKeys => ({ - getScreenshotLayout: jest.fn(), + getScreenshotContext: jest.fn(), isScreenshotMode: jest.fn(() => false), }), createStartContract: (): DeeplyMockedKeys => ({ - getScreenshotLayout: jest.fn(), + getScreenshotContext: jest.fn(), isScreenshotMode: jest.fn(() => false), }), }; diff --git a/src/plugins/screenshot_mode/public/plugin.ts b/src/plugins/screenshot_mode/public/plugin.ts index bb34fe84e2c39..2df8585cd6817 100644 --- a/src/plugins/screenshot_mode/public/plugin.ts +++ b/src/plugins/screenshot_mode/public/plugin.ts @@ -6,16 +6,14 @@ * Side Public License, v 1. */ -import { CoreSetup, CoreStart, Plugin } from '../../../core/public'; - -import { ScreenshotModePluginSetup, ScreenshotModePluginStart } from './types'; - -import { getScreenshotMode, getScreenshotLayout } from '../common'; +import type { CoreSetup, CoreStart, Plugin } from 'src/core/public'; +import { getScreenshotContext, getScreenshotMode } from '../common'; +import type { ScreenshotModePluginSetup, ScreenshotModePluginStart } from './types'; export class ScreenshotModePlugin implements Plugin { private publicContract = Object.freeze({ + getScreenshotContext, isScreenshotMode: () => getScreenshotMode() === true, - getScreenshotLayout, }); public setup(core: CoreSetup): ScreenshotModePluginSetup { diff --git a/src/plugins/screenshot_mode/public/types.ts b/src/plugins/screenshot_mode/public/types.ts index d1603cbceb26f..9de538bc9f8fb 100644 --- a/src/plugins/screenshot_mode/public/types.ts +++ b/src/plugins/screenshot_mode/public/types.ts @@ -6,18 +6,20 @@ * Side Public License, v 1. */ -import type { Layout } from '../common'; +export interface ScreenshotModePluginSetup { + /** + * Retrieves a value from the screenshotting context. + * @param key Context key to get. + * @param defaultValue Value to return if the key is not found. + * @return The value stored in the screenshotting context. + */ + getScreenshotContext(key: string, defaultValue?: T): T | undefined; -export interface IScreenshotModeService { /** * Returns a boolean indicating whether the current user agent (browser) would like to view UI optimized for * screenshots or printing. */ - isScreenshotMode: () => boolean; - - /** @deprecated */ - getScreenshotLayout: () => undefined | Layout; + isScreenshotMode(): boolean; } -export type ScreenshotModePluginSetup = IScreenshotModeService; -export type ScreenshotModePluginStart = IScreenshotModeService; +export type ScreenshotModePluginStart = ScreenshotModePluginSetup; diff --git a/src/plugins/screenshot_mode/server/is_screenshot_mode.ts b/src/plugins/screenshot_mode/server/is_screenshot_mode.ts index 79787bcd1fb50..8b8819f462770 100644 --- a/src/plugins/screenshot_mode/server/is_screenshot_mode.ts +++ b/src/plugins/screenshot_mode/server/is_screenshot_mode.ts @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -import { KibanaRequest } from 'src/core/server'; +import type { KibanaRequest } from 'src/core/server'; import { KBN_SCREENSHOT_MODE_HEADER } from '../common'; export const isScreenshotMode = (request: KibanaRequest): boolean => { diff --git a/src/plugins/screenshot_mode/server/plugin.ts b/src/plugins/screenshot_mode/server/plugin.ts index b885ff97bf262..ff150b2f1a934 100644 --- a/src/plugins/screenshot_mode/server/plugin.ts +++ b/src/plugins/screenshot_mode/server/plugin.ts @@ -6,8 +6,8 @@ * Side Public License, v 1. */ -import { Plugin, CoreSetup } from '../../../core/server'; -import { +import type { Plugin, CoreSetup } from 'src/core/server'; +import type { ScreenshotModeRequestHandlerContext, ScreenshotModePluginSetup, ScreenshotModePluginStart, @@ -30,11 +30,11 @@ export class ScreenshotModePlugin // We use "require" here to ensure the import does not have external references due to code bundling that // commonly happens during transpiling. External references would be missing in the environment puppeteer creates. // eslint-disable-next-line @typescript-eslint/no-var-requires - const { setScreenshotModeEnabled, setScreenshotLayout } = require('../common'); + const { setScreenshotContext, setScreenshotModeEnabled } = require('../common'); return { + setScreenshotContext, setScreenshotModeEnabled, - setScreenshotLayout, isScreenshotMode, }; } diff --git a/src/plugins/screenshot_mode/server/types.ts b/src/plugins/screenshot_mode/server/types.ts index 1b9f3868f0966..5b9e50657674a 100644 --- a/src/plugins/screenshot_mode/server/types.ts +++ b/src/plugins/screenshot_mode/server/types.ts @@ -7,30 +7,29 @@ */ import type { RequestHandlerContext, KibanaRequest } from 'src/core/server'; -import type { Layout } from '../common'; -/** - * Any context that requires access to the screenshot mode flag but does not have access - * to request context {@link ScreenshotModeRequestHandlerContext}, for instance if they are pre-context, - * can use this function to check whether the request originates from a client that is in screenshot mode. - */ -type IsScreenshotMode = (request: KibanaRequest) => boolean; +export interface ScreenshotModePluginStart { + /** + * Any context that requires access to the screenshot mode flag but does not have access + * to request context {@link ScreenshotModeRequestHandlerContext}, for instance if they are pre-context, + * can use this function to check whether the request originates from a client that is in screenshot mode. + */ + isScreenshotMode(request: KibanaRequest): boolean; +} -export interface ScreenshotModePluginSetup { - isScreenshotMode: IsScreenshotMode; +export interface ScreenshotModePluginSetup extends ScreenshotModePluginStart { + /** + * Stores a value in the screenshotting context. + * @param key Context key to set. + * @param value Value to set. + */ + setScreenshotContext(key: string, value: T): void; /** * Set the current environment to screenshot mode. Intended to run in a browser-environment, before any other scripts * on the page have run to ensure that screenshot mode is detected as early as possible. */ - setScreenshotModeEnabled: () => void; - - /** @deprecated */ - setScreenshotLayout: (value: Layout) => void; -} - -export interface ScreenshotModePluginStart { - isScreenshotMode: IsScreenshotMode; + setScreenshotModeEnabled(): void; } export interface ScreenshotModeRequestHandlerContext extends RequestHandlerContext { diff --git a/x-pack/examples/reporting_example/kibana.json b/x-pack/examples/reporting_example/kibana.json index 489b2bcd9f506..21329eba30a68 100644 --- a/x-pack/examples/reporting_example/kibana.json +++ b/x-pack/examples/reporting_example/kibana.json @@ -17,6 +17,5 @@ "navigation", "screenshotMode", "share" - ], - "requiredBundles": ["screenshotting"] + ] } diff --git a/x-pack/examples/reporting_example/public/containers/main.tsx b/x-pack/examples/reporting_example/public/containers/main.tsx index 2a72f0ee71661..6242073485220 100644 --- a/x-pack/examples/reporting_example/public/containers/main.tsx +++ b/x-pack/examples/reporting_example/public/containers/main.tsx @@ -40,7 +40,7 @@ import type { JobParamsPNGV2, } from '../../../../plugins/reporting/common/types'; import type { ReportingStart } from '../../../../plugins/reporting/public'; -import { LayoutTypes } from '../../../../plugins/screenshotting/public'; +import { LayoutTypes } from '../../../../plugins/screenshotting/common'; import { REPORTING_EXAMPLE_LOCATOR_ID } from '../../common'; import { useApplicationContext } from '../application_context'; import { ROUTES } from '../constants'; diff --git a/x-pack/plugins/reporting/public/plugin.ts b/x-pack/plugins/reporting/public/plugin.ts index 466ac2decefa1..39edef1cb6b0d 100644 --- a/x-pack/plugins/reporting/public/plugin.ts +++ b/x-pack/plugins/reporting/public/plugin.ts @@ -19,7 +19,7 @@ import { PluginInitializerContext, ThemeServiceStart, } from 'src/core/public'; -import type { ScreenshottingSetup } from '../../screenshotting/public'; +import type { ScreenshotModePluginSetup } from 'src/plugins/screenshot_mode/public'; import { CONTEXT_MENU_TRIGGER } from '../../../../src/plugins/embeddable/public'; import { FeatureCatalogueCategory, @@ -79,7 +79,7 @@ export interface ReportingPublicPluginSetupDendencies { home: HomePublicPluginSetup; management: ManagementSetup; uiActions: UiActionsSetup; - screenshotting: ScreenshottingSetup; + screenshotMode: ScreenshotModePluginSetup; share: SharePluginSetup; } @@ -152,7 +152,7 @@ export class ReportingPublicPlugin setupDeps: ReportingPublicPluginSetupDendencies ) { const { getStartServices, uiSettings } = core; - const { home, management, screenshotting, share, uiActions } = setupDeps; + const { home, management, screenshotMode, share, uiActions } = setupDeps; const startServices$ = Rx.from(getStartServices()); const usesUiCapabilities = !this.config.roles.enabled; @@ -209,7 +209,7 @@ export class ReportingPublicPlugin id: 'reportingRedirect', mount: async (params) => { const { mountRedirectApp } = await import('./redirect'); - return mountRedirectApp({ ...params, apiClient, screenshotting, share }); + return mountRedirectApp({ ...params, apiClient, screenshotMode, share }); }, title: 'Reporting redirect app', searchable: false, diff --git a/x-pack/plugins/reporting/public/redirect/mount_redirect_app.tsx b/x-pack/plugins/reporting/public/redirect/mount_redirect_app.tsx index fa658126efebc..20a6ee4eebac0 100644 --- a/x-pack/plugins/reporting/public/redirect/mount_redirect_app.tsx +++ b/x-pack/plugins/reporting/public/redirect/mount_redirect_app.tsx @@ -10,7 +10,7 @@ import React from 'react'; import { EuiErrorBoundary } from '@elastic/eui'; import type { AppMountParameters } from 'kibana/public'; -import type { ScreenshottingSetup } from '../../../screenshotting/public'; +import type { ScreenshotModePluginSetup } from 'src/plugins/screenshot_mode/public'; import type { SharePluginSetup } from '../shared_imports'; import type { ReportingAPIClient } from '../lib/reporting_api_client'; @@ -18,7 +18,7 @@ import { RedirectApp } from './redirect_app'; interface MountParams extends AppMountParameters { apiClient: ReportingAPIClient; - screenshotting: ScreenshottingSetup; + screenshotMode: ScreenshotModePluginSetup; share: SharePluginSetup; } @@ -26,7 +26,7 @@ export const mountRedirectApp = ({ element, apiClient, history, - screenshotting, + screenshotMode, share, }: MountParams) => { render( @@ -34,7 +34,7 @@ export const mountRedirectApp = ({ , diff --git a/x-pack/plugins/reporting/public/redirect/redirect_app.tsx b/x-pack/plugins/reporting/public/redirect/redirect_app.tsx index 9f0b3f51f2731..31b5f2fa454de 100644 --- a/x-pack/plugins/reporting/public/redirect/redirect_app.tsx +++ b/x-pack/plugins/reporting/public/redirect/redirect_app.tsx @@ -12,7 +12,7 @@ import { i18n } from '@kbn/i18n'; import { EuiCallOut, EuiCodeBlock } from '@elastic/eui'; import type { ScopedHistory } from 'src/core/public'; -import type { ScreenshottingSetup } from '../../../screenshotting/public'; +import type { ScreenshotModePluginSetup } from 'src/plugins/screenshot_mode/public'; import { REPORTING_REDIRECT_LOCATOR_STORE_KEY } from '../../common/constants'; import { LocatorParams } from '../../common/types'; @@ -25,7 +25,7 @@ import './redirect_app.scss'; interface Props { apiClient: ReportingAPIClient; history: ScopedHistory; - screenshotting: ScreenshottingSetup; + screenshotMode: ScreenshotModePluginSetup; share: SharePluginSetup; } @@ -41,9 +41,7 @@ const i18nTexts = { ), }; -type ReportingContext = Record; - -export const RedirectApp: FunctionComponent = ({ apiClient, screenshotting, share }) => { +export const RedirectApp: FunctionComponent = ({ apiClient, screenshotMode, share }) => { const [error, setError] = useState(); useEffect(() => { @@ -57,8 +55,9 @@ export const RedirectApp: FunctionComponent = ({ apiClient, screenshottin const result = await apiClient.getInfo(jobId as string); locatorParams = result?.locatorParams?.[0]; } else { - locatorParams = - screenshotting.getContext()?.[REPORTING_REDIRECT_LOCATOR_STORE_KEY]; + locatorParams = screenshotMode.getScreenshotContext( + REPORTING_REDIRECT_LOCATOR_STORE_KEY + ); } if (!locatorParams) { @@ -73,7 +72,7 @@ export const RedirectApp: FunctionComponent = ({ apiClient, screenshottin throw e; } })(); - }, [apiClient, screenshotting, share]); + }, [apiClient, screenshotMode, share]); return (
diff --git a/x-pack/plugins/screenshotting/common/context.ts b/x-pack/plugins/screenshotting/common/context.ts deleted file mode 100644 index c47f8706533b8..0000000000000 --- a/x-pack/plugins/screenshotting/common/context.ts +++ /dev/null @@ -1,17 +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 - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -/** - * Screenshot context. - * This is a serializable object that can be passed from the screenshotting backend and then deserialized on the target page. - */ -export type Context = Record; - -/** - * @interal - */ -export const SCREENSHOTTING_CONTEXT_KEY = '__SCREENSHOTTING_CONTEXT_KEY__'; diff --git a/x-pack/plugins/screenshotting/common/index.ts b/x-pack/plugins/screenshotting/common/index.ts index 04296dd5426b5..1492f3f945abe 100644 --- a/x-pack/plugins/screenshotting/common/index.ts +++ b/x-pack/plugins/screenshotting/common/index.ts @@ -5,6 +5,5 @@ * 2.0. */ -export type { Context } from './context'; export type { LayoutParams } from './layout'; export { LayoutTypes } from './layout'; diff --git a/x-pack/plugins/screenshotting/kibana.json b/x-pack/plugins/screenshotting/kibana.json index 32446551627e0..9a071bdf46f46 100644 --- a/x-pack/plugins/screenshotting/kibana.json +++ b/x-pack/plugins/screenshotting/kibana.json @@ -9,6 +9,5 @@ "description": "Kibana Screenshotting Plugin", "requiredPlugins": ["screenshotMode"], "configPath": ["xpack", "screenshotting"], - "server": true, - "ui": true + "server": true } diff --git a/x-pack/plugins/screenshotting/public/context_storage.ts b/x-pack/plugins/screenshotting/public/context_storage.ts deleted file mode 100644 index 76a2cf231cf83..0000000000000 --- a/x-pack/plugins/screenshotting/public/context_storage.ts +++ /dev/null @@ -1,20 +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 - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { Context, SCREENSHOTTING_CONTEXT_KEY } from '../common/context'; - -declare global { - interface Window { - [SCREENSHOTTING_CONTEXT_KEY]?: Context; - } -} - -export class ContextStorage { - get(): T { - return (window[SCREENSHOTTING_CONTEXT_KEY] ?? {}) as T; - } -} diff --git a/x-pack/plugins/screenshotting/public/index.ts b/x-pack/plugins/screenshotting/public/index.ts deleted file mode 100644 index 659dbc81917a7..0000000000000 --- a/x-pack/plugins/screenshotting/public/index.ts +++ /dev/null @@ -1,18 +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 - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { ScreenshottingPlugin } from './plugin'; - -/** - * Screenshotting plugin entry point. - */ -export function plugin(...args: ConstructorParameters) { - return new ScreenshottingPlugin(...args); -} - -export { LayoutTypes } from '../common'; -export type { ScreenshottingSetup, ScreenshottingStart } from './plugin'; diff --git a/x-pack/plugins/screenshotting/public/plugin.tsx b/x-pack/plugins/screenshotting/public/plugin.tsx deleted file mode 100755 index 4ba5046b8a881..0000000000000 --- a/x-pack/plugins/screenshotting/public/plugin.tsx +++ /dev/null @@ -1,42 +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 - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import type { Plugin } from 'src/core/public'; -import { ContextStorage } from './context_storage'; - -/** - * Setup public contract. - */ -export interface ScreenshottingSetup { - /** - * Gathers screenshot context that has been set on the backend. - */ - getContext: ContextStorage['get']; -} - -/** - * Start public contract. - */ -export type ScreenshottingStart = ScreenshottingSetup; - -export class ScreenshottingPlugin implements Plugin { - private contextStorage = new ContextStorage(); - - setup(): ScreenshottingSetup { - return { - getContext: () => this.contextStorage.get(), - }; - } - - start(): ScreenshottingStart { - return { - getContext: () => this.contextStorage.get(), - }; - } - - stop() {} -} diff --git a/x-pack/plugins/screenshotting/server/browsers/chromium/driver.ts b/x-pack/plugins/screenshotting/server/browsers/chromium/driver.ts index 57f987f866ec9..4e71194486d01 100644 --- a/x-pack/plugins/screenshotting/server/browsers/chromium/driver.ts +++ b/x-pack/plugins/screenshotting/server/browsers/chromium/driver.ts @@ -10,12 +10,10 @@ import open from 'opn'; import puppeteer, { ElementHandle, EvaluateFn, Page, SerializableOrJSHandle } from 'puppeteer'; import { parse as parseUrl } from 'url'; import { Logger } from 'src/core/server'; -import type { Layout } from 'src/plugins/screenshot_mode/common'; import { KBN_SCREENSHOT_MODE_HEADER, ScreenshotModePluginSetup, } from '../../../../../../src/plugins/screenshot_mode/server'; -import { Context, SCREENSHOTTING_CONTEXT_KEY } from '../../../common/context'; import { ConfigType } from '../../config'; import { allowRequest } from '../network_policy'; @@ -31,6 +29,8 @@ export interface ConditionalHeaders { conditions: ConditionalHeadersConditions; } +export type Context = Record; + export interface ElementPosition { boundingClientRect: { // modern browsers support x/y, but older ones don't @@ -56,7 +56,6 @@ interface OpenOptions { context?: Context; waitForSelector: string; timeout: number; - layout?: Layout; } interface WaitForSelectorOpts { @@ -124,13 +123,7 @@ export class HeadlessChromiumDriver { */ async open( url: string, - { - conditionalHeaders, - context, - layout, - waitForSelector: pageLoadSelector, - timeout, - }: OpenOptions, + { conditionalHeaders, context, waitForSelector: pageLoadSelector, timeout }: OpenOptions, logger: Logger ): Promise { logger.info(`opening url ${url}`); @@ -144,23 +137,8 @@ export class HeadlessChromiumDriver { */ await this.page.evaluateOnNewDocument(this.screenshotMode.setScreenshotModeEnabled); - if (context) { - await this.page.evaluateOnNewDocument( - (key: string, value: unknown) => { - Object.defineProperty(window, key, { - configurable: false, - writable: true, - enumerable: true, - value, - }); - }, - SCREENSHOTTING_CONTEXT_KEY, - context - ); - } - - if (layout) { - await this.page.evaluateOnNewDocument(this.screenshotMode.setScreenshotLayout, layout); + for (const [key, value] of Object.entries(context ?? {})) { + await this.page.evaluateOnNewDocument(this.screenshotMode.setScreenshotContext, key, value); } await this.page.setRequestInterception(true); diff --git a/x-pack/plugins/screenshotting/server/browsers/chromium/index.ts b/x-pack/plugins/screenshotting/server/browsers/chromium/index.ts index 31a48cae7475e..88572081c5491 100644 --- a/x-pack/plugins/screenshotting/server/browsers/chromium/index.ts +++ b/x-pack/plugins/screenshotting/server/browsers/chromium/index.ts @@ -9,7 +9,7 @@ export const getChromiumDisconnectedError = () => new Error('Browser was closed unexpectedly! Check the server logs for more info.'); export { HeadlessChromiumDriver } from './driver'; -export type { ConditionalHeaders } from './driver'; +export type { ConditionalHeaders, Context } from './driver'; export { DEFAULT_VIEWPORT, HeadlessChromiumDriverFactory } from './driver_factory'; export type { PerformanceMetrics } from './driver_factory'; export { ChromiumArchivePaths } from './paths'; diff --git a/x-pack/plugins/screenshotting/server/browsers/index.ts b/x-pack/plugins/screenshotting/server/browsers/index.ts index ef5069ae51112..51687d74ff31d 100644 --- a/x-pack/plugins/screenshotting/server/browsers/index.ts +++ b/x-pack/plugins/screenshotting/server/browsers/index.ts @@ -7,7 +7,7 @@ export { download } from './download'; export { install } from './install'; -export type { ConditionalHeaders, PerformanceMetrics } from './chromium'; +export type { ConditionalHeaders, Context, PerformanceMetrics } from './chromium'; export { getChromiumDisconnectedError, ChromiumArchivePaths, diff --git a/x-pack/plugins/screenshotting/server/screenshots/observable.ts b/x-pack/plugins/screenshotting/server/screenshots/observable.ts index a238af5bcc25b..5cfda2c841cb8 100644 --- a/x-pack/plugins/screenshotting/server/screenshots/observable.ts +++ b/x-pack/plugins/screenshotting/server/screenshots/observable.ts @@ -9,8 +9,7 @@ import type { Transaction } from 'elastic-apm-node'; import { defer, forkJoin, throwError, Observable } from 'rxjs'; import { catchError, mergeMap, switchMapTo, timeoutWith } from 'rxjs/operators'; import type { Logger } from 'src/core/server'; -import type { Layout as ScreenshotModeLayout } from 'src/plugins/screenshot_mode/common'; -import type { ConditionalHeaders, HeadlessChromiumDriver } from '../browsers'; +import type { ConditionalHeaders, Context, HeadlessChromiumDriver } from '../browsers'; import { getChromiumDisconnectedError, DEFAULT_VIEWPORT } from '../browsers'; import type { Layout } from '../layouts'; import type { ElementsPositionAndAttribute } from './get_element_position_data'; @@ -22,7 +21,6 @@ import type { Screenshot } from './get_screenshots'; import { getTimeRange } from './get_time_range'; import { injectCustomCss } from './inject_css'; import { openUrl } from './open_url'; -import type { UrlOrUrlWithContext } from './open_url'; import { waitForRenderComplete } from './wait_for_render'; import { waitForVisualizations } from './wait_for_visualizations'; @@ -48,6 +46,10 @@ export interface PhaseTimeouts { loadDelay: number; } +type Url = string; +type UrlWithContext = [url: Url, context: Context]; +export type UrlOrUrlWithContext = Url | UrlWithContext; + export interface ScreenshotObservableOptions { /** * The browser timezone that will be emulated in the browser instance. @@ -157,18 +159,27 @@ export class ScreenshotObservableHandler { ); } - private openUrl(index: number, url: UrlOrUrlWithContext) { - return defer(() => - openUrl( + private openUrl(index: number, urlOrUrlWithContext: UrlOrUrlWithContext) { + return defer(() => { + let url: string; + let context: Context | undefined; + + if (typeof urlOrUrlWithContext === 'string') { + url = urlOrUrlWithContext; + } else { + [url, context] = urlOrUrlWithContext; + } + + return openUrl( this.driver, this.logger, this.options.timeouts.openUrl, index, url, - this.options.conditionalHeaders, - this.layout.id as ScreenshotModeLayout - ) - ).pipe(this.waitUntil(this.options.timeouts.openUrl, 'open URL')); + { ...(context ?? {}), layout: this.layout.id }, + this.options.conditionalHeaders + ); + }).pipe(this.waitUntil(this.options.timeouts.openUrl, 'open URL')); } private waitForElements() { diff --git a/x-pack/plugins/screenshotting/server/screenshots/open_url.ts b/x-pack/plugins/screenshotting/server/screenshots/open_url.ts index a27c9b5db4090..a4c4bd6217205 100644 --- a/x-pack/plugins/screenshotting/server/screenshots/open_url.ts +++ b/x-pack/plugins/screenshotting/server/screenshots/open_url.ts @@ -7,24 +7,18 @@ import apm from 'elastic-apm-node'; import type { Logger } from 'src/core/server'; -import type { Layout } from 'src/plugins/screenshot_mode/common'; -import { Context } from '../../common'; import type { HeadlessChromiumDriver } from '../browsers'; -import type { ConditionalHeaders } from '../browsers'; +import type { ConditionalHeaders, Context } from '../browsers'; import { DEFAULT_PAGELOAD_SELECTOR } from './constants'; -type Url = string; -type UrlWithContext = [url: Url, context: Context]; -export type UrlOrUrlWithContext = Url | UrlWithContext; - export const openUrl = async ( browser: HeadlessChromiumDriver, logger: Logger, timeout: number, index: number, - urlOrUrlWithContext: UrlOrUrlWithContext, - conditionalHeaders: ConditionalHeaders, - layout?: Layout + url: string, + context: Context, + conditionalHeaders: ConditionalHeaders ): Promise => { // If we're moving to another page in the app, we'll want to wait for the app to tell us // it's loaded the next page. @@ -32,21 +26,8 @@ export const openUrl = async ( const waitForSelector = page > 1 ? `[data-shared-page="${page}"]` : DEFAULT_PAGELOAD_SELECTOR; const span = apm.startSpan('open_url', 'wait'); - let url: string; - let context: Context | undefined; - - if (typeof urlOrUrlWithContext === 'string') { - url = urlOrUrlWithContext; - } else { - [url, context] = urlOrUrlWithContext; - } - try { - await browser.open( - url, - { conditionalHeaders, context, layout, waitForSelector, timeout }, - logger - ); + await browser.open(url, { conditionalHeaders, context, waitForSelector, timeout }, logger); } catch (err) { logger.error(err); throw new Error(`An error occurred when trying to open the Kibana URL: ${err.message}`); diff --git a/x-pack/plugins/screenshotting/tsconfig.json b/x-pack/plugins/screenshotting/tsconfig.json index a1e81c4fb38d9..bc9b65441f53d 100644 --- a/x-pack/plugins/screenshotting/tsconfig.json +++ b/x-pack/plugins/screenshotting/tsconfig.json @@ -8,7 +8,6 @@ }, "include": [ "common/**/*", - "public/**/*", "server/**/*", "../../../typings/**/*" ],