UNPKG

@elastic/synthetics

Version:

Elastic synthetic monitoring agent

158 lines (141 loc) 4.6 kB
/** * MIT License * * Copyright (c) 2020-present, Elastic NV * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * */ import { PluginOutput, Driver, APIDriver, NetworkInfo } from '../common_types'; import { BrowserConsole, NetworkManager, PerformanceManager, Tracing, TraceOptions, } from './'; import { Step } from '../dsl'; import { APINetworkManager } from './api-network'; type PluginType = 'network' | 'trace' | 'performance' | 'browserconsole'; // Shared shape for `NetworkManager` and `APINetworkManager` so the manager // stays agnostic to the driver type. export type NetworkPlugin = { results: Array<NetworkInfo>; _currentStep: Partial<Step> | null; start(): Promise<void>; stop(): Promise<Array<NetworkInfo>>; }; type Plugin = | NetworkManager | Tracing | PerformanceManager | BrowserConsole | APINetworkManager; type PluginOptions = TraceOptions; function isBrowserDriver(driver: Driver | APIDriver): driver is Driver { return 'context' in driver; } function isNetworkPlugin( plugin: Plugin ): plugin is NetworkManager | APINetworkManager { return ( plugin instanceof NetworkManager || plugin instanceof APINetworkManager ); } export class PluginManager { protected plugins = new Map<PluginType, Plugin>(); public PLUGIN_TYPES: Array<PluginType> = [ 'network', 'trace', 'performance', 'browserconsole', ]; constructor(private driver: Driver | APIDriver) {} register(type: PluginType, options: PluginOptions) { let instance: Plugin; if (isBrowserDriver(this.driver)) { switch (type) { case 'network': instance = new NetworkManager(this.driver); break; case 'trace': instance = new Tracing(this.driver, options); break; case 'performance': instance = new PerformanceManager(this.driver); break; case 'browserconsole': instance = new BrowserConsole(this.driver); break; } } else { // API journeys only record network; skip browser-only plugins. if (type === 'network') { instance = new APINetworkManager(this.driver); } } instance && this.plugins.set(type, instance); return instance; } registerAll(options: PluginOptions) { for (const type of this.PLUGIN_TYPES) { this.register(type, options); } } unregisterAll() { for (const type of this.PLUGIN_TYPES) { this.plugins.delete(type); } } async stop(type: PluginType) { const instance = this.plugins.get(type); if (instance) { return await instance.stop(); } return {}; } async start(type: PluginType) { const instance = this.plugins.get(type); instance && (await instance.start()); return instance; } get(type: PluginType) { return this.plugins.get(type); } // Propagate the active step to step-scoped plugins (no-op when absent). onStep(step: Step) { const browserConsole = this.plugins.get('browserconsole') as | BrowserConsole | undefined; if (browserConsole) browserConsole._currentStep = step; const network = this.plugins.get('network'); if (network && isNetworkPlugin(network)) network._currentStep = step; } async output() { const data: PluginOutput = {}; for (const [, plugin] of this.plugins) { if (isNetworkPlugin(plugin)) { data.networkinfo = await plugin.stop(); } else if (plugin instanceof BrowserConsole) { data.browserconsole = plugin.stop(); } } return data; } }