processHost.js 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. "use strict";
  2. var __create = Object.create;
  3. var __defProp = Object.defineProperty;
  4. var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
  5. var __getOwnPropNames = Object.getOwnPropertyNames;
  6. var __getProtoOf = Object.getPrototypeOf;
  7. var __hasOwnProp = Object.prototype.hasOwnProperty;
  8. var __export = (target, all) => {
  9. for (var name in all)
  10. __defProp(target, name, { get: all[name], enumerable: true });
  11. };
  12. var __copyProps = (to, from, except, desc) => {
  13. if (from && typeof from === "object" || typeof from === "function") {
  14. for (let key of __getOwnPropNames(from))
  15. if (!__hasOwnProp.call(to, key) && key !== except)
  16. __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
  17. }
  18. return to;
  19. };
  20. var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
  21. // If the importer is in node compatibility mode or this is not an ESM
  22. // file that has been converted to a CommonJS file using a Babel-
  23. // compatible transform (i.e. "__esModule" has not been set), then set
  24. // "default" to the CommonJS "module.exports" for node compatibility.
  25. isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
  26. mod
  27. ));
  28. var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
  29. var processHost_exports = {};
  30. __export(processHost_exports, {
  31. ProcessHost: () => ProcessHost
  32. });
  33. module.exports = __toCommonJS(processHost_exports);
  34. var import_child_process = __toESM(require("child_process"));
  35. var import_events = require("events");
  36. var import_utils = require("playwright-core/lib/utils");
  37. var import_utilsBundle = require("playwright-core/lib/utilsBundle");
  38. class ProcessHost extends import_events.EventEmitter {
  39. constructor(runnerScript, processName, env) {
  40. super();
  41. this._didSendStop = false;
  42. this._processDidExit = false;
  43. this._didExitAndRanOnExit = false;
  44. this._lastMessageId = 0;
  45. this._callbacks = /* @__PURE__ */ new Map();
  46. this._producedEnv = {};
  47. this._runnerScript = runnerScript;
  48. this._processName = processName;
  49. this._extraEnv = env;
  50. }
  51. async startRunner(runnerParams, options = {}) {
  52. (0, import_utils.assert)(!this.process, "Internal error: starting the same process twice");
  53. this.process = import_child_process.default.fork(require.resolve("../common/process"), {
  54. detached: false,
  55. env: {
  56. ...process.env,
  57. ...this._extraEnv
  58. },
  59. stdio: [
  60. "ignore",
  61. options.onStdOut ? "pipe" : "inherit",
  62. options.onStdErr && !process.env.PW_RUNNER_DEBUG ? "pipe" : "inherit",
  63. "ipc"
  64. ]
  65. });
  66. this.process.on("exit", async (code, signal) => {
  67. this._processDidExit = true;
  68. await this.onExit();
  69. this._didExitAndRanOnExit = true;
  70. this.emit("exit", { unexpectedly: !this._didSendStop, code, signal });
  71. });
  72. this.process.on("error", (e) => {
  73. });
  74. this.process.on("message", (message) => {
  75. if (import_utilsBundle.debug.enabled("pw:test:protocol"))
  76. (0, import_utilsBundle.debug)("pw:test:protocol")("\u25C0 RECV " + JSON.stringify(message));
  77. if (message.method === "__env_produced__") {
  78. const producedEnv = message.params;
  79. this._producedEnv = Object.fromEntries(producedEnv.map((e) => [e[0], e[1] ?? void 0]));
  80. } else if (message.method === "__dispatch__") {
  81. const { id, error: error2, method, params, result } = message.params;
  82. if (id && this._callbacks.has(id)) {
  83. const { resolve, reject } = this._callbacks.get(id);
  84. this._callbacks.delete(id);
  85. if (error2) {
  86. const errorObject = new Error(error2.message);
  87. errorObject.stack = error2.stack;
  88. reject(errorObject);
  89. } else {
  90. resolve(result);
  91. }
  92. } else {
  93. this.emit(method, params);
  94. }
  95. } else {
  96. this.emit(message.method, message.params);
  97. }
  98. });
  99. if (options.onStdOut)
  100. this.process.stdout?.on("data", options.onStdOut);
  101. if (options.onStdErr)
  102. this.process.stderr?.on("data", options.onStdErr);
  103. const error = await new Promise((resolve) => {
  104. this.process.once("exit", (code, signal) => resolve({ unexpectedly: true, code, signal }));
  105. this.once("ready", () => resolve(void 0));
  106. });
  107. if (error)
  108. return error;
  109. const processParams = {
  110. processName: this._processName,
  111. timeOrigin: (0, import_utils.timeOrigin)()
  112. };
  113. this.send({
  114. method: "__init__",
  115. params: {
  116. processParams,
  117. runnerScript: this._runnerScript,
  118. runnerParams
  119. }
  120. });
  121. }
  122. sendMessage(message) {
  123. const id = ++this._lastMessageId;
  124. this.send({
  125. method: "__dispatch__",
  126. params: { id, ...message }
  127. });
  128. return new Promise((resolve, reject) => {
  129. this._callbacks.set(id, { resolve, reject });
  130. });
  131. }
  132. sendMessageNoReply(message) {
  133. this.sendMessage(message).catch(() => {
  134. });
  135. }
  136. async onExit() {
  137. }
  138. async stop() {
  139. if (!this._processDidExit && !this._didSendStop) {
  140. this.send({ method: "__stop__" });
  141. this._didSendStop = true;
  142. }
  143. if (!this._didExitAndRanOnExit)
  144. await new Promise((f) => this.once("exit", f));
  145. }
  146. didSendStop() {
  147. return this._didSendStop;
  148. }
  149. producedEnv() {
  150. return this._producedEnv;
  151. }
  152. send(message) {
  153. if (import_utilsBundle.debug.enabled("pw:test:protocol"))
  154. (0, import_utilsBundle.debug)("pw:test:protocol")("SEND \u25BA " + JSON.stringify(message));
  155. this.process?.send(message);
  156. }
  157. }
  158. // Annotate the CommonJS export names for ESM import in node:
  159. 0 && (module.exports = {
  160. ProcessHost
  161. });