browserDispatcher.js 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", {
  3. value: true
  4. });
  5. exports.ConnectedBrowserDispatcher = exports.BrowserDispatcher = void 0;
  6. var _browser = require("../browser");
  7. var _browserContextDispatcher = require("./browserContextDispatcher");
  8. var _cdpSessionDispatcher = require("./cdpSessionDispatcher");
  9. var _dispatcher = require("./dispatcher");
  10. var _browserContext = require("../browserContext");
  11. var _selectors = require("../selectors");
  12. var _artifactDispatcher = require("./artifactDispatcher");
  13. /**
  14. * Copyright (c) Microsoft Corporation.
  15. *
  16. * Licensed under the Apache License, Version 2.0 (the 'License");
  17. * you may not use this file except in compliance with the License.
  18. * You may obtain a copy of the License at
  19. *
  20. * http://www.apache.org/licenses/LICENSE-2.0
  21. *
  22. * Unless required by applicable law or agreed to in writing, software
  23. * distributed under the License is distributed on an "AS IS" BASIS,
  24. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  25. * See the License for the specific language governing permissions and
  26. * limitations under the License.
  27. */
  28. class BrowserDispatcher extends _dispatcher.Dispatcher {
  29. constructor(scope, browser) {
  30. super(scope, browser, 'Browser', {
  31. version: browser.version(),
  32. name: browser.options.name
  33. });
  34. this._type_Browser = true;
  35. this.addObjectListener(_browser.Browser.Events.Disconnected, () => this._didClose());
  36. }
  37. _didClose() {
  38. this._dispatchEvent('close');
  39. this._dispose();
  40. }
  41. async newContext(params, metadata) {
  42. const context = await this._object.newContext(metadata, params);
  43. return {
  44. context: new _browserContextDispatcher.BrowserContextDispatcher(this, context)
  45. };
  46. }
  47. async newContextForReuse(params, metadata) {
  48. return await newContextForReuse(this._object, this, params, null, metadata);
  49. }
  50. async stopPendingOperations(params, metadata) {
  51. await this._object.stopPendingOperations(params.reason);
  52. }
  53. async close(params, metadata) {
  54. metadata.potentiallyClosesScope = true;
  55. await this._object.close(params);
  56. }
  57. async killForTests(_, metadata) {
  58. metadata.potentiallyClosesScope = true;
  59. await this._object.killForTests();
  60. }
  61. async defaultUserAgentForTest() {
  62. return {
  63. userAgent: this._object.userAgent()
  64. };
  65. }
  66. async newBrowserCDPSession() {
  67. if (!this._object.options.isChromium) throw new Error(`CDP session is only available in Chromium`);
  68. const crBrowser = this._object;
  69. return {
  70. session: new _cdpSessionDispatcher.CDPSessionDispatcher(this, await crBrowser.newBrowserCDPSession())
  71. };
  72. }
  73. async startTracing(params) {
  74. if (!this._object.options.isChromium) throw new Error(`Tracing is only available in Chromium`);
  75. const crBrowser = this._object;
  76. await crBrowser.startTracing(params.page ? params.page._object : undefined, params);
  77. }
  78. async stopTracing() {
  79. if (!this._object.options.isChromium) throw new Error(`Tracing is only available in Chromium`);
  80. const crBrowser = this._object;
  81. return {
  82. artifact: _artifactDispatcher.ArtifactDispatcher.from(this, await crBrowser.stopTracing())
  83. };
  84. }
  85. }
  86. // This class implements multiplexing browser dispatchers over a single Browser instance.
  87. exports.BrowserDispatcher = BrowserDispatcher;
  88. class ConnectedBrowserDispatcher extends _dispatcher.Dispatcher {
  89. constructor(scope, browser) {
  90. super(scope, browser, 'Browser', {
  91. version: browser.version(),
  92. name: browser.options.name
  93. });
  94. // When we have a remotely-connected browser, each client gets a fresh Selector instance,
  95. // so that two clients do not interfere between each other.
  96. this._type_Browser = true;
  97. this._contexts = new Set();
  98. this.selectors = void 0;
  99. this.selectors = new _selectors.Selectors();
  100. }
  101. async newContext(params, metadata) {
  102. if (params.recordVideo) params.recordVideo.dir = this._object.options.artifactsDir;
  103. const context = await this._object.newContext(metadata, params);
  104. this._contexts.add(context);
  105. context.setSelectors(this.selectors);
  106. context.on(_browserContext.BrowserContext.Events.Close, () => this._contexts.delete(context));
  107. return {
  108. context: new _browserContextDispatcher.BrowserContextDispatcher(this, context)
  109. };
  110. }
  111. async newContextForReuse(params, metadata) {
  112. return await newContextForReuse(this._object, this, params, this.selectors, metadata);
  113. }
  114. async stopPendingOperations(params, metadata) {
  115. await this._object.stopPendingOperations(params.reason);
  116. }
  117. async close() {
  118. // Client should not send us Browser.close.
  119. }
  120. async killForTests() {
  121. // Client should not send us Browser.killForTests.
  122. }
  123. async defaultUserAgentForTest() {
  124. throw new Error('Client should not send us Browser.defaultUserAgentForTest');
  125. }
  126. async newBrowserCDPSession() {
  127. if (!this._object.options.isChromium) throw new Error(`CDP session is only available in Chromium`);
  128. const crBrowser = this._object;
  129. return {
  130. session: new _cdpSessionDispatcher.CDPSessionDispatcher(this, await crBrowser.newBrowserCDPSession())
  131. };
  132. }
  133. async startTracing(params) {
  134. if (!this._object.options.isChromium) throw new Error(`Tracing is only available in Chromium`);
  135. const crBrowser = this._object;
  136. await crBrowser.startTracing(params.page ? params.page._object : undefined, params);
  137. }
  138. async stopTracing() {
  139. if (!this._object.options.isChromium) throw new Error(`Tracing is only available in Chromium`);
  140. const crBrowser = this._object;
  141. return {
  142. artifact: _artifactDispatcher.ArtifactDispatcher.from(this, await crBrowser.stopTracing())
  143. };
  144. }
  145. async cleanupContexts() {
  146. await Promise.all(Array.from(this._contexts).map(context => context.close({
  147. reason: 'Global context cleanup (connection terminated)'
  148. })));
  149. }
  150. }
  151. exports.ConnectedBrowserDispatcher = ConnectedBrowserDispatcher;
  152. async function newContextForReuse(browser, scope, params, selectors, metadata) {
  153. const {
  154. context,
  155. needsReset
  156. } = await browser.newContextForReuse(params, metadata);
  157. if (needsReset) {
  158. const oldContextDispatcher = (0, _dispatcher.existingDispatcher)(context);
  159. if (oldContextDispatcher) oldContextDispatcher._dispose();
  160. await context.resetForReuse(metadata, params);
  161. }
  162. if (selectors) context.setSelectors(selectors);
  163. const contextDispatcher = new _browserContextDispatcher.BrowserContextDispatcher(scope, context);
  164. return {
  165. context: contextDispatcher
  166. };
  167. }