@elastic/synthetics
Version:
Elastic synthetic monitoring agent
145 lines • 6.29 kB
JavaScript
;
/**
* 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.
*
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.Gatherer = void 0;
const playwright_core_1 = require("playwright-core");
const plugins_1 = require("../plugins");
const logger_1 = require("./logger");
// Default timeout for Playwright actions and Navigations
const DEFAULT_TIMEOUT = 50000;
/**
* Purpose of the Gatherer is to set up the necessary browser driver
* related capabilities for the runner to run all journeys
*/
class Gatherer {
static browser;
static pluginManager;
static async launchBrowser(options) {
if (Gatherer.browser != null) {
return;
}
(0, logger_1.log)('Gatherer: setup browser');
const { wsEndpoint, playwrightOptions } = options;
if (wsEndpoint) {
(0, logger_1.log)(`Gatherer: connecting to WS endpoint: ${wsEndpoint}`);
Gatherer.browser = await playwright_core_1.chromium.connect(wsEndpoint);
}
else {
Gatherer.browser = await playwright_core_1.chromium.launch({
...playwrightOptions,
args: [
...(playwrightOptions?.headless ? ['--disable-gpu'] : []),
...(playwrightOptions?.args ?? []),
],
});
}
// Register sig int handler to close the browser
process.on('SIGINT', async () => {
await Gatherer.stop();
process.exit(130);
});
}
static async setupDriver(options) {
await Gatherer.launchBrowser(options);
const { playwrightOptions } = options;
const context = await Gatherer.browser.newContext({
...playwrightOptions,
userAgent: await Gatherer.getUserAgent(playwrightOptions?.userAgent),
});
// Set timeouts for actions and navigations
context.setDefaultTimeout(playwrightOptions?.actionTimeout ?? DEFAULT_TIMEOUT);
context.setDefaultNavigationTimeout(playwrightOptions?.navigationTimeout ?? DEFAULT_TIMEOUT);
// TODO: Network throttling via chrome devtools emulation is disabled for now.
// See docs/throttling.md for more details.
// Gatherer.setNetworkConditions(context, networkConditions);
if (playwrightOptions?.testIdAttribute) {
playwright_core_1.selectors.setTestIdAttribute(playwrightOptions.testIdAttribute);
}
const page = await context.newPage();
const client = await context.newCDPSession(page);
const request = await playwright_core_1.request.newContext({ ...playwrightOptions });
return { browser: Gatherer.browser, context, page, client, request };
}
static async getUserAgent(userAgent) {
if (!userAgent) {
const session = await Gatherer.browser.newBrowserCDPSession();
({ userAgent } = await session.send('Browser.getVersion'));
return userAgent + ' Elastic/Synthetics';
}
return userAgent;
}
static setNetworkConditions(context, networkConditions) {
if (networkConditions) {
context.on('page', page => {
const context = page.context();
const emulatePromise = context
.newCDPSession(page)
.then(client => client.send('Network.emulateNetworkConditions', networkConditions));
/**
* Guard against pages that gets closed before the emulation kicks to capture
* unhandled rejections from accessing the CDP session of closed page
*/
Promise.race([
new Promise(resolve => page.on('close', () => resolve())),
emulatePromise,
]);
});
}
}
/**
* Starts recording all events related to the v8 devtools protocol
* https://chromedevtools.github.io/devtools-protocol/v8/
*/
static async beginRecording(driver, options) {
(0, logger_1.log)('Gatherer: started recording');
const { network, metrics } = options;
Gatherer.pluginManager = new plugins_1.PluginManager(driver);
Gatherer.pluginManager.registerAll(options);
const plugins = [await Gatherer.pluginManager.start('browserconsole')];
network && plugins.push(await Gatherer.pluginManager.start('network'));
metrics && plugins.push(await Gatherer.pluginManager.start('performance'));
await Promise.all(plugins);
return Gatherer.pluginManager;
}
static async endRecording() {
(0, logger_1.log)('Gatherer: ended recording');
await Gatherer.pluginManager.unregisterAll();
}
static async dispose(driver) {
(0, logger_1.log)(`Gatherer: closing all contexts`);
await driver.request.dispose();
await driver.context.close();
}
static async stop() {
(0, logger_1.log)(`Gatherer: closing browser`);
if (Gatherer.browser) {
await Gatherer.browser.close();
Gatherer.browser = null;
}
}
}
exports.Gatherer = Gatherer;
//# sourceMappingURL=gatherer.js.map