connection.js 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318
  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 connection_exports = {};
  20. __export(connection_exports, {
  21. Connection: () => Connection
  22. });
  23. module.exports = __toCommonJS(connection_exports);
  24. var import_eventEmitter = require("./eventEmitter");
  25. var import_android = require("./android");
  26. var import_artifact = require("./artifact");
  27. var import_browser = require("./browser");
  28. var import_browserContext = require("./browserContext");
  29. var import_browserType = require("./browserType");
  30. var import_cdpSession = require("./cdpSession");
  31. var import_channelOwner = require("./channelOwner");
  32. var import_clientInstrumentation = require("./clientInstrumentation");
  33. var import_dialog = require("./dialog");
  34. var import_electron = require("./electron");
  35. var import_elementHandle = require("./elementHandle");
  36. var import_errors = require("./errors");
  37. var import_fetch = require("./fetch");
  38. var import_frame = require("./frame");
  39. var import_jsHandle = require("./jsHandle");
  40. var import_jsonPipe = require("./jsonPipe");
  41. var import_localUtils = require("./localUtils");
  42. var import_network = require("./network");
  43. var import_page = require("./page");
  44. var import_playwright = require("./playwright");
  45. var import_stream = require("./stream");
  46. var import_tracing = require("./tracing");
  47. var import_worker = require("./worker");
  48. var import_writableStream = require("./writableStream");
  49. var import_validator = require("../protocol/validator");
  50. var import_stackTrace = require("../utils/isomorphic/stackTrace");
  51. var import_pageAgent = require("./pageAgent");
  52. class Root extends import_channelOwner.ChannelOwner {
  53. constructor(connection) {
  54. super(connection, "Root", "", {});
  55. }
  56. async initialize() {
  57. return import_playwright.Playwright.from((await this._channel.initialize({
  58. sdkLanguage: "javascript"
  59. })).playwright);
  60. }
  61. }
  62. class DummyChannelOwner extends import_channelOwner.ChannelOwner {
  63. }
  64. class Connection extends import_eventEmitter.EventEmitter {
  65. constructor(platform, localUtils, instrumentation, headers = []) {
  66. super(platform);
  67. this._objects = /* @__PURE__ */ new Map();
  68. this.onmessage = (message) => {
  69. };
  70. this._lastId = 0;
  71. this._callbacks = /* @__PURE__ */ new Map();
  72. this._isRemote = false;
  73. this._rawBuffers = false;
  74. this._tracingCount = 0;
  75. this._instrumentation = instrumentation || (0, import_clientInstrumentation.createInstrumentation)();
  76. this._localUtils = localUtils;
  77. this._rootObject = new Root(this);
  78. this.headers = headers;
  79. }
  80. markAsRemote() {
  81. this._isRemote = true;
  82. }
  83. isRemote() {
  84. return this._isRemote;
  85. }
  86. useRawBuffers() {
  87. this._rawBuffers = true;
  88. }
  89. rawBuffers() {
  90. return this._rawBuffers;
  91. }
  92. localUtils() {
  93. return this._localUtils;
  94. }
  95. async initializePlaywright() {
  96. return await this._rootObject.initialize();
  97. }
  98. getObjectWithKnownName(guid) {
  99. return this._objects.get(guid);
  100. }
  101. setIsTracing(isTracing) {
  102. if (isTracing)
  103. this._tracingCount++;
  104. else
  105. this._tracingCount--;
  106. }
  107. async sendMessageToServer(object, method, params, options) {
  108. if (this._closedError)
  109. throw this._closedError;
  110. if (object._wasCollected)
  111. throw new Error("The object has been collected to prevent unbounded heap growth.");
  112. const guid = object._guid;
  113. const type = object._type;
  114. const id = ++this._lastId;
  115. const message = { id, guid, method, params };
  116. if (this._platform.isLogEnabled("channel")) {
  117. this._platform.log("channel", "SEND> " + JSON.stringify(message));
  118. }
  119. const location = options.frames?.[0] ? { file: options.frames[0].file, line: options.frames[0].line, column: options.frames[0].column } : void 0;
  120. const metadata = { title: options.title, location, internal: options.internal, stepId: options.stepId };
  121. if (this._tracingCount && options.frames && type !== "LocalUtils")
  122. this._localUtils?.addStackToTracingNoReply({ callData: { stack: options.frames ?? [], id } }).catch(() => {
  123. });
  124. this._platform.zones.empty.run(() => this.onmessage({ ...message, metadata }));
  125. return await new Promise((resolve, reject) => this._callbacks.set(id, { resolve, reject, title: options.title, type, method }));
  126. }
  127. _validatorFromWireContext() {
  128. return {
  129. tChannelImpl: this._tChannelImplFromWire.bind(this),
  130. binary: this._rawBuffers ? "buffer" : "fromBase64",
  131. isUnderTest: () => this._platform.isUnderTest()
  132. };
  133. }
  134. dispatch(message) {
  135. if (this._closedError)
  136. return;
  137. const { id, guid, method, params, result, error, log } = message;
  138. if (id) {
  139. if (this._platform.isLogEnabled("channel"))
  140. this._platform.log("channel", "<RECV " + JSON.stringify(message));
  141. const callback = this._callbacks.get(id);
  142. if (!callback)
  143. throw new Error(`Cannot find command to respond: ${id}`);
  144. this._callbacks.delete(id);
  145. if (error && !result) {
  146. const parsedError = (0, import_errors.parseError)(error);
  147. (0, import_stackTrace.rewriteErrorMessage)(parsedError, parsedError.message + formatCallLog(this._platform, log));
  148. callback.reject(parsedError);
  149. } else {
  150. const validator2 = (0, import_validator.findValidator)(callback.type, callback.method, "Result");
  151. callback.resolve(validator2(result, "", this._validatorFromWireContext()));
  152. }
  153. return;
  154. }
  155. if (this._platform.isLogEnabled("channel"))
  156. this._platform.log("channel", "<EVENT " + JSON.stringify(message));
  157. if (method === "__create__") {
  158. this._createRemoteObject(guid, params.type, params.guid, params.initializer);
  159. return;
  160. }
  161. const object = this._objects.get(guid);
  162. if (!object)
  163. throw new Error(`Cannot find object to "${method}": ${guid}`);
  164. if (method === "__adopt__") {
  165. const child = this._objects.get(params.guid);
  166. if (!child)
  167. throw new Error(`Unknown new child: ${params.guid}`);
  168. object._adopt(child);
  169. return;
  170. }
  171. if (method === "__dispose__") {
  172. object._dispose(params.reason);
  173. return;
  174. }
  175. const validator = (0, import_validator.findValidator)(object._type, method, "Event");
  176. object._channel.emit(method, validator(params, "", this._validatorFromWireContext()));
  177. }
  178. close(cause) {
  179. if (this._closedError)
  180. return;
  181. this._closedError = new import_errors.TargetClosedError(cause);
  182. for (const callback of this._callbacks.values())
  183. callback.reject(this._closedError);
  184. this._callbacks.clear();
  185. this.emit("close");
  186. }
  187. _tChannelImplFromWire(names, arg, path, context) {
  188. if (arg && typeof arg === "object" && typeof arg.guid === "string") {
  189. const object = this._objects.get(arg.guid);
  190. if (!object)
  191. throw new Error(`Object with guid ${arg.guid} was not bound in the connection`);
  192. if (names !== "*" && !names.includes(object._type))
  193. throw new import_validator.ValidationError(`${path}: expected channel ${names.toString()}`);
  194. return object._channel;
  195. }
  196. throw new import_validator.ValidationError(`${path}: expected channel ${names.toString()}`);
  197. }
  198. _createRemoteObject(parentGuid, type, guid, initializer) {
  199. const parent = this._objects.get(parentGuid);
  200. if (!parent)
  201. throw new Error(`Cannot find parent object ${parentGuid} to create ${guid}`);
  202. let result;
  203. const validator = (0, import_validator.findValidator)(type, "", "Initializer");
  204. initializer = validator(initializer, "", this._validatorFromWireContext());
  205. switch (type) {
  206. case "Android":
  207. result = new import_android.Android(parent, type, guid, initializer);
  208. break;
  209. case "AndroidSocket":
  210. result = new import_android.AndroidSocket(parent, type, guid, initializer);
  211. break;
  212. case "AndroidDevice":
  213. result = new import_android.AndroidDevice(parent, type, guid, initializer);
  214. break;
  215. case "APIRequestContext":
  216. result = new import_fetch.APIRequestContext(parent, type, guid, initializer);
  217. break;
  218. case "Artifact":
  219. result = new import_artifact.Artifact(parent, type, guid, initializer);
  220. break;
  221. case "BindingCall":
  222. result = new import_page.BindingCall(parent, type, guid, initializer);
  223. break;
  224. case "Browser":
  225. result = new import_browser.Browser(parent, type, guid, initializer);
  226. break;
  227. case "BrowserContext":
  228. result = new import_browserContext.BrowserContext(parent, type, guid, initializer);
  229. break;
  230. case "BrowserType":
  231. result = new import_browserType.BrowserType(parent, type, guid, initializer);
  232. break;
  233. case "CDPSession":
  234. result = new import_cdpSession.CDPSession(parent, type, guid, initializer);
  235. break;
  236. case "Dialog":
  237. result = new import_dialog.Dialog(parent, type, guid, initializer);
  238. break;
  239. case "Electron":
  240. result = new import_electron.Electron(parent, type, guid, initializer);
  241. break;
  242. case "ElectronApplication":
  243. result = new import_electron.ElectronApplication(parent, type, guid, initializer);
  244. break;
  245. case "ElementHandle":
  246. result = new import_elementHandle.ElementHandle(parent, type, guid, initializer);
  247. break;
  248. case "Frame":
  249. result = new import_frame.Frame(parent, type, guid, initializer);
  250. break;
  251. case "JSHandle":
  252. result = new import_jsHandle.JSHandle(parent, type, guid, initializer);
  253. break;
  254. case "JsonPipe":
  255. result = new import_jsonPipe.JsonPipe(parent, type, guid, initializer);
  256. break;
  257. case "LocalUtils":
  258. result = new import_localUtils.LocalUtils(parent, type, guid, initializer);
  259. if (!this._localUtils)
  260. this._localUtils = result;
  261. break;
  262. case "Page":
  263. result = new import_page.Page(parent, type, guid, initializer);
  264. break;
  265. case "PageAgent":
  266. result = new import_pageAgent.PageAgent(parent, type, guid, initializer);
  267. break;
  268. case "Playwright":
  269. result = new import_playwright.Playwright(parent, type, guid, initializer);
  270. break;
  271. case "Request":
  272. result = new import_network.Request(parent, type, guid, initializer);
  273. break;
  274. case "Response":
  275. result = new import_network.Response(parent, type, guid, initializer);
  276. break;
  277. case "Route":
  278. result = new import_network.Route(parent, type, guid, initializer);
  279. break;
  280. case "Stream":
  281. result = new import_stream.Stream(parent, type, guid, initializer);
  282. break;
  283. case "SocksSupport":
  284. result = new DummyChannelOwner(parent, type, guid, initializer);
  285. break;
  286. case "Tracing":
  287. result = new import_tracing.Tracing(parent, type, guid, initializer);
  288. break;
  289. case "WebSocket":
  290. result = new import_network.WebSocket(parent, type, guid, initializer);
  291. break;
  292. case "WebSocketRoute":
  293. result = new import_network.WebSocketRoute(parent, type, guid, initializer);
  294. break;
  295. case "Worker":
  296. result = new import_worker.Worker(parent, type, guid, initializer);
  297. break;
  298. case "WritableStream":
  299. result = new import_writableStream.WritableStream(parent, type, guid, initializer);
  300. break;
  301. default:
  302. throw new Error("Missing type " + type);
  303. }
  304. return result;
  305. }
  306. }
  307. function formatCallLog(platform, log) {
  308. if (!log || !log.some((l) => !!l))
  309. return "";
  310. return `
  311. Call log:
  312. ${platform.colors.dim(log.join("\n"))}
  313. `;
  314. }
  315. // Annotate the CommonJS export names for ESM import in node:
  316. 0 && (module.exports = {
  317. Connection
  318. });