-
Notifications
You must be signed in to change notification settings - Fork 8.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Screenshot mode] Create plugin to provide "screenshot mode" awareness #99627
[Screenshot mode] Create plugin to provide "screenshot mode" awareness #99627
Conversation
@elasticmachine merge upstream |
@elasticmachine merge upstream |
Also hooked it up to the chromium browser imitating the preload functionality of electron to set up the environment before code runs.
screenshot mode
@elasticmachine merge upstream |
Pinging @elastic/kibana-app-services (Team:AppServices) |
Pinging @elastic/kibana-reporting-services (Team:Reporting Services) |
Added a server-side example for screenshot mode Export the screenshot mode header in both public and server
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changes under operations team code owners LGTM
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just two minor comments for now
* Side Public License, v 1. | ||
*/ | ||
|
||
export const KBN_SCREENSHOT_MODE_HEADER = 'x-kbn-screenshot-mode'.toLowerCase(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like .toLowerCase()
can be removed
* localStorage. The ability to set a value in localStorage enables more convenient development and testing | ||
* in functionality that needs to detect screenshot mode. | ||
*/ | ||
export const getScreenshotMode = (): unknown => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't this return a boolean?
move require() to screenshotMode plugin
@elasticmachine merge upstream |
changed the screenshotmode detection function to check for a specific value.
@@ -0,0 +1,51 @@ | |||
/* |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
question: Just out of curiosity, I see this common
file has a hard dependency on window
, how does this code work on the server side?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's a good question, it doesn't 😅 . It is intended for use by reporting which injects this function into the "preload" phase of opening a page.
Happy to capture that in a comment or consider a different implementation. WDYT?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That makes sense, thanks! I think mentioning this in the comment would be beneficial, just in case someone like me stumbles upon this file in the future.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
++ it took me a minute to understand it too - but it's pretty cool how it works
|
||
export class ScreenshotModePlugin implements Plugin<ScreenshotModePluginSetup> { | ||
public setup(core: CoreSetup) { | ||
core.http.registerRouteHandlerContext<ScreenshotModeRequestHandlerContext, 'screenshotMode'>( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
issue: having isScreenshot
in the request context is great, but unfortunately request context isn't available during authentication. Authentication is performed within auth
handler that doesn't have access to the request context.
Maybe you can expose an additional method from the start
or setup
(or both) contract too, so that the code that doesn't have access to request context for one reason or another can use it instead (with a drawback of having dependency on screenshotMode
plugin)?
public setup/start() {
return {
isScreenshot: (request: KibanaRequest) =>
Object.keys(request.headers).some((header) => {
return header.toLowerCase() === KBN_SCREENSHOT_MODE_HEADER;
}),
};
}
In the future, I believe the Kibana platform should be the one who determines in which mode Kibana is used. This way it can extend KibanaRequest
with additional property or propagate this knowledge to plugins in any other way without introducing additional plugin dependencies. But it's too early to generalize, let's see if this solution is enough.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the input @azasypkin , that trade-off makes sense to me!
* references as possible to make it portable. For instance, running inside puppeteer. | ||
*/ | ||
export const setScreenshotModeEnabled = () => { | ||
Object.defineProperty(window, '__KBN_SCREENSHOT_MODE_ENABLED_KEY__', { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
question: Btw, should we use constant here (and in setScreenshotModeDisabled
)?
Object.defineProperty(window, '__KBN_SCREENSHOT_MODE_ENABLED_KEY__', { | |
Object.defineProperty(window, KBN_SCREENSHOT_MODE_ENABLED_KEY, { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because this function is used in puppeteer it cannot have references to external variables that are not available from within the puppeteer environment where this code is run.
I'll add an inline comment to this effect.
checks a kibana request to determine whether we in screenshot mode
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The API exposed by the screenshotMode
plugin LGTM, thanks!
@elasticmachine merge upstream |
update reporting example
@elasticmachine merge upstream |
💚 Build Succeeded
Metrics [docs]Module Count
Public APIs missing comments
Page load bundle
Unknown metric groupsAPI count
References to deprecated APIs
History
To update your PR or re-run it, just comment with: |
elastic#99627) * initial version of the screenshot mode service * First iteration of client side of screenshot mode plugin Also hooked it up to the chromium browser imitating the preload functionality of electron to set up the environment before code runs. * First implementation of server-side logic for detecting screenshot mode * fix some type issues and do a small refactor * fix size limits, docs and ts issues * fixed types issues and made sure screenshot mode is correctly detected on the client * Moved the screenshot mode header definition to common Added a server-side example for screenshot mode Export the screenshot mode header in both public and server * move require() to screenshotMode plugin * Update chromium_driver.ts * cleaned up some comments, minor refactor in ReportingCore and changed the screenshotmode detection function to check for a specific value. * fix export * Expanded server-side screenshot mode contract with function that checks a kibana request to determine whether we in screenshot mode * added comments to explain use of literal value rather than external reference * updated comment * update reporting example Co-authored-by: Kibana Machine <[email protected]> Co-authored-by: Timothy Sullivan <[email protected]> Co-authored-by: Tim Sullivan <[email protected]> # Conflicts: # x-pack/plugins/reporting/server/core.ts # x-pack/plugins/reporting/server/plugin.ts
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM!
…areness (#99627) (#100331) * [Screenshot mode] Create plugin to provide "screenshot mode" awareness (#99627) * initial version of the screenshot mode service * First iteration of client side of screenshot mode plugin Also hooked it up to the chromium browser imitating the preload functionality of electron to set up the environment before code runs. * First implementation of server-side logic for detecting screenshot mode * fix some type issues and do a small refactor * fix size limits, docs and ts issues * fixed types issues and made sure screenshot mode is correctly detected on the client * Moved the screenshot mode header definition to common Added a server-side example for screenshot mode Export the screenshot mode header in both public and server * move require() to screenshotMode plugin * Update chromium_driver.ts * cleaned up some comments, minor refactor in ReportingCore and changed the screenshotmode detection function to check for a specific value. * fix export * Expanded server-side screenshot mode contract with function that checks a kibana request to determine whether we in screenshot mode * added comments to explain use of literal value rather than external reference * updated comment * update reporting example Co-authored-by: Kibana Machine <[email protected]> Co-authored-by: Timothy Sullivan <[email protected]> Co-authored-by: Tim Sullivan <[email protected]> # Conflicts: # x-pack/plugins/reporting/server/core.ts # x-pack/plugins/reporting/server/plugin.ts * satisfy for tslint formatting Co-authored-by: Kibana Machine <[email protected]>
elastic#99627) * initial version of the screenshot mode service * First iteration of client side of screenshot mode plugin Also hooked it up to the chromium browser imitating the preload functionality of electron to set up the environment before code runs. * First implementation of server-side logic for detecting screenshot mode * fix some type issues and do a small refactor * fix size limits, docs and ts issues * fixed types issues and made sure screenshot mode is correctly detected on the client * Moved the screenshot mode header definition to common Added a server-side example for screenshot mode Export the screenshot mode header in both public and server * move require() to screenshotMode plugin * Update chromium_driver.ts * cleaned up some comments, minor refactor in ReportingCore and changed the screenshotmode detection function to check for a specific value. * fix export * Expanded server-side screenshot mode contract with function that checks a kibana request to determine whether we in screenshot mode * added comments to explain use of literal value rather than external reference * updated comment * update reporting example Co-authored-by: Kibana Machine <[email protected]> Co-authored-by: Timothy Sullivan <[email protected]> Co-authored-by: Tim Sullivan <[email protected]>
Summary
Fixes #99011
This contribution adds the new screenshot mode low-level plugin (a plugin that does not depend on other plugins) to Kibana.
The consumer plugins of this plugin should typically be fairly low-level plugins. This provides a way for resources (code, data, network requests) to not be loaded unnecessarily for an environment flagged as intended for screenshots (i.e., no user interaction). For example it does not make sense to report UI telemetry (client side) or API usage telemetry (server side).
Client-side
We expose a service that can be used by consumers to determine whether we are in screenshot mode. Screenshot mode should be detected pre-setup phase to expose this information before services or resources are started.
Server-side
We expose a flag request handler context object (
RequestHandlerContext
) to indicate that a request originated from a client that has optimised for taking screenshots.To reviewers
require
to a load a function from a file in the screenshot mode service that is passed into puppeteer, not sure whether this might have implications for any release builds? (seex-pack/plugins/reporting/server/browsers/chromium/driver/chromium_driver.ts
)Additional notes
The intended use case, per the README, is not to be used by higher-level plugins for determining when to render a reporting or print-friendly layout. The recommendation is to rather create a dedicated app route that loads only the UI and resources needed by the app.
Checklist
Delete any items that are not applicable to this PR.