rebrowser-playwright-core
Version:
A drop-in replacement for playwright-core patched with rebrowser-patches. It allows to pass modern automation detection tests.
145 lines (144 loc) • 4.92 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.Browser = void 0;
var _fs = _interopRequireDefault(require("fs"));
var _browserContext = require("./browserContext");
var _channelOwner = require("./channelOwner");
var _events = require("./events");
var _errors = require("./errors");
var _cdpSession = require("./cdpSession");
var _artifact = require("./artifact");
var _utils = require("../utils");
let _Symbol$asyncDispose;
/**
* 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.
*/
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
_Symbol$asyncDispose = Symbol.asyncDispose;
class Browser extends _channelOwner.ChannelOwner {
static from(browser) {
return browser._object;
}
constructor(parent, type, guid, initializer) {
super(parent, type, guid, initializer);
this._contexts = new Set();
this._isConnected = true;
this._closedPromise = void 0;
this._shouldCloseConnectionOnClose = false;
this._browserType = void 0;
this._options = {};
this._name = void 0;
this._path = void 0;
// Used from @playwright/test fixtures.
this._connectHeaders = void 0;
this._closeReason = void 0;
this._name = initializer.name;
this._channel.on('close', () => this._didClose());
this._closedPromise = new Promise(f => this.once(_events.Events.Browser.Disconnected, f));
}
browserType() {
return this._browserType;
}
async newContext(options = {}) {
return await this._innerNewContext(options, false);
}
async _newContextForReuse(options = {}) {
return await this._wrapApiCall(async () => {
for (const context of this._contexts) {
await this._browserType._willCloseContext(context);
for (const page of context.pages()) page._onClose();
context._onClose();
}
return await this._innerNewContext(options, true);
}, true);
}
async _stopPendingOperations(reason) {
return await this._wrapApiCall(async () => {
await this._channel.stopPendingOperations({
reason
});
}, true);
}
async _innerNewContext(options = {}, forReuse) {
options = {
...this._browserType._defaultContextOptions,
...options
};
const contextOptions = await (0, _browserContext.prepareBrowserContextParams)(options);
const response = forReuse ? await this._channel.newContextForReuse(contextOptions) : await this._channel.newContext(contextOptions);
const context = _browserContext.BrowserContext.from(response.context);
await this._browserType._didCreateContext(context, contextOptions, this._options, options.logger || this._logger);
return context;
}
contexts() {
return [...this._contexts];
}
version() {
return this._initializer.version;
}
async newPage(options = {}) {
return await this._wrapApiCall(async () => {
const context = await this.newContext(options);
const page = await context.newPage();
page._ownedContext = context;
context._ownerPage = page;
return page;
});
}
isConnected() {
return this._isConnected;
}
async newBrowserCDPSession() {
return _cdpSession.CDPSession.from((await this._channel.newBrowserCDPSession()).session);
}
async startTracing(page, options = {}) {
this._path = options.path;
await this._channel.startTracing({
...options,
page: page ? page._channel : undefined
});
}
async stopTracing() {
const artifact = _artifact.Artifact.from((await this._channel.stopTracing()).artifact);
const buffer = await artifact.readIntoBuffer();
await artifact.delete();
if (this._path) {
await (0, _utils.mkdirIfNeeded)(this._path);
await _fs.default.promises.writeFile(this._path, buffer);
this._path = undefined;
}
return buffer;
}
async [_Symbol$asyncDispose]() {
await this.close();
}
async close(options = {}) {
this._closeReason = options.reason;
try {
if (this._shouldCloseConnectionOnClose) this._connection.close();else await this._channel.close(options);
await this._closedPromise;
} catch (e) {
if ((0, _errors.isTargetClosedError)(e)) return;
throw e;
}
}
_didClose() {
this._isConnected = false;
this.emit(_events.Events.Browser.Disconnected, this);
}
}
exports.Browser = Browser;