connection.js 12 KB

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