@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.js CHANGED
@@ -2899,6 +2899,180 @@ var DeviceInput = {
2899
2899
  }
2900
2900
  };
2901
2901
 
2902
+ // src/device-view.js
2903
+ import { devices } from "playwright";
2904
+ var DEFAULT_MOBILE_DESCRIPTOR = "Pixel 7";
2905
+ var clonePlain = (value) => {
2906
+ if (!value || typeof value !== "object") return value;
2907
+ try {
2908
+ return JSON.parse(JSON.stringify(value));
2909
+ } catch {
2910
+ return { ...value };
2911
+ }
2912
+ };
2913
+ var resolveDescriptor = (descriptor, device) => {
2914
+ if (descriptor && typeof descriptor === "object") {
2915
+ return descriptor;
2916
+ }
2917
+ const name = String(descriptor || (device === Device.Mobile ? DEFAULT_MOBILE_DESCRIPTOR : "")).trim();
2918
+ if (!name) return null;
2919
+ const resolved = devices[name];
2920
+ if (!resolved) {
2921
+ throw new Error(`DeviceView.withPageDevice unknown Playwright device descriptor: ${name}`);
2922
+ }
2923
+ return resolved;
2924
+ };
2925
+ var attachRuntimeState = (page, state) => {
2926
+ Object.defineProperty(page, PageRuntimeStateKey, {
2927
+ configurable: true,
2928
+ enumerable: false,
2929
+ writable: true,
2930
+ value: state
2931
+ });
2932
+ };
2933
+ var restoreRuntimeState = (page, snapshot) => {
2934
+ if (snapshot.hadRuntimeState) {
2935
+ attachRuntimeState(page, snapshot.runtimeState);
2936
+ return;
2937
+ }
2938
+ delete page[PageRuntimeStateKey];
2939
+ };
2940
+ var waitFor2 = (page, timeout) => {
2941
+ if (!timeout) return Promise.resolve();
2942
+ if (page && typeof page.waitForTimeout === "function") {
2943
+ return page.waitForTimeout(timeout);
2944
+ }
2945
+ return new Promise((resolve) => setTimeout(resolve, timeout));
2946
+ };
2947
+ var dispatchTouchTap = async (client, page, x, y) => {
2948
+ await client.send("Input.dispatchTouchEvent", {
2949
+ type: "touchStart",
2950
+ touchPoints: [{ x, y, id: 1 }]
2951
+ });
2952
+ await waitFor2(page, 30);
2953
+ await client.send("Input.dispatchTouchEvent", {
2954
+ type: "touchEnd",
2955
+ touchPoints: []
2956
+ });
2957
+ };
2958
+ var installScopedTouchscreenTap = (page, client, enabled) => {
2959
+ if (!enabled || !page?.touchscreen || typeof page.touchscreen.tap !== "function") {
2960
+ return () => {
2961
+ };
2962
+ }
2963
+ const originalTap = page.touchscreen.tap;
2964
+ page.touchscreen.tap = async (x, y) => {
2965
+ try {
2966
+ return await originalTap.call(page.touchscreen, x, y);
2967
+ } catch (error) {
2968
+ if (!String(error?.message || error).includes("hasTouch must be enabled")) {
2969
+ throw error;
2970
+ }
2971
+ return await dispatchTouchTap(client, page, x, y);
2972
+ }
2973
+ };
2974
+ return () => {
2975
+ page.touchscreen.tap = originalTap;
2976
+ };
2977
+ };
2978
+ var buildScopedRuntimeState = (page, runtimeState, device) => ({
2979
+ ...clonePlain(runtimeState || page?.[PageRuntimeStateKey] || {}) || {},
2980
+ device
2981
+ });
2982
+ var applyDeviceEmulation = async (page, descriptor, device, options = {}) => {
2983
+ if (!descriptor) return { client: null, restoreTouchscreenTap: () => {
2984
+ } };
2985
+ const client = await page.context().newCDPSession(page);
2986
+ const viewport = descriptor.viewport || null;
2987
+ const isMobile = device === Device.Mobile || descriptor.isMobile === true;
2988
+ const hasTouch = device === Device.Mobile || descriptor.hasTouch === true;
2989
+ const deviceScaleFactor = Number(descriptor.deviceScaleFactor || 1);
2990
+ if (descriptor.userAgent) {
2991
+ await client.send("Emulation.setUserAgentOverride", {
2992
+ userAgent: descriptor.userAgent,
2993
+ platform: options.platform || (isMobile ? "Android" : void 0)
2994
+ });
2995
+ }
2996
+ if (viewport?.width > 0 && viewport?.height > 0) {
2997
+ await page.setViewportSize({
2998
+ width: viewport.width,
2999
+ height: viewport.height
3000
+ });
3001
+ await client.send("Emulation.setDeviceMetricsOverride", {
3002
+ width: viewport.width,
3003
+ height: viewport.height,
3004
+ deviceScaleFactor,
3005
+ mobile: isMobile,
3006
+ screenWidth: descriptor.screen?.width || viewport.width,
3007
+ screenHeight: descriptor.screen?.height || viewport.height
3008
+ });
3009
+ }
3010
+ await client.send("Emulation.setTouchEmulationEnabled", {
3011
+ enabled: hasTouch,
3012
+ maxTouchPoints: hasTouch ? Number(options.maxTouchPoints || 5) : 0
3013
+ });
3014
+ return {
3015
+ client,
3016
+ restoreTouchscreenTap: installScopedTouchscreenTap(page, client, hasTouch)
3017
+ };
3018
+ };
3019
+ var restoreDeviceEmulation = async (page, emulation, snapshot) => {
3020
+ const client = emulation?.client;
3021
+ emulation?.restoreTouchscreenTap?.();
3022
+ if (!client) return;
3023
+ await client.send("Emulation.setTouchEmulationEnabled", { enabled: false }).catch(() => {
3024
+ });
3025
+ await client.send("Emulation.clearDeviceMetricsOverride").catch(() => {
3026
+ });
3027
+ if (snapshot.userAgent) {
3028
+ await client.send("Emulation.setUserAgentOverride", {
3029
+ userAgent: snapshot.userAgent,
3030
+ platform: snapshot.platform || void 0
3031
+ }).catch(() => {
3032
+ });
3033
+ }
3034
+ if (snapshot.viewport) {
3035
+ await page.setViewportSize(snapshot.viewport).catch(() => {
3036
+ });
3037
+ }
3038
+ await client.detach().catch(() => {
3039
+ });
3040
+ };
3041
+ var DeviceView = {
3042
+ async withPageDevice(page, options = {}, callback) {
3043
+ if (!page || typeof page !== "object") {
3044
+ throw new Error("DeviceView.withPageDevice requires a Playwright page");
3045
+ }
3046
+ if (typeof callback !== "function") {
3047
+ throw new Error("DeviceView.withPageDevice requires a callback");
3048
+ }
3049
+ const device = normalizeDevice(options.device);
3050
+ const descriptor = resolveDescriptor(options.descriptor, device);
3051
+ const snapshot = {
3052
+ hadRuntimeState: Object.prototype.hasOwnProperty.call(page, PageRuntimeStateKey),
3053
+ runtimeState: clonePlain(page[PageRuntimeStateKey]),
3054
+ viewport: page.viewportSize?.() || null,
3055
+ userAgent: await page.evaluate(() => navigator.userAgent).catch(() => ""),
3056
+ platform: await page.evaluate(() => navigator.platform).catch(() => "")
3057
+ };
3058
+ const runtimeState = buildScopedRuntimeState(page, options.runtimeState, device);
3059
+ let emulation = null;
3060
+ attachRuntimeState(page, runtimeState);
3061
+ try {
3062
+ emulation = await applyDeviceEmulation(page, descriptor, device, options);
3063
+ return await callback({
3064
+ page,
3065
+ device,
3066
+ descriptor,
3067
+ runtimeState
3068
+ });
3069
+ } finally {
3070
+ restoreRuntimeState(page, snapshot);
3071
+ await restoreDeviceEmulation(page, emulation, snapshot);
3072
+ }
3073
+ }
3074
+ };
3075
+
2902
3076
  // src/internals/humanize/desktop.js
2903
3077
  import delay2 from "delay";
2904
3078
  import { createCursor } from "ghost-cursor-playwright";
@@ -9336,6 +9510,7 @@ var usePlaywrightToolKit = () => {
9336
9510
  ApifyKit,
9337
9511
  AntiCheat,
9338
9512
  DeviceInput,
9513
+ DeviceView,
9339
9514
  Humanize: Humanize2,
9340
9515
  Launch,
9341
9516
  LiveView,