browser.js 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. "use strict";
  2. var __defProp = Object.defineProperty;
  3. var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
  4. var __getOwnPropNames = Object.getOwnPropertyNames;
  5. var __hasOwnProp = Object.prototype.hasOwnProperty;
  6. var __export = (target, all) => {
  7. for (var name in all)
  8. __defProp(target, name, { get: all[name], enumerable: true });
  9. };
  10. var __copyProps = (to, from, except, desc) => {
  11. if (from && typeof from === "object" || typeof from === "function") {
  12. for (let key of __getOwnPropNames(from))
  13. if (!__hasOwnProp.call(to, key) && key !== except)
  14. __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
  15. }
  16. return to;
  17. };
  18. var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
  19. var browser_exports = {};
  20. __export(browser_exports, {
  21. Browser: () => Browser
  22. });
  23. module.exports = __toCommonJS(browser_exports);
  24. var import_artifact = require("./artifact");
  25. var import_browserContext = require("./browserContext");
  26. var import_download = require("./download");
  27. var import_instrumentation = require("./instrumentation");
  28. var import_page = require("./page");
  29. var import_socksClientCertificatesInterceptor = require("./socksClientCertificatesInterceptor");
  30. class Browser extends import_instrumentation.SdkObject {
  31. constructor(parent, options) {
  32. super(parent, "browser");
  33. this._downloads = /* @__PURE__ */ new Map();
  34. this._defaultContext = null;
  35. this._startedClosing = false;
  36. this._idToVideo = /* @__PURE__ */ new Map();
  37. this._isCollocatedWithServer = true;
  38. this.attribution.browser = this;
  39. this.options = options;
  40. this.instrumentation.onBrowserOpen(this);
  41. }
  42. static {
  43. this.Events = {
  44. Context: "context",
  45. Disconnected: "disconnected"
  46. };
  47. }
  48. sdkLanguage() {
  49. return this.options.sdkLanguage || this.attribution.playwright.options.sdkLanguage;
  50. }
  51. async newContext(progress, options) {
  52. (0, import_browserContext.validateBrowserContextOptions)(options, this.options);
  53. let clientCertificatesProxy;
  54. let context;
  55. try {
  56. if (options.clientCertificates?.length) {
  57. clientCertificatesProxy = await import_socksClientCertificatesInterceptor.ClientCertificatesProxy.create(progress, options);
  58. options = { ...options };
  59. options.proxyOverride = clientCertificatesProxy.proxySettings();
  60. options.internalIgnoreHTTPSErrors = true;
  61. }
  62. context = await progress.race(this.doCreateNewContext(options));
  63. context._clientCertificatesProxy = clientCertificatesProxy;
  64. if (options.__testHookBeforeSetStorageState)
  65. await progress.race(options.__testHookBeforeSetStorageState());
  66. await context.setStorageState(progress, options.storageState, "initial");
  67. this.emit(Browser.Events.Context, context);
  68. return context;
  69. } catch (error) {
  70. await context?.close({ reason: "Failed to create context" }).catch(() => {
  71. });
  72. await clientCertificatesProxy?.close().catch(() => {
  73. });
  74. throw error;
  75. }
  76. }
  77. async newContextForReuse(progress, params) {
  78. const hash = import_browserContext.BrowserContext.reusableContextHash(params);
  79. if (!this._contextForReuse || hash !== this._contextForReuse.hash || !this._contextForReuse.context.canResetForReuse()) {
  80. if (this._contextForReuse)
  81. await this._contextForReuse.context.close({ reason: "Context reused" });
  82. this._contextForReuse = { context: await this.newContext(progress, params), hash };
  83. return this._contextForReuse.context;
  84. }
  85. await this._contextForReuse.context.resetForReuse(progress, params);
  86. return this._contextForReuse.context;
  87. }
  88. contextForReuse() {
  89. return this._contextForReuse?.context;
  90. }
  91. _downloadCreated(page, uuid, url, suggestedFilename) {
  92. const download = new import_download.Download(page, this.options.downloadsPath || "", uuid, url, suggestedFilename);
  93. this._downloads.set(uuid, download);
  94. }
  95. _downloadFilenameSuggested(uuid, suggestedFilename) {
  96. const download = this._downloads.get(uuid);
  97. if (!download)
  98. return;
  99. download._filenameSuggested(suggestedFilename);
  100. }
  101. _downloadFinished(uuid, error) {
  102. const download = this._downloads.get(uuid);
  103. if (!download)
  104. return;
  105. download.artifact.reportFinished(error ? new Error(error) : void 0);
  106. this._downloads.delete(uuid);
  107. }
  108. _videoStarted(context, videoId, path, pageOrError) {
  109. const artifact = new import_artifact.Artifact(context, path);
  110. this._idToVideo.set(videoId, { context, artifact });
  111. pageOrError.then((page) => {
  112. if (page instanceof import_page.Page) {
  113. page.video = artifact;
  114. page.emitOnContext(import_browserContext.BrowserContext.Events.VideoStarted, artifact);
  115. page.emit(import_page.Page.Events.Video, artifact);
  116. }
  117. });
  118. }
  119. _takeVideo(videoId) {
  120. const video = this._idToVideo.get(videoId);
  121. this._idToVideo.delete(videoId);
  122. return video?.artifact;
  123. }
  124. _didClose() {
  125. for (const context of this.contexts())
  126. context._browserClosed();
  127. if (this._defaultContext)
  128. this._defaultContext._browserClosed();
  129. this.emit(Browser.Events.Disconnected);
  130. this.instrumentation.onBrowserClose(this);
  131. }
  132. async close(options) {
  133. if (!this._startedClosing) {
  134. if (options.reason)
  135. this._closeReason = options.reason;
  136. this._startedClosing = true;
  137. await this.options.browserProcess.close();
  138. }
  139. if (this.isConnected())
  140. await new Promise((x) => this.once(Browser.Events.Disconnected, x));
  141. }
  142. async killForTests() {
  143. await this.options.browserProcess.kill();
  144. }
  145. }
  146. // Annotate the CommonJS export names for ESM import in node:
  147. 0 && (module.exports = {
  148. Browser
  149. });