browser.js 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", {
  3. value: true
  4. });
  5. exports.Browser = void 0;
  6. var _fs = _interopRequireDefault(require("fs"));
  7. var _browserContext = require("./browserContext");
  8. var _channelOwner = require("./channelOwner");
  9. var _events = require("./events");
  10. var _errors = require("./errors");
  11. var _cdpSession = require("./cdpSession");
  12. var _artifact = require("./artifact");
  13. var _utils = require("../utils");
  14. let _Symbol$asyncDispose;
  15. /**
  16. * Copyright (c) Microsoft Corporation.
  17. *
  18. * Licensed under the Apache License, Version 2.0 (the "License");
  19. * you may not use this file except in compliance with the License.
  20. * You may obtain a copy of the License at
  21. *
  22. * http://www.apache.org/licenses/LICENSE-2.0
  23. *
  24. * Unless required by applicable law or agreed to in writing, software
  25. * distributed under the License is distributed on an "AS IS" BASIS,
  26. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  27. * See the License for the specific language governing permissions and
  28. * limitations under the License.
  29. */
  30. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
  31. _Symbol$asyncDispose = Symbol.asyncDispose;
  32. class Browser extends _channelOwner.ChannelOwner {
  33. static from(browser) {
  34. return browser._object;
  35. }
  36. constructor(parent, type, guid, initializer) {
  37. super(parent, type, guid, initializer);
  38. this._contexts = new Set();
  39. this._isConnected = true;
  40. this._closedPromise = void 0;
  41. this._shouldCloseConnectionOnClose = false;
  42. this._browserType = void 0;
  43. this._options = {};
  44. this._name = void 0;
  45. this._path = void 0;
  46. // Used from @playwright/test fixtures.
  47. this._connectHeaders = void 0;
  48. this._closeReason = void 0;
  49. this._name = initializer.name;
  50. this._channel.on('close', () => this._didClose());
  51. this._closedPromise = new Promise(f => this.once(_events.Events.Browser.Disconnected, f));
  52. }
  53. browserType() {
  54. return this._browserType;
  55. }
  56. async newContext(options = {}) {
  57. return await this._innerNewContext(options, false);
  58. }
  59. async _newContextForReuse(options = {}) {
  60. return await this._wrapApiCall(async () => {
  61. for (const context of this._contexts) {
  62. await this._browserType._willCloseContext(context);
  63. for (const page of context.pages()) page._onClose();
  64. context._onClose();
  65. }
  66. return await this._innerNewContext(options, true);
  67. }, true);
  68. }
  69. async _stopPendingOperations(reason) {
  70. return await this._wrapApiCall(async () => {
  71. await this._channel.stopPendingOperations({
  72. reason
  73. });
  74. }, true);
  75. }
  76. async _innerNewContext(options = {}, forReuse) {
  77. options = {
  78. ...this._browserType._defaultContextOptions,
  79. ...options
  80. };
  81. const contextOptions = await (0, _browserContext.prepareBrowserContextParams)(options);
  82. const response = forReuse ? await this._channel.newContextForReuse(contextOptions) : await this._channel.newContext(contextOptions);
  83. const context = _browserContext.BrowserContext.from(response.context);
  84. await this._browserType._didCreateContext(context, contextOptions, this._options, options.logger || this._logger);
  85. return context;
  86. }
  87. contexts() {
  88. return [...this._contexts];
  89. }
  90. version() {
  91. return this._initializer.version;
  92. }
  93. async newPage(options = {}) {
  94. return await this._wrapApiCall(async () => {
  95. const context = await this.newContext(options);
  96. const page = await context.newPage();
  97. page._ownedContext = context;
  98. context._ownerPage = page;
  99. return page;
  100. });
  101. }
  102. isConnected() {
  103. return this._isConnected;
  104. }
  105. async newBrowserCDPSession() {
  106. return _cdpSession.CDPSession.from((await this._channel.newBrowserCDPSession()).session);
  107. }
  108. async startTracing(page, options = {}) {
  109. this._path = options.path;
  110. await this._channel.startTracing({
  111. ...options,
  112. page: page ? page._channel : undefined
  113. });
  114. }
  115. async stopTracing() {
  116. const artifact = _artifact.Artifact.from((await this._channel.stopTracing()).artifact);
  117. const buffer = await artifact.readIntoBuffer();
  118. await artifact.delete();
  119. if (this._path) {
  120. await (0, _utils.mkdirIfNeeded)(this._path);
  121. await _fs.default.promises.writeFile(this._path, buffer);
  122. this._path = undefined;
  123. }
  124. return buffer;
  125. }
  126. async [_Symbol$asyncDispose]() {
  127. await this.close();
  128. }
  129. async close(options = {}) {
  130. this._closeReason = options.reason;
  131. try {
  132. if (this._shouldCloseConnectionOnClose) this._connection.close();else await this._channel.close(options);
  133. await this._closedPromise;
  134. } catch (e) {
  135. if ((0, _errors.isTargetClosedError)(e)) return;
  136. throw e;
  137. }
  138. }
  139. _didClose() {
  140. this._isConnected = false;
  141. this.emit(_events.Events.Browser.Disconnected, this);
  142. }
  143. }
  144. exports.Browser = Browser;