screenshot/test_1
This commit is contained in:
297
node_modules/playwright-core/lib/server/electron/electron.js
generated
vendored
Normal file
297
node_modules/playwright-core/lib/server/electron/electron.js
generated
vendored
Normal file
@@ -0,0 +1,297 @@
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.ElectronApplication = exports.Electron = void 0;
|
||||
var _fs = _interopRequireDefault(require("fs"));
|
||||
var _os = _interopRequireDefault(require("os"));
|
||||
var _path = _interopRequireDefault(require("path"));
|
||||
var readline = _interopRequireWildcard(require("readline"));
|
||||
var _timeoutSettings = require("../timeoutSettings");
|
||||
var _utils = require("../../utils");
|
||||
var _ascii = require("../utils/ascii");
|
||||
var _debugLogger = require("../utils/debugLogger");
|
||||
var _eventsHelper = require("../utils/eventsHelper");
|
||||
var _browserContext = require("../browserContext");
|
||||
var _crBrowser = require("../chromium/crBrowser");
|
||||
var _crConnection = require("../chromium/crConnection");
|
||||
var _crExecutionContext = require("../chromium/crExecutionContext");
|
||||
var _crProtocolHelper = require("../chromium/crProtocolHelper");
|
||||
var _console = require("../console");
|
||||
var _helper = require("../helper");
|
||||
var _instrumentation = require("../instrumentation");
|
||||
var js = _interopRequireWildcard(require("../javascript"));
|
||||
var _processLauncher = require("../utils/processLauncher");
|
||||
var _progress = require("../progress");
|
||||
var _transport = require("../transport");
|
||||
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
|
||||
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
|
||||
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
||||
/**
|
||||
* Copyright (c) Microsoft Corporation.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
const ARTIFACTS_FOLDER = _path.default.join(_os.default.tmpdir(), 'playwright-artifacts-');
|
||||
class ElectronApplication extends _instrumentation.SdkObject {
|
||||
constructor(parent, browser, nodeConnection, process) {
|
||||
super(parent, 'electron-app');
|
||||
this._browserContext = void 0;
|
||||
this._nodeConnection = void 0;
|
||||
this._nodeSession = void 0;
|
||||
this._nodeExecutionContext = void 0;
|
||||
this._nodeElectronHandlePromise = new _utils.ManualPromise();
|
||||
this._timeoutSettings = new _timeoutSettings.TimeoutSettings();
|
||||
this._process = void 0;
|
||||
this._process = process;
|
||||
this._browserContext = browser._defaultContext;
|
||||
this._nodeConnection = nodeConnection;
|
||||
this._nodeSession = nodeConnection.rootSession;
|
||||
this._nodeSession.on('Runtime.executionContextCreated', async event => {
|
||||
if (!event.context.auxData || !event.context.auxData.isDefault) return;
|
||||
const crExecutionContext = new _crExecutionContext.CRExecutionContext(this._nodeSession, event.context);
|
||||
this._nodeExecutionContext = new js.ExecutionContext(this, crExecutionContext, 'electron');
|
||||
const {
|
||||
result: remoteObject
|
||||
} = await crExecutionContext._client.send('Runtime.evaluate', {
|
||||
expression: `require('electron')`,
|
||||
contextId: event.context.id,
|
||||
// Needed after Electron 28 to get access to require: https://github.com/microsoft/playwright/issues/28048
|
||||
includeCommandLineAPI: true
|
||||
});
|
||||
this._nodeElectronHandlePromise.resolve(new js.JSHandle(this._nodeExecutionContext, 'object', 'ElectronModule', remoteObject.objectId));
|
||||
});
|
||||
this._nodeSession.on('Runtime.consoleAPICalled', event => this._onConsoleAPI(event));
|
||||
const appClosePromise = new Promise(f => this.once(ElectronApplication.Events.Close, f));
|
||||
this._browserContext.setCustomCloseHandler(async () => {
|
||||
await this._browserContext.stopVideoRecording();
|
||||
const electronHandle = await this._nodeElectronHandlePromise;
|
||||
await electronHandle.evaluate(({
|
||||
app
|
||||
}) => app.quit()).catch(() => {});
|
||||
this._nodeConnection.close();
|
||||
await appClosePromise;
|
||||
});
|
||||
}
|
||||
async _onConsoleAPI(event) {
|
||||
if (event.executionContextId === 0) {
|
||||
// DevTools protocol stores the last 1000 console messages. These
|
||||
// messages are always reported even for removed execution contexts. In
|
||||
// this case, they are marked with executionContextId = 0 and are
|
||||
// reported upon enabling Runtime agent.
|
||||
//
|
||||
// Ignore these messages since:
|
||||
// - there's no execution context we can use to operate with message
|
||||
// arguments
|
||||
// - these messages are reported before Playwright clients can subscribe
|
||||
// to the 'console'
|
||||
// page event.
|
||||
//
|
||||
// @see https://github.com/GoogleChrome/puppeteer/issues/3865
|
||||
return;
|
||||
}
|
||||
if (!this._nodeExecutionContext) return;
|
||||
const args = event.args.map(arg => (0, _crExecutionContext.createHandle)(this._nodeExecutionContext, arg));
|
||||
const message = new _console.ConsoleMessage(null, event.type, undefined, args, (0, _crProtocolHelper.toConsoleMessageLocation)(event.stackTrace));
|
||||
this.emit(ElectronApplication.Events.Console, message);
|
||||
}
|
||||
async initialize() {
|
||||
await this._nodeSession.send('Runtime.enable', {});
|
||||
// Delay loading the app until browser is started and the browser targets are configured to auto-attach.
|
||||
await this._nodeSession.send('Runtime.evaluate', {
|
||||
expression: '__playwright_run()'
|
||||
});
|
||||
}
|
||||
process() {
|
||||
return this._process;
|
||||
}
|
||||
context() {
|
||||
return this._browserContext;
|
||||
}
|
||||
async close() {
|
||||
// This will call BrowserContext.setCustomCloseHandler.
|
||||
await this._browserContext.close({
|
||||
reason: 'Application exited'
|
||||
});
|
||||
}
|
||||
async browserWindow(page) {
|
||||
// Assume CRPage as Electron is always Chromium.
|
||||
const targetId = page._delegate._targetId;
|
||||
const electronHandle = await this._nodeElectronHandlePromise;
|
||||
return await electronHandle.evaluateHandle(({
|
||||
BrowserWindow,
|
||||
webContents
|
||||
}, targetId) => {
|
||||
const wc = webContents.fromDevToolsTargetId(targetId);
|
||||
return BrowserWindow.fromWebContents(wc);
|
||||
}, targetId);
|
||||
}
|
||||
}
|
||||
exports.ElectronApplication = ElectronApplication;
|
||||
ElectronApplication.Events = {
|
||||
Close: 'close',
|
||||
Console: 'console'
|
||||
};
|
||||
class Electron extends _instrumentation.SdkObject {
|
||||
constructor(playwright) {
|
||||
super(playwright, 'electron');
|
||||
}
|
||||
async launch(options) {
|
||||
const {
|
||||
args = []
|
||||
} = options;
|
||||
const controller = new _progress.ProgressController((0, _instrumentation.serverSideCallMetadata)(), this);
|
||||
controller.setLogName('browser');
|
||||
return controller.run(async progress => {
|
||||
let app = undefined;
|
||||
// --remote-debugging-port=0 must be the last playwright's argument, loader.ts relies on it.
|
||||
let electronArguments = ['--inspect=0', '--remote-debugging-port=0', ...args];
|
||||
if (_os.default.platform() === 'linux') {
|
||||
const runningAsRoot = process.geteuid && process.geteuid() === 0;
|
||||
if (runningAsRoot && electronArguments.indexOf('--no-sandbox') === -1) electronArguments.unshift('--no-sandbox');
|
||||
}
|
||||
const artifactsDir = await _fs.default.promises.mkdtemp(ARTIFACTS_FOLDER);
|
||||
const browserLogsCollector = new _debugLogger.RecentLogsCollector();
|
||||
const env = options.env ? (0, _processLauncher.envArrayToObject)(options.env) : process.env;
|
||||
let command;
|
||||
if (options.executablePath) {
|
||||
command = options.executablePath;
|
||||
} else {
|
||||
try {
|
||||
// By default we fallback to the Electron App executable path.
|
||||
// 'electron/index.js' resolves to the actual Electron App.
|
||||
command = require('electron/index.js');
|
||||
} catch (error) {
|
||||
if ((error === null || error === void 0 ? void 0 : error.code) === 'MODULE_NOT_FOUND') {
|
||||
throw new Error('\n' + (0, _ascii.wrapInASCIIBox)(['Electron executablePath not found!', 'Please install it using `npm install -D electron` or set the executablePath to your Electron executable.'].join('\n'), 1));
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
// Only use our own loader for non-packaged apps.
|
||||
// Packaged apps might have their own command line handling.
|
||||
electronArguments.unshift('-r', require.resolve('./loader'));
|
||||
}
|
||||
let shell = false;
|
||||
if (process.platform === 'win32') {
|
||||
// On Windows in order to run .cmd files, shell: true is required.
|
||||
// https://github.com/nodejs/node/issues/52554
|
||||
shell = true;
|
||||
// On Windows, we need to quote the executable path due to shell: true.
|
||||
command = `"${command}"`;
|
||||
// On Windows, we need to quote the arguments due to shell: true.
|
||||
electronArguments = electronArguments.map(arg => `"${arg}"`);
|
||||
}
|
||||
|
||||
// When debugging Playwright test that runs Electron, NODE_OPTIONS
|
||||
// will make the debugger attach to Electron's Node. But Playwright
|
||||
// also needs to attach to drive the automation. Disable external debugging.
|
||||
delete env.NODE_OPTIONS;
|
||||
const {
|
||||
launchedProcess,
|
||||
gracefullyClose,
|
||||
kill
|
||||
} = await (0, _processLauncher.launchProcess)({
|
||||
command,
|
||||
args: electronArguments,
|
||||
env,
|
||||
log: message => {
|
||||
progress.log(message);
|
||||
browserLogsCollector.log(message);
|
||||
},
|
||||
shell,
|
||||
stdio: 'pipe',
|
||||
cwd: options.cwd,
|
||||
tempDirectories: [artifactsDir],
|
||||
attemptToGracefullyClose: () => app.close(),
|
||||
handleSIGINT: true,
|
||||
handleSIGTERM: true,
|
||||
handleSIGHUP: true,
|
||||
onExit: () => {
|
||||
var _app;
|
||||
return (_app = app) === null || _app === void 0 ? void 0 : _app.emit(ElectronApplication.Events.Close);
|
||||
}
|
||||
});
|
||||
|
||||
// All waitForLines must be started immediately.
|
||||
// Otherwise the lines might come before we are ready.
|
||||
const waitForXserverError = new Promise(async (resolve, reject) => {
|
||||
waitForLine(progress, launchedProcess, /Unable to open X display/).then(() => reject(new Error(['Unable to open X display!', `================================`, 'Most likely this is because there is no X server available.', "Use 'xvfb-run' on Linux to launch your tests with an emulated display server.", "For example: 'xvfb-run npm run test:e2e'", `================================`, progress.metadata.log].join('\n')))).catch(() => {});
|
||||
});
|
||||
const nodeMatchPromise = waitForLine(progress, launchedProcess, /^Debugger listening on (ws:\/\/.*)$/);
|
||||
const chromeMatchPromise = waitForLine(progress, launchedProcess, /^DevTools listening on (ws:\/\/.*)$/);
|
||||
const debuggerDisconnectPromise = waitForLine(progress, launchedProcess, /Waiting for the debugger to disconnect\.\.\./);
|
||||
const nodeMatch = await nodeMatchPromise;
|
||||
const nodeTransport = await _transport.WebSocketTransport.connect(progress, nodeMatch[1]);
|
||||
const nodeConnection = new _crConnection.CRConnection(nodeTransport, _helper.helper.debugProtocolLogger(), browserLogsCollector);
|
||||
|
||||
// Immediately release exiting process under debug.
|
||||
debuggerDisconnectPromise.then(() => {
|
||||
nodeTransport.close();
|
||||
}).catch(() => {});
|
||||
const chromeMatch = await Promise.race([chromeMatchPromise, waitForXserverError]);
|
||||
const chromeTransport = await _transport.WebSocketTransport.connect(progress, chromeMatch[1]);
|
||||
const browserProcess = {
|
||||
onclose: undefined,
|
||||
process: launchedProcess,
|
||||
close: gracefullyClose,
|
||||
kill
|
||||
};
|
||||
const contextOptions = {
|
||||
...options,
|
||||
noDefaultViewport: true
|
||||
};
|
||||
const browserOptions = {
|
||||
name: 'electron',
|
||||
isChromium: true,
|
||||
headful: true,
|
||||
persistent: contextOptions,
|
||||
browserProcess,
|
||||
protocolLogger: _helper.helper.debugProtocolLogger(),
|
||||
browserLogsCollector,
|
||||
artifactsDir,
|
||||
downloadsPath: artifactsDir,
|
||||
tracesDir: options.tracesDir || artifactsDir,
|
||||
originalLaunchOptions: {}
|
||||
};
|
||||
(0, _browserContext.validateBrowserContextOptions)(contextOptions, browserOptions);
|
||||
const browser = await _crBrowser.CRBrowser.connect(this.attribution.playwright, chromeTransport, browserOptions);
|
||||
app = new ElectronApplication(this, browser, nodeConnection, launchedProcess);
|
||||
await app.initialize();
|
||||
return app;
|
||||
}, _timeoutSettings.TimeoutSettings.launchTimeout(options));
|
||||
}
|
||||
}
|
||||
exports.Electron = Electron;
|
||||
function waitForLine(progress, process, regex) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const rl = readline.createInterface({
|
||||
input: process.stderr
|
||||
});
|
||||
const failError = new Error('Process failed to launch!');
|
||||
const listeners = [_eventsHelper.eventsHelper.addEventListener(rl, 'line', onLine), _eventsHelper.eventsHelper.addEventListener(rl, 'close', reject.bind(null, failError)), _eventsHelper.eventsHelper.addEventListener(process, 'exit', reject.bind(null, failError)),
|
||||
// It is Ok to remove error handler because we did not create process and there is another listener.
|
||||
_eventsHelper.eventsHelper.addEventListener(process, 'error', reject.bind(null, failError))];
|
||||
progress.cleanupWhenAborted(cleanup);
|
||||
function onLine(line) {
|
||||
const match = line.match(regex);
|
||||
if (!match) return;
|
||||
cleanup();
|
||||
resolve(match);
|
||||
}
|
||||
function cleanup() {
|
||||
_eventsHelper.eventsHelper.removeEventListeners(listeners);
|
||||
}
|
||||
});
|
||||
}
|
||||
57
node_modules/playwright-core/lib/server/electron/loader.js
generated
vendored
Normal file
57
node_modules/playwright-core/lib/server/electron/loader.js
generated
vendored
Normal file
@@ -0,0 +1,57 @@
|
||||
"use strict";
|
||||
|
||||
/**
|
||||
* Copyright (c) Microsoft Corporation.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
const {
|
||||
app
|
||||
} = require('electron');
|
||||
const {
|
||||
chromiumSwitches
|
||||
} = require('../chromium/chromiumSwitches');
|
||||
|
||||
// Always pass user arguments first, see https://github.com/microsoft/playwright/issues/16614 and
|
||||
// https://github.com/microsoft/playwright/issues/29198.
|
||||
// [Electron, -r, loader.js[, --no-sandbox>], --inspect=0, --remote-debugging-port=0, ...args]
|
||||
process.argv.splice(1, process.argv.indexOf('--remote-debugging-port=0'));
|
||||
for (const arg of chromiumSwitches) {
|
||||
const match = arg.match(/--([^=]*)=?(.*)/);
|
||||
app.commandLine.appendSwitch(match[1], match[2]);
|
||||
}
|
||||
|
||||
// Defer ready event.
|
||||
const originalWhenReady = app.whenReady();
|
||||
const originalEmit = app.emit.bind(app);
|
||||
let readyEventArgs;
|
||||
app.emit = (event, ...args) => {
|
||||
if (event === 'ready') {
|
||||
readyEventArgs = args;
|
||||
return app.listenerCount('ready') > 0;
|
||||
}
|
||||
return originalEmit(event, ...args);
|
||||
};
|
||||
let isReady = false;
|
||||
let whenReadyCallback;
|
||||
const whenReadyPromise = new Promise(f => whenReadyCallback = f);
|
||||
app.isReady = () => isReady;
|
||||
app.whenReady = () => whenReadyPromise;
|
||||
globalThis.__playwright_run = async () => {
|
||||
// Wait for app to be ready to avoid browser initialization races.
|
||||
const event = await originalWhenReady;
|
||||
isReady = true;
|
||||
whenReadyCallback(event);
|
||||
originalEmit('ready', ...readyEventArgs);
|
||||
};
|
||||
Reference in New Issue
Block a user