@skrillex1224/playwright-toolkit 2.1.264 → 2.1.265

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -2927,6 +2927,180 @@ var DeviceInput = {
2927
2927
  }
2928
2928
  };
2929
2929
 
2930
+ // src/device-view.js
2931
+ var import_playwright = require("playwright");
2932
+ var DEFAULT_MOBILE_DESCRIPTOR = "Pixel 7";
2933
+ var clonePlain = (value) => {
2934
+ if (!value || typeof value !== "object") return value;
2935
+ try {
2936
+ return JSON.parse(JSON.stringify(value));
2937
+ } catch {
2938
+ return { ...value };
2939
+ }
2940
+ };
2941
+ var resolveDescriptor = (descriptor, device) => {
2942
+ if (descriptor && typeof descriptor === "object") {
2943
+ return descriptor;
2944
+ }
2945
+ const name = String(descriptor || (device === Device.Mobile ? DEFAULT_MOBILE_DESCRIPTOR : "")).trim();
2946
+ if (!name) return null;
2947
+ const resolved = import_playwright.devices[name];
2948
+ if (!resolved) {
2949
+ throw new Error(`DeviceView.withPageDevice unknown Playwright device descriptor: ${name}`);
2950
+ }
2951
+ return resolved;
2952
+ };
2953
+ var attachRuntimeState = (page, state) => {
2954
+ Object.defineProperty(page, PageRuntimeStateKey, {
2955
+ configurable: true,
2956
+ enumerable: false,
2957
+ writable: true,
2958
+ value: state
2959
+ });
2960
+ };
2961
+ var restoreRuntimeState = (page, snapshot) => {
2962
+ if (snapshot.hadRuntimeState) {
2963
+ attachRuntimeState(page, snapshot.runtimeState);
2964
+ return;
2965
+ }
2966
+ delete page[PageRuntimeStateKey];
2967
+ };
2968
+ var waitFor2 = (page, timeout) => {
2969
+ if (!timeout) return Promise.resolve();
2970
+ if (page && typeof page.waitForTimeout === "function") {
2971
+ return page.waitForTimeout(timeout);
2972
+ }
2973
+ return new Promise((resolve) => setTimeout(resolve, timeout));
2974
+ };
2975
+ var dispatchTouchTap = async (client, page, x, y) => {
2976
+ await client.send("Input.dispatchTouchEvent", {
2977
+ type: "touchStart",
2978
+ touchPoints: [{ x, y, id: 1 }]
2979
+ });
2980
+ await waitFor2(page, 30);
2981
+ await client.send("Input.dispatchTouchEvent", {
2982
+ type: "touchEnd",
2983
+ touchPoints: []
2984
+ });
2985
+ };
2986
+ var installScopedTouchscreenTap = (page, client, enabled) => {
2987
+ if (!enabled || !page?.touchscreen || typeof page.touchscreen.tap !== "function") {
2988
+ return () => {
2989
+ };
2990
+ }
2991
+ const originalTap = page.touchscreen.tap;
2992
+ page.touchscreen.tap = async (x, y) => {
2993
+ try {
2994
+ return await originalTap.call(page.touchscreen, x, y);
2995
+ } catch (error) {
2996
+ if (!String(error?.message || error).includes("hasTouch must be enabled")) {
2997
+ throw error;
2998
+ }
2999
+ return await dispatchTouchTap(client, page, x, y);
3000
+ }
3001
+ };
3002
+ return () => {
3003
+ page.touchscreen.tap = originalTap;
3004
+ };
3005
+ };
3006
+ var buildScopedRuntimeState = (page, runtimeState, device) => ({
3007
+ ...clonePlain(runtimeState || page?.[PageRuntimeStateKey] || {}) || {},
3008
+ device
3009
+ });
3010
+ var applyDeviceEmulation = async (page, descriptor, device, options = {}) => {
3011
+ if (!descriptor) return { client: null, restoreTouchscreenTap: () => {
3012
+ } };
3013
+ const client = await page.context().newCDPSession(page);
3014
+ const viewport = descriptor.viewport || null;
3015
+ const isMobile = device === Device.Mobile || descriptor.isMobile === true;
3016
+ const hasTouch = device === Device.Mobile || descriptor.hasTouch === true;
3017
+ const deviceScaleFactor = Number(descriptor.deviceScaleFactor || 1);
3018
+ if (descriptor.userAgent) {
3019
+ await client.send("Emulation.setUserAgentOverride", {
3020
+ userAgent: descriptor.userAgent,
3021
+ platform: options.platform || (isMobile ? "Android" : void 0)
3022
+ });
3023
+ }
3024
+ if (viewport?.width > 0 && viewport?.height > 0) {
3025
+ await page.setViewportSize({
3026
+ width: viewport.width,
3027
+ height: viewport.height
3028
+ });
3029
+ await client.send("Emulation.setDeviceMetricsOverride", {
3030
+ width: viewport.width,
3031
+ height: viewport.height,
3032
+ deviceScaleFactor,
3033
+ mobile: isMobile,
3034
+ screenWidth: descriptor.screen?.width || viewport.width,
3035
+ screenHeight: descriptor.screen?.height || viewport.height
3036
+ });
3037
+ }
3038
+ await client.send("Emulation.setTouchEmulationEnabled", {
3039
+ enabled: hasTouch,
3040
+ maxTouchPoints: hasTouch ? Number(options.maxTouchPoints || 5) : 0
3041
+ });
3042
+ return {
3043
+ client,
3044
+ restoreTouchscreenTap: installScopedTouchscreenTap(page, client, hasTouch)
3045
+ };
3046
+ };
3047
+ var restoreDeviceEmulation = async (page, emulation, snapshot) => {
3048
+ const client = emulation?.client;
3049
+ emulation?.restoreTouchscreenTap?.();
3050
+ if (!client) return;
3051
+ await client.send("Emulation.setTouchEmulationEnabled", { enabled: false }).catch(() => {
3052
+ });
3053
+ await client.send("Emulation.clearDeviceMetricsOverride").catch(() => {
3054
+ });
3055
+ if (snapshot.userAgent) {
3056
+ await client.send("Emulation.setUserAgentOverride", {
3057
+ userAgent: snapshot.userAgent,
3058
+ platform: snapshot.platform || void 0
3059
+ }).catch(() => {
3060
+ });
3061
+ }
3062
+ if (snapshot.viewport) {
3063
+ await page.setViewportSize(snapshot.viewport).catch(() => {
3064
+ });
3065
+ }
3066
+ await client.detach().catch(() => {
3067
+ });
3068
+ };
3069
+ var DeviceView = {
3070
+ async withPageDevice(page, options = {}, callback) {
3071
+ if (!page || typeof page !== "object") {
3072
+ throw new Error("DeviceView.withPageDevice requires a Playwright page");
3073
+ }
3074
+ if (typeof callback !== "function") {
3075
+ throw new Error("DeviceView.withPageDevice requires a callback");
3076
+ }
3077
+ const device = normalizeDevice(options.device);
3078
+ const descriptor = resolveDescriptor(options.descriptor, device);
3079
+ const snapshot = {
3080
+ hadRuntimeState: Object.prototype.hasOwnProperty.call(page, PageRuntimeStateKey),
3081
+ runtimeState: clonePlain(page[PageRuntimeStateKey]),
3082
+ viewport: page.viewportSize?.() || null,
3083
+ userAgent: await page.evaluate(() => navigator.userAgent).catch(() => ""),
3084
+ platform: await page.evaluate(() => navigator.platform).catch(() => "")
3085
+ };
3086
+ const runtimeState = buildScopedRuntimeState(page, options.runtimeState, device);
3087
+ let emulation = null;
3088
+ attachRuntimeState(page, runtimeState);
3089
+ try {
3090
+ emulation = await applyDeviceEmulation(page, descriptor, device, options);
3091
+ return await callback({
3092
+ page,
3093
+ device,
3094
+ descriptor,
3095
+ runtimeState
3096
+ });
3097
+ } finally {
3098
+ restoreRuntimeState(page, snapshot);
3099
+ await restoreDeviceEmulation(page, emulation, snapshot);
3100
+ }
3101
+ }
3102
+ };
3103
+
2930
3104
  // src/internals/humanize/desktop.js
2931
3105
  var import_delay2 = __toESM(require("delay"), 1);
2932
3106
  var import_ghost_cursor_playwright = require("ghost-cursor-playwright");
@@ -9364,6 +9538,7 @@ var usePlaywrightToolKit = () => {
9364
9538
  ApifyKit,
9365
9539
  AntiCheat,
9366
9540
  DeviceInput,
9541
+ DeviceView,
9367
9542
  Humanize: Humanize2,
9368
9543
  Launch,
9369
9544
  LiveView,