PSF: Foundry Progress Sync. 57 high-fidelity blueprints established. Open Fleet routing (Kimi/Qwen) active. GTD updated.
This commit is contained in:
21
projects/org-skill-web-research/node_modules/playwright-extra/LICENSE
generated
vendored
Normal file
21
projects/org-skill-web-research/node_modules/playwright-extra/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2019 berstend <github@berstend.com>
|
||||
|
||||
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.
|
||||
53
projects/org-skill-web-research/node_modules/playwright-extra/dist/extra.d.ts
generated
vendored
Normal file
53
projects/org-skill-web-research/node_modules/playwright-extra/dist/extra.d.ts
generated
vendored
Normal file
@@ -0,0 +1,53 @@
|
||||
import type * as pw from 'playwright-core';
|
||||
import type { CompatiblePlugin } from './types';
|
||||
import { PluginList } from './plugins';
|
||||
declare type PlaywrightBrowserLauncher = pw.BrowserType;
|
||||
/**
|
||||
* The Playwright browser launcher APIs we're augmenting
|
||||
* @private
|
||||
*/
|
||||
interface AugmentedLauncherAPIs extends Pick<PlaywrightBrowserLauncher, 'launch' | 'launchPersistentContext' | 'connect' | 'connectOverCDP'> {
|
||||
}
|
||||
/**
|
||||
* Modular plugin framework to teach `playwright` new tricks.
|
||||
*/
|
||||
export declare class PlaywrightExtraClass implements AugmentedLauncherAPIs {
|
||||
private _launcher?;
|
||||
/** Plugin manager */
|
||||
readonly plugins: PluginList;
|
||||
constructor(_launcher?: Partial<PlaywrightBrowserLauncher> | undefined);
|
||||
/**
|
||||
* The **main interface** to register plugins.
|
||||
*
|
||||
* Can be called multiple times to enable multiple plugins.
|
||||
*
|
||||
* Plugins derived from `PuppeteerExtraPlugin` will be used with a compatiblity layer.
|
||||
*
|
||||
* @example
|
||||
* chromium.use(plugin1).use(plugin2)
|
||||
* firefox.use(plugin1).use(plugin2)
|
||||
*
|
||||
* @see [PuppeteerExtraPlugin]
|
||||
*
|
||||
* @return The same `PlaywrightExtra` instance (for optional chaining)
|
||||
*/
|
||||
use(plugin: CompatiblePlugin): this;
|
||||
launch(...args: Parameters<PlaywrightBrowserLauncher['launch']>): ReturnType<PlaywrightBrowserLauncher['launch']>;
|
||||
launchPersistentContext(...args: Parameters<PlaywrightBrowserLauncher['launchPersistentContext']>): ReturnType<PlaywrightBrowserLauncher['launchPersistentContext']>;
|
||||
connect(wsEndpointOrOptions: string | (pw.ConnectOptions & {
|
||||
wsEndpoint?: string;
|
||||
}), wsOptions?: pw.ConnectOptions): ReturnType<PlaywrightBrowserLauncher['connect']>;
|
||||
connectOverCDP(wsEndpointOrOptions: string | (pw.ConnectOverCDPOptions & {
|
||||
endpointURL?: string;
|
||||
}), wsOptions?: pw.ConnectOverCDPOptions): ReturnType<PlaywrightBrowserLauncher['connectOverCDP']>;
|
||||
protected _bindBrowserContextEvents(context: pw.BrowserContext, contextOptions?: pw.BrowserContextOptions): Promise<void>;
|
||||
protected _bindBrowserEvents(browser: pw.Browser): Promise<void>;
|
||||
}
|
||||
/**
|
||||
* PlaywrightExtra class with additional launcher methods.
|
||||
*
|
||||
* Augments the class with an instance proxy to pass on methods that are not augmented to the original target.
|
||||
*
|
||||
*/
|
||||
export declare const PlaywrightExtra: typeof PlaywrightExtraClass;
|
||||
export {};
|
||||
230
projects/org-skill-web-research/node_modules/playwright-extra/dist/extra.js
generated
vendored
Normal file
230
projects/org-skill-web-research/node_modules/playwright-extra/dist/extra.js
generated
vendored
Normal file
@@ -0,0 +1,230 @@
|
||||
"use strict";
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.PlaywrightExtra = exports.PlaywrightExtraClass = void 0;
|
||||
const debug_1 = __importDefault(require("debug"));
|
||||
const debug = (0, debug_1.default)('playwright-extra');
|
||||
const plugins_1 = require("./plugins");
|
||||
const loader_1 = require("./helper/loader");
|
||||
/**
|
||||
* Modular plugin framework to teach `playwright` new tricks.
|
||||
*/
|
||||
class PlaywrightExtraClass {
|
||||
constructor(_launcher) {
|
||||
this._launcher = _launcher;
|
||||
this.plugins = new plugins_1.PluginList();
|
||||
}
|
||||
/**
|
||||
* The **main interface** to register plugins.
|
||||
*
|
||||
* Can be called multiple times to enable multiple plugins.
|
||||
*
|
||||
* Plugins derived from `PuppeteerExtraPlugin` will be used with a compatiblity layer.
|
||||
*
|
||||
* @example
|
||||
* chromium.use(plugin1).use(plugin2)
|
||||
* firefox.use(plugin1).use(plugin2)
|
||||
*
|
||||
* @see [PuppeteerExtraPlugin]
|
||||
*
|
||||
* @return The same `PlaywrightExtra` instance (for optional chaining)
|
||||
*/
|
||||
use(plugin) {
|
||||
const isValid = plugin && 'name' in plugin;
|
||||
if (!isValid) {
|
||||
throw new Error('A plugin must be provided to .use()');
|
||||
}
|
||||
if (this.plugins.add(plugin)) {
|
||||
debug('Plugin registered', plugin.name);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
/**
|
||||
* In order to support a default export which will require vanilla playwright automatically,
|
||||
* as well as `addExtra` to patch a provided launcher, we need to so some gymnastics here.
|
||||
*
|
||||
* Otherwise this would throw immediately, even when only using the `addExtra` export with an arbitrary compatible launcher.
|
||||
*
|
||||
* The solution is to make the vanilla launcher optional and only throw once we try to effectively use and can't find it.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
get launcher() {
|
||||
if (!this._launcher) {
|
||||
throw loader_1.playwrightLoader.requireError;
|
||||
}
|
||||
return this._launcher;
|
||||
}
|
||||
async launch(...args) {
|
||||
if (!this.launcher.launch) {
|
||||
throw new Error('Launcher does not support "launch"');
|
||||
}
|
||||
let [options] = args;
|
||||
options = Object.assign({ args: [] }, (options || {})); // Initialize args array
|
||||
debug('launch', options);
|
||||
this.plugins.prepare();
|
||||
// Give plugins the chance to modify the options before continuing
|
||||
options =
|
||||
(await this.plugins.dispatchBlocking('beforeLaunch', options)) || options;
|
||||
debug('launch with options', options);
|
||||
if ('userDataDir' in options) {
|
||||
debug("A plugin defined userDataDir during .launch, which isn't supported by playwright - ignoring");
|
||||
delete options.userDataDir;
|
||||
}
|
||||
const browser = await this.launcher['launch'](options);
|
||||
await this.plugins.dispatchBlocking('onBrowser', browser);
|
||||
await this._bindBrowserEvents(browser);
|
||||
await this.plugins.dispatchBlocking('afterLaunch', browser);
|
||||
return browser;
|
||||
}
|
||||
async launchPersistentContext(...args) {
|
||||
if (!this.launcher.launchPersistentContext) {
|
||||
throw new Error('Launcher does not support "launchPersistentContext"');
|
||||
}
|
||||
let [userDataDir, options] = args;
|
||||
options = Object.assign({ args: [] }, (options || {})); // Initialize args array
|
||||
debug('launchPersistentContext', options);
|
||||
this.plugins.prepare();
|
||||
// Give plugins the chance to modify the options before continuing
|
||||
options =
|
||||
(await this.plugins.dispatchBlocking('beforeLaunch', options)) || options;
|
||||
const context = await this.launcher['launchPersistentContext'](userDataDir, options);
|
||||
await this.plugins.dispatchBlocking('afterLaunch', context);
|
||||
this._bindBrowserContextEvents(context);
|
||||
return context;
|
||||
}
|
||||
async connect(wsEndpointOrOptions, wsOptions = {}) {
|
||||
if (!this.launcher.connect) {
|
||||
throw new Error('Launcher does not support "connect"');
|
||||
}
|
||||
this.plugins.prepare();
|
||||
// Playwright currently supports two function signatures for .connect
|
||||
let options = {};
|
||||
let wsEndpointAsString = false;
|
||||
if (typeof wsEndpointOrOptions === 'object') {
|
||||
options = Object.assign(Object.assign({}, wsEndpointOrOptions), wsOptions);
|
||||
}
|
||||
else {
|
||||
wsEndpointAsString = true;
|
||||
options = Object.assign({ wsEndpoint: wsEndpointOrOptions }, wsOptions);
|
||||
}
|
||||
debug('connect', options);
|
||||
// Give plugins the chance to modify the options before launch/connect
|
||||
options =
|
||||
(await this.plugins.dispatchBlocking('beforeConnect', options)) || options;
|
||||
// Follow call signature of end user
|
||||
const args = [];
|
||||
const wsEndpoint = options.wsEndpoint;
|
||||
if (wsEndpointAsString) {
|
||||
delete options.wsEndpoint;
|
||||
args.push(wsEndpoint, options);
|
||||
}
|
||||
else {
|
||||
args.push(options);
|
||||
}
|
||||
const browser = (await this.launcher['connect'](...args));
|
||||
await this.plugins.dispatchBlocking('onBrowser', browser);
|
||||
await this._bindBrowserEvents(browser);
|
||||
await this.plugins.dispatchBlocking('afterConnect', browser);
|
||||
return browser;
|
||||
}
|
||||
async connectOverCDP(wsEndpointOrOptions, wsOptions = {}) {
|
||||
if (!this.launcher.connectOverCDP) {
|
||||
throw new Error(`Launcher does not implement 'connectOverCDP'`);
|
||||
}
|
||||
this.plugins.prepare();
|
||||
// Playwright currently supports two function signatures for .connectOverCDP
|
||||
let options = {};
|
||||
let wsEndpointAsString = false;
|
||||
if (typeof wsEndpointOrOptions === 'object') {
|
||||
options = Object.assign(Object.assign({}, wsEndpointOrOptions), wsOptions);
|
||||
}
|
||||
else {
|
||||
wsEndpointAsString = true;
|
||||
options = Object.assign({ endpointURL: wsEndpointOrOptions }, wsOptions);
|
||||
}
|
||||
debug('connectOverCDP'), options;
|
||||
// Give plugins the chance to modify the options before launch/connect
|
||||
options =
|
||||
(await this.plugins.dispatchBlocking('beforeConnect', options)) || options;
|
||||
// Follow call signature of end user
|
||||
const args = [];
|
||||
const endpointURL = options.endpointURL;
|
||||
if (wsEndpointAsString) {
|
||||
delete options.endpointURL;
|
||||
args.push(endpointURL, options);
|
||||
}
|
||||
else {
|
||||
args.push(options);
|
||||
}
|
||||
const browser = (await this.launcher['connectOverCDP'](...args));
|
||||
await this.plugins.dispatchBlocking('onBrowser', browser);
|
||||
await this._bindBrowserEvents(browser);
|
||||
await this.plugins.dispatchBlocking('afterConnect', browser);
|
||||
return browser;
|
||||
}
|
||||
async _bindBrowserContextEvents(context, contextOptions) {
|
||||
debug('_bindBrowserContextEvents');
|
||||
this.plugins.dispatch('onContextCreated', context, contextOptions);
|
||||
// Make sure things like `addInitScript` show an effect on the very first page as well
|
||||
context.newPage = ((originalMethod, ctx) => {
|
||||
return async () => {
|
||||
const page = await originalMethod.call(ctx);
|
||||
await page.goto('about:blank');
|
||||
return page;
|
||||
};
|
||||
})(context.newPage, context);
|
||||
context.on('close', () => {
|
||||
// When using `launchPersistentContext` context closing is the same as browser closing
|
||||
if (!context.browser()) {
|
||||
this.plugins.dispatch('onDisconnected');
|
||||
}
|
||||
});
|
||||
context.on('page', page => {
|
||||
this.plugins.dispatch('onPageCreated', page);
|
||||
page.on('close', () => {
|
||||
this.plugins.dispatch('onPageClose', page);
|
||||
});
|
||||
});
|
||||
}
|
||||
async _bindBrowserEvents(browser) {
|
||||
debug('_bindPlaywrightBrowserEvents');
|
||||
browser.on('disconnected', () => {
|
||||
this.plugins.dispatch('onDisconnected', browser);
|
||||
});
|
||||
// Note: `browser.newPage` will implicitly call `browser.newContext` as well
|
||||
browser.newContext = ((originalMethod, ctx) => {
|
||||
return async (options = {}) => {
|
||||
const contextOptions = (await this.plugins.dispatchBlocking('beforeContext', options, browser)) || options;
|
||||
const context = await originalMethod.call(ctx, contextOptions);
|
||||
this._bindBrowserContextEvents(context, contextOptions);
|
||||
return context;
|
||||
};
|
||||
})(browser.newContext, browser);
|
||||
}
|
||||
}
|
||||
exports.PlaywrightExtraClass = PlaywrightExtraClass;
|
||||
/**
|
||||
* PlaywrightExtra class with additional launcher methods.
|
||||
*
|
||||
* Augments the class with an instance proxy to pass on methods that are not augmented to the original target.
|
||||
*
|
||||
*/
|
||||
exports.PlaywrightExtra = new Proxy(PlaywrightExtraClass, {
|
||||
construct(classTarget, args) {
|
||||
debug(`create instance of ${classTarget.name}`);
|
||||
const result = Reflect.construct(classTarget, args);
|
||||
return new Proxy(result, {
|
||||
get(target, prop) {
|
||||
if (prop in target) {
|
||||
return Reflect.get(target, prop);
|
||||
}
|
||||
debug('proxying property to original launcher: ', prop);
|
||||
return Reflect.get(target.launcher, prop);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
//# sourceMappingURL=extra.js.map
|
||||
1
projects/org-skill-web-research/node_modules/playwright-extra/dist/extra.js.map
generated
vendored
Normal file
1
projects/org-skill-web-research/node_modules/playwright-extra/dist/extra.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
26
projects/org-skill-web-research/node_modules/playwright-extra/dist/helper/loader.d.ts
generated
vendored
Normal file
26
projects/org-skill-web-research/node_modules/playwright-extra/dist/helper/loader.d.ts
generated
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
import type * as pw from 'playwright-core';
|
||||
/** Node.js module loader helper */
|
||||
export declare class Loader<TargetModule> {
|
||||
moduleName: string;
|
||||
packageNames: string[];
|
||||
constructor(moduleName: string, packageNames: string[]);
|
||||
/**
|
||||
* Lazy load a top level export from another module by wrapping it in a JS proxy.
|
||||
*
|
||||
* This allows us to re-export e.g. `devices` from `playwright` while redirecting direct calls
|
||||
* to it to the module version the user has installed, rather than shipping with a hardcoded version.
|
||||
*
|
||||
* If we don't do this and the user doesn't have the target module installed we'd throw immediately when our code is imported.
|
||||
*
|
||||
* We use a "super" Proxy defining all traps, so calls like `Object.keys(playwright.devices).length` will return the correct value.
|
||||
*/
|
||||
lazyloadExportOrDie<T extends keyof TargetModule>(exportName: T): TargetModule[T];
|
||||
/** Load the module if possible */
|
||||
loadModule(): TargetModule | undefined;
|
||||
/** Load the module if possible or throw */
|
||||
loadModuleOrDie(): TargetModule;
|
||||
get requireError(): Error;
|
||||
}
|
||||
export declare function requirePackages<TargetModule = any>(packageNames: string[]): TargetModule | undefined;
|
||||
/** Playwright specific module loader */
|
||||
export declare const playwrightLoader: Loader<typeof pw>;
|
||||
80
projects/org-skill-web-research/node_modules/playwright-extra/dist/helper/loader.js
generated
vendored
Normal file
80
projects/org-skill-web-research/node_modules/playwright-extra/dist/helper/loader.js
generated
vendored
Normal file
@@ -0,0 +1,80 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.playwrightLoader = exports.requirePackages = exports.Loader = void 0;
|
||||
/** Node.js module loader helper */
|
||||
class Loader {
|
||||
constructor(moduleName, packageNames) {
|
||||
this.moduleName = moduleName;
|
||||
this.packageNames = packageNames;
|
||||
}
|
||||
/**
|
||||
* Lazy load a top level export from another module by wrapping it in a JS proxy.
|
||||
*
|
||||
* This allows us to re-export e.g. `devices` from `playwright` while redirecting direct calls
|
||||
* to it to the module version the user has installed, rather than shipping with a hardcoded version.
|
||||
*
|
||||
* If we don't do this and the user doesn't have the target module installed we'd throw immediately when our code is imported.
|
||||
*
|
||||
* We use a "super" Proxy defining all traps, so calls like `Object.keys(playwright.devices).length` will return the correct value.
|
||||
*/
|
||||
lazyloadExportOrDie(exportName) {
|
||||
const that = this;
|
||||
const trapHandler = Object.fromEntries(Object.getOwnPropertyNames(Reflect).map((name) => [
|
||||
name,
|
||||
function (target, ...args) {
|
||||
const moduleExport = that.loadModuleOrDie()[exportName];
|
||||
const customTarget = moduleExport;
|
||||
const result = Reflect[name](customTarget || target, ...args);
|
||||
return result;
|
||||
}
|
||||
]));
|
||||
return new Proxy({}, trapHandler);
|
||||
}
|
||||
/** Load the module if possible */
|
||||
loadModule() {
|
||||
return requirePackages(this.packageNames);
|
||||
}
|
||||
/** Load the module if possible or throw */
|
||||
loadModuleOrDie() {
|
||||
const module = requirePackages(this.packageNames);
|
||||
if (module) {
|
||||
return module;
|
||||
}
|
||||
throw this.requireError;
|
||||
}
|
||||
get requireError() {
|
||||
const moduleNamePretty = this.moduleName.charAt(0).toUpperCase() + this.moduleName.slice(1);
|
||||
return new Error(`
|
||||
${moduleNamePretty} is missing. :-)
|
||||
|
||||
I've tried loading ${this.packageNames
|
||||
.map(p => `"${p}"`)
|
||||
.join(', ')} - no luck.
|
||||
|
||||
Make sure you install one of those packages or use the named 'addExtra' export,
|
||||
to patch a specific (and maybe non-standard) implementation of ${moduleNamePretty}.
|
||||
|
||||
To get the latest stable version of ${moduleNamePretty} run:
|
||||
'yarn add ${this.moduleName}' or 'npm i ${this.moduleName}'
|
||||
`);
|
||||
}
|
||||
}
|
||||
exports.Loader = Loader;
|
||||
function requirePackages(packageNames) {
|
||||
for (const name of packageNames) {
|
||||
try {
|
||||
return require(name);
|
||||
}
|
||||
catch (_) {
|
||||
continue; // noop
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
exports.requirePackages = requirePackages;
|
||||
/** Playwright specific module loader */
|
||||
exports.playwrightLoader = new Loader('playwright', [
|
||||
'playwright-core',
|
||||
'playwright'
|
||||
]);
|
||||
//# sourceMappingURL=loader.js.map
|
||||
1
projects/org-skill-web-research/node_modules/playwright-extra/dist/helper/loader.js.map
generated
vendored
Normal file
1
projects/org-skill-web-research/node_modules/playwright-extra/dist/helper/loader.js.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"loader.js","sourceRoot":"","sources":["../../src/helper/loader.ts"],"names":[],"mappings":";;;AAEA,mCAAmC;AACnC,MAAa,MAAM;IACjB,YAAmB,UAAkB,EAAS,YAAsB;QAAjD,eAAU,GAAV,UAAU,CAAQ;QAAS,iBAAY,GAAZ,YAAY,CAAU;IAAG,CAAC;IAExE;;;;;;;;;OASG;IACI,mBAAmB,CAA+B,UAAa;QACpE,MAAM,IAAI,GAAG,IAAI,CAAA;QACjB,MAAM,WAAW,GAAG,MAAM,CAAC,WAAW,CACpC,MAAM,CAAC,mBAAmB,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,IAAS,EAAE,EAAE,CAAC;YACrD,IAAI;YACJ,UAAU,MAAW,EAAE,GAAG,IAAW;gBACnC,MAAM,YAAY,GAAG,IAAI,CAAC,eAAe,EAAE,CAAC,UAAU,CAAC,CAAA;gBACvD,MAAM,YAAY,GAAG,YAAmB,CAAA;gBACxC,MAAM,MAAM,GAAK,OAAe,CAAC,IAAI,CAAS,CAC5C,YAAY,IAAI,MAAM,EACtB,GAAG,IAAI,CACR,CAAA;gBACD,OAAO,MAAM,CAAA;YACf,CAAC;SACF,CAAC,CACH,CAAA;QACD,OAAO,IAAI,KAAK,CAAC,EAAE,EAAE,WAAW,CAAoB,CAAA;IACtD,CAAC;IAED,kCAAkC;IAC3B,UAAU;QACf,OAAO,eAAe,CAAe,IAAI,CAAC,YAAY,CAAC,CAAA;IACzD,CAAC;IAED,2CAA2C;IACpC,eAAe;QACpB,MAAM,MAAM,GAAG,eAAe,CAAe,IAAI,CAAC,YAAY,CAAC,CAAA;QAC/D,IAAI,MAAM,EAAE;YACV,OAAO,MAAM,CAAA;SACd;QACD,MAAM,IAAI,CAAC,YAAY,CAAA;IACzB,CAAC;IAED,IAAW,YAAY;QACrB,MAAM,gBAAgB,GACpB,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;QACpE,OAAO,IAAI,KAAK,CAAC;IACjB,gBAAgB;;uBAEG,IAAI,CAAC,YAAY;aACnC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC;aAClB,IAAI,CAAC,IAAI,CAAC;;;mEAGoD,gBAAgB;;wCAE3C,gBAAgB;cAC1C,IAAI,CAAC,UAAU,eAAe,IAAI,CAAC,UAAU;GACxD,CAAC,CAAA;IACF,CAAC;CACF;AA/DD,wBA+DC;AAED,SAAgB,eAAe,CAAqB,YAAsB;IACxE,KAAK,MAAM,IAAI,IAAI,YAAY,EAAE;QAC/B,IAAI;YACF,OAAO,OAAO,CAAC,IAAI,CAAiB,CAAA;SACrC;QAAC,OAAO,CAAC,EAAE;YACV,SAAQ,CAAC,OAAO;SACjB;KACF;IACD,OAAM;AACR,CAAC;AATD,0CASC;AAED,wCAAwC;AAC3B,QAAA,gBAAgB,GAAG,IAAI,MAAM,CAAY,YAAY,EAAE;IAClE,iBAAiB;IACjB,YAAY;CACb,CAAC,CAAA"}
|
||||
934
projects/org-skill-web-research/node_modules/playwright-extra/dist/index.cjs.js
generated
vendored
Normal file
934
projects/org-skill-web-research/node_modules/playwright-extra/dist/index.cjs.js
generated
vendored
Normal file
@@ -0,0 +1,934 @@
|
||||
/*!
|
||||
* playwright-extra v4.3.5 by berstend
|
||||
* https://github.com/berstend/puppeteer-extra/tree/master/packages/playwright-extra#readme
|
||||
* @license MIT
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
Object.defineProperty(exports, '__esModule', { value: true });
|
||||
|
||||
function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }
|
||||
|
||||
var Debug = _interopDefault(require('debug'));
|
||||
|
||||
/** Node.js module loader helper */
|
||||
class Loader {
|
||||
constructor(moduleName, packageNames) {
|
||||
this.moduleName = moduleName;
|
||||
this.packageNames = packageNames;
|
||||
}
|
||||
/**
|
||||
* Lazy load a top level export from another module by wrapping it in a JS proxy.
|
||||
*
|
||||
* This allows us to re-export e.g. `devices` from `playwright` while redirecting direct calls
|
||||
* to it to the module version the user has installed, rather than shipping with a hardcoded version.
|
||||
*
|
||||
* If we don't do this and the user doesn't have the target module installed we'd throw immediately when our code is imported.
|
||||
*
|
||||
* We use a "super" Proxy defining all traps, so calls like `Object.keys(playwright.devices).length` will return the correct value.
|
||||
*/
|
||||
lazyloadExportOrDie(exportName) {
|
||||
const that = this;
|
||||
const trapHandler = Object.fromEntries(Object.getOwnPropertyNames(Reflect).map((name) => [
|
||||
name,
|
||||
function (target, ...args) {
|
||||
const moduleExport = that.loadModuleOrDie()[exportName];
|
||||
const customTarget = moduleExport;
|
||||
const result = Reflect[name](customTarget || target, ...args);
|
||||
return result;
|
||||
}
|
||||
]));
|
||||
return new Proxy({}, trapHandler);
|
||||
}
|
||||
/** Load the module if possible */
|
||||
loadModule() {
|
||||
return requirePackages(this.packageNames);
|
||||
}
|
||||
/** Load the module if possible or throw */
|
||||
loadModuleOrDie() {
|
||||
const module = requirePackages(this.packageNames);
|
||||
if (module) {
|
||||
return module;
|
||||
}
|
||||
throw this.requireError;
|
||||
}
|
||||
get requireError() {
|
||||
const moduleNamePretty = this.moduleName.charAt(0).toUpperCase() + this.moduleName.slice(1);
|
||||
return new Error(`
|
||||
${moduleNamePretty} is missing. :-)
|
||||
|
||||
I've tried loading ${this.packageNames
|
||||
.map(p => `"${p}"`)
|
||||
.join(', ')} - no luck.
|
||||
|
||||
Make sure you install one of those packages or use the named 'addExtra' export,
|
||||
to patch a specific (and maybe non-standard) implementation of ${moduleNamePretty}.
|
||||
|
||||
To get the latest stable version of ${moduleNamePretty} run:
|
||||
'yarn add ${this.moduleName}' or 'npm i ${this.moduleName}'
|
||||
`);
|
||||
}
|
||||
}
|
||||
function requirePackages(packageNames) {
|
||||
for (const name of packageNames) {
|
||||
try {
|
||||
return require(name);
|
||||
}
|
||||
catch (_) {
|
||||
continue; // noop
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
/** Playwright specific module loader */
|
||||
const playwrightLoader = new Loader('playwright', [
|
||||
'playwright-core',
|
||||
'playwright'
|
||||
]);
|
||||
|
||||
const debug = Debug('playwright-extra:puppeteer-compat');
|
||||
const isPlaywrightPage = (obj) => {
|
||||
return 'unroute' in obj;
|
||||
};
|
||||
const isPlaywrightFrame = (obj) => {
|
||||
return ['parentFrame', 'frameLocator'].every(x => x in obj);
|
||||
};
|
||||
const isPlaywrightBrowser = (obj) => {
|
||||
return 'newContext' in obj;
|
||||
};
|
||||
const isPuppeteerCompat = (obj) => {
|
||||
return !!obj && typeof obj === 'object' && !!obj.isCompatShim;
|
||||
};
|
||||
const cache = {
|
||||
objectToShim: new Map(),
|
||||
cdpSession: {
|
||||
page: new Map(),
|
||||
browser: new Map()
|
||||
}
|
||||
};
|
||||
/** Augment a Playwright object with compatibility with certain Puppeteer methods */
|
||||
function addPuppeteerCompat(object) {
|
||||
if (!object || typeof object !== 'object') {
|
||||
return object;
|
||||
}
|
||||
if (cache.objectToShim.has(object)) {
|
||||
return cache.objectToShim.get(object);
|
||||
}
|
||||
if (isPuppeteerCompat(object)) {
|
||||
return object;
|
||||
}
|
||||
debug('addPuppeteerCompat', cache.objectToShim.size);
|
||||
if (isPlaywrightPage(object) || isPlaywrightFrame(object)) {
|
||||
const shim = createPageShim(object);
|
||||
cache.objectToShim.set(object, shim);
|
||||
return shim;
|
||||
}
|
||||
if (isPlaywrightBrowser(object)) {
|
||||
const shim = createBrowserShim(object);
|
||||
cache.objectToShim.set(object, shim);
|
||||
return shim;
|
||||
}
|
||||
debug('Received unknown object:', Reflect.ownKeys(object));
|
||||
return object;
|
||||
}
|
||||
// Only chromium browsers support CDP
|
||||
const dummyCDPClient = {
|
||||
send: async (...args) => {
|
||||
debug('dummy CDP client called', 'send', args);
|
||||
},
|
||||
on: (...args) => {
|
||||
debug('dummy CDP client called', 'on', args);
|
||||
}
|
||||
};
|
||||
async function getPageCDPSession(page) {
|
||||
let session = cache.cdpSession.page.get(page);
|
||||
if (session) {
|
||||
debug('getPageCDPSession: use existing');
|
||||
return session;
|
||||
}
|
||||
debug('getPageCDPSession: use new');
|
||||
const context = isPlaywrightFrame(page)
|
||||
? page.page().context()
|
||||
: page.context();
|
||||
try {
|
||||
session = await context.newCDPSession(page);
|
||||
cache.cdpSession.page.set(page, session);
|
||||
return session;
|
||||
}
|
||||
catch (err) {
|
||||
debug('getPageCDPSession: error while creating session:', err.message);
|
||||
debug('getPageCDPSession: Unable create CDP session (most likely a different browser than chromium) - returning a dummy');
|
||||
}
|
||||
return dummyCDPClient;
|
||||
}
|
||||
async function getBrowserCDPSession(browser) {
|
||||
let session = cache.cdpSession.browser.get(browser);
|
||||
if (session) {
|
||||
debug('getBrowserCDPSession: use existing');
|
||||
return session;
|
||||
}
|
||||
debug('getBrowserCDPSession: use new');
|
||||
try {
|
||||
session = await browser.newBrowserCDPSession();
|
||||
cache.cdpSession.browser.set(browser, session);
|
||||
return session;
|
||||
}
|
||||
catch (err) {
|
||||
debug('getBrowserCDPSession: error while creating session:', err.message);
|
||||
debug('getBrowserCDPSession: Unable create CDP session (most likely a different browser than chromium) - returning a dummy');
|
||||
}
|
||||
return dummyCDPClient;
|
||||
}
|
||||
function createPageShim(page) {
|
||||
const objId = Math.random().toString(36).substring(2, 7);
|
||||
const shim = new Proxy(page, {
|
||||
get(target, prop) {
|
||||
if (prop === 'isCompatShim' || prop === 'isPlaywright') {
|
||||
return true;
|
||||
}
|
||||
debug('page - get', objId, prop);
|
||||
if (prop === '_client') {
|
||||
return () => ({
|
||||
send: async (method, params) => {
|
||||
const session = await getPageCDPSession(page);
|
||||
return await session.send(method, params);
|
||||
},
|
||||
on: (event, listener) => {
|
||||
getPageCDPSession(page).then(session => {
|
||||
session.on(event, listener);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
if (prop === 'setBypassCSP') {
|
||||
return async (enabled) => {
|
||||
const session = await getPageCDPSession(page);
|
||||
return await session.send('Page.setBypassCSP', {
|
||||
enabled
|
||||
});
|
||||
};
|
||||
}
|
||||
if (prop === 'setUserAgent') {
|
||||
return async (userAgent, userAgentMetadata) => {
|
||||
const session = await getPageCDPSession(page);
|
||||
return await session.send('Emulation.setUserAgentOverride', {
|
||||
userAgent,
|
||||
userAgentMetadata
|
||||
});
|
||||
};
|
||||
}
|
||||
if (prop === 'browser') {
|
||||
if (isPlaywrightPage(page)) {
|
||||
return () => {
|
||||
let browser = page.context().browser();
|
||||
if (!browser) {
|
||||
debug('page.browser() - not available, most likely due to launchPersistentContext');
|
||||
// Use a page shim as quick drop-in (so browser.userAgent() still works)
|
||||
browser = page;
|
||||
}
|
||||
return addPuppeteerCompat(browser);
|
||||
};
|
||||
}
|
||||
}
|
||||
if (prop === 'evaluateOnNewDocument') {
|
||||
if (isPlaywrightPage(page)) {
|
||||
return async function (pageFunction, ...args) {
|
||||
return await page.addInitScript(pageFunction, args[0]);
|
||||
};
|
||||
}
|
||||
}
|
||||
// Only relevant when page is being used a pseudo stand-in for the browser object (launchPersistentContext)
|
||||
if (prop === 'userAgent') {
|
||||
return async (enabled) => {
|
||||
const session = await getPageCDPSession(page);
|
||||
const data = await session.send('Browser.getVersion');
|
||||
return data.userAgent;
|
||||
};
|
||||
}
|
||||
return Reflect.get(target, prop);
|
||||
}
|
||||
});
|
||||
return shim;
|
||||
}
|
||||
function createBrowserShim(browser) {
|
||||
const objId = Math.random().toString(36).substring(2, 7);
|
||||
const shim = new Proxy(browser, {
|
||||
get(target, prop) {
|
||||
if (prop === 'isCompatShim' || prop === 'isPlaywright') {
|
||||
return true;
|
||||
}
|
||||
debug('browser - get', objId, prop);
|
||||
if (prop === 'pages') {
|
||||
return () => browser
|
||||
.contexts()
|
||||
.flatMap(c => c.pages().map(page => addPuppeteerCompat(page)));
|
||||
}
|
||||
if (prop === 'userAgent') {
|
||||
return async () => {
|
||||
const session = await getBrowserCDPSession(browser);
|
||||
const data = await session.send('Browser.getVersion');
|
||||
return data.userAgent;
|
||||
};
|
||||
}
|
||||
return Reflect.get(target, prop);
|
||||
}
|
||||
});
|
||||
return shim;
|
||||
}
|
||||
|
||||
const debug$1 = Debug('playwright-extra:plugins');
|
||||
class PluginList {
|
||||
constructor() {
|
||||
this._plugins = [];
|
||||
this._dependencyDefaults = new Map();
|
||||
this._dependencyResolution = new Map();
|
||||
}
|
||||
/**
|
||||
* Get a list of all registered plugins.
|
||||
*/
|
||||
get list() {
|
||||
return this._plugins;
|
||||
}
|
||||
/**
|
||||
* Get the names of all registered plugins.
|
||||
*/
|
||||
get names() {
|
||||
return this._plugins.map(p => p.name);
|
||||
}
|
||||
/**
|
||||
* Add a new plugin to the list (after checking if it's well-formed).
|
||||
*
|
||||
* @param plugin
|
||||
* @internal
|
||||
*/
|
||||
add(plugin) {
|
||||
var _a;
|
||||
if (!this.isValidPluginInstance(plugin)) {
|
||||
return false;
|
||||
}
|
||||
if (!!plugin.onPluginRegistered) {
|
||||
plugin.onPluginRegistered({ framework: 'playwright' });
|
||||
}
|
||||
// PuppeteerExtraPlugin: Populate `_childClassMembers` list containing methods defined by the plugin
|
||||
if (!!plugin._registerChildClassMembers) {
|
||||
plugin._registerChildClassMembers(Object.getPrototypeOf(plugin));
|
||||
}
|
||||
if ((_a = plugin.requirements) === null || _a === void 0 ? void 0 : _a.has('dataFromPlugins')) {
|
||||
plugin.getDataFromPlugins = this.getData.bind(this);
|
||||
}
|
||||
this._plugins.push(plugin);
|
||||
return true;
|
||||
}
|
||||
/** Check if the shape of a plugin is correct or warn */
|
||||
isValidPluginInstance(plugin) {
|
||||
if (!plugin ||
|
||||
typeof plugin !== 'object' ||
|
||||
!plugin._isPuppeteerExtraPlugin) {
|
||||
console.error(`Warning: Plugin is not derived from PuppeteerExtraPlugin, ignoring.`, plugin);
|
||||
return false;
|
||||
}
|
||||
if (!plugin.name) {
|
||||
console.error(`Warning: Plugin with no name registering, ignoring.`, plugin);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
/** Error callback in case calling a plugin method throws an error. Can be overwritten. */
|
||||
onPluginError(plugin, method, err) {
|
||||
console.warn(`An error occured while executing "${method}" in plugin "${plugin.name}":`, err);
|
||||
}
|
||||
/**
|
||||
* Define default values for plugins implicitly required through the `dependencies` plugin stanza.
|
||||
*
|
||||
* @param dependencyPath - The string by which the dependency is listed (not the plugin name)
|
||||
*
|
||||
* @example
|
||||
* chromium.use(stealth)
|
||||
* chromium.plugins.setDependencyDefaults('stealth/evasions/webgl.vendor', { vendor: 'Bob', renderer: 'Alice' })
|
||||
*/
|
||||
setDependencyDefaults(dependencyPath, opts) {
|
||||
this._dependencyDefaults.set(dependencyPath, opts);
|
||||
return this;
|
||||
}
|
||||
/**
|
||||
* Define custom plugin modules for plugins implicitly required through the `dependencies` plugin stanza.
|
||||
*
|
||||
* Using this will prevent dynamic imports from being used, which JS bundlers often have issues with.
|
||||
*
|
||||
* @example
|
||||
* chromium.use(stealth)
|
||||
* chromium.plugins.setDependencyResolution('stealth/evasions/webgl.vendor', VendorPlugin)
|
||||
*/
|
||||
setDependencyResolution(dependencyPath, pluginModule) {
|
||||
this._dependencyResolution.set(dependencyPath, pluginModule);
|
||||
return this;
|
||||
}
|
||||
/**
|
||||
* Prepare plugins to be used (resolve dependencies, ordering)
|
||||
* @internal
|
||||
*/
|
||||
prepare() {
|
||||
this.resolveDependencies();
|
||||
this.order();
|
||||
}
|
||||
/** Return all plugins using the supplied method */
|
||||
filterByMethod(methodName) {
|
||||
return this._plugins.filter(plugin => {
|
||||
// PuppeteerExtraPlugin: The base class will already define all methods, hence we need to do a different check
|
||||
if (!!plugin._childClassMembers &&
|
||||
Array.isArray(plugin._childClassMembers)) {
|
||||
return plugin._childClassMembers.includes(methodName);
|
||||
}
|
||||
return methodName in plugin;
|
||||
});
|
||||
}
|
||||
/** Conditionally add puppeteer compatibility to values provided to the plugins */
|
||||
_addPuppeteerCompatIfNeeded(plugin, method, args) {
|
||||
const canUseShim = plugin._isPuppeteerExtraPlugin && !plugin.noPuppeteerShim;
|
||||
const methodWhitelist = [
|
||||
'onBrowser',
|
||||
'onPageCreated',
|
||||
'onPageClose',
|
||||
'afterConnect',
|
||||
'afterLaunch'
|
||||
];
|
||||
const shouldUseShim = methodWhitelist.includes(method);
|
||||
if (!canUseShim || !shouldUseShim) {
|
||||
return args;
|
||||
}
|
||||
debug$1('add puppeteer compatibility', plugin.name, method);
|
||||
return [...args.map(arg => addPuppeteerCompat(arg))];
|
||||
}
|
||||
/**
|
||||
* Dispatch plugin lifecycle events in a typesafe way.
|
||||
* Only Plugins that expose the supplied property will be called.
|
||||
*
|
||||
* Will not await results to dispatch events as fast as possible to all plugins.
|
||||
*
|
||||
* @param method - The lifecycle method name
|
||||
* @param args - Optional: Any arguments to be supplied to the plugin methods
|
||||
* @internal
|
||||
*/
|
||||
dispatch(method, ...args) {
|
||||
var _a, _b;
|
||||
const plugins = this.filterByMethod(method);
|
||||
debug$1('dispatch', method, {
|
||||
all: this._plugins.length,
|
||||
filteredByMethod: plugins.length
|
||||
});
|
||||
for (const plugin of plugins) {
|
||||
try {
|
||||
args = this._addPuppeteerCompatIfNeeded.bind(this)(plugin, method, args);
|
||||
const fnType = (_b = (_a = plugin[method]) === null || _a === void 0 ? void 0 : _a.constructor) === null || _b === void 0 ? void 0 : _b.name;
|
||||
debug$1('dispatch to plugin', {
|
||||
plugin: plugin.name,
|
||||
method,
|
||||
fnType
|
||||
});
|
||||
if (fnType === 'AsyncFunction') {
|
||||
;
|
||||
plugin[method](...args).catch((err) => this.onPluginError(plugin, method, err));
|
||||
}
|
||||
else {
|
||||
;
|
||||
plugin[method](...args);
|
||||
}
|
||||
}
|
||||
catch (err) {
|
||||
this.onPluginError(plugin, method, err);
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Dispatch plugin lifecycle events in a typesafe way.
|
||||
* Only Plugins that expose the supplied property will be called.
|
||||
*
|
||||
* Can also be used to get a definite return value after passing it to plugins:
|
||||
* Calls plugins sequentially and passes on a value (waterfall style).
|
||||
*
|
||||
* The plugins can either modify the value or return an updated one.
|
||||
* Will return the latest, updated value which ran through all plugins.
|
||||
*
|
||||
* By convention only the first argument will be used as the updated value.
|
||||
*
|
||||
* @param method - The lifecycle method name
|
||||
* @param args - Optional: Any arguments to be supplied to the plugin methods
|
||||
* @internal
|
||||
*/
|
||||
async dispatchBlocking(method, ...args) {
|
||||
const plugins = this.filterByMethod(method);
|
||||
debug$1('dispatchBlocking', method, {
|
||||
all: this._plugins.length,
|
||||
filteredByMethod: plugins.length
|
||||
});
|
||||
let retValue = null;
|
||||
for (const plugin of plugins) {
|
||||
try {
|
||||
args = this._addPuppeteerCompatIfNeeded.bind(this)(plugin, method, args);
|
||||
retValue = await plugin[method](...args);
|
||||
// In case we got a return value use that as new first argument for followup function calls
|
||||
if (retValue !== undefined) {
|
||||
args[0] = retValue;
|
||||
}
|
||||
}
|
||||
catch (err) {
|
||||
this.onPluginError(plugin, method, err);
|
||||
return retValue;
|
||||
}
|
||||
}
|
||||
return retValue;
|
||||
}
|
||||
/**
|
||||
* Order plugins that have expressed a special placement requirement.
|
||||
*
|
||||
* This is useful/necessary for e.g. plugins that depend on the data from other plugins.
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
order() {
|
||||
debug$1('order:before', this.names);
|
||||
const runLast = this._plugins
|
||||
.filter(p => { var _a; return (_a = p.requirements) === null || _a === void 0 ? void 0 : _a.has('runLast'); })
|
||||
.map(p => p.name);
|
||||
for (const name of runLast) {
|
||||
const index = this._plugins.findIndex(p => p.name === name);
|
||||
this._plugins.push(this._plugins.splice(index, 1)[0]);
|
||||
}
|
||||
debug$1('order:after', this.names);
|
||||
}
|
||||
/**
|
||||
* Collects the exposed `data` property of all registered plugins.
|
||||
* Will be reduced/flattened to a single array.
|
||||
*
|
||||
* Can be accessed by plugins that listed the `dataFromPlugins` requirement.
|
||||
*
|
||||
* Implemented mainly for plugins that need data from other plugins (e.g. `user-preferences`).
|
||||
*
|
||||
* @see [PuppeteerExtraPlugin]/data
|
||||
* @param name - Filter data by optional name
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
getData(name) {
|
||||
const data = this._plugins
|
||||
.filter((p) => !!p.data)
|
||||
.map((p) => (Array.isArray(p.data) ? p.data : [p.data]))
|
||||
.reduce((acc, arr) => [...acc, ...arr], []);
|
||||
return name ? data.filter((d) => d.name === name) : data;
|
||||
}
|
||||
/**
|
||||
* Handle `plugins` stanza (already instantiated plugins that don't require dynamic imports)
|
||||
*/
|
||||
resolvePluginsStanza() {
|
||||
debug$1('resolvePluginsStanza');
|
||||
const pluginNames = new Set(this.names);
|
||||
this._plugins
|
||||
.filter(p => !!p.plugins && p.plugins.length)
|
||||
.filter(p => !pluginNames.has(p.name)) // TBD: Do we want to filter out existing?
|
||||
.forEach(parent => {
|
||||
(parent.plugins || []).forEach(p => {
|
||||
debug$1(parent.name, 'adding missing plugin', p.name);
|
||||
this.add(p);
|
||||
});
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Handle `dependencies` stanza (which requires dynamic imports)
|
||||
*
|
||||
* Plugins can define `dependencies` as a Set or Array of dependency paths, or a Map with additional opts
|
||||
*
|
||||
* @note
|
||||
* - The default opts for implicit dependencies can be defined using `setDependencyDefaults()`
|
||||
* - Dynamic imports can be avoided by providing plugin modules with `setDependencyResolution()`
|
||||
*/
|
||||
resolveDependenciesStanza() {
|
||||
debug$1('resolveDependenciesStanza');
|
||||
/** Attempt to dynamically require a plugin module */
|
||||
const requireDependencyOrDie = (parentName, dependencyPath) => {
|
||||
// If the user provided the plugin module already we use that
|
||||
if (this._dependencyResolution.has(dependencyPath)) {
|
||||
return this._dependencyResolution.get(dependencyPath);
|
||||
}
|
||||
const possiblePrefixes = ['puppeteer-extra-plugin-']; // could be extended later
|
||||
const isAlreadyPrefixed = possiblePrefixes.some(prefix => dependencyPath.startsWith(prefix));
|
||||
const packagePaths = [];
|
||||
// If the dependency is not already prefixed we attempt to require all possible combinations to find one that works
|
||||
if (!isAlreadyPrefixed) {
|
||||
packagePaths.push(...possiblePrefixes.map(prefix => prefix + dependencyPath));
|
||||
}
|
||||
// We always attempt to require the path verbatim (as a last resort)
|
||||
packagePaths.push(dependencyPath);
|
||||
const pluginModule = requirePackages(packagePaths);
|
||||
if (pluginModule) {
|
||||
return pluginModule;
|
||||
}
|
||||
const explanation = `
|
||||
The plugin '${parentName}' listed '${dependencyPath}' as dependency,
|
||||
which could not be found. Please install it:
|
||||
|
||||
${packagePaths
|
||||
.map(packagePath => `yarn add ${packagePath.split('/')[0]}`)
|
||||
.join(`\n or:\n`)}
|
||||
|
||||
Note: You don't need to require the plugin yourself,
|
||||
unless you want to modify it's default settings.
|
||||
|
||||
If your bundler has issues with dynamic imports take a look at '.plugins.setDependencyResolution()'.
|
||||
`;
|
||||
console.warn(explanation);
|
||||
throw new Error('Plugin dependency not found');
|
||||
};
|
||||
const existingPluginNames = new Set(this.names);
|
||||
const recursivelyLoadMissingDependencies = ({ name: parentName, dependencies }) => {
|
||||
if (!dependencies) {
|
||||
return;
|
||||
}
|
||||
const processDependency = (dependencyPath, opts) => {
|
||||
const pluginModule = requireDependencyOrDie(parentName, dependencyPath);
|
||||
opts = opts || this._dependencyDefaults.get(dependencyPath) || {};
|
||||
const plugin = pluginModule(opts);
|
||||
if (existingPluginNames.has(plugin.name)) {
|
||||
debug$1(parentName, '=> dependency already exists:', plugin.name);
|
||||
return;
|
||||
}
|
||||
existingPluginNames.add(plugin.name);
|
||||
debug$1(parentName, '=> adding new dependency:', plugin.name, opts);
|
||||
this.add(plugin);
|
||||
return recursivelyLoadMissingDependencies(plugin);
|
||||
};
|
||||
if (dependencies instanceof Set || Array.isArray(dependencies)) {
|
||||
return [...dependencies].forEach(dependencyPath => processDependency(dependencyPath));
|
||||
}
|
||||
if (dependencies instanceof Map) {
|
||||
// Note: `k,v => v,k` (Map + forEach will reverse the order)
|
||||
return dependencies.forEach((v, k) => processDependency(k, v));
|
||||
}
|
||||
};
|
||||
this.list.forEach(recursivelyLoadMissingDependencies);
|
||||
}
|
||||
/**
|
||||
* Lightweight plugin dependency management to require plugins and code mods on demand.
|
||||
* @private
|
||||
*/
|
||||
resolveDependencies() {
|
||||
debug$1('resolveDependencies');
|
||||
this.resolvePluginsStanza();
|
||||
this.resolveDependenciesStanza();
|
||||
}
|
||||
}
|
||||
|
||||
const debug$2 = Debug('playwright-extra');
|
||||
/**
|
||||
* Modular plugin framework to teach `playwright` new tricks.
|
||||
*/
|
||||
class PlaywrightExtraClass {
|
||||
constructor(_launcher) {
|
||||
this._launcher = _launcher;
|
||||
this.plugins = new PluginList();
|
||||
}
|
||||
/**
|
||||
* The **main interface** to register plugins.
|
||||
*
|
||||
* Can be called multiple times to enable multiple plugins.
|
||||
*
|
||||
* Plugins derived from `PuppeteerExtraPlugin` will be used with a compatiblity layer.
|
||||
*
|
||||
* @example
|
||||
* chromium.use(plugin1).use(plugin2)
|
||||
* firefox.use(plugin1).use(plugin2)
|
||||
*
|
||||
* @see [PuppeteerExtraPlugin]
|
||||
*
|
||||
* @return The same `PlaywrightExtra` instance (for optional chaining)
|
||||
*/
|
||||
use(plugin) {
|
||||
const isValid = plugin && 'name' in plugin;
|
||||
if (!isValid) {
|
||||
throw new Error('A plugin must be provided to .use()');
|
||||
}
|
||||
if (this.plugins.add(plugin)) {
|
||||
debug$2('Plugin registered', plugin.name);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
/**
|
||||
* In order to support a default export which will require vanilla playwright automatically,
|
||||
* as well as `addExtra` to patch a provided launcher, we need to so some gymnastics here.
|
||||
*
|
||||
* Otherwise this would throw immediately, even when only using the `addExtra` export with an arbitrary compatible launcher.
|
||||
*
|
||||
* The solution is to make the vanilla launcher optional and only throw once we try to effectively use and can't find it.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
get launcher() {
|
||||
if (!this._launcher) {
|
||||
throw playwrightLoader.requireError;
|
||||
}
|
||||
return this._launcher;
|
||||
}
|
||||
async launch(...args) {
|
||||
if (!this.launcher.launch) {
|
||||
throw new Error('Launcher does not support "launch"');
|
||||
}
|
||||
let [options] = args;
|
||||
options = Object.assign({ args: [] }, (options || {})); // Initialize args array
|
||||
debug$2('launch', options);
|
||||
this.plugins.prepare();
|
||||
// Give plugins the chance to modify the options before continuing
|
||||
options =
|
||||
(await this.plugins.dispatchBlocking('beforeLaunch', options)) || options;
|
||||
debug$2('launch with options', options);
|
||||
if ('userDataDir' in options) {
|
||||
debug$2("A plugin defined userDataDir during .launch, which isn't supported by playwright - ignoring");
|
||||
delete options.userDataDir;
|
||||
}
|
||||
const browser = await this.launcher['launch'](options);
|
||||
await this.plugins.dispatchBlocking('onBrowser', browser);
|
||||
await this._bindBrowserEvents(browser);
|
||||
await this.plugins.dispatchBlocking('afterLaunch', browser);
|
||||
return browser;
|
||||
}
|
||||
async launchPersistentContext(...args) {
|
||||
if (!this.launcher.launchPersistentContext) {
|
||||
throw new Error('Launcher does not support "launchPersistentContext"');
|
||||
}
|
||||
let [userDataDir, options] = args;
|
||||
options = Object.assign({ args: [] }, (options || {})); // Initialize args array
|
||||
debug$2('launchPersistentContext', options);
|
||||
this.plugins.prepare();
|
||||
// Give plugins the chance to modify the options before continuing
|
||||
options =
|
||||
(await this.plugins.dispatchBlocking('beforeLaunch', options)) || options;
|
||||
const context = await this.launcher['launchPersistentContext'](userDataDir, options);
|
||||
await this.plugins.dispatchBlocking('afterLaunch', context);
|
||||
this._bindBrowserContextEvents(context);
|
||||
return context;
|
||||
}
|
||||
async connect(wsEndpointOrOptions, wsOptions = {}) {
|
||||
if (!this.launcher.connect) {
|
||||
throw new Error('Launcher does not support "connect"');
|
||||
}
|
||||
this.plugins.prepare();
|
||||
// Playwright currently supports two function signatures for .connect
|
||||
let options = {};
|
||||
let wsEndpointAsString = false;
|
||||
if (typeof wsEndpointOrOptions === 'object') {
|
||||
options = Object.assign(Object.assign({}, wsEndpointOrOptions), wsOptions);
|
||||
}
|
||||
else {
|
||||
wsEndpointAsString = true;
|
||||
options = Object.assign({ wsEndpoint: wsEndpointOrOptions }, wsOptions);
|
||||
}
|
||||
debug$2('connect', options);
|
||||
// Give plugins the chance to modify the options before launch/connect
|
||||
options =
|
||||
(await this.plugins.dispatchBlocking('beforeConnect', options)) || options;
|
||||
// Follow call signature of end user
|
||||
const args = [];
|
||||
const wsEndpoint = options.wsEndpoint;
|
||||
if (wsEndpointAsString) {
|
||||
delete options.wsEndpoint;
|
||||
args.push(wsEndpoint, options);
|
||||
}
|
||||
else {
|
||||
args.push(options);
|
||||
}
|
||||
const browser = (await this.launcher['connect'](...args));
|
||||
await this.plugins.dispatchBlocking('onBrowser', browser);
|
||||
await this._bindBrowserEvents(browser);
|
||||
await this.plugins.dispatchBlocking('afterConnect', browser);
|
||||
return browser;
|
||||
}
|
||||
async connectOverCDP(wsEndpointOrOptions, wsOptions = {}) {
|
||||
if (!this.launcher.connectOverCDP) {
|
||||
throw new Error(`Launcher does not implement 'connectOverCDP'`);
|
||||
}
|
||||
this.plugins.prepare();
|
||||
// Playwright currently supports two function signatures for .connectOverCDP
|
||||
let options = {};
|
||||
let wsEndpointAsString = false;
|
||||
if (typeof wsEndpointOrOptions === 'object') {
|
||||
options = Object.assign(Object.assign({}, wsEndpointOrOptions), wsOptions);
|
||||
}
|
||||
else {
|
||||
wsEndpointAsString = true;
|
||||
options = Object.assign({ endpointURL: wsEndpointOrOptions }, wsOptions);
|
||||
}
|
||||
debug$2('connectOverCDP'), options;
|
||||
// Give plugins the chance to modify the options before launch/connect
|
||||
options =
|
||||
(await this.plugins.dispatchBlocking('beforeConnect', options)) || options;
|
||||
// Follow call signature of end user
|
||||
const args = [];
|
||||
const endpointURL = options.endpointURL;
|
||||
if (wsEndpointAsString) {
|
||||
delete options.endpointURL;
|
||||
args.push(endpointURL, options);
|
||||
}
|
||||
else {
|
||||
args.push(options);
|
||||
}
|
||||
const browser = (await this.launcher['connectOverCDP'](...args));
|
||||
await this.plugins.dispatchBlocking('onBrowser', browser);
|
||||
await this._bindBrowserEvents(browser);
|
||||
await this.plugins.dispatchBlocking('afterConnect', browser);
|
||||
return browser;
|
||||
}
|
||||
async _bindBrowserContextEvents(context, contextOptions) {
|
||||
debug$2('_bindBrowserContextEvents');
|
||||
this.plugins.dispatch('onContextCreated', context, contextOptions);
|
||||
// Make sure things like `addInitScript` show an effect on the very first page as well
|
||||
context.newPage = ((originalMethod, ctx) => {
|
||||
return async () => {
|
||||
const page = await originalMethod.call(ctx);
|
||||
await page.goto('about:blank');
|
||||
return page;
|
||||
};
|
||||
})(context.newPage, context);
|
||||
context.on('close', () => {
|
||||
// When using `launchPersistentContext` context closing is the same as browser closing
|
||||
if (!context.browser()) {
|
||||
this.plugins.dispatch('onDisconnected');
|
||||
}
|
||||
});
|
||||
context.on('page', page => {
|
||||
this.plugins.dispatch('onPageCreated', page);
|
||||
page.on('close', () => {
|
||||
this.plugins.dispatch('onPageClose', page);
|
||||
});
|
||||
});
|
||||
}
|
||||
async _bindBrowserEvents(browser) {
|
||||
debug$2('_bindPlaywrightBrowserEvents');
|
||||
browser.on('disconnected', () => {
|
||||
this.plugins.dispatch('onDisconnected', browser);
|
||||
});
|
||||
// Note: `browser.newPage` will implicitly call `browser.newContext` as well
|
||||
browser.newContext = ((originalMethod, ctx) => {
|
||||
return async (options = {}) => {
|
||||
const contextOptions = (await this.plugins.dispatchBlocking('beforeContext', options, browser)) || options;
|
||||
const context = await originalMethod.call(ctx, contextOptions);
|
||||
this._bindBrowserContextEvents(context, contextOptions);
|
||||
return context;
|
||||
};
|
||||
})(browser.newContext, browser);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* PlaywrightExtra class with additional launcher methods.
|
||||
*
|
||||
* Augments the class with an instance proxy to pass on methods that are not augmented to the original target.
|
||||
*
|
||||
*/
|
||||
const PlaywrightExtra = new Proxy(PlaywrightExtraClass, {
|
||||
construct(classTarget, args) {
|
||||
debug$2(`create instance of ${classTarget.name}`);
|
||||
const result = Reflect.construct(classTarget, args);
|
||||
return new Proxy(result, {
|
||||
get(target, prop) {
|
||||
if (prop in target) {
|
||||
return Reflect.get(target, prop);
|
||||
}
|
||||
debug$2('proxying property to original launcher: ', prop);
|
||||
return Reflect.get(target.launcher, prop);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Augment the provided Playwright browser launcher with plugin functionality.
|
||||
*
|
||||
* Using `addExtra` will always create a fresh PlaywrightExtra instance.
|
||||
*
|
||||
* @example
|
||||
* import playwright from 'playwright'
|
||||
* import { addExtra } from 'playwright-extra'
|
||||
*
|
||||
* const chromium = addExtra(playwright.chromium)
|
||||
* chromium.use(plugin)
|
||||
*
|
||||
* @param launcher - Playwright (or compatible) browser launcher
|
||||
*/
|
||||
const addExtra = (launcher) => new PlaywrightExtra(launcher);
|
||||
/**
|
||||
* This object can be used to launch or connect to Chromium with plugin functionality.
|
||||
*
|
||||
* This default export will behave exactly the same as the regular playwright
|
||||
* (just with extra plugin functionality) and can be used as a drop-in replacement.
|
||||
*
|
||||
* Behind the scenes it will try to require either the `playwright-core`
|
||||
* or `playwright` module from the installed dependencies.
|
||||
*
|
||||
* @note
|
||||
* Due to Node.js import caching this will result in a single
|
||||
* PlaywrightExtra instance, even when used in different files. If you need multiple
|
||||
* instances with different plugins please use `addExtra`.
|
||||
*
|
||||
* @example
|
||||
* // javascript import
|
||||
* const { chromium } = require('playwright-extra')
|
||||
*
|
||||
* // typescript/es6 module import
|
||||
* import { chromium } from 'playwright-extra'
|
||||
*
|
||||
* // Add plugins
|
||||
* chromium.use(...)
|
||||
*/
|
||||
const chromium = addExtra((playwrightLoader.loadModule() || {}).chromium);
|
||||
/**
|
||||
* This object can be used to launch or connect to Firefox with plugin functionality
|
||||
* @note This export will always return the same instance, if you wish to use multiple instances with different plugins use `addExtra`
|
||||
*/
|
||||
const firefox = addExtra((playwrightLoader.loadModule() || {}).firefox);
|
||||
/**
|
||||
* This object can be used to launch or connect to Webkit with plugin functionality
|
||||
* @note This export will always return the same instance, if you wish to use multiple instances with different plugins use `addExtra`
|
||||
*/
|
||||
const webkit = addExtra((playwrightLoader.loadModule() || {}).webkit);
|
||||
// Other playwright module exports we simply re-export with lazy loading
|
||||
const _android = playwrightLoader.lazyloadExportOrDie('_android');
|
||||
const _electron = playwrightLoader.lazyloadExportOrDie('_electron');
|
||||
const request = playwrightLoader.lazyloadExportOrDie('request');
|
||||
const selectors = playwrightLoader.lazyloadExportOrDie('selectors');
|
||||
const devices = playwrightLoader.lazyloadExportOrDie('devices');
|
||||
const errors = playwrightLoader.lazyloadExportOrDie('errors');
|
||||
/** Playwright with plugin functionality */
|
||||
const moduleExports = {
|
||||
// custom exports
|
||||
PlaywrightExtra,
|
||||
PlaywrightExtraClass,
|
||||
PluginList,
|
||||
addExtra,
|
||||
chromium,
|
||||
firefox,
|
||||
webkit,
|
||||
// vanilla exports
|
||||
_android,
|
||||
_electron,
|
||||
request,
|
||||
selectors,
|
||||
devices,
|
||||
errors
|
||||
};
|
||||
|
||||
exports.PlaywrightExtra = PlaywrightExtra;
|
||||
exports.PlaywrightExtraClass = PlaywrightExtraClass;
|
||||
exports.PluginList = PluginList;
|
||||
exports._android = _android;
|
||||
exports._electron = _electron;
|
||||
exports.addExtra = addExtra;
|
||||
exports.chromium = chromium;
|
||||
exports.default = moduleExports;
|
||||
exports.devices = devices;
|
||||
exports.errors = errors;
|
||||
exports.firefox = firefox;
|
||||
exports.request = request;
|
||||
exports.selectors = selectors;
|
||||
exports.webkit = webkit;
|
||||
|
||||
|
||||
module.exports = exports.default || {}
|
||||
Object.entries(exports).forEach(([key, value]) => { module.exports[key] = value })
|
||||
//# sourceMappingURL=index.cjs.js.map
|
||||
1
projects/org-skill-web-research/node_modules/playwright-extra/dist/index.cjs.js.map
generated
vendored
Normal file
1
projects/org-skill-web-research/node_modules/playwright-extra/dist/index.cjs.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
1024
projects/org-skill-web-research/node_modules/playwright-extra/dist/index.d.ts
generated
vendored
Normal file
1024
projects/org-skill-web-research/node_modules/playwright-extra/dist/index.d.ts
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
912
projects/org-skill-web-research/node_modules/playwright-extra/dist/index.esm.js
generated
vendored
Normal file
912
projects/org-skill-web-research/node_modules/playwright-extra/dist/index.esm.js
generated
vendored
Normal file
@@ -0,0 +1,912 @@
|
||||
/*!
|
||||
* playwright-extra v4.3.5 by berstend
|
||||
* https://github.com/berstend/puppeteer-extra/tree/master/packages/playwright-extra#readme
|
||||
* @license MIT
|
||||
*/
|
||||
import Debug from 'debug';
|
||||
|
||||
/** Node.js module loader helper */
|
||||
class Loader {
|
||||
constructor(moduleName, packageNames) {
|
||||
this.moduleName = moduleName;
|
||||
this.packageNames = packageNames;
|
||||
}
|
||||
/**
|
||||
* Lazy load a top level export from another module by wrapping it in a JS proxy.
|
||||
*
|
||||
* This allows us to re-export e.g. `devices` from `playwright` while redirecting direct calls
|
||||
* to it to the module version the user has installed, rather than shipping with a hardcoded version.
|
||||
*
|
||||
* If we don't do this and the user doesn't have the target module installed we'd throw immediately when our code is imported.
|
||||
*
|
||||
* We use a "super" Proxy defining all traps, so calls like `Object.keys(playwright.devices).length` will return the correct value.
|
||||
*/
|
||||
lazyloadExportOrDie(exportName) {
|
||||
const that = this;
|
||||
const trapHandler = Object.fromEntries(Object.getOwnPropertyNames(Reflect).map((name) => [
|
||||
name,
|
||||
function (target, ...args) {
|
||||
const moduleExport = that.loadModuleOrDie()[exportName];
|
||||
const customTarget = moduleExport;
|
||||
const result = Reflect[name](customTarget || target, ...args);
|
||||
return result;
|
||||
}
|
||||
]));
|
||||
return new Proxy({}, trapHandler);
|
||||
}
|
||||
/** Load the module if possible */
|
||||
loadModule() {
|
||||
return requirePackages(this.packageNames);
|
||||
}
|
||||
/** Load the module if possible or throw */
|
||||
loadModuleOrDie() {
|
||||
const module = requirePackages(this.packageNames);
|
||||
if (module) {
|
||||
return module;
|
||||
}
|
||||
throw this.requireError;
|
||||
}
|
||||
get requireError() {
|
||||
const moduleNamePretty = this.moduleName.charAt(0).toUpperCase() + this.moduleName.slice(1);
|
||||
return new Error(`
|
||||
${moduleNamePretty} is missing. :-)
|
||||
|
||||
I've tried loading ${this.packageNames
|
||||
.map(p => `"${p}"`)
|
||||
.join(', ')} - no luck.
|
||||
|
||||
Make sure you install one of those packages or use the named 'addExtra' export,
|
||||
to patch a specific (and maybe non-standard) implementation of ${moduleNamePretty}.
|
||||
|
||||
To get the latest stable version of ${moduleNamePretty} run:
|
||||
'yarn add ${this.moduleName}' or 'npm i ${this.moduleName}'
|
||||
`);
|
||||
}
|
||||
}
|
||||
function requirePackages(packageNames) {
|
||||
for (const name of packageNames) {
|
||||
try {
|
||||
return require(name);
|
||||
}
|
||||
catch (_) {
|
||||
continue; // noop
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
/** Playwright specific module loader */
|
||||
const playwrightLoader = new Loader('playwright', [
|
||||
'playwright-core',
|
||||
'playwright'
|
||||
]);
|
||||
|
||||
const debug = Debug('playwright-extra:puppeteer-compat');
|
||||
const isPlaywrightPage = (obj) => {
|
||||
return 'unroute' in obj;
|
||||
};
|
||||
const isPlaywrightFrame = (obj) => {
|
||||
return ['parentFrame', 'frameLocator'].every(x => x in obj);
|
||||
};
|
||||
const isPlaywrightBrowser = (obj) => {
|
||||
return 'newContext' in obj;
|
||||
};
|
||||
const isPuppeteerCompat = (obj) => {
|
||||
return !!obj && typeof obj === 'object' && !!obj.isCompatShim;
|
||||
};
|
||||
const cache = {
|
||||
objectToShim: new Map(),
|
||||
cdpSession: {
|
||||
page: new Map(),
|
||||
browser: new Map()
|
||||
}
|
||||
};
|
||||
/** Augment a Playwright object with compatibility with certain Puppeteer methods */
|
||||
function addPuppeteerCompat(object) {
|
||||
if (!object || typeof object !== 'object') {
|
||||
return object;
|
||||
}
|
||||
if (cache.objectToShim.has(object)) {
|
||||
return cache.objectToShim.get(object);
|
||||
}
|
||||
if (isPuppeteerCompat(object)) {
|
||||
return object;
|
||||
}
|
||||
debug('addPuppeteerCompat', cache.objectToShim.size);
|
||||
if (isPlaywrightPage(object) || isPlaywrightFrame(object)) {
|
||||
const shim = createPageShim(object);
|
||||
cache.objectToShim.set(object, shim);
|
||||
return shim;
|
||||
}
|
||||
if (isPlaywrightBrowser(object)) {
|
||||
const shim = createBrowserShim(object);
|
||||
cache.objectToShim.set(object, shim);
|
||||
return shim;
|
||||
}
|
||||
debug('Received unknown object:', Reflect.ownKeys(object));
|
||||
return object;
|
||||
}
|
||||
// Only chromium browsers support CDP
|
||||
const dummyCDPClient = {
|
||||
send: async (...args) => {
|
||||
debug('dummy CDP client called', 'send', args);
|
||||
},
|
||||
on: (...args) => {
|
||||
debug('dummy CDP client called', 'on', args);
|
||||
}
|
||||
};
|
||||
async function getPageCDPSession(page) {
|
||||
let session = cache.cdpSession.page.get(page);
|
||||
if (session) {
|
||||
debug('getPageCDPSession: use existing');
|
||||
return session;
|
||||
}
|
||||
debug('getPageCDPSession: use new');
|
||||
const context = isPlaywrightFrame(page)
|
||||
? page.page().context()
|
||||
: page.context();
|
||||
try {
|
||||
session = await context.newCDPSession(page);
|
||||
cache.cdpSession.page.set(page, session);
|
||||
return session;
|
||||
}
|
||||
catch (err) {
|
||||
debug('getPageCDPSession: error while creating session:', err.message);
|
||||
debug('getPageCDPSession: Unable create CDP session (most likely a different browser than chromium) - returning a dummy');
|
||||
}
|
||||
return dummyCDPClient;
|
||||
}
|
||||
async function getBrowserCDPSession(browser) {
|
||||
let session = cache.cdpSession.browser.get(browser);
|
||||
if (session) {
|
||||
debug('getBrowserCDPSession: use existing');
|
||||
return session;
|
||||
}
|
||||
debug('getBrowserCDPSession: use new');
|
||||
try {
|
||||
session = await browser.newBrowserCDPSession();
|
||||
cache.cdpSession.browser.set(browser, session);
|
||||
return session;
|
||||
}
|
||||
catch (err) {
|
||||
debug('getBrowserCDPSession: error while creating session:', err.message);
|
||||
debug('getBrowserCDPSession: Unable create CDP session (most likely a different browser than chromium) - returning a dummy');
|
||||
}
|
||||
return dummyCDPClient;
|
||||
}
|
||||
function createPageShim(page) {
|
||||
const objId = Math.random().toString(36).substring(2, 7);
|
||||
const shim = new Proxy(page, {
|
||||
get(target, prop) {
|
||||
if (prop === 'isCompatShim' || prop === 'isPlaywright') {
|
||||
return true;
|
||||
}
|
||||
debug('page - get', objId, prop);
|
||||
if (prop === '_client') {
|
||||
return () => ({
|
||||
send: async (method, params) => {
|
||||
const session = await getPageCDPSession(page);
|
||||
return await session.send(method, params);
|
||||
},
|
||||
on: (event, listener) => {
|
||||
getPageCDPSession(page).then(session => {
|
||||
session.on(event, listener);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
if (prop === 'setBypassCSP') {
|
||||
return async (enabled) => {
|
||||
const session = await getPageCDPSession(page);
|
||||
return await session.send('Page.setBypassCSP', {
|
||||
enabled
|
||||
});
|
||||
};
|
||||
}
|
||||
if (prop === 'setUserAgent') {
|
||||
return async (userAgent, userAgentMetadata) => {
|
||||
const session = await getPageCDPSession(page);
|
||||
return await session.send('Emulation.setUserAgentOverride', {
|
||||
userAgent,
|
||||
userAgentMetadata
|
||||
});
|
||||
};
|
||||
}
|
||||
if (prop === 'browser') {
|
||||
if (isPlaywrightPage(page)) {
|
||||
return () => {
|
||||
let browser = page.context().browser();
|
||||
if (!browser) {
|
||||
debug('page.browser() - not available, most likely due to launchPersistentContext');
|
||||
// Use a page shim as quick drop-in (so browser.userAgent() still works)
|
||||
browser = page;
|
||||
}
|
||||
return addPuppeteerCompat(browser);
|
||||
};
|
||||
}
|
||||
}
|
||||
if (prop === 'evaluateOnNewDocument') {
|
||||
if (isPlaywrightPage(page)) {
|
||||
return async function (pageFunction, ...args) {
|
||||
return await page.addInitScript(pageFunction, args[0]);
|
||||
};
|
||||
}
|
||||
}
|
||||
// Only relevant when page is being used a pseudo stand-in for the browser object (launchPersistentContext)
|
||||
if (prop === 'userAgent') {
|
||||
return async (enabled) => {
|
||||
const session = await getPageCDPSession(page);
|
||||
const data = await session.send('Browser.getVersion');
|
||||
return data.userAgent;
|
||||
};
|
||||
}
|
||||
return Reflect.get(target, prop);
|
||||
}
|
||||
});
|
||||
return shim;
|
||||
}
|
||||
function createBrowserShim(browser) {
|
||||
const objId = Math.random().toString(36).substring(2, 7);
|
||||
const shim = new Proxy(browser, {
|
||||
get(target, prop) {
|
||||
if (prop === 'isCompatShim' || prop === 'isPlaywright') {
|
||||
return true;
|
||||
}
|
||||
debug('browser - get', objId, prop);
|
||||
if (prop === 'pages') {
|
||||
return () => browser
|
||||
.contexts()
|
||||
.flatMap(c => c.pages().map(page => addPuppeteerCompat(page)));
|
||||
}
|
||||
if (prop === 'userAgent') {
|
||||
return async () => {
|
||||
const session = await getBrowserCDPSession(browser);
|
||||
const data = await session.send('Browser.getVersion');
|
||||
return data.userAgent;
|
||||
};
|
||||
}
|
||||
return Reflect.get(target, prop);
|
||||
}
|
||||
});
|
||||
return shim;
|
||||
}
|
||||
|
||||
const debug$1 = Debug('playwright-extra:plugins');
|
||||
class PluginList {
|
||||
constructor() {
|
||||
this._plugins = [];
|
||||
this._dependencyDefaults = new Map();
|
||||
this._dependencyResolution = new Map();
|
||||
}
|
||||
/**
|
||||
* Get a list of all registered plugins.
|
||||
*/
|
||||
get list() {
|
||||
return this._plugins;
|
||||
}
|
||||
/**
|
||||
* Get the names of all registered plugins.
|
||||
*/
|
||||
get names() {
|
||||
return this._plugins.map(p => p.name);
|
||||
}
|
||||
/**
|
||||
* Add a new plugin to the list (after checking if it's well-formed).
|
||||
*
|
||||
* @param plugin
|
||||
* @internal
|
||||
*/
|
||||
add(plugin) {
|
||||
var _a;
|
||||
if (!this.isValidPluginInstance(plugin)) {
|
||||
return false;
|
||||
}
|
||||
if (!!plugin.onPluginRegistered) {
|
||||
plugin.onPluginRegistered({ framework: 'playwright' });
|
||||
}
|
||||
// PuppeteerExtraPlugin: Populate `_childClassMembers` list containing methods defined by the plugin
|
||||
if (!!plugin._registerChildClassMembers) {
|
||||
plugin._registerChildClassMembers(Object.getPrototypeOf(plugin));
|
||||
}
|
||||
if ((_a = plugin.requirements) === null || _a === void 0 ? void 0 : _a.has('dataFromPlugins')) {
|
||||
plugin.getDataFromPlugins = this.getData.bind(this);
|
||||
}
|
||||
this._plugins.push(plugin);
|
||||
return true;
|
||||
}
|
||||
/** Check if the shape of a plugin is correct or warn */
|
||||
isValidPluginInstance(plugin) {
|
||||
if (!plugin ||
|
||||
typeof plugin !== 'object' ||
|
||||
!plugin._isPuppeteerExtraPlugin) {
|
||||
console.error(`Warning: Plugin is not derived from PuppeteerExtraPlugin, ignoring.`, plugin);
|
||||
return false;
|
||||
}
|
||||
if (!plugin.name) {
|
||||
console.error(`Warning: Plugin with no name registering, ignoring.`, plugin);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
/** Error callback in case calling a plugin method throws an error. Can be overwritten. */
|
||||
onPluginError(plugin, method, err) {
|
||||
console.warn(`An error occured while executing "${method}" in plugin "${plugin.name}":`, err);
|
||||
}
|
||||
/**
|
||||
* Define default values for plugins implicitly required through the `dependencies` plugin stanza.
|
||||
*
|
||||
* @param dependencyPath - The string by which the dependency is listed (not the plugin name)
|
||||
*
|
||||
* @example
|
||||
* chromium.use(stealth)
|
||||
* chromium.plugins.setDependencyDefaults('stealth/evasions/webgl.vendor', { vendor: 'Bob', renderer: 'Alice' })
|
||||
*/
|
||||
setDependencyDefaults(dependencyPath, opts) {
|
||||
this._dependencyDefaults.set(dependencyPath, opts);
|
||||
return this;
|
||||
}
|
||||
/**
|
||||
* Define custom plugin modules for plugins implicitly required through the `dependencies` plugin stanza.
|
||||
*
|
||||
* Using this will prevent dynamic imports from being used, which JS bundlers often have issues with.
|
||||
*
|
||||
* @example
|
||||
* chromium.use(stealth)
|
||||
* chromium.plugins.setDependencyResolution('stealth/evasions/webgl.vendor', VendorPlugin)
|
||||
*/
|
||||
setDependencyResolution(dependencyPath, pluginModule) {
|
||||
this._dependencyResolution.set(dependencyPath, pluginModule);
|
||||
return this;
|
||||
}
|
||||
/**
|
||||
* Prepare plugins to be used (resolve dependencies, ordering)
|
||||
* @internal
|
||||
*/
|
||||
prepare() {
|
||||
this.resolveDependencies();
|
||||
this.order();
|
||||
}
|
||||
/** Return all plugins using the supplied method */
|
||||
filterByMethod(methodName) {
|
||||
return this._plugins.filter(plugin => {
|
||||
// PuppeteerExtraPlugin: The base class will already define all methods, hence we need to do a different check
|
||||
if (!!plugin._childClassMembers &&
|
||||
Array.isArray(plugin._childClassMembers)) {
|
||||
return plugin._childClassMembers.includes(methodName);
|
||||
}
|
||||
return methodName in plugin;
|
||||
});
|
||||
}
|
||||
/** Conditionally add puppeteer compatibility to values provided to the plugins */
|
||||
_addPuppeteerCompatIfNeeded(plugin, method, args) {
|
||||
const canUseShim = plugin._isPuppeteerExtraPlugin && !plugin.noPuppeteerShim;
|
||||
const methodWhitelist = [
|
||||
'onBrowser',
|
||||
'onPageCreated',
|
||||
'onPageClose',
|
||||
'afterConnect',
|
||||
'afterLaunch'
|
||||
];
|
||||
const shouldUseShim = methodWhitelist.includes(method);
|
||||
if (!canUseShim || !shouldUseShim) {
|
||||
return args;
|
||||
}
|
||||
debug$1('add puppeteer compatibility', plugin.name, method);
|
||||
return [...args.map(arg => addPuppeteerCompat(arg))];
|
||||
}
|
||||
/**
|
||||
* Dispatch plugin lifecycle events in a typesafe way.
|
||||
* Only Plugins that expose the supplied property will be called.
|
||||
*
|
||||
* Will not await results to dispatch events as fast as possible to all plugins.
|
||||
*
|
||||
* @param method - The lifecycle method name
|
||||
* @param args - Optional: Any arguments to be supplied to the plugin methods
|
||||
* @internal
|
||||
*/
|
||||
dispatch(method, ...args) {
|
||||
var _a, _b;
|
||||
const plugins = this.filterByMethod(method);
|
||||
debug$1('dispatch', method, {
|
||||
all: this._plugins.length,
|
||||
filteredByMethod: plugins.length
|
||||
});
|
||||
for (const plugin of plugins) {
|
||||
try {
|
||||
args = this._addPuppeteerCompatIfNeeded.bind(this)(plugin, method, args);
|
||||
const fnType = (_b = (_a = plugin[method]) === null || _a === void 0 ? void 0 : _a.constructor) === null || _b === void 0 ? void 0 : _b.name;
|
||||
debug$1('dispatch to plugin', {
|
||||
plugin: plugin.name,
|
||||
method,
|
||||
fnType
|
||||
});
|
||||
if (fnType === 'AsyncFunction') {
|
||||
;
|
||||
plugin[method](...args).catch((err) => this.onPluginError(plugin, method, err));
|
||||
}
|
||||
else {
|
||||
;
|
||||
plugin[method](...args);
|
||||
}
|
||||
}
|
||||
catch (err) {
|
||||
this.onPluginError(plugin, method, err);
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Dispatch plugin lifecycle events in a typesafe way.
|
||||
* Only Plugins that expose the supplied property will be called.
|
||||
*
|
||||
* Can also be used to get a definite return value after passing it to plugins:
|
||||
* Calls plugins sequentially and passes on a value (waterfall style).
|
||||
*
|
||||
* The plugins can either modify the value or return an updated one.
|
||||
* Will return the latest, updated value which ran through all plugins.
|
||||
*
|
||||
* By convention only the first argument will be used as the updated value.
|
||||
*
|
||||
* @param method - The lifecycle method name
|
||||
* @param args - Optional: Any arguments to be supplied to the plugin methods
|
||||
* @internal
|
||||
*/
|
||||
async dispatchBlocking(method, ...args) {
|
||||
const plugins = this.filterByMethod(method);
|
||||
debug$1('dispatchBlocking', method, {
|
||||
all: this._plugins.length,
|
||||
filteredByMethod: plugins.length
|
||||
});
|
||||
let retValue = null;
|
||||
for (const plugin of plugins) {
|
||||
try {
|
||||
args = this._addPuppeteerCompatIfNeeded.bind(this)(plugin, method, args);
|
||||
retValue = await plugin[method](...args);
|
||||
// In case we got a return value use that as new first argument for followup function calls
|
||||
if (retValue !== undefined) {
|
||||
args[0] = retValue;
|
||||
}
|
||||
}
|
||||
catch (err) {
|
||||
this.onPluginError(plugin, method, err);
|
||||
return retValue;
|
||||
}
|
||||
}
|
||||
return retValue;
|
||||
}
|
||||
/**
|
||||
* Order plugins that have expressed a special placement requirement.
|
||||
*
|
||||
* This is useful/necessary for e.g. plugins that depend on the data from other plugins.
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
order() {
|
||||
debug$1('order:before', this.names);
|
||||
const runLast = this._plugins
|
||||
.filter(p => { var _a; return (_a = p.requirements) === null || _a === void 0 ? void 0 : _a.has('runLast'); })
|
||||
.map(p => p.name);
|
||||
for (const name of runLast) {
|
||||
const index = this._plugins.findIndex(p => p.name === name);
|
||||
this._plugins.push(this._plugins.splice(index, 1)[0]);
|
||||
}
|
||||
debug$1('order:after', this.names);
|
||||
}
|
||||
/**
|
||||
* Collects the exposed `data` property of all registered plugins.
|
||||
* Will be reduced/flattened to a single array.
|
||||
*
|
||||
* Can be accessed by plugins that listed the `dataFromPlugins` requirement.
|
||||
*
|
||||
* Implemented mainly for plugins that need data from other plugins (e.g. `user-preferences`).
|
||||
*
|
||||
* @see [PuppeteerExtraPlugin]/data
|
||||
* @param name - Filter data by optional name
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
getData(name) {
|
||||
const data = this._plugins
|
||||
.filter((p) => !!p.data)
|
||||
.map((p) => (Array.isArray(p.data) ? p.data : [p.data]))
|
||||
.reduce((acc, arr) => [...acc, ...arr], []);
|
||||
return name ? data.filter((d) => d.name === name) : data;
|
||||
}
|
||||
/**
|
||||
* Handle `plugins` stanza (already instantiated plugins that don't require dynamic imports)
|
||||
*/
|
||||
resolvePluginsStanza() {
|
||||
debug$1('resolvePluginsStanza');
|
||||
const pluginNames = new Set(this.names);
|
||||
this._plugins
|
||||
.filter(p => !!p.plugins && p.plugins.length)
|
||||
.filter(p => !pluginNames.has(p.name)) // TBD: Do we want to filter out existing?
|
||||
.forEach(parent => {
|
||||
(parent.plugins || []).forEach(p => {
|
||||
debug$1(parent.name, 'adding missing plugin', p.name);
|
||||
this.add(p);
|
||||
});
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Handle `dependencies` stanza (which requires dynamic imports)
|
||||
*
|
||||
* Plugins can define `dependencies` as a Set or Array of dependency paths, or a Map with additional opts
|
||||
*
|
||||
* @note
|
||||
* - The default opts for implicit dependencies can be defined using `setDependencyDefaults()`
|
||||
* - Dynamic imports can be avoided by providing plugin modules with `setDependencyResolution()`
|
||||
*/
|
||||
resolveDependenciesStanza() {
|
||||
debug$1('resolveDependenciesStanza');
|
||||
/** Attempt to dynamically require a plugin module */
|
||||
const requireDependencyOrDie = (parentName, dependencyPath) => {
|
||||
// If the user provided the plugin module already we use that
|
||||
if (this._dependencyResolution.has(dependencyPath)) {
|
||||
return this._dependencyResolution.get(dependencyPath);
|
||||
}
|
||||
const possiblePrefixes = ['puppeteer-extra-plugin-']; // could be extended later
|
||||
const isAlreadyPrefixed = possiblePrefixes.some(prefix => dependencyPath.startsWith(prefix));
|
||||
const packagePaths = [];
|
||||
// If the dependency is not already prefixed we attempt to require all possible combinations to find one that works
|
||||
if (!isAlreadyPrefixed) {
|
||||
packagePaths.push(...possiblePrefixes.map(prefix => prefix + dependencyPath));
|
||||
}
|
||||
// We always attempt to require the path verbatim (as a last resort)
|
||||
packagePaths.push(dependencyPath);
|
||||
const pluginModule = requirePackages(packagePaths);
|
||||
if (pluginModule) {
|
||||
return pluginModule;
|
||||
}
|
||||
const explanation = `
|
||||
The plugin '${parentName}' listed '${dependencyPath}' as dependency,
|
||||
which could not be found. Please install it:
|
||||
|
||||
${packagePaths
|
||||
.map(packagePath => `yarn add ${packagePath.split('/')[0]}`)
|
||||
.join(`\n or:\n`)}
|
||||
|
||||
Note: You don't need to require the plugin yourself,
|
||||
unless you want to modify it's default settings.
|
||||
|
||||
If your bundler has issues with dynamic imports take a look at '.plugins.setDependencyResolution()'.
|
||||
`;
|
||||
console.warn(explanation);
|
||||
throw new Error('Plugin dependency not found');
|
||||
};
|
||||
const existingPluginNames = new Set(this.names);
|
||||
const recursivelyLoadMissingDependencies = ({ name: parentName, dependencies }) => {
|
||||
if (!dependencies) {
|
||||
return;
|
||||
}
|
||||
const processDependency = (dependencyPath, opts) => {
|
||||
const pluginModule = requireDependencyOrDie(parentName, dependencyPath);
|
||||
opts = opts || this._dependencyDefaults.get(dependencyPath) || {};
|
||||
const plugin = pluginModule(opts);
|
||||
if (existingPluginNames.has(plugin.name)) {
|
||||
debug$1(parentName, '=> dependency already exists:', plugin.name);
|
||||
return;
|
||||
}
|
||||
existingPluginNames.add(plugin.name);
|
||||
debug$1(parentName, '=> adding new dependency:', plugin.name, opts);
|
||||
this.add(plugin);
|
||||
return recursivelyLoadMissingDependencies(plugin);
|
||||
};
|
||||
if (dependencies instanceof Set || Array.isArray(dependencies)) {
|
||||
return [...dependencies].forEach(dependencyPath => processDependency(dependencyPath));
|
||||
}
|
||||
if (dependencies instanceof Map) {
|
||||
// Note: `k,v => v,k` (Map + forEach will reverse the order)
|
||||
return dependencies.forEach((v, k) => processDependency(k, v));
|
||||
}
|
||||
};
|
||||
this.list.forEach(recursivelyLoadMissingDependencies);
|
||||
}
|
||||
/**
|
||||
* Lightweight plugin dependency management to require plugins and code mods on demand.
|
||||
* @private
|
||||
*/
|
||||
resolveDependencies() {
|
||||
debug$1('resolveDependencies');
|
||||
this.resolvePluginsStanza();
|
||||
this.resolveDependenciesStanza();
|
||||
}
|
||||
}
|
||||
|
||||
const debug$2 = Debug('playwright-extra');
|
||||
/**
|
||||
* Modular plugin framework to teach `playwright` new tricks.
|
||||
*/
|
||||
class PlaywrightExtraClass {
|
||||
constructor(_launcher) {
|
||||
this._launcher = _launcher;
|
||||
this.plugins = new PluginList();
|
||||
}
|
||||
/**
|
||||
* The **main interface** to register plugins.
|
||||
*
|
||||
* Can be called multiple times to enable multiple plugins.
|
||||
*
|
||||
* Plugins derived from `PuppeteerExtraPlugin` will be used with a compatiblity layer.
|
||||
*
|
||||
* @example
|
||||
* chromium.use(plugin1).use(plugin2)
|
||||
* firefox.use(plugin1).use(plugin2)
|
||||
*
|
||||
* @see [PuppeteerExtraPlugin]
|
||||
*
|
||||
* @return The same `PlaywrightExtra` instance (for optional chaining)
|
||||
*/
|
||||
use(plugin) {
|
||||
const isValid = plugin && 'name' in plugin;
|
||||
if (!isValid) {
|
||||
throw new Error('A plugin must be provided to .use()');
|
||||
}
|
||||
if (this.plugins.add(plugin)) {
|
||||
debug$2('Plugin registered', plugin.name);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
/**
|
||||
* In order to support a default export which will require vanilla playwright automatically,
|
||||
* as well as `addExtra` to patch a provided launcher, we need to so some gymnastics here.
|
||||
*
|
||||
* Otherwise this would throw immediately, even when only using the `addExtra` export with an arbitrary compatible launcher.
|
||||
*
|
||||
* The solution is to make the vanilla launcher optional and only throw once we try to effectively use and can't find it.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
get launcher() {
|
||||
if (!this._launcher) {
|
||||
throw playwrightLoader.requireError;
|
||||
}
|
||||
return this._launcher;
|
||||
}
|
||||
async launch(...args) {
|
||||
if (!this.launcher.launch) {
|
||||
throw new Error('Launcher does not support "launch"');
|
||||
}
|
||||
let [options] = args;
|
||||
options = Object.assign({ args: [] }, (options || {})); // Initialize args array
|
||||
debug$2('launch', options);
|
||||
this.plugins.prepare();
|
||||
// Give plugins the chance to modify the options before continuing
|
||||
options =
|
||||
(await this.plugins.dispatchBlocking('beforeLaunch', options)) || options;
|
||||
debug$2('launch with options', options);
|
||||
if ('userDataDir' in options) {
|
||||
debug$2("A plugin defined userDataDir during .launch, which isn't supported by playwright - ignoring");
|
||||
delete options.userDataDir;
|
||||
}
|
||||
const browser = await this.launcher['launch'](options);
|
||||
await this.plugins.dispatchBlocking('onBrowser', browser);
|
||||
await this._bindBrowserEvents(browser);
|
||||
await this.plugins.dispatchBlocking('afterLaunch', browser);
|
||||
return browser;
|
||||
}
|
||||
async launchPersistentContext(...args) {
|
||||
if (!this.launcher.launchPersistentContext) {
|
||||
throw new Error('Launcher does not support "launchPersistentContext"');
|
||||
}
|
||||
let [userDataDir, options] = args;
|
||||
options = Object.assign({ args: [] }, (options || {})); // Initialize args array
|
||||
debug$2('launchPersistentContext', options);
|
||||
this.plugins.prepare();
|
||||
// Give plugins the chance to modify the options before continuing
|
||||
options =
|
||||
(await this.plugins.dispatchBlocking('beforeLaunch', options)) || options;
|
||||
const context = await this.launcher['launchPersistentContext'](userDataDir, options);
|
||||
await this.plugins.dispatchBlocking('afterLaunch', context);
|
||||
this._bindBrowserContextEvents(context);
|
||||
return context;
|
||||
}
|
||||
async connect(wsEndpointOrOptions, wsOptions = {}) {
|
||||
if (!this.launcher.connect) {
|
||||
throw new Error('Launcher does not support "connect"');
|
||||
}
|
||||
this.plugins.prepare();
|
||||
// Playwright currently supports two function signatures for .connect
|
||||
let options = {};
|
||||
let wsEndpointAsString = false;
|
||||
if (typeof wsEndpointOrOptions === 'object') {
|
||||
options = Object.assign(Object.assign({}, wsEndpointOrOptions), wsOptions);
|
||||
}
|
||||
else {
|
||||
wsEndpointAsString = true;
|
||||
options = Object.assign({ wsEndpoint: wsEndpointOrOptions }, wsOptions);
|
||||
}
|
||||
debug$2('connect', options);
|
||||
// Give plugins the chance to modify the options before launch/connect
|
||||
options =
|
||||
(await this.plugins.dispatchBlocking('beforeConnect', options)) || options;
|
||||
// Follow call signature of end user
|
||||
const args = [];
|
||||
const wsEndpoint = options.wsEndpoint;
|
||||
if (wsEndpointAsString) {
|
||||
delete options.wsEndpoint;
|
||||
args.push(wsEndpoint, options);
|
||||
}
|
||||
else {
|
||||
args.push(options);
|
||||
}
|
||||
const browser = (await this.launcher['connect'](...args));
|
||||
await this.plugins.dispatchBlocking('onBrowser', browser);
|
||||
await this._bindBrowserEvents(browser);
|
||||
await this.plugins.dispatchBlocking('afterConnect', browser);
|
||||
return browser;
|
||||
}
|
||||
async connectOverCDP(wsEndpointOrOptions, wsOptions = {}) {
|
||||
if (!this.launcher.connectOverCDP) {
|
||||
throw new Error(`Launcher does not implement 'connectOverCDP'`);
|
||||
}
|
||||
this.plugins.prepare();
|
||||
// Playwright currently supports two function signatures for .connectOverCDP
|
||||
let options = {};
|
||||
let wsEndpointAsString = false;
|
||||
if (typeof wsEndpointOrOptions === 'object') {
|
||||
options = Object.assign(Object.assign({}, wsEndpointOrOptions), wsOptions);
|
||||
}
|
||||
else {
|
||||
wsEndpointAsString = true;
|
||||
options = Object.assign({ endpointURL: wsEndpointOrOptions }, wsOptions);
|
||||
}
|
||||
debug$2('connectOverCDP'), options;
|
||||
// Give plugins the chance to modify the options before launch/connect
|
||||
options =
|
||||
(await this.plugins.dispatchBlocking('beforeConnect', options)) || options;
|
||||
// Follow call signature of end user
|
||||
const args = [];
|
||||
const endpointURL = options.endpointURL;
|
||||
if (wsEndpointAsString) {
|
||||
delete options.endpointURL;
|
||||
args.push(endpointURL, options);
|
||||
}
|
||||
else {
|
||||
args.push(options);
|
||||
}
|
||||
const browser = (await this.launcher['connectOverCDP'](...args));
|
||||
await this.plugins.dispatchBlocking('onBrowser', browser);
|
||||
await this._bindBrowserEvents(browser);
|
||||
await this.plugins.dispatchBlocking('afterConnect', browser);
|
||||
return browser;
|
||||
}
|
||||
async _bindBrowserContextEvents(context, contextOptions) {
|
||||
debug$2('_bindBrowserContextEvents');
|
||||
this.plugins.dispatch('onContextCreated', context, contextOptions);
|
||||
// Make sure things like `addInitScript` show an effect on the very first page as well
|
||||
context.newPage = ((originalMethod, ctx) => {
|
||||
return async () => {
|
||||
const page = await originalMethod.call(ctx);
|
||||
await page.goto('about:blank');
|
||||
return page;
|
||||
};
|
||||
})(context.newPage, context);
|
||||
context.on('close', () => {
|
||||
// When using `launchPersistentContext` context closing is the same as browser closing
|
||||
if (!context.browser()) {
|
||||
this.plugins.dispatch('onDisconnected');
|
||||
}
|
||||
});
|
||||
context.on('page', page => {
|
||||
this.plugins.dispatch('onPageCreated', page);
|
||||
page.on('close', () => {
|
||||
this.plugins.dispatch('onPageClose', page);
|
||||
});
|
||||
});
|
||||
}
|
||||
async _bindBrowserEvents(browser) {
|
||||
debug$2('_bindPlaywrightBrowserEvents');
|
||||
browser.on('disconnected', () => {
|
||||
this.plugins.dispatch('onDisconnected', browser);
|
||||
});
|
||||
// Note: `browser.newPage` will implicitly call `browser.newContext` as well
|
||||
browser.newContext = ((originalMethod, ctx) => {
|
||||
return async (options = {}) => {
|
||||
const contextOptions = (await this.plugins.dispatchBlocking('beforeContext', options, browser)) || options;
|
||||
const context = await originalMethod.call(ctx, contextOptions);
|
||||
this._bindBrowserContextEvents(context, contextOptions);
|
||||
return context;
|
||||
};
|
||||
})(browser.newContext, browser);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* PlaywrightExtra class with additional launcher methods.
|
||||
*
|
||||
* Augments the class with an instance proxy to pass on methods that are not augmented to the original target.
|
||||
*
|
||||
*/
|
||||
const PlaywrightExtra = new Proxy(PlaywrightExtraClass, {
|
||||
construct(classTarget, args) {
|
||||
debug$2(`create instance of ${classTarget.name}`);
|
||||
const result = Reflect.construct(classTarget, args);
|
||||
return new Proxy(result, {
|
||||
get(target, prop) {
|
||||
if (prop in target) {
|
||||
return Reflect.get(target, prop);
|
||||
}
|
||||
debug$2('proxying property to original launcher: ', prop);
|
||||
return Reflect.get(target.launcher, prop);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Augment the provided Playwright browser launcher with plugin functionality.
|
||||
*
|
||||
* Using `addExtra` will always create a fresh PlaywrightExtra instance.
|
||||
*
|
||||
* @example
|
||||
* import playwright from 'playwright'
|
||||
* import { addExtra } from 'playwright-extra'
|
||||
*
|
||||
* const chromium = addExtra(playwright.chromium)
|
||||
* chromium.use(plugin)
|
||||
*
|
||||
* @param launcher - Playwright (or compatible) browser launcher
|
||||
*/
|
||||
const addExtra = (launcher) => new PlaywrightExtra(launcher);
|
||||
/**
|
||||
* This object can be used to launch or connect to Chromium with plugin functionality.
|
||||
*
|
||||
* This default export will behave exactly the same as the regular playwright
|
||||
* (just with extra plugin functionality) and can be used as a drop-in replacement.
|
||||
*
|
||||
* Behind the scenes it will try to require either the `playwright-core`
|
||||
* or `playwright` module from the installed dependencies.
|
||||
*
|
||||
* @note
|
||||
* Due to Node.js import caching this will result in a single
|
||||
* PlaywrightExtra instance, even when used in different files. If you need multiple
|
||||
* instances with different plugins please use `addExtra`.
|
||||
*
|
||||
* @example
|
||||
* // javascript import
|
||||
* const { chromium } = require('playwright-extra')
|
||||
*
|
||||
* // typescript/es6 module import
|
||||
* import { chromium } from 'playwright-extra'
|
||||
*
|
||||
* // Add plugins
|
||||
* chromium.use(...)
|
||||
*/
|
||||
const chromium = addExtra((playwrightLoader.loadModule() || {}).chromium);
|
||||
/**
|
||||
* This object can be used to launch or connect to Firefox with plugin functionality
|
||||
* @note This export will always return the same instance, if you wish to use multiple instances with different plugins use `addExtra`
|
||||
*/
|
||||
const firefox = addExtra((playwrightLoader.loadModule() || {}).firefox);
|
||||
/**
|
||||
* This object can be used to launch or connect to Webkit with plugin functionality
|
||||
* @note This export will always return the same instance, if you wish to use multiple instances with different plugins use `addExtra`
|
||||
*/
|
||||
const webkit = addExtra((playwrightLoader.loadModule() || {}).webkit);
|
||||
// Other playwright module exports we simply re-export with lazy loading
|
||||
const _android = playwrightLoader.lazyloadExportOrDie('_android');
|
||||
const _electron = playwrightLoader.lazyloadExportOrDie('_electron');
|
||||
const request = playwrightLoader.lazyloadExportOrDie('request');
|
||||
const selectors = playwrightLoader.lazyloadExportOrDie('selectors');
|
||||
const devices = playwrightLoader.lazyloadExportOrDie('devices');
|
||||
const errors = playwrightLoader.lazyloadExportOrDie('errors');
|
||||
/** Playwright with plugin functionality */
|
||||
const moduleExports = {
|
||||
// custom exports
|
||||
PlaywrightExtra,
|
||||
PlaywrightExtraClass,
|
||||
PluginList,
|
||||
addExtra,
|
||||
chromium,
|
||||
firefox,
|
||||
webkit,
|
||||
// vanilla exports
|
||||
_android,
|
||||
_electron,
|
||||
request,
|
||||
selectors,
|
||||
devices,
|
||||
errors
|
||||
};
|
||||
|
||||
export default moduleExports;
|
||||
export { PlaywrightExtra, PlaywrightExtraClass, PluginList, _android, _electron, addExtra, chromium, devices, errors, firefox, request, selectors, webkit };
|
||||
//# sourceMappingURL=index.esm.js.map
|
||||
1
projects/org-skill-web-research/node_modules/playwright-extra/dist/index.esm.js.map
generated
vendored
Normal file
1
projects/org-skill-web-research/node_modules/playwright-extra/dist/index.esm.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
89
projects/org-skill-web-research/node_modules/playwright-extra/dist/index.js
generated
vendored
Normal file
89
projects/org-skill-web-research/node_modules/playwright-extra/dist/index.js
generated
vendored
Normal file
@@ -0,0 +1,89 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.errors = exports.devices = exports.selectors = exports.request = exports._electron = exports._android = exports.webkit = exports.firefox = exports.chromium = exports.addExtra = exports.PluginList = exports.PlaywrightExtraClass = exports.PlaywrightExtra = void 0;
|
||||
const extra_1 = require("./extra");
|
||||
const plugins_1 = require("./plugins");
|
||||
const loader_1 = require("./helper/loader");
|
||||
var extra_2 = require("./extra");
|
||||
Object.defineProperty(exports, "PlaywrightExtra", { enumerable: true, get: function () { return extra_2.PlaywrightExtra; } });
|
||||
Object.defineProperty(exports, "PlaywrightExtraClass", { enumerable: true, get: function () { return extra_2.PlaywrightExtraClass; } });
|
||||
var plugins_2 = require("./plugins");
|
||||
Object.defineProperty(exports, "PluginList", { enumerable: true, get: function () { return plugins_2.PluginList; } });
|
||||
/**
|
||||
* Augment the provided Playwright browser launcher with plugin functionality.
|
||||
*
|
||||
* Using `addExtra` will always create a fresh PlaywrightExtra instance.
|
||||
*
|
||||
* @example
|
||||
* import playwright from 'playwright'
|
||||
* import { addExtra } from 'playwright-extra'
|
||||
*
|
||||
* const chromium = addExtra(playwright.chromium)
|
||||
* chromium.use(plugin)
|
||||
*
|
||||
* @param launcher - Playwright (or compatible) browser launcher
|
||||
*/
|
||||
const addExtra = (launcher) => new extra_1.PlaywrightExtra(launcher);
|
||||
exports.addExtra = addExtra;
|
||||
/**
|
||||
* This object can be used to launch or connect to Chromium with plugin functionality.
|
||||
*
|
||||
* This default export will behave exactly the same as the regular playwright
|
||||
* (just with extra plugin functionality) and can be used as a drop-in replacement.
|
||||
*
|
||||
* Behind the scenes it will try to require either the `playwright-core`
|
||||
* or `playwright` module from the installed dependencies.
|
||||
*
|
||||
* @note
|
||||
* Due to Node.js import caching this will result in a single
|
||||
* PlaywrightExtra instance, even when used in different files. If you need multiple
|
||||
* instances with different plugins please use `addExtra`.
|
||||
*
|
||||
* @example
|
||||
* // javascript import
|
||||
* const { chromium } = require('playwright-extra')
|
||||
*
|
||||
* // typescript/es6 module import
|
||||
* import { chromium } from 'playwright-extra'
|
||||
*
|
||||
* // Add plugins
|
||||
* chromium.use(...)
|
||||
*/
|
||||
exports.chromium = (0, exports.addExtra)((loader_1.playwrightLoader.loadModule() || {}).chromium);
|
||||
/**
|
||||
* This object can be used to launch or connect to Firefox with plugin functionality
|
||||
* @note This export will always return the same instance, if you wish to use multiple instances with different plugins use `addExtra`
|
||||
*/
|
||||
exports.firefox = (0, exports.addExtra)((loader_1.playwrightLoader.loadModule() || {}).firefox);
|
||||
/**
|
||||
* This object can be used to launch or connect to Webkit with plugin functionality
|
||||
* @note This export will always return the same instance, if you wish to use multiple instances with different plugins use `addExtra`
|
||||
*/
|
||||
exports.webkit = (0, exports.addExtra)((loader_1.playwrightLoader.loadModule() || {}).webkit);
|
||||
// Other playwright module exports we simply re-export with lazy loading
|
||||
exports._android = loader_1.playwrightLoader.lazyloadExportOrDie('_android');
|
||||
exports._electron = loader_1.playwrightLoader.lazyloadExportOrDie('_electron');
|
||||
exports.request = loader_1.playwrightLoader.lazyloadExportOrDie('request');
|
||||
exports.selectors = loader_1.playwrightLoader.lazyloadExportOrDie('selectors');
|
||||
exports.devices = loader_1.playwrightLoader.lazyloadExportOrDie('devices');
|
||||
exports.errors = loader_1.playwrightLoader.lazyloadExportOrDie('errors');
|
||||
/** Playwright with plugin functionality */
|
||||
const moduleExports = {
|
||||
// custom exports
|
||||
PlaywrightExtra: extra_1.PlaywrightExtra,
|
||||
PlaywrightExtraClass: extra_1.PlaywrightExtraClass,
|
||||
PluginList: plugins_1.PluginList,
|
||||
addExtra: exports.addExtra,
|
||||
chromium: exports.chromium,
|
||||
firefox: exports.firefox,
|
||||
webkit: exports.webkit,
|
||||
// vanilla exports
|
||||
_android: exports._android,
|
||||
_electron: exports._electron,
|
||||
request: exports.request,
|
||||
selectors: exports.selectors,
|
||||
devices: exports.devices,
|
||||
errors: exports.errors
|
||||
};
|
||||
exports.default = moduleExports;
|
||||
//# sourceMappingURL=index.js.map
|
||||
1
projects/org-skill-web-research/node_modules/playwright-extra/dist/index.js.map
generated
vendored
Normal file
1
projects/org-skill-web-research/node_modules/playwright-extra/dist/index.js.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAEA,mCAA+D;AAC/D,uCAAsC;AACtC,4CAA4D;AAE5D,iCAA+D;AAAtD,wGAAA,eAAe,OAAA;AAAE,6GAAA,oBAAoB,OAAA;AAC9C,qCAAsC;AAA7B,qGAAA,UAAU,OAAA;AA+BnB;;;;;;;;;;;;;GAaG;AACI,MAAM,QAAQ,GAAG,CACtB,QAAmB,EACnB,EAAE,CAAC,IAAI,uBAAe,CAAC,QAAQ,CAAoC,CAAA;AAFxD,QAAA,QAAQ,YAEgD;AAErE;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACU,QAAA,QAAQ,GAAG,IAAA,gBAAQ,EAAC,CAAC,yBAAM,CAAC,UAAU,EAAE,IAAI,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAA;AACtE;;;GAGG;AACU,QAAA,OAAO,GAAG,IAAA,gBAAQ,EAAC,CAAC,yBAAM,CAAC,UAAU,EAAE,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,CAAA;AACpE;;;GAGG;AACU,QAAA,MAAM,GAAG,IAAA,gBAAQ,EAAC,CAAC,yBAAM,CAAC,UAAU,EAAE,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,CAAA;AAElE,wEAAwE;AAC3D,QAAA,QAAQ,GAAG,yBAAM,CAAC,mBAAmB,CAAC,UAAU,CAAC,CAAA;AACjD,QAAA,SAAS,GAAG,yBAAM,CAAC,mBAAmB,CAAC,WAAW,CAAC,CAAA;AACnD,QAAA,OAAO,GAAG,yBAAM,CAAC,mBAAmB,CAAC,SAAS,CAAC,CAAA;AAC/C,QAAA,SAAS,GAAG,yBAAM,CAAC,mBAAmB,CAAC,WAAW,CAAC,CAAA;AACnD,QAAA,OAAO,GAAG,yBAAM,CAAC,mBAAmB,CAAC,SAAS,CAAC,CAAA;AAC/C,QAAA,MAAM,GAAG,yBAAM,CAAC,mBAAmB,CAAC,QAAQ,CAAC,CAAA;AAE1D,2CAA2C;AAC3C,MAAM,aAAa,GAAiD;IAClE,iBAAiB;IACjB,eAAe,EAAf,uBAAe;IACf,oBAAoB,EAApB,4BAAoB;IACpB,UAAU,EAAV,oBAAU;IACV,QAAQ,EAAR,gBAAQ;IACR,QAAQ,EAAR,gBAAQ;IACR,OAAO,EAAP,eAAO;IACP,MAAM,EAAN,cAAM;IAEN,kBAAkB;IAClB,QAAQ,EAAR,gBAAQ;IACR,SAAS,EAAT,iBAAS;IACT,OAAO,EAAP,eAAO;IACP,SAAS,EAAT,iBAAS;IACT,OAAO,EAAP,eAAO;IACP,MAAM,EAAN,cAAM;CACP,CAAA;AAED,kBAAe,aAAa,CAAA"}
|
||||
84
projects/org-skill-web-research/node_modules/playwright-extra/dist/plugins.d.ts
generated
vendored
Normal file
84
projects/org-skill-web-research/node_modules/playwright-extra/dist/plugins.d.ts
generated
vendored
Normal file
@@ -0,0 +1,84 @@
|
||||
import { Plugin, PluginMethodName, PluginMethodFn, CompatiblePluginModule } from './types';
|
||||
export declare class PluginList {
|
||||
private readonly _plugins;
|
||||
private readonly _dependencyDefaults;
|
||||
private readonly _dependencyResolution;
|
||||
constructor();
|
||||
/**
|
||||
* Get a list of all registered plugins.
|
||||
*/
|
||||
get list(): import("./types").PuppeteerExtraPlugin[];
|
||||
/**
|
||||
* Get the names of all registered plugins.
|
||||
*/
|
||||
get names(): string[];
|
||||
/** Check if the shape of a plugin is correct or warn */
|
||||
protected isValidPluginInstance(plugin: Plugin): boolean;
|
||||
/** Error callback in case calling a plugin method throws an error. Can be overwritten. */
|
||||
onPluginError(plugin: Plugin, method: PluginMethodName, err: Error): void;
|
||||
/**
|
||||
* Define default values for plugins implicitly required through the `dependencies` plugin stanza.
|
||||
*
|
||||
* @param dependencyPath - The string by which the dependency is listed (not the plugin name)
|
||||
*
|
||||
* @example
|
||||
* chromium.use(stealth)
|
||||
* chromium.plugins.setDependencyDefaults('stealth/evasions/webgl.vendor', { vendor: 'Bob', renderer: 'Alice' })
|
||||
*/
|
||||
setDependencyDefaults(dependencyPath: string, opts: any): this;
|
||||
/**
|
||||
* Define custom plugin modules for plugins implicitly required through the `dependencies` plugin stanza.
|
||||
*
|
||||
* Using this will prevent dynamic imports from being used, which JS bundlers often have issues with.
|
||||
*
|
||||
* @example
|
||||
* chromium.use(stealth)
|
||||
* chromium.plugins.setDependencyResolution('stealth/evasions/webgl.vendor', VendorPlugin)
|
||||
*/
|
||||
setDependencyResolution(dependencyPath: string, pluginModule: CompatiblePluginModule): this;
|
||||
/** Return all plugins using the supplied method */
|
||||
protected filterByMethod(methodName: PluginMethodName): import("./types").PuppeteerExtraPlugin[];
|
||||
/** Conditionally add puppeteer compatibility to values provided to the plugins */
|
||||
protected _addPuppeteerCompatIfNeeded<TMethod extends PluginMethodName>(plugin: Plugin, method: TMethod, args: Parameters<PluginMethodFn<TMethod>>): Parameters<PluginMethodFn<TMethod>>;
|
||||
/**
|
||||
* Order plugins that have expressed a special placement requirement.
|
||||
*
|
||||
* This is useful/necessary for e.g. plugins that depend on the data from other plugins.
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
protected order(): void;
|
||||
/**
|
||||
* Collects the exposed `data` property of all registered plugins.
|
||||
* Will be reduced/flattened to a single array.
|
||||
*
|
||||
* Can be accessed by plugins that listed the `dataFromPlugins` requirement.
|
||||
*
|
||||
* Implemented mainly for plugins that need data from other plugins (e.g. `user-preferences`).
|
||||
*
|
||||
* @see [PuppeteerExtraPlugin]/data
|
||||
* @param name - Filter data by optional name
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
protected getData(name?: string): any;
|
||||
/**
|
||||
* Handle `plugins` stanza (already instantiated plugins that don't require dynamic imports)
|
||||
*/
|
||||
protected resolvePluginsStanza(): void;
|
||||
/**
|
||||
* Handle `dependencies` stanza (which requires dynamic imports)
|
||||
*
|
||||
* Plugins can define `dependencies` as a Set or Array of dependency paths, or a Map with additional opts
|
||||
*
|
||||
* @note
|
||||
* - The default opts for implicit dependencies can be defined using `setDependencyDefaults()`
|
||||
* - Dynamic imports can be avoided by providing plugin modules with `setDependencyResolution()`
|
||||
*/
|
||||
protected resolveDependenciesStanza(): void;
|
||||
/**
|
||||
* Lightweight plugin dependency management to require plugins and code mods on demand.
|
||||
* @private
|
||||
*/
|
||||
protected resolveDependencies(): void;
|
||||
}
|
||||
352
projects/org-skill-web-research/node_modules/playwright-extra/dist/plugins.js
generated
vendored
Normal file
352
projects/org-skill-web-research/node_modules/playwright-extra/dist/plugins.js
generated
vendored
Normal file
@@ -0,0 +1,352 @@
|
||||
"use strict";
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.PluginList = void 0;
|
||||
const debug_1 = __importDefault(require("debug"));
|
||||
const debug = (0, debug_1.default)('playwright-extra:plugins');
|
||||
const loader_1 = require("./helper/loader");
|
||||
const puppeteer_compatiblity_shim_1 = require("./puppeteer-compatiblity-shim");
|
||||
class PluginList {
|
||||
constructor() {
|
||||
this._plugins = [];
|
||||
this._dependencyDefaults = new Map();
|
||||
this._dependencyResolution = new Map();
|
||||
}
|
||||
/**
|
||||
* Get a list of all registered plugins.
|
||||
*/
|
||||
get list() {
|
||||
return this._plugins;
|
||||
}
|
||||
/**
|
||||
* Get the names of all registered plugins.
|
||||
*/
|
||||
get names() {
|
||||
return this._plugins.map(p => p.name);
|
||||
}
|
||||
/**
|
||||
* Add a new plugin to the list (after checking if it's well-formed).
|
||||
*
|
||||
* @param plugin
|
||||
* @internal
|
||||
*/
|
||||
add(plugin) {
|
||||
var _a;
|
||||
if (!this.isValidPluginInstance(plugin)) {
|
||||
return false;
|
||||
}
|
||||
if (!!plugin.onPluginRegistered) {
|
||||
plugin.onPluginRegistered({ framework: 'playwright' });
|
||||
}
|
||||
// PuppeteerExtraPlugin: Populate `_childClassMembers` list containing methods defined by the plugin
|
||||
if (!!plugin._registerChildClassMembers) {
|
||||
plugin._registerChildClassMembers(Object.getPrototypeOf(plugin));
|
||||
}
|
||||
if ((_a = plugin.requirements) === null || _a === void 0 ? void 0 : _a.has('dataFromPlugins')) {
|
||||
plugin.getDataFromPlugins = this.getData.bind(this);
|
||||
}
|
||||
this._plugins.push(plugin);
|
||||
return true;
|
||||
}
|
||||
/** Check if the shape of a plugin is correct or warn */
|
||||
isValidPluginInstance(plugin) {
|
||||
if (!plugin ||
|
||||
typeof plugin !== 'object' ||
|
||||
!plugin._isPuppeteerExtraPlugin) {
|
||||
console.error(`Warning: Plugin is not derived from PuppeteerExtraPlugin, ignoring.`, plugin);
|
||||
return false;
|
||||
}
|
||||
if (!plugin.name) {
|
||||
console.error(`Warning: Plugin with no name registering, ignoring.`, plugin);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
/** Error callback in case calling a plugin method throws an error. Can be overwritten. */
|
||||
onPluginError(plugin, method, err) {
|
||||
console.warn(`An error occured while executing "${method}" in plugin "${plugin.name}":`, err);
|
||||
}
|
||||
/**
|
||||
* Define default values for plugins implicitly required through the `dependencies` plugin stanza.
|
||||
*
|
||||
* @param dependencyPath - The string by which the dependency is listed (not the plugin name)
|
||||
*
|
||||
* @example
|
||||
* chromium.use(stealth)
|
||||
* chromium.plugins.setDependencyDefaults('stealth/evasions/webgl.vendor', { vendor: 'Bob', renderer: 'Alice' })
|
||||
*/
|
||||
setDependencyDefaults(dependencyPath, opts) {
|
||||
this._dependencyDefaults.set(dependencyPath, opts);
|
||||
return this;
|
||||
}
|
||||
/**
|
||||
* Define custom plugin modules for plugins implicitly required through the `dependencies` plugin stanza.
|
||||
*
|
||||
* Using this will prevent dynamic imports from being used, which JS bundlers often have issues with.
|
||||
*
|
||||
* @example
|
||||
* chromium.use(stealth)
|
||||
* chromium.plugins.setDependencyResolution('stealth/evasions/webgl.vendor', VendorPlugin)
|
||||
*/
|
||||
setDependencyResolution(dependencyPath, pluginModule) {
|
||||
this._dependencyResolution.set(dependencyPath, pluginModule);
|
||||
return this;
|
||||
}
|
||||
/**
|
||||
* Prepare plugins to be used (resolve dependencies, ordering)
|
||||
* @internal
|
||||
*/
|
||||
prepare() {
|
||||
this.resolveDependencies();
|
||||
this.order();
|
||||
}
|
||||
/** Return all plugins using the supplied method */
|
||||
filterByMethod(methodName) {
|
||||
return this._plugins.filter(plugin => {
|
||||
// PuppeteerExtraPlugin: The base class will already define all methods, hence we need to do a different check
|
||||
if (!!plugin._childClassMembers &&
|
||||
Array.isArray(plugin._childClassMembers)) {
|
||||
return plugin._childClassMembers.includes(methodName);
|
||||
}
|
||||
return methodName in plugin;
|
||||
});
|
||||
}
|
||||
/** Conditionally add puppeteer compatibility to values provided to the plugins */
|
||||
_addPuppeteerCompatIfNeeded(plugin, method, args) {
|
||||
const canUseShim = plugin._isPuppeteerExtraPlugin && !plugin.noPuppeteerShim;
|
||||
const methodWhitelist = [
|
||||
'onBrowser',
|
||||
'onPageCreated',
|
||||
'onPageClose',
|
||||
'afterConnect',
|
||||
'afterLaunch'
|
||||
];
|
||||
const shouldUseShim = methodWhitelist.includes(method);
|
||||
if (!canUseShim || !shouldUseShim) {
|
||||
return args;
|
||||
}
|
||||
debug('add puppeteer compatibility', plugin.name, method);
|
||||
return [...args.map(arg => (0, puppeteer_compatiblity_shim_1.addPuppeteerCompat)(arg))];
|
||||
}
|
||||
/**
|
||||
* Dispatch plugin lifecycle events in a typesafe way.
|
||||
* Only Plugins that expose the supplied property will be called.
|
||||
*
|
||||
* Will not await results to dispatch events as fast as possible to all plugins.
|
||||
*
|
||||
* @param method - The lifecycle method name
|
||||
* @param args - Optional: Any arguments to be supplied to the plugin methods
|
||||
* @internal
|
||||
*/
|
||||
dispatch(method, ...args) {
|
||||
var _a, _b;
|
||||
const plugins = this.filterByMethod(method);
|
||||
debug('dispatch', method, {
|
||||
all: this._plugins.length,
|
||||
filteredByMethod: plugins.length
|
||||
});
|
||||
for (const plugin of plugins) {
|
||||
try {
|
||||
args = this._addPuppeteerCompatIfNeeded.bind(this)(plugin, method, args);
|
||||
const fnType = (_b = (_a = plugin[method]) === null || _a === void 0 ? void 0 : _a.constructor) === null || _b === void 0 ? void 0 : _b.name;
|
||||
debug('dispatch to plugin', {
|
||||
plugin: plugin.name,
|
||||
method,
|
||||
fnType
|
||||
});
|
||||
if (fnType === 'AsyncFunction') {
|
||||
;
|
||||
plugin[method](...args).catch((err) => this.onPluginError(plugin, method, err));
|
||||
}
|
||||
else {
|
||||
;
|
||||
plugin[method](...args);
|
||||
}
|
||||
}
|
||||
catch (err) {
|
||||
this.onPluginError(plugin, method, err);
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Dispatch plugin lifecycle events in a typesafe way.
|
||||
* Only Plugins that expose the supplied property will be called.
|
||||
*
|
||||
* Can also be used to get a definite return value after passing it to plugins:
|
||||
* Calls plugins sequentially and passes on a value (waterfall style).
|
||||
*
|
||||
* The plugins can either modify the value or return an updated one.
|
||||
* Will return the latest, updated value which ran through all plugins.
|
||||
*
|
||||
* By convention only the first argument will be used as the updated value.
|
||||
*
|
||||
* @param method - The lifecycle method name
|
||||
* @param args - Optional: Any arguments to be supplied to the plugin methods
|
||||
* @internal
|
||||
*/
|
||||
async dispatchBlocking(method, ...args) {
|
||||
const plugins = this.filterByMethod(method);
|
||||
debug('dispatchBlocking', method, {
|
||||
all: this._plugins.length,
|
||||
filteredByMethod: plugins.length
|
||||
});
|
||||
let retValue = null;
|
||||
for (const plugin of plugins) {
|
||||
try {
|
||||
args = this._addPuppeteerCompatIfNeeded.bind(this)(plugin, method, args);
|
||||
retValue = await plugin[method](...args);
|
||||
// In case we got a return value use that as new first argument for followup function calls
|
||||
if (retValue !== undefined) {
|
||||
args[0] = retValue;
|
||||
}
|
||||
}
|
||||
catch (err) {
|
||||
this.onPluginError(plugin, method, err);
|
||||
return retValue;
|
||||
}
|
||||
}
|
||||
return retValue;
|
||||
}
|
||||
/**
|
||||
* Order plugins that have expressed a special placement requirement.
|
||||
*
|
||||
* This is useful/necessary for e.g. plugins that depend on the data from other plugins.
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
order() {
|
||||
debug('order:before', this.names);
|
||||
const runLast = this._plugins
|
||||
.filter(p => { var _a; return (_a = p.requirements) === null || _a === void 0 ? void 0 : _a.has('runLast'); })
|
||||
.map(p => p.name);
|
||||
for (const name of runLast) {
|
||||
const index = this._plugins.findIndex(p => p.name === name);
|
||||
this._plugins.push(this._plugins.splice(index, 1)[0]);
|
||||
}
|
||||
debug('order:after', this.names);
|
||||
}
|
||||
/**
|
||||
* Collects the exposed `data` property of all registered plugins.
|
||||
* Will be reduced/flattened to a single array.
|
||||
*
|
||||
* Can be accessed by plugins that listed the `dataFromPlugins` requirement.
|
||||
*
|
||||
* Implemented mainly for plugins that need data from other plugins (e.g. `user-preferences`).
|
||||
*
|
||||
* @see [PuppeteerExtraPlugin]/data
|
||||
* @param name - Filter data by optional name
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
getData(name) {
|
||||
const data = this._plugins
|
||||
.filter((p) => !!p.data)
|
||||
.map((p) => (Array.isArray(p.data) ? p.data : [p.data]))
|
||||
.reduce((acc, arr) => [...acc, ...arr], []);
|
||||
return name ? data.filter((d) => d.name === name) : data;
|
||||
}
|
||||
/**
|
||||
* Handle `plugins` stanza (already instantiated plugins that don't require dynamic imports)
|
||||
*/
|
||||
resolvePluginsStanza() {
|
||||
debug('resolvePluginsStanza');
|
||||
const pluginNames = new Set(this.names);
|
||||
this._plugins
|
||||
.filter(p => !!p.plugins && p.plugins.length)
|
||||
.filter(p => !pluginNames.has(p.name)) // TBD: Do we want to filter out existing?
|
||||
.forEach(parent => {
|
||||
;
|
||||
(parent.plugins || []).forEach(p => {
|
||||
debug(parent.name, 'adding missing plugin', p.name);
|
||||
this.add(p);
|
||||
});
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Handle `dependencies` stanza (which requires dynamic imports)
|
||||
*
|
||||
* Plugins can define `dependencies` as a Set or Array of dependency paths, or a Map with additional opts
|
||||
*
|
||||
* @note
|
||||
* - The default opts for implicit dependencies can be defined using `setDependencyDefaults()`
|
||||
* - Dynamic imports can be avoided by providing plugin modules with `setDependencyResolution()`
|
||||
*/
|
||||
resolveDependenciesStanza() {
|
||||
debug('resolveDependenciesStanza');
|
||||
/** Attempt to dynamically require a plugin module */
|
||||
const requireDependencyOrDie = (parentName, dependencyPath) => {
|
||||
// If the user provided the plugin module already we use that
|
||||
if (this._dependencyResolution.has(dependencyPath)) {
|
||||
return this._dependencyResolution.get(dependencyPath);
|
||||
}
|
||||
const possiblePrefixes = ['puppeteer-extra-plugin-']; // could be extended later
|
||||
const isAlreadyPrefixed = possiblePrefixes.some(prefix => dependencyPath.startsWith(prefix));
|
||||
const packagePaths = [];
|
||||
// If the dependency is not already prefixed we attempt to require all possible combinations to find one that works
|
||||
if (!isAlreadyPrefixed) {
|
||||
packagePaths.push(...possiblePrefixes.map(prefix => prefix + dependencyPath));
|
||||
}
|
||||
// We always attempt to require the path verbatim (as a last resort)
|
||||
packagePaths.push(dependencyPath);
|
||||
const pluginModule = (0, loader_1.requirePackages)(packagePaths);
|
||||
if (pluginModule) {
|
||||
return pluginModule;
|
||||
}
|
||||
const explanation = `
|
||||
The plugin '${parentName}' listed '${dependencyPath}' as dependency,
|
||||
which could not be found. Please install it:
|
||||
|
||||
${packagePaths
|
||||
.map(packagePath => `yarn add ${packagePath.split('/')[0]}`)
|
||||
.join(`\n or:\n`)}
|
||||
|
||||
Note: You don't need to require the plugin yourself,
|
||||
unless you want to modify it's default settings.
|
||||
|
||||
If your bundler has issues with dynamic imports take a look at '.plugins.setDependencyResolution()'.
|
||||
`;
|
||||
console.warn(explanation);
|
||||
throw new Error('Plugin dependency not found');
|
||||
};
|
||||
const existingPluginNames = new Set(this.names);
|
||||
const recursivelyLoadMissingDependencies = ({ name: parentName, dependencies }) => {
|
||||
if (!dependencies) {
|
||||
return;
|
||||
}
|
||||
const processDependency = (dependencyPath, opts) => {
|
||||
const pluginModule = requireDependencyOrDie(parentName, dependencyPath);
|
||||
opts = opts || this._dependencyDefaults.get(dependencyPath) || {};
|
||||
const plugin = pluginModule(opts);
|
||||
if (existingPluginNames.has(plugin.name)) {
|
||||
debug(parentName, '=> dependency already exists:', plugin.name);
|
||||
return;
|
||||
}
|
||||
existingPluginNames.add(plugin.name);
|
||||
debug(parentName, '=> adding new dependency:', plugin.name, opts);
|
||||
this.add(plugin);
|
||||
return recursivelyLoadMissingDependencies(plugin);
|
||||
};
|
||||
if (dependencies instanceof Set || Array.isArray(dependencies)) {
|
||||
return [...dependencies].forEach(dependencyPath => processDependency(dependencyPath));
|
||||
}
|
||||
if (dependencies instanceof Map) {
|
||||
// Note: `k,v => v,k` (Map + forEach will reverse the order)
|
||||
return dependencies.forEach((v, k) => processDependency(k, v));
|
||||
}
|
||||
};
|
||||
this.list.forEach(recursivelyLoadMissingDependencies);
|
||||
}
|
||||
/**
|
||||
* Lightweight plugin dependency management to require plugins and code mods on demand.
|
||||
* @private
|
||||
*/
|
||||
resolveDependencies() {
|
||||
debug('resolveDependencies');
|
||||
this.resolvePluginsStanza();
|
||||
this.resolveDependenciesStanza();
|
||||
}
|
||||
}
|
||||
exports.PluginList = PluginList;
|
||||
//# sourceMappingURL=plugins.js.map
|
||||
1
projects/org-skill-web-research/node_modules/playwright-extra/dist/plugins.js.map
generated
vendored
Normal file
1
projects/org-skill-web-research/node_modules/playwright-extra/dist/plugins.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
25
projects/org-skill-web-research/node_modules/playwright-extra/dist/puppeteer-compatiblity-shim/index.d.ts
generated
vendored
Normal file
25
projects/org-skill-web-research/node_modules/playwright-extra/dist/puppeteer-compatiblity-shim/index.d.ts
generated
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
import type * as pw from 'playwright-core';
|
||||
export declare type PlaywrightObject = pw.Page | pw.Frame | pw.Browser;
|
||||
export interface PuppeteerBrowserShim {
|
||||
isCompatShim?: boolean;
|
||||
isPlaywright?: boolean;
|
||||
pages?: pw.BrowserContext['pages'];
|
||||
userAgent: () => Promise<'string'>;
|
||||
}
|
||||
export interface PuppeteerPageShim {
|
||||
isCompatShim?: boolean;
|
||||
isPlaywright?: boolean;
|
||||
browser?: () => pw.Browser;
|
||||
evaluateOnNewDocument?: pw.Page['addInitScript'];
|
||||
_client: () => pw.CDPSession;
|
||||
}
|
||||
export declare const isPlaywrightPage: (obj: unknown) => obj is pw.Page;
|
||||
export declare const isPlaywrightFrame: (obj: unknown) => obj is pw.Frame;
|
||||
export declare const isPlaywrightBrowser: (obj: unknown) => obj is pw.Browser;
|
||||
export declare const isPuppeteerCompat: (obj?: unknown) => obj is PlaywrightObject;
|
||||
/** Augment a Playwright object with compatibility with certain Puppeteer methods */
|
||||
export declare function addPuppeteerCompat<Input extends pw.Page | pw.Frame | pw.Browser | null>(object: Input): Input;
|
||||
export declare function getPageCDPSession(page: pw.Page | pw.Frame): Promise<pw.CDPSession>;
|
||||
export declare function getBrowserCDPSession(browser: pw.Browser): Promise<pw.CDPSession>;
|
||||
export declare function createPageShim(page: pw.Page | pw.Frame): pw.Page | pw.Frame;
|
||||
export declare function createBrowserShim(browser: pw.Browser): pw.Browser;
|
||||
206
projects/org-skill-web-research/node_modules/playwright-extra/dist/puppeteer-compatiblity-shim/index.js
generated
vendored
Normal file
206
projects/org-skill-web-research/node_modules/playwright-extra/dist/puppeteer-compatiblity-shim/index.js
generated
vendored
Normal file
@@ -0,0 +1,206 @@
|
||||
"use strict";
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.createBrowserShim = exports.createPageShim = exports.getBrowserCDPSession = exports.getPageCDPSession = exports.addPuppeteerCompat = exports.isPuppeteerCompat = exports.isPlaywrightBrowser = exports.isPlaywrightFrame = exports.isPlaywrightPage = void 0;
|
||||
const debug_1 = __importDefault(require("debug"));
|
||||
const debug = (0, debug_1.default)('playwright-extra:puppeteer-compat');
|
||||
const isPlaywrightPage = (obj) => {
|
||||
return 'unroute' in obj;
|
||||
};
|
||||
exports.isPlaywrightPage = isPlaywrightPage;
|
||||
const isPlaywrightFrame = (obj) => {
|
||||
return ['parentFrame', 'frameLocator'].every(x => x in obj);
|
||||
};
|
||||
exports.isPlaywrightFrame = isPlaywrightFrame;
|
||||
const isPlaywrightBrowser = (obj) => {
|
||||
return 'newContext' in obj;
|
||||
};
|
||||
exports.isPlaywrightBrowser = isPlaywrightBrowser;
|
||||
const isPuppeteerCompat = (obj) => {
|
||||
return !!obj && typeof obj === 'object' && !!obj.isCompatShim;
|
||||
};
|
||||
exports.isPuppeteerCompat = isPuppeteerCompat;
|
||||
const cache = {
|
||||
objectToShim: new Map(),
|
||||
cdpSession: {
|
||||
page: new Map(),
|
||||
browser: new Map()
|
||||
}
|
||||
};
|
||||
/** Augment a Playwright object with compatibility with certain Puppeteer methods */
|
||||
function addPuppeteerCompat(object) {
|
||||
if (!object || typeof object !== 'object') {
|
||||
return object;
|
||||
}
|
||||
if (cache.objectToShim.has(object)) {
|
||||
return cache.objectToShim.get(object);
|
||||
}
|
||||
if ((0, exports.isPuppeteerCompat)(object)) {
|
||||
return object;
|
||||
}
|
||||
debug('addPuppeteerCompat', cache.objectToShim.size);
|
||||
if ((0, exports.isPlaywrightPage)(object) || (0, exports.isPlaywrightFrame)(object)) {
|
||||
const shim = createPageShim(object);
|
||||
cache.objectToShim.set(object, shim);
|
||||
return shim;
|
||||
}
|
||||
if ((0, exports.isPlaywrightBrowser)(object)) {
|
||||
const shim = createBrowserShim(object);
|
||||
cache.objectToShim.set(object, shim);
|
||||
return shim;
|
||||
}
|
||||
debug('Received unknown object:', Reflect.ownKeys(object));
|
||||
return object;
|
||||
}
|
||||
exports.addPuppeteerCompat = addPuppeteerCompat;
|
||||
// Only chromium browsers support CDP
|
||||
const dummyCDPClient = {
|
||||
send: async (...args) => {
|
||||
debug('dummy CDP client called', 'send', args);
|
||||
},
|
||||
on: (...args) => {
|
||||
debug('dummy CDP client called', 'on', args);
|
||||
}
|
||||
};
|
||||
async function getPageCDPSession(page) {
|
||||
let session = cache.cdpSession.page.get(page);
|
||||
if (session) {
|
||||
debug('getPageCDPSession: use existing');
|
||||
return session;
|
||||
}
|
||||
debug('getPageCDPSession: use new');
|
||||
const context = (0, exports.isPlaywrightFrame)(page)
|
||||
? page.page().context()
|
||||
: page.context();
|
||||
try {
|
||||
session = await context.newCDPSession(page);
|
||||
cache.cdpSession.page.set(page, session);
|
||||
return session;
|
||||
}
|
||||
catch (err) {
|
||||
debug('getPageCDPSession: error while creating session:', err.message);
|
||||
debug('getPageCDPSession: Unable create CDP session (most likely a different browser than chromium) - returning a dummy');
|
||||
}
|
||||
return dummyCDPClient;
|
||||
}
|
||||
exports.getPageCDPSession = getPageCDPSession;
|
||||
async function getBrowserCDPSession(browser) {
|
||||
let session = cache.cdpSession.browser.get(browser);
|
||||
if (session) {
|
||||
debug('getBrowserCDPSession: use existing');
|
||||
return session;
|
||||
}
|
||||
debug('getBrowserCDPSession: use new');
|
||||
try {
|
||||
session = await browser.newBrowserCDPSession();
|
||||
cache.cdpSession.browser.set(browser, session);
|
||||
return session;
|
||||
}
|
||||
catch (err) {
|
||||
debug('getBrowserCDPSession: error while creating session:', err.message);
|
||||
debug('getBrowserCDPSession: Unable create CDP session (most likely a different browser than chromium) - returning a dummy');
|
||||
}
|
||||
return dummyCDPClient;
|
||||
}
|
||||
exports.getBrowserCDPSession = getBrowserCDPSession;
|
||||
function createPageShim(page) {
|
||||
const objId = Math.random().toString(36).substring(2, 7);
|
||||
const shim = new Proxy(page, {
|
||||
get(target, prop) {
|
||||
if (prop === 'isCompatShim' || prop === 'isPlaywright') {
|
||||
return true;
|
||||
}
|
||||
debug('page - get', objId, prop);
|
||||
if (prop === '_client') {
|
||||
return () => ({
|
||||
send: async (method, params) => {
|
||||
const session = await getPageCDPSession(page);
|
||||
return await session.send(method, params);
|
||||
},
|
||||
on: (event, listener) => {
|
||||
getPageCDPSession(page).then(session => {
|
||||
session.on(event, listener);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
if (prop === 'setBypassCSP') {
|
||||
return async (enabled) => {
|
||||
const session = await getPageCDPSession(page);
|
||||
return await session.send('Page.setBypassCSP', {
|
||||
enabled
|
||||
});
|
||||
};
|
||||
}
|
||||
if (prop === 'setUserAgent') {
|
||||
return async (userAgent, userAgentMetadata) => {
|
||||
const session = await getPageCDPSession(page);
|
||||
return await session.send('Emulation.setUserAgentOverride', {
|
||||
userAgent,
|
||||
userAgentMetadata
|
||||
});
|
||||
};
|
||||
}
|
||||
if (prop === 'browser') {
|
||||
if ((0, exports.isPlaywrightPage)(page)) {
|
||||
return () => {
|
||||
let browser = page.context().browser();
|
||||
if (!browser) {
|
||||
debug('page.browser() - not available, most likely due to launchPersistentContext');
|
||||
// Use a page shim as quick drop-in (so browser.userAgent() still works)
|
||||
browser = page;
|
||||
}
|
||||
return addPuppeteerCompat(browser);
|
||||
};
|
||||
}
|
||||
}
|
||||
if (prop === 'evaluateOnNewDocument') {
|
||||
if ((0, exports.isPlaywrightPage)(page)) {
|
||||
return async function (pageFunction, ...args) {
|
||||
return await page.addInitScript(pageFunction, args[0]);
|
||||
};
|
||||
}
|
||||
}
|
||||
// Only relevant when page is being used a pseudo stand-in for the browser object (launchPersistentContext)
|
||||
if (prop === 'userAgent') {
|
||||
return async (enabled) => {
|
||||
const session = await getPageCDPSession(page);
|
||||
const data = await session.send('Browser.getVersion');
|
||||
return data.userAgent;
|
||||
};
|
||||
}
|
||||
return Reflect.get(target, prop);
|
||||
}
|
||||
});
|
||||
return shim;
|
||||
}
|
||||
exports.createPageShim = createPageShim;
|
||||
function createBrowserShim(browser) {
|
||||
const objId = Math.random().toString(36).substring(2, 7);
|
||||
const shim = new Proxy(browser, {
|
||||
get(target, prop) {
|
||||
if (prop === 'isCompatShim' || prop === 'isPlaywright') {
|
||||
return true;
|
||||
}
|
||||
debug('browser - get', objId, prop);
|
||||
if (prop === 'pages') {
|
||||
return () => browser
|
||||
.contexts()
|
||||
.flatMap(c => c.pages().map(page => addPuppeteerCompat(page)));
|
||||
}
|
||||
if (prop === 'userAgent') {
|
||||
return async () => {
|
||||
const session = await getBrowserCDPSession(browser);
|
||||
const data = await session.send('Browser.getVersion');
|
||||
return data.userAgent;
|
||||
};
|
||||
}
|
||||
return Reflect.get(target, prop);
|
||||
}
|
||||
});
|
||||
return shim;
|
||||
}
|
||||
exports.createBrowserShim = createBrowserShim;
|
||||
//# sourceMappingURL=index.js.map
|
||||
1
projects/org-skill-web-research/node_modules/playwright-extra/dist/puppeteer-compatiblity-shim/index.js.map
generated
vendored
Normal file
1
projects/org-skill-web-research/node_modules/playwright-extra/dist/puppeteer-compatiblity-shim/index.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
11
projects/org-skill-web-research/node_modules/playwright-extra/dist/puppeteer-compatiblity-shim/playwright-shim.d.ts
generated
vendored
Normal file
11
projects/org-skill-web-research/node_modules/playwright-extra/dist/puppeteer-compatiblity-shim/playwright-shim.d.ts
generated
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
// Playwright objects extended with puppeteer compatiblity shims
|
||||
|
||||
import type {} from 'playwright-core'
|
||||
|
||||
import type { PuppeteerPageShim, PuppeteerBrowserShim } from '.'
|
||||
|
||||
declare module 'playwright-core' {
|
||||
interface Page extends PuppeteerPageShim {}
|
||||
interface Frame extends PuppeteerPageShim {}
|
||||
interface Browser extends PuppeteerBrowserShim {}
|
||||
}
|
||||
87
projects/org-skill-web-research/node_modules/playwright-extra/dist/types/index.d.ts
generated
vendored
Normal file
87
projects/org-skill-web-research/node_modules/playwright-extra/dist/types/index.d.ts
generated
vendored
Normal file
@@ -0,0 +1,87 @@
|
||||
import type * as pw from 'playwright-core';
|
||||
declare type PropType<TObj, TProp extends keyof TObj> = TObj[TProp];
|
||||
declare type PluginEnv = {
|
||||
framework: 'playwright';
|
||||
};
|
||||
/** Strongly typed plugin lifecycle events for internal use */
|
||||
export declare abstract class PluginLifecycleMethods {
|
||||
onPluginRegistered(env?: PluginEnv): Promise<void>;
|
||||
beforeLaunch(options: pw.LaunchOptions): Promise<pw.LaunchOptions | void>;
|
||||
afterLaunch(browserOrContext?: pw.Browser | pw.BrowserContext): Promise<void>;
|
||||
beforeConnect(options: pw.ConnectOptions): Promise<pw.ConnectOptions | void>;
|
||||
afterConnect(browser: pw.Browser): Promise<void>;
|
||||
onBrowser(browser: pw.Browser): Promise<void>;
|
||||
onPageCreated(page: pw.Page): Promise<void>;
|
||||
onPageClose(page: pw.Page): Promise<void>;
|
||||
onDisconnected(browser?: pw.Browser): Promise<void>;
|
||||
beforeContext(options?: pw.BrowserContextOptions, browser?: pw.Browser): Promise<pw.BrowserContextOptions | void>;
|
||||
onContextCreated(context?: pw.BrowserContext, options?: pw.BrowserContextOptions): Promise<void>;
|
||||
}
|
||||
/** A valid plugin method name */
|
||||
export declare type PluginMethodName = keyof PluginLifecycleMethods;
|
||||
/** A valid plugin method function */
|
||||
export declare type PluginMethodFn<TName extends PluginMethodName> = PropType<PluginLifecycleMethods, TName>;
|
||||
declare type PluginRequirements = Set<'launch' | 'headful' | 'dataFromPlugins' | 'runLast'>;
|
||||
declare type PluginDependencies = Set<string> | Map<string, any> | string[];
|
||||
interface PluginData {
|
||||
name: string | {
|
||||
[key: string]: any;
|
||||
};
|
||||
value: {
|
||||
[key: string]: any;
|
||||
};
|
||||
}
|
||||
export interface CompatiblePluginLifecycleMethods {
|
||||
onPluginRegistered(...any: any[]): Promise<any> | any;
|
||||
beforeLaunch(...any: any[]): Promise<any> | any;
|
||||
afterLaunch(...any: any[]): Promise<any> | any;
|
||||
beforeConnect(...any: any[]): Promise<any> | any;
|
||||
afterConnect(...any: any[]): Promise<any> | any;
|
||||
onBrowser(...any: any[]): Promise<any> | any;
|
||||
onPageCreated(...any: any[]): Promise<any> | any;
|
||||
onPageClose(...any: any[]): Promise<any> | any;
|
||||
onDisconnected(...any: any[]): Promise<any> | any;
|
||||
beforeContext(...any: any[]): Promise<any> | any;
|
||||
onContextCreated(...any: any[]): Promise<any> | any;
|
||||
}
|
||||
/**
|
||||
* PuppeteerExtraPlugin interface, strongly typed for internal use
|
||||
* @private
|
||||
*/
|
||||
export interface PuppeteerExtraPlugin extends Partial<PluginLifecycleMethods> {
|
||||
_isPuppeteerExtraPlugin: boolean;
|
||||
name: string;
|
||||
/** Disable the puppeteer compatibility shim for this plugin */
|
||||
noPuppeteerShim?: boolean;
|
||||
requirements?: PluginRequirements;
|
||||
dependencies?: PluginDependencies;
|
||||
data?: PluginData[];
|
||||
getDataFromPlugins?(name?: string): void;
|
||||
_registerChildClassMembers?(prototype: any): void;
|
||||
_childClassMembers?: string[];
|
||||
plugins?: CompatiblePlugin[];
|
||||
}
|
||||
/**
|
||||
* Minimal compatible PuppeteerExtraPlugin interface
|
||||
* @private
|
||||
*/
|
||||
export interface CompatiblePuppeteerPlugin extends Partial<CompatiblePluginLifecycleMethods> {
|
||||
_isPuppeteerExtraPlugin: boolean;
|
||||
name?: string;
|
||||
}
|
||||
export interface CompatiblePlaywrightPlugin extends Partial<CompatiblePluginLifecycleMethods> {
|
||||
_isPlaywrightExtraPlugin: boolean;
|
||||
name?: string;
|
||||
}
|
||||
export interface CompatibleExtraPlugin extends Partial<CompatiblePluginLifecycleMethods> {
|
||||
_isExtraPlugin: boolean;
|
||||
name?: string;
|
||||
}
|
||||
/**
|
||||
* A compatible plugin
|
||||
*/
|
||||
export declare type CompatiblePlugin = CompatiblePuppeteerPlugin | CompatiblePlaywrightPlugin | CompatibleExtraPlugin;
|
||||
export declare type CompatiblePluginModule = (...args: any[]) => CompatiblePlugin;
|
||||
export declare type Plugin = PuppeteerExtraPlugin;
|
||||
export declare type PluginModule = (...args: any[]) => Plugin;
|
||||
export {};
|
||||
20
projects/org-skill-web-research/node_modules/playwright-extra/dist/types/index.js
generated
vendored
Normal file
20
projects/org-skill-web-research/node_modules/playwright-extra/dist/types/index.js
generated
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.PluginLifecycleMethods = void 0;
|
||||
/** Strongly typed plugin lifecycle events for internal use */
|
||||
class PluginLifecycleMethods {
|
||||
async onPluginRegistered(env) { }
|
||||
async beforeLaunch(options) { }
|
||||
async afterLaunch(browserOrContext) { }
|
||||
async beforeConnect(options) { }
|
||||
async afterConnect(browser) { }
|
||||
async onBrowser(browser) { }
|
||||
async onPageCreated(page) { }
|
||||
async onPageClose(page) { }
|
||||
async onDisconnected(browser) { }
|
||||
// Playwright only at the moment
|
||||
async beforeContext(options, browser) { }
|
||||
async onContextCreated(context, options) { }
|
||||
}
|
||||
exports.PluginLifecycleMethods = PluginLifecycleMethods;
|
||||
//# sourceMappingURL=index.js.map
|
||||
1
projects/org-skill-web-research/node_modules/playwright-extra/dist/types/index.js.map
generated
vendored
Normal file
1
projects/org-skill-web-research/node_modules/playwright-extra/dist/types/index.js.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":";;;AAKA,8DAA8D;AAC9D,MAAsB,sBAAsB;IAC1C,KAAK,CAAC,kBAAkB,CAAC,GAAe,IAAkB,CAAC;IAC3D,KAAK,CAAC,YAAY,CAChB,OAAyB,IACU,CAAC;IACtC,KAAK,CAAC,WAAW,CAAC,gBAAiD,IAAG,CAAC;IACvE,KAAK,CAAC,aAAa,CACjB,OAA0B,IACU,CAAC;IACvC,KAAK,CAAC,YAAY,CAAC,OAAmB,IAAG,CAAC;IAC1C,KAAK,CAAC,SAAS,CAAC,OAAmB,IAAG,CAAC;IACvC,KAAK,CAAC,aAAa,CAAC,IAAa,IAAG,CAAC;IACrC,KAAK,CAAC,WAAW,CAAC,IAAa,IAAG,CAAC;IACnC,KAAK,CAAC,cAAc,CAAC,OAAoB,IAAG,CAAC;IAC7C,gCAAgC;IAChC,KAAK,CAAC,aAAa,CACjB,OAAkC,EAClC,OAAoB,IACuB,CAAC;IAC9C,KAAK,CAAC,gBAAgB,CACpB,OAA2B,EAC3B,OAAkC,IACjC,CAAC;CACL;AAvBD,wDAuBC"}
|
||||
76
projects/org-skill-web-research/node_modules/playwright-extra/package.json
generated
vendored
Normal file
76
projects/org-skill-web-research/node_modules/playwright-extra/package.json
generated
vendored
Normal file
@@ -0,0 +1,76 @@
|
||||
{
|
||||
"name": "playwright-extra",
|
||||
"version": "4.3.6",
|
||||
"description": "Teach playwright new tricks through plugins.",
|
||||
"repository": "berstend/puppeteer-extra",
|
||||
"homepage": "https://github.com/berstend/puppeteer-extra/tree/master/packages/playwright-extra#readme",
|
||||
"author": "berstend",
|
||||
"license": "MIT",
|
||||
"typings": "dist/index.d.ts",
|
||||
"main": "dist/index.cjs.js",
|
||||
"module": "dist/index.esm.js",
|
||||
"files": [
|
||||
"dist"
|
||||
],
|
||||
"scripts": {
|
||||
"clean": "rimraf dist/*",
|
||||
"prebuild": "run-s clean",
|
||||
"build": "run-s build:tsc build:rollup ambient-dts",
|
||||
"build:tsc": "tsc --module commonjs",
|
||||
"build:rollup": "rollup -c rollup.config.ts",
|
||||
"docs": "echo \"No docs\"",
|
||||
"test": "yarn playwright test --config test/playwright.config.ts",
|
||||
"test-ci": "run-s test",
|
||||
"ambient-dts": "run-s ambient-dts-copy ambient-dts-fix-path",
|
||||
"ambient-dts-copy": "copyfiles -u 1 \"src/**/*.d.ts\" dist",
|
||||
"ambient-dts-fix-path": "replace-in-files --string='/// <reference path=\"../src/' --replacement='/// <reference path=\"../dist/' 'dist/**/*.d.ts'"
|
||||
},
|
||||
"keywords": [
|
||||
"playwright",
|
||||
"playwright-extra",
|
||||
"stealth",
|
||||
"recaptcha",
|
||||
"user-preferences",
|
||||
"chrome",
|
||||
"headless",
|
||||
"pupeteer"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@playwright/test": "^1.23.1",
|
||||
"@types/debug": "^4.1.7",
|
||||
"@types/node": "^18.0.0",
|
||||
"esbuild": "^0.14.47",
|
||||
"esbuild-register": "^3.3.3",
|
||||
"npm-run-all": "^4.1.5",
|
||||
"playwright": "1.24.2",
|
||||
"prettier": "^2.7.1",
|
||||
"puppeteer-extra-plugin": "^3.2.3",
|
||||
"puppeteer-extra-plugin-anonymize-ua": "^2.4.5",
|
||||
"rimraf": "^3.0.0",
|
||||
"rollup": "^1.27.5",
|
||||
"rollup-plugin-commonjs": "^10.1.0",
|
||||
"rollup-plugin-node-resolve": "^5.2.0",
|
||||
"rollup-plugin-sourcemaps": "^0.4.2",
|
||||
"rollup-plugin-typescript2": "^0.25.2",
|
||||
"typescript": "4.4.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"debug": "^4.3.4"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"playwright": "*",
|
||||
"playwright-core": "*"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"playwright": {
|
||||
"optional": true
|
||||
},
|
||||
"playwright-core": {
|
||||
"optional": true
|
||||
}
|
||||
},
|
||||
"gitHead": "2f4a357f233b35a7a20f16ce007f5ef3f62765b9"
|
||||
}
|
||||
282
projects/org-skill-web-research/node_modules/playwright-extra/readme.md
generated
vendored
Normal file
282
projects/org-skill-web-research/node_modules/playwright-extra/readme.md
generated
vendored
Normal file
@@ -0,0 +1,282 @@
|
||||
# playwright-extra [](https://github.com/berstend/puppeteer-extra/actions) [](https://extra.community) [](https://www.npmjs.com/package/playwright-extra)
|
||||
|
||||
> A modular plugin framework for [playwright](https://github.com/microsoft/playwright) to enable cool [plugins](#plugins) through a clean interface.
|
||||
|
||||
## Installation
|
||||
|
||||
```bash
|
||||
yarn add playwright playwright-extra
|
||||
# - or -
|
||||
npm install playwright playwright-extra
|
||||
```
|
||||
|
||||
<details>
|
||||
<summary>Changelog</summary>
|
||||
|
||||
> Please check the `announcements` channel in our [discord server](https://extra.community) until we've automated readme updates. :)
|
||||
|
||||
- **v4.3**
|
||||
- Rerelease due to versioning issues with previous beta packages
|
||||
- **v3.3**
|
||||
- Initial public release
|
||||
</details>
|
||||
|
||||
## Quickstart
|
||||
|
||||
```js
|
||||
// playwright-extra is a drop-in replacement for playwright,
|
||||
// it augments the installed playwright with plugin functionality
|
||||
const { chromium } = require('playwright-extra')
|
||||
|
||||
// Load the stealth plugin and use defaults (all tricks to hide playwright usage)
|
||||
// Note: playwright-extra is compatible with most puppeteer-extra plugins
|
||||
const stealth = require('puppeteer-extra-plugin-stealth')()
|
||||
|
||||
// Add the plugin to playwright (any number of plugins can be added)
|
||||
chromium.use(stealth)
|
||||
|
||||
// That's it, the rest is playwright usage as normal 😊
|
||||
chromium.launch({ headless: true }).then(async browser => {
|
||||
const page = await browser.newPage()
|
||||
|
||||
console.log('Testing the stealth plugin..')
|
||||
await page.goto('https://bot.sannysoft.com', { waitUntil: 'networkidle' })
|
||||
await page.screenshot({ path: 'stealth.png', fullPage: true })
|
||||
|
||||
console.log('All done, check the screenshot. ✨')
|
||||
await browser.close()
|
||||
})
|
||||
```
|
||||
|
||||
The above example uses the compatible [`stealth`](/packages/puppeteer-extra-plugin-stealth) plugin from puppeteer-extra, that plugin needs to be installed as well:
|
||||
|
||||
```bash
|
||||
yarn add puppeteer-extra-plugin-stealth
|
||||
# - or -
|
||||
npm install puppeteer-extra-plugin-stealth
|
||||
```
|
||||
|
||||
If you'd like to see debug output just run your script like so:
|
||||
|
||||
```bash
|
||||
# macOS/Linux (Bash)
|
||||
DEBUG=playwright-extra*,puppeteer-extra* node myscript.js
|
||||
|
||||
# Windows (Powershell)
|
||||
$env:DEBUG='playwright-extra*,puppeteer-extra*';node myscript.js
|
||||
```
|
||||
|
||||
### More examples
|
||||
|
||||
<details>
|
||||
<summary><strong>TypeScript & ESM usage</strong></summary><br/>
|
||||
|
||||
`playwright-extra` and most plugins are written in TS, so you get perfect type support out of the box. :)
|
||||
|
||||
```ts
|
||||
// playwright-extra is a drop-in replacement for playwright,
|
||||
// it augments the installed playwright with plugin functionality
|
||||
import { chromium } from 'playwright-extra'
|
||||
|
||||
// Load the stealth plugin and use defaults (all tricks to hide playwright usage)
|
||||
// Note: playwright-extra is compatible with most puppeteer-extra plugins
|
||||
import StealthPlugin from 'puppeteer-extra-plugin-stealth'
|
||||
|
||||
// Add the plugin to playwright (any number of plugins can be added)
|
||||
chromium.use(StealthPlugin())
|
||||
|
||||
// ...(the rest of the quickstart code example is the same)
|
||||
chromium.launch({ headless: true }).then(async browser => {
|
||||
const page = await browser.newPage()
|
||||
|
||||
console.log('Testing the stealth plugin..')
|
||||
await page.goto('https://bot.sannysoft.com', { waitUntil: 'networkidle' })
|
||||
await page.screenshot({ path: 'stealth.png', fullPage: true })
|
||||
|
||||
console.log('All done, check the screenshot. ✨')
|
||||
await browser.close()
|
||||
})
|
||||
```
|
||||
|
||||
New to Typescript? Here it is in 30 seconds or less 😄:
|
||||
|
||||
```bash
|
||||
# Optional: If you don't have yarn yet
|
||||
npm i --global yarn
|
||||
|
||||
# Optional: Create new package.json if it's a new project
|
||||
yarn init -y
|
||||
|
||||
# Add basic typescript dependencies
|
||||
yarn add --dev typescript @types/node esbuild esbuild-register
|
||||
|
||||
# Bootstrap a tsconfig.json
|
||||
yarn tsc --init --target ES2020 --lib ES2020 --module commonjs --rootDir src --outDir dist
|
||||
|
||||
# Add dependencies used in the quick start example
|
||||
yarn add playwright playwright-extra puppeteer-extra-plugin-stealth
|
||||
|
||||
# Create source folder for the .ts files
|
||||
mkdir src
|
||||
|
||||
# Now place the example code above in `src/index.ts`
|
||||
|
||||
# Run the typescript code without the need of compiling it first
|
||||
node -r esbuild-register src/index.ts
|
||||
|
||||
# You can now add Typescript to your CV 🎉
|
||||
```
|
||||
|
||||
</details>
|
||||
<details>
|
||||
<summary><strong>Using different browsers</strong></summary><br/>
|
||||
|
||||
```ts
|
||||
// Any browser supported by playwright can be used with plugins
|
||||
import { chromium, firefox, webkit } from 'playwright-extra'
|
||||
|
||||
chromium.use(plugin)
|
||||
firefox.use(plugin)
|
||||
webkit.use(plugin)
|
||||
```
|
||||
|
||||
</details>
|
||||
<details>
|
||||
<summary><strong>Multiple instances with different plugins</strong></summary><br/>
|
||||
|
||||
Node.js imports are cached, therefore the default `chromium`, `firefox`, `webkit` export from `playwright-extra` will always return the same playwright instance.
|
||||
|
||||
```ts
|
||||
// Use `addExtra` to create a fresh and independent instance
|
||||
import playwright from 'playwright'
|
||||
import { addExtra } from 'playwright-extra'
|
||||
|
||||
const chromium1 = addExtra(playwright.chromium)
|
||||
const chromium2 = addExtra(playwright.chromium)
|
||||
|
||||
chromium1.use(onePlugin)
|
||||
chromium2.use(anotherPlugin)
|
||||
// chromium1 and chromium2 are independent
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
---
|
||||
|
||||
## Plugins
|
||||
|
||||
We're currently in the process of making the existing [puppeteer-extra](/packages/puppeteer-extra) plugins compatible with playwright-extra, the following plugins have been successfully tested already:
|
||||
|
||||
### 🔥 [`puppeteer-extra-plugin-stealth`](/packages/puppeteer-extra-plugin-stealth)
|
||||
|
||||
- Applies various evasion techniques to make detection of an automated browser harder
|
||||
- Compatible with Puppeteer & Playwright and chromium based browsers
|
||||
|
||||
<details>
|
||||
<summary> Example: Using stealth in Playwright with custom options</summary>
|
||||
|
||||
```js
|
||||
// The stealth plugin is optimized for chromium based browsers currently
|
||||
import { chromium } from 'playwright-extra'
|
||||
|
||||
import StealthPlugin from 'puppeteer-extra-plugin-stealth'
|
||||
chromium.use(StealthPlugin())
|
||||
|
||||
// New way to overwrite the default options of stealth evasion plugins
|
||||
// https://github.com/berstend/puppeteer-extra/tree/master/packages/puppeteer-extra-plugin-stealth/evasions
|
||||
chromium.plugins.setDependencyDefaults('stealth/evasions/webgl.vendor', {
|
||||
vendor: 'Bob',
|
||||
renderer: 'Alice'
|
||||
})
|
||||
|
||||
// That's it, the rest is playwright usage as normal 😊
|
||||
chromium.launch({ headless: true }).then(async browser => {
|
||||
const page = await browser.newPage()
|
||||
|
||||
console.log('Testing the webgl spoofing feature of the stealth plugin..')
|
||||
await page.goto('https://webglreport.com', { waitUntil: 'networkidle' })
|
||||
await page.screenshot({ path: 'webgl.png', fullPage: true })
|
||||
|
||||
console.log('All done, check the screenshot. ✨')
|
||||
await browser.close()
|
||||
})
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
### 🏴 [`puppeteer-extra-plugin-recaptcha`](/packages/puppeteer-extra-plugin-recaptcha)
|
||||
|
||||
- Solves reCAPTCHAs and hCaptchas automatically, using a single line of code: `page.solveRecaptchas()`
|
||||
- Compatible with Puppeteer & Playwright and all browsers (chromium, firefox, webkit)
|
||||
<details>
|
||||
<summary> Example: Solving captchas in Playwright & Firefox</summary>
|
||||
|
||||
```js
|
||||
// Any browser (chromium, webkit, firefox) can be used
|
||||
import { firefox } from 'playwright-extra'
|
||||
|
||||
import RecaptchaPlugin from 'puppeteer-extra-plugin-recaptcha'
|
||||
firefox.use(
|
||||
RecaptchaPlugin({
|
||||
provider: {
|
||||
id: '2captcha',
|
||||
token: process.env.TWOCAPTCHA_TOKEN || 'YOUR_API_KEY'
|
||||
}
|
||||
})
|
||||
)
|
||||
|
||||
// Works in headless as well, just so you can see it in action
|
||||
firefox.launch({ headless: false }).then(async browser => {
|
||||
const context = await browser.newContext()
|
||||
const page = await context.newPage()
|
||||
const url = 'https://www.google.com/recaptcha/api2/demo'
|
||||
await page.goto(url, { waitUntil: 'networkidle' })
|
||||
|
||||
console.log('Solving captchas..')
|
||||
await page.solveRecaptchas()
|
||||
|
||||
await Promise.all([
|
||||
page.waitForNavigation({ waitUntil: 'networkidle' }),
|
||||
page.click(`#recaptcha-demo-submit`)
|
||||
])
|
||||
|
||||
const content = await page.content()
|
||||
const isSuccess = content.includes('Verification Success')
|
||||
console.log('Done', { isSuccess })
|
||||
await browser.close()
|
||||
})
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
### 🆕 [`plugin-proxy-router`](/packages/plugin-proxy-router)
|
||||
|
||||
- Use multiple proxies dynamically with flexible per-host routing and more
|
||||
- Compatible with Puppeteer & Playwright and all browsers (chromium, firefox, webkit)
|
||||
|
||||
**Notes**
|
||||
|
||||
- If you're in need of adblocking use [this package](https://www.npmjs.com/package/@cliqz/adblocker-playwright) or [block resources natively](https://github.com/berstend/puppeteer-extra/wiki/Block-resources-without-request-interception)
|
||||
- We're focussing on compatiblity with existing plugins at the moment, more documentation on how to write your own playwright-extra plugins will follow
|
||||
|
||||
---
|
||||
|
||||
## Contributors
|
||||
|
||||
<a href="https://github.com/berstend/puppeteer-extra/graphs/contributors">
|
||||
<img src="https://contributors-img.firebaseapp.com/image?repo=berstend/puppeteer-extra" />
|
||||
</a>
|
||||
|
||||
---
|
||||
|
||||
## License
|
||||
|
||||
Copyright © 2018 - 2023, [berstend̡̲̫̹̠̖͚͓̔̄̓̐̄͛̀͘](https://github.com/berstend). Released under the MIT License.
|
||||
|
||||
<!--
|
||||
Reference links
|
||||
-->
|
||||
|
||||
[playwright-extra]: https://github.com/berstend/puppeteer-extra/tree/master/packages/playwright-extra
|
||||
[puppeteer-extra]: https://github.com/berstend/puppeteer-extra/tree/master/packages/puppeteer-extra
|
||||
[`puppeteer-extra`]: https://github.com/berstend/puppeteer-extra/tree/master/packages/puppeteer-extra
|
||||
Reference in New Issue
Block a user