page.js 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745
  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 page_exports = {};
  20. __export(page_exports, {
  21. BindingCall: () => BindingCall,
  22. Page: () => Page
  23. });
  24. module.exports = __toCommonJS(page_exports);
  25. var import_artifact = require("./artifact");
  26. var import_channelOwner = require("./channelOwner");
  27. var import_clientHelper = require("./clientHelper");
  28. var import_coverage = require("./coverage");
  29. var import_download = require("./download");
  30. var import_elementHandle = require("./elementHandle");
  31. var import_errors = require("./errors");
  32. var import_events = require("./events");
  33. var import_fileChooser = require("./fileChooser");
  34. var import_frame = require("./frame");
  35. var import_harRouter = require("./harRouter");
  36. var import_input = require("./input");
  37. var import_jsHandle = require("./jsHandle");
  38. var import_network = require("./network");
  39. var import_video = require("./video");
  40. var import_waiter = require("./waiter");
  41. var import_worker = require("./worker");
  42. var import_timeoutSettings = require("./timeoutSettings");
  43. var import_assert = require("../utils/isomorphic/assert");
  44. var import_fileUtils = require("./fileUtils");
  45. var import_headers = require("../utils/isomorphic/headers");
  46. var import_stringUtils = require("../utils/isomorphic/stringUtils");
  47. var import_urlMatch = require("../utils/isomorphic/urlMatch");
  48. var import_manualPromise = require("../utils/isomorphic/manualPromise");
  49. var import_rtti = require("../utils/isomorphic/rtti");
  50. var import_consoleMessage = require("./consoleMessage");
  51. var import_pageAgent = require("./pageAgent");
  52. class Page extends import_channelOwner.ChannelOwner {
  53. constructor(parent, type, guid, initializer) {
  54. super(parent, type, guid, initializer);
  55. this._frames = /* @__PURE__ */ new Set();
  56. this._workers = /* @__PURE__ */ new Set();
  57. this._closed = false;
  58. this._closedOrCrashedScope = new import_manualPromise.LongStandingScope();
  59. this._routes = [];
  60. this._webSocketRoutes = [];
  61. this._bindings = /* @__PURE__ */ new Map();
  62. this._video = null;
  63. this._closeWasCalled = false;
  64. this._harRouters = [];
  65. this._locatorHandlers = /* @__PURE__ */ new Map();
  66. this._instrumentation.onPage(this);
  67. this._browserContext = parent;
  68. this._timeoutSettings = new import_timeoutSettings.TimeoutSettings(this._platform, this._browserContext._timeoutSettings);
  69. this.keyboard = new import_input.Keyboard(this);
  70. this.mouse = new import_input.Mouse(this);
  71. this.request = this._browserContext.request;
  72. this.touchscreen = new import_input.Touchscreen(this);
  73. this.clock = this._browserContext.clock;
  74. this._mainFrame = import_frame.Frame.from(initializer.mainFrame);
  75. this._mainFrame._page = this;
  76. this._frames.add(this._mainFrame);
  77. this._viewportSize = initializer.viewportSize;
  78. this._closed = initializer.isClosed;
  79. this._opener = Page.fromNullable(initializer.opener);
  80. this._channel.on("bindingCall", ({ binding }) => this._onBinding(BindingCall.from(binding)));
  81. this._channel.on("close", () => this._onClose());
  82. this._channel.on("crash", () => this._onCrash());
  83. this._channel.on("download", ({ url, suggestedFilename, artifact }) => {
  84. const artifactObject = import_artifact.Artifact.from(artifact);
  85. this.emit(import_events.Events.Page.Download, new import_download.Download(this, url, suggestedFilename, artifactObject));
  86. });
  87. this._channel.on("fileChooser", ({ element, isMultiple }) => this.emit(import_events.Events.Page.FileChooser, new import_fileChooser.FileChooser(this, import_elementHandle.ElementHandle.from(element), isMultiple)));
  88. this._channel.on("frameAttached", ({ frame }) => this._onFrameAttached(import_frame.Frame.from(frame)));
  89. this._channel.on("frameDetached", ({ frame }) => this._onFrameDetached(import_frame.Frame.from(frame)));
  90. this._channel.on("locatorHandlerTriggered", ({ uid }) => this._onLocatorHandlerTriggered(uid));
  91. this._channel.on("route", ({ route }) => this._onRoute(import_network.Route.from(route)));
  92. this._channel.on("webSocketRoute", ({ webSocketRoute }) => this._onWebSocketRoute(import_network.WebSocketRoute.from(webSocketRoute)));
  93. this._channel.on("video", ({ artifact }) => {
  94. const artifactObject = import_artifact.Artifact.from(artifact);
  95. this._forceVideo()._artifactReady(artifactObject);
  96. });
  97. this._channel.on("viewportSizeChanged", ({ viewportSize }) => this._viewportSize = viewportSize);
  98. this._channel.on("webSocket", ({ webSocket }) => this.emit(import_events.Events.Page.WebSocket, import_network.WebSocket.from(webSocket)));
  99. this._channel.on("worker", ({ worker }) => this._onWorker(import_worker.Worker.from(worker)));
  100. this.coverage = new import_coverage.Coverage(this._channel);
  101. this.once(import_events.Events.Page.Close, () => this._closedOrCrashedScope.close(this._closeErrorWithReason()));
  102. this.once(import_events.Events.Page.Crash, () => this._closedOrCrashedScope.close(new import_errors.TargetClosedError()));
  103. this._setEventToSubscriptionMapping(/* @__PURE__ */ new Map([
  104. [import_events.Events.Page.Console, "console"],
  105. [import_events.Events.Page.Dialog, "dialog"],
  106. [import_events.Events.Page.Request, "request"],
  107. [import_events.Events.Page.Response, "response"],
  108. [import_events.Events.Page.RequestFinished, "requestFinished"],
  109. [import_events.Events.Page.RequestFailed, "requestFailed"],
  110. [import_events.Events.Page.FileChooser, "fileChooser"]
  111. ]));
  112. }
  113. static from(page) {
  114. return page._object;
  115. }
  116. static fromNullable(page) {
  117. return page ? Page.from(page) : null;
  118. }
  119. _onFrameAttached(frame) {
  120. frame._page = this;
  121. this._frames.add(frame);
  122. if (frame._parentFrame)
  123. frame._parentFrame._childFrames.add(frame);
  124. this.emit(import_events.Events.Page.FrameAttached, frame);
  125. }
  126. _onFrameDetached(frame) {
  127. this._frames.delete(frame);
  128. frame._detached = true;
  129. if (frame._parentFrame)
  130. frame._parentFrame._childFrames.delete(frame);
  131. this.emit(import_events.Events.Page.FrameDetached, frame);
  132. }
  133. async _onRoute(route) {
  134. route._context = this.context();
  135. const routeHandlers = this._routes.slice();
  136. for (const routeHandler of routeHandlers) {
  137. if (this._closeWasCalled || this._browserContext._closingStatus !== "none")
  138. return;
  139. if (!routeHandler.matches(route.request().url()))
  140. continue;
  141. const index = this._routes.indexOf(routeHandler);
  142. if (index === -1)
  143. continue;
  144. if (routeHandler.willExpire())
  145. this._routes.splice(index, 1);
  146. const handled = await routeHandler.handle(route);
  147. if (!this._routes.length)
  148. this._updateInterceptionPatterns({ internal: true }).catch(() => {
  149. });
  150. if (handled)
  151. return;
  152. }
  153. await this._browserContext._onRoute(route);
  154. }
  155. async _onWebSocketRoute(webSocketRoute) {
  156. const routeHandler = this._webSocketRoutes.find((route) => route.matches(webSocketRoute.url()));
  157. if (routeHandler)
  158. await routeHandler.handle(webSocketRoute);
  159. else
  160. await this._browserContext._onWebSocketRoute(webSocketRoute);
  161. }
  162. async _onBinding(bindingCall) {
  163. const func = this._bindings.get(bindingCall._initializer.name);
  164. if (func) {
  165. await bindingCall.call(func);
  166. return;
  167. }
  168. await this._browserContext._onBinding(bindingCall);
  169. }
  170. _onWorker(worker) {
  171. this._workers.add(worker);
  172. worker._page = this;
  173. this.emit(import_events.Events.Page.Worker, worker);
  174. }
  175. _onClose() {
  176. this._closed = true;
  177. this._browserContext._pages.delete(this);
  178. this._disposeHarRouters();
  179. this.emit(import_events.Events.Page.Close, this);
  180. }
  181. _onCrash() {
  182. this.emit(import_events.Events.Page.Crash, this);
  183. }
  184. context() {
  185. return this._browserContext;
  186. }
  187. async opener() {
  188. if (!this._opener || this._opener.isClosed())
  189. return null;
  190. return this._opener;
  191. }
  192. mainFrame() {
  193. return this._mainFrame;
  194. }
  195. frame(frameSelector) {
  196. const name = (0, import_rtti.isString)(frameSelector) ? frameSelector : frameSelector.name;
  197. const url = (0, import_rtti.isObject)(frameSelector) ? frameSelector.url : void 0;
  198. (0, import_assert.assert)(name || url, "Either name or url matcher should be specified");
  199. return this.frames().find((f) => {
  200. if (name)
  201. return f.name() === name;
  202. return (0, import_urlMatch.urlMatches)(this._browserContext._options.baseURL, f.url(), url);
  203. }) || null;
  204. }
  205. frames() {
  206. return [...this._frames];
  207. }
  208. setDefaultNavigationTimeout(timeout) {
  209. this._timeoutSettings.setDefaultNavigationTimeout(timeout);
  210. }
  211. setDefaultTimeout(timeout) {
  212. this._timeoutSettings.setDefaultTimeout(timeout);
  213. }
  214. _forceVideo() {
  215. if (!this._video)
  216. this._video = new import_video.Video(this, this._connection);
  217. return this._video;
  218. }
  219. video() {
  220. if (!this._browserContext._options.recordVideo)
  221. return null;
  222. return this._forceVideo();
  223. }
  224. async $(selector, options) {
  225. return await this._mainFrame.$(selector, options);
  226. }
  227. async waitForSelector(selector, options) {
  228. return await this._mainFrame.waitForSelector(selector, options);
  229. }
  230. async dispatchEvent(selector, type, eventInit, options) {
  231. return await this._mainFrame.dispatchEvent(selector, type, eventInit, options);
  232. }
  233. async evaluateHandle(pageFunction, arg) {
  234. (0, import_jsHandle.assertMaxArguments)(arguments.length, 2);
  235. return await this._mainFrame.evaluateHandle(pageFunction, arg);
  236. }
  237. async $eval(selector, pageFunction, arg) {
  238. (0, import_jsHandle.assertMaxArguments)(arguments.length, 3);
  239. return await this._mainFrame.$eval(selector, pageFunction, arg);
  240. }
  241. async $$eval(selector, pageFunction, arg) {
  242. (0, import_jsHandle.assertMaxArguments)(arguments.length, 3);
  243. return await this._mainFrame.$$eval(selector, pageFunction, arg);
  244. }
  245. async $$(selector) {
  246. return await this._mainFrame.$$(selector);
  247. }
  248. async addScriptTag(options = {}) {
  249. return await this._mainFrame.addScriptTag(options);
  250. }
  251. async addStyleTag(options = {}) {
  252. return await this._mainFrame.addStyleTag(options);
  253. }
  254. async exposeFunction(name, callback) {
  255. await this._channel.exposeBinding({ name });
  256. const binding = (source, ...args) => callback(...args);
  257. this._bindings.set(name, binding);
  258. }
  259. async exposeBinding(name, callback, options = {}) {
  260. await this._channel.exposeBinding({ name, needsHandle: options.handle });
  261. this._bindings.set(name, callback);
  262. }
  263. async setExtraHTTPHeaders(headers) {
  264. (0, import_network.validateHeaders)(headers);
  265. await this._channel.setExtraHTTPHeaders({ headers: (0, import_headers.headersObjectToArray)(headers) });
  266. }
  267. url() {
  268. return this._mainFrame.url();
  269. }
  270. async content() {
  271. return await this._mainFrame.content();
  272. }
  273. async setContent(html, options) {
  274. return await this._mainFrame.setContent(html, options);
  275. }
  276. async goto(url, options) {
  277. return await this._mainFrame.goto(url, options);
  278. }
  279. async reload(options = {}) {
  280. const waitUntil = (0, import_frame.verifyLoadState)("waitUntil", options.waitUntil === void 0 ? "load" : options.waitUntil);
  281. return import_network.Response.fromNullable((await this._channel.reload({ ...options, waitUntil, timeout: this._timeoutSettings.navigationTimeout(options) })).response);
  282. }
  283. async addLocatorHandler(locator, handler, options = {}) {
  284. if (locator._frame !== this._mainFrame)
  285. throw new Error(`Locator must belong to the main frame of this page`);
  286. if (options.times === 0)
  287. return;
  288. const { uid } = await this._channel.registerLocatorHandler({ selector: locator._selector, noWaitAfter: options.noWaitAfter });
  289. this._locatorHandlers.set(uid, { locator, handler, times: options.times });
  290. }
  291. async _onLocatorHandlerTriggered(uid) {
  292. let remove = false;
  293. try {
  294. const handler = this._locatorHandlers.get(uid);
  295. if (handler && handler.times !== 0) {
  296. if (handler.times !== void 0)
  297. handler.times--;
  298. await handler.handler(handler.locator);
  299. }
  300. remove = handler?.times === 0;
  301. } finally {
  302. if (remove)
  303. this._locatorHandlers.delete(uid);
  304. this._channel.resolveLocatorHandlerNoReply({ uid, remove }).catch(() => {
  305. });
  306. }
  307. }
  308. async removeLocatorHandler(locator) {
  309. for (const [uid, data] of this._locatorHandlers) {
  310. if (data.locator._equals(locator)) {
  311. this._locatorHandlers.delete(uid);
  312. await this._channel.unregisterLocatorHandler({ uid }).catch(() => {
  313. });
  314. }
  315. }
  316. }
  317. async waitForLoadState(state, options) {
  318. return await this._mainFrame.waitForLoadState(state, options);
  319. }
  320. async waitForNavigation(options) {
  321. return await this._mainFrame.waitForNavigation(options);
  322. }
  323. async waitForURL(url, options) {
  324. return await this._mainFrame.waitForURL(url, options);
  325. }
  326. async waitForRequest(urlOrPredicate, options = {}) {
  327. const predicate = async (request) => {
  328. if ((0, import_rtti.isString)(urlOrPredicate) || (0, import_rtti.isRegExp)(urlOrPredicate))
  329. return (0, import_urlMatch.urlMatches)(this._browserContext._options.baseURL, request.url(), urlOrPredicate);
  330. return await urlOrPredicate(request);
  331. };
  332. const trimmedUrl = trimUrl(urlOrPredicate);
  333. const logLine = trimmedUrl ? `waiting for request ${trimmedUrl}` : void 0;
  334. return await this._waitForEvent(import_events.Events.Page.Request, { predicate, timeout: options.timeout }, logLine);
  335. }
  336. async waitForResponse(urlOrPredicate, options = {}) {
  337. const predicate = async (response) => {
  338. if ((0, import_rtti.isString)(urlOrPredicate) || (0, import_rtti.isRegExp)(urlOrPredicate))
  339. return (0, import_urlMatch.urlMatches)(this._browserContext._options.baseURL, response.url(), urlOrPredicate);
  340. return await urlOrPredicate(response);
  341. };
  342. const trimmedUrl = trimUrl(urlOrPredicate);
  343. const logLine = trimmedUrl ? `waiting for response ${trimmedUrl}` : void 0;
  344. return await this._waitForEvent(import_events.Events.Page.Response, { predicate, timeout: options.timeout }, logLine);
  345. }
  346. async waitForEvent(event, optionsOrPredicate = {}) {
  347. return await this._waitForEvent(event, optionsOrPredicate, `waiting for event "${event}"`);
  348. }
  349. _closeErrorWithReason() {
  350. return new import_errors.TargetClosedError(this._closeReason || this._browserContext._effectiveCloseReason());
  351. }
  352. async _waitForEvent(event, optionsOrPredicate, logLine) {
  353. return await this._wrapApiCall(async () => {
  354. const timeout = this._timeoutSettings.timeout(typeof optionsOrPredicate === "function" ? {} : optionsOrPredicate);
  355. const predicate = typeof optionsOrPredicate === "function" ? optionsOrPredicate : optionsOrPredicate.predicate;
  356. const waiter = import_waiter.Waiter.createForEvent(this, event);
  357. if (logLine)
  358. waiter.log(logLine);
  359. waiter.rejectOnTimeout(timeout, `Timeout ${timeout}ms exceeded while waiting for event "${event}"`);
  360. if (event !== import_events.Events.Page.Crash)
  361. waiter.rejectOnEvent(this, import_events.Events.Page.Crash, new Error("Page crashed"));
  362. if (event !== import_events.Events.Page.Close)
  363. waiter.rejectOnEvent(this, import_events.Events.Page.Close, () => this._closeErrorWithReason());
  364. const result = await waiter.waitForEvent(this, event, predicate);
  365. waiter.dispose();
  366. return result;
  367. });
  368. }
  369. async goBack(options = {}) {
  370. const waitUntil = (0, import_frame.verifyLoadState)("waitUntil", options.waitUntil === void 0 ? "load" : options.waitUntil);
  371. return import_network.Response.fromNullable((await this._channel.goBack({ ...options, waitUntil, timeout: this._timeoutSettings.navigationTimeout(options) })).response);
  372. }
  373. async goForward(options = {}) {
  374. const waitUntil = (0, import_frame.verifyLoadState)("waitUntil", options.waitUntil === void 0 ? "load" : options.waitUntil);
  375. return import_network.Response.fromNullable((await this._channel.goForward({ ...options, waitUntil, timeout: this._timeoutSettings.navigationTimeout(options) })).response);
  376. }
  377. async requestGC() {
  378. await this._channel.requestGC();
  379. }
  380. async emulateMedia(options = {}) {
  381. await this._channel.emulateMedia({
  382. media: options.media === null ? "no-override" : options.media,
  383. colorScheme: options.colorScheme === null ? "no-override" : options.colorScheme,
  384. reducedMotion: options.reducedMotion === null ? "no-override" : options.reducedMotion,
  385. forcedColors: options.forcedColors === null ? "no-override" : options.forcedColors,
  386. contrast: options.contrast === null ? "no-override" : options.contrast
  387. });
  388. }
  389. async setViewportSize(viewportSize) {
  390. this._viewportSize = viewportSize;
  391. await this._channel.setViewportSize({ viewportSize });
  392. }
  393. viewportSize() {
  394. return this._viewportSize || null;
  395. }
  396. async evaluate(pageFunction, arg) {
  397. (0, import_jsHandle.assertMaxArguments)(arguments.length, 2);
  398. return await this._mainFrame.evaluate(pageFunction, arg);
  399. }
  400. async _evaluateFunction(functionDeclaration) {
  401. return this._mainFrame._evaluateFunction(functionDeclaration);
  402. }
  403. async addInitScript(script, arg) {
  404. const source = await (0, import_clientHelper.evaluationScript)(this._platform, script, arg);
  405. await this._channel.addInitScript({ source });
  406. }
  407. async route(url, handler, options = {}) {
  408. this._routes.unshift(new import_network.RouteHandler(this._platform, this._browserContext._options.baseURL, url, handler, options.times));
  409. await this._updateInterceptionPatterns({ title: "Route requests" });
  410. }
  411. async routeFromHAR(har, options = {}) {
  412. const localUtils = this._connection.localUtils();
  413. if (!localUtils)
  414. throw new Error("Route from har is not supported in thin clients");
  415. if (options.update) {
  416. await this._browserContext._recordIntoHAR(har, this, options);
  417. return;
  418. }
  419. const harRouter = await import_harRouter.HarRouter.create(localUtils, har, options.notFound || "abort", { urlMatch: options.url });
  420. this._harRouters.push(harRouter);
  421. await harRouter.addPageRoute(this);
  422. }
  423. async routeWebSocket(url, handler) {
  424. this._webSocketRoutes.unshift(new import_network.WebSocketRouteHandler(this._browserContext._options.baseURL, url, handler));
  425. await this._updateWebSocketInterceptionPatterns({ title: "Route WebSockets" });
  426. }
  427. _disposeHarRouters() {
  428. this._harRouters.forEach((router) => router.dispose());
  429. this._harRouters = [];
  430. }
  431. async unrouteAll(options) {
  432. await this._unrouteInternal(this._routes, [], options?.behavior);
  433. this._disposeHarRouters();
  434. }
  435. async unroute(url, handler) {
  436. const removed = [];
  437. const remaining = [];
  438. for (const route of this._routes) {
  439. if ((0, import_urlMatch.urlMatchesEqual)(route.url, url) && (!handler || route.handler === handler))
  440. removed.push(route);
  441. else
  442. remaining.push(route);
  443. }
  444. await this._unrouteInternal(removed, remaining, "default");
  445. }
  446. async _unrouteInternal(removed, remaining, behavior) {
  447. this._routes = remaining;
  448. if (behavior && behavior !== "default") {
  449. const promises = removed.map((routeHandler) => routeHandler.stop(behavior));
  450. await Promise.all(promises);
  451. }
  452. await this._updateInterceptionPatterns({ title: "Unroute requests" });
  453. }
  454. async _updateInterceptionPatterns(options) {
  455. const patterns = import_network.RouteHandler.prepareInterceptionPatterns(this._routes);
  456. await this._wrapApiCall(() => this._channel.setNetworkInterceptionPatterns({ patterns }), options);
  457. }
  458. async _updateWebSocketInterceptionPatterns(options) {
  459. const patterns = import_network.WebSocketRouteHandler.prepareInterceptionPatterns(this._webSocketRoutes);
  460. await this._wrapApiCall(() => this._channel.setWebSocketInterceptionPatterns({ patterns }), options);
  461. }
  462. async screenshot(options = {}) {
  463. const mask = options.mask;
  464. const copy = { ...options, mask: void 0, timeout: this._timeoutSettings.timeout(options) };
  465. if (!copy.type)
  466. copy.type = (0, import_elementHandle.determineScreenshotType)(options);
  467. if (mask) {
  468. copy.mask = mask.map((locator) => ({
  469. frame: locator._frame._channel,
  470. selector: locator._selector
  471. }));
  472. }
  473. const result = await this._channel.screenshot(copy);
  474. if (options.path) {
  475. await (0, import_fileUtils.mkdirIfNeeded)(this._platform, options.path);
  476. await this._platform.fs().promises.writeFile(options.path, result.binary);
  477. }
  478. return result.binary;
  479. }
  480. async _expectScreenshot(options) {
  481. const mask = options?.mask ? options?.mask.map((locator2) => ({
  482. frame: locator2._frame._channel,
  483. selector: locator2._selector
  484. })) : void 0;
  485. const locator = options.locator ? {
  486. frame: options.locator._frame._channel,
  487. selector: options.locator._selector
  488. } : void 0;
  489. return await this._channel.expectScreenshot({
  490. ...options,
  491. isNot: !!options.isNot,
  492. locator,
  493. mask
  494. });
  495. }
  496. async title() {
  497. return await this._mainFrame.title();
  498. }
  499. async bringToFront() {
  500. await this._channel.bringToFront();
  501. }
  502. async [Symbol.asyncDispose]() {
  503. await this.close();
  504. }
  505. async close(options = {}) {
  506. this._closeReason = options.reason;
  507. if (!options.runBeforeUnload)
  508. this._closeWasCalled = true;
  509. try {
  510. if (this._ownedContext)
  511. await this._ownedContext.close();
  512. else
  513. await this._channel.close(options);
  514. } catch (e) {
  515. if ((0, import_errors.isTargetClosedError)(e) && !options.runBeforeUnload)
  516. return;
  517. throw e;
  518. }
  519. }
  520. isClosed() {
  521. return this._closed;
  522. }
  523. async click(selector, options) {
  524. return await this._mainFrame.click(selector, options);
  525. }
  526. async dragAndDrop(source, target, options) {
  527. return await this._mainFrame.dragAndDrop(source, target, options);
  528. }
  529. async dblclick(selector, options) {
  530. await this._mainFrame.dblclick(selector, options);
  531. }
  532. async tap(selector, options) {
  533. return await this._mainFrame.tap(selector, options);
  534. }
  535. async fill(selector, value, options) {
  536. return await this._mainFrame.fill(selector, value, options);
  537. }
  538. async consoleMessages() {
  539. const { messages } = await this._channel.consoleMessages();
  540. return messages.map((message) => new import_consoleMessage.ConsoleMessage(this._platform, message, this, null));
  541. }
  542. async pageErrors() {
  543. const { errors } = await this._channel.pageErrors();
  544. return errors.map((error) => (0, import_errors.parseError)(error));
  545. }
  546. locator(selector, options) {
  547. return this.mainFrame().locator(selector, options);
  548. }
  549. getByTestId(testId) {
  550. return this.mainFrame().getByTestId(testId);
  551. }
  552. getByAltText(text, options) {
  553. return this.mainFrame().getByAltText(text, options);
  554. }
  555. getByLabel(text, options) {
  556. return this.mainFrame().getByLabel(text, options);
  557. }
  558. getByPlaceholder(text, options) {
  559. return this.mainFrame().getByPlaceholder(text, options);
  560. }
  561. getByText(text, options) {
  562. return this.mainFrame().getByText(text, options);
  563. }
  564. getByTitle(text, options) {
  565. return this.mainFrame().getByTitle(text, options);
  566. }
  567. getByRole(role, options = {}) {
  568. return this.mainFrame().getByRole(role, options);
  569. }
  570. frameLocator(selector) {
  571. return this.mainFrame().frameLocator(selector);
  572. }
  573. async focus(selector, options) {
  574. return await this._mainFrame.focus(selector, options);
  575. }
  576. async textContent(selector, options) {
  577. return await this._mainFrame.textContent(selector, options);
  578. }
  579. async innerText(selector, options) {
  580. return await this._mainFrame.innerText(selector, options);
  581. }
  582. async innerHTML(selector, options) {
  583. return await this._mainFrame.innerHTML(selector, options);
  584. }
  585. async getAttribute(selector, name, options) {
  586. return await this._mainFrame.getAttribute(selector, name, options);
  587. }
  588. async inputValue(selector, options) {
  589. return await this._mainFrame.inputValue(selector, options);
  590. }
  591. async isChecked(selector, options) {
  592. return await this._mainFrame.isChecked(selector, options);
  593. }
  594. async isDisabled(selector, options) {
  595. return await this._mainFrame.isDisabled(selector, options);
  596. }
  597. async isEditable(selector, options) {
  598. return await this._mainFrame.isEditable(selector, options);
  599. }
  600. async isEnabled(selector, options) {
  601. return await this._mainFrame.isEnabled(selector, options);
  602. }
  603. async isHidden(selector, options) {
  604. return await this._mainFrame.isHidden(selector, options);
  605. }
  606. async isVisible(selector, options) {
  607. return await this._mainFrame.isVisible(selector, options);
  608. }
  609. async hover(selector, options) {
  610. return await this._mainFrame.hover(selector, options);
  611. }
  612. async selectOption(selector, values, options) {
  613. return await this._mainFrame.selectOption(selector, values, options);
  614. }
  615. async setInputFiles(selector, files, options) {
  616. return await this._mainFrame.setInputFiles(selector, files, options);
  617. }
  618. async type(selector, text, options) {
  619. return await this._mainFrame.type(selector, text, options);
  620. }
  621. async press(selector, key, options) {
  622. return await this._mainFrame.press(selector, key, options);
  623. }
  624. async check(selector, options) {
  625. return await this._mainFrame.check(selector, options);
  626. }
  627. async uncheck(selector, options) {
  628. return await this._mainFrame.uncheck(selector, options);
  629. }
  630. async setChecked(selector, checked, options) {
  631. return await this._mainFrame.setChecked(selector, checked, options);
  632. }
  633. async waitForTimeout(timeout) {
  634. return await this._mainFrame.waitForTimeout(timeout);
  635. }
  636. async waitForFunction(pageFunction, arg, options) {
  637. return await this._mainFrame.waitForFunction(pageFunction, arg, options);
  638. }
  639. async requests() {
  640. const { requests } = await this._channel.requests();
  641. return requests.map((request) => import_network.Request.from(request));
  642. }
  643. workers() {
  644. return [...this._workers];
  645. }
  646. async pause(_options) {
  647. if (this._platform.isJSDebuggerAttached())
  648. return;
  649. const defaultNavigationTimeout = this._browserContext._timeoutSettings.defaultNavigationTimeout();
  650. const defaultTimeout = this._browserContext._timeoutSettings.defaultTimeout();
  651. this._browserContext.setDefaultNavigationTimeout(0);
  652. this._browserContext.setDefaultTimeout(0);
  653. this._instrumentation?.onWillPause({ keepTestTimeout: !!_options?.__testHookKeepTestTimeout });
  654. await this._closedOrCrashedScope.safeRace(this.context()._channel.pause());
  655. this._browserContext.setDefaultNavigationTimeout(defaultNavigationTimeout);
  656. this._browserContext.setDefaultTimeout(defaultTimeout);
  657. }
  658. async pdf(options = {}) {
  659. const transportOptions = { ...options };
  660. if (transportOptions.margin)
  661. transportOptions.margin = { ...transportOptions.margin };
  662. if (typeof options.width === "number")
  663. transportOptions.width = options.width + "px";
  664. if (typeof options.height === "number")
  665. transportOptions.height = options.height + "px";
  666. for (const margin of ["top", "right", "bottom", "left"]) {
  667. const index = margin;
  668. if (options.margin && typeof options.margin[index] === "number")
  669. transportOptions.margin[index] = transportOptions.margin[index] + "px";
  670. }
  671. const result = await this._channel.pdf(transportOptions);
  672. if (options.path) {
  673. const platform = this._platform;
  674. await platform.fs().promises.mkdir(platform.path().dirname(options.path), { recursive: true });
  675. await platform.fs().promises.writeFile(options.path, result.pdf);
  676. }
  677. return result.pdf;
  678. }
  679. // @ts-expect-error agents are hidden
  680. async agent(options = {}) {
  681. const params = {
  682. api: options.provider?.api,
  683. apiEndpoint: options.provider?.apiEndpoint,
  684. apiKey: options.provider?.apiKey,
  685. apiTimeout: options.provider?.apiTimeout,
  686. apiCacheFile: options.provider?._apiCacheFile,
  687. doNotRenderActive: options._doNotRenderActive,
  688. model: options.provider?.model,
  689. cacheFile: options.cache?.cacheFile,
  690. cacheOutFile: options.cache?.cacheOutFile,
  691. maxTokens: options.limits?.maxTokens,
  692. maxActions: options.limits?.maxActions,
  693. maxActionRetries: options.limits?.maxActionRetries,
  694. // @ts-expect-error runAgents is hidden
  695. secrets: options.secrets ? Object.entries(options.secrets).map(([name, value]) => ({ name, value })) : void 0,
  696. systemPrompt: options.systemPrompt
  697. };
  698. const { agent } = await this._channel.agent(params);
  699. const pageAgent = import_pageAgent.PageAgent.from(agent);
  700. pageAgent._expectTimeout = options?.expect?.timeout;
  701. return pageAgent;
  702. }
  703. async _snapshotForAI(options = {}) {
  704. return await this._channel.snapshotForAI({ timeout: this._timeoutSettings.timeout(options), track: options.track });
  705. }
  706. }
  707. class BindingCall extends import_channelOwner.ChannelOwner {
  708. static from(channel) {
  709. return channel._object;
  710. }
  711. constructor(parent, type, guid, initializer) {
  712. super(parent, type, guid, initializer);
  713. }
  714. async call(func) {
  715. try {
  716. const frame = import_frame.Frame.from(this._initializer.frame);
  717. const source = {
  718. context: frame._page.context(),
  719. page: frame._page,
  720. frame
  721. };
  722. let result;
  723. if (this._initializer.handle)
  724. result = await func(source, import_jsHandle.JSHandle.from(this._initializer.handle));
  725. else
  726. result = await func(source, ...this._initializer.args.map(import_jsHandle.parseResult));
  727. this._channel.resolve({ result: (0, import_jsHandle.serializeArgument)(result) }).catch(() => {
  728. });
  729. } catch (e) {
  730. this._channel.reject({ error: (0, import_errors.serializeError)(e) }).catch(() => {
  731. });
  732. }
  733. }
  734. }
  735. function trimUrl(param) {
  736. if ((0, import_rtti.isRegExp)(param))
  737. return `/${(0, import_stringUtils.trimStringWithEllipsis)(param.source, 50)}/${param.flags}`;
  738. if ((0, import_rtti.isString)(param))
  739. return `"${(0, import_stringUtils.trimStringWithEllipsis)(param, 50)}"`;
  740. }
  741. // Annotate the CommonJS export names for ESM import in node:
  742. 0 && (module.exports = {
  743. BindingCall,
  744. Page
  745. });