@applitools/eyes-cypress 3.50.3 → 3.51.0

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/CHANGELOG.md CHANGED
@@ -1,5 +1,22 @@
1
1
  # Changelog
2
2
 
3
+ ## [3.51.0](https://github.com/Applitools-Dev/sdk/compare/js/eyes-cypress@3.50.3...js/eyes-cypress@3.51.0) (2025-04-03)
4
+
5
+
6
+ ### Features
7
+
8
+ * allow sending callback functions to waitBeforeCapture ([#2780](https://github.com/Applitools-Dev/sdk/issues/2780)) ([4caa2e8](https://github.com/Applitools-Dev/sdk/commit/4caa2e8ae055d3dd48164eeceaa4c691eeadcdd4))
9
+
10
+
11
+ ### Dependencies
12
+
13
+ * @applitools/core bumped to 4.35.1
14
+ #### Bug Fixes
15
+
16
+ * dummy ([9b8ffef](https://github.com/Applitools-Dev/sdk/commit/9b8ffef6277015a9073caf50f5dc5741986fbf07))
17
+ * @applitools/eyes bumped to 1.33.2
18
+
19
+
3
20
  ## [3.50.3](https://github.com/Applitools-Dev/sdk/compare/js/eyes-cypress@3.50.2...js/eyes-cypress@3.50.3) (2025-03-06)
4
21
 
5
22
 
@@ -0,0 +1,82 @@
1
+ "use strict";
2
+ /* global Node */
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ const uuid = require('uuid');
5
+ const REF_ID = 'applitools-ref-id';
6
+ class Refer {
7
+ constructor() {
8
+ this.store = new Map();
9
+ this.relation = new Map();
10
+ }
11
+ isRef(ref) {
12
+ // isRef(ref) {
13
+ return Boolean(ref && ref[REF_ID]);
14
+ }
15
+ check(value) {
16
+ // check(value) {
17
+ if (!value)
18
+ return;
19
+ if (value === '__CYPRESS_DRIVER__') {
20
+ return 'cypress-driver';
21
+ }
22
+ else if (value.nodeType === Node.ELEMENT_NODE) {
23
+ return 'element';
24
+ }
25
+ else if (value.nodeType === Node.DOCUMENT_NODE || value.ownerDocument) {
26
+ return 'context';
27
+ }
28
+ else if (value.constructor && value.constructor.name === 'Window') {
29
+ return 'driver';
30
+ }
31
+ else if (typeof value === 'function') {
32
+ return 'function';
33
+ }
34
+ }
35
+ ref(value, parentRef) {
36
+ // ref(value, parentRef) {
37
+ const refType = this.check(value);
38
+ if (refType) {
39
+ const ref = uuid.v4();
40
+ this.store.set(ref, value);
41
+ if (parentRef) {
42
+ let childRefs = this.relation.get(parentRef[REF_ID]);
43
+ if (!childRefs) {
44
+ childRefs = new Set();
45
+ this.relation.set(parentRef[REF_ID], childRefs);
46
+ }
47
+ childRefs.add({ [REF_ID]: ref });
48
+ }
49
+ return { [REF_ID]: ref, type: refType };
50
+ }
51
+ else if (Array.isArray(value)) {
52
+ return value.map(value => this.ref(value, parentRef));
53
+ }
54
+ else if (typeof value === 'object' && value !== null) {
55
+ return Object.entries(value).reduce((obj, [key, value]) => {
56
+ return Object.assign(obj, { [key]: this.ref(value, parentRef) });
57
+ }, {});
58
+ }
59
+ else {
60
+ return value;
61
+ }
62
+ }
63
+ deref(ref) {
64
+ if (this.isRef(ref)) {
65
+ const value = this.store.get(ref[REF_ID]);
66
+ return value === '__CYPRESS_DRIVER__' ? cy.state('document') : value;
67
+ }
68
+ else {
69
+ return ref;
70
+ }
71
+ }
72
+ destroy(ref) {
73
+ if (!this.isRef(ref))
74
+ return;
75
+ const childRefs = this.relation.get(ref[REF_ID]);
76
+ if (childRefs) {
77
+ childRefs.forEach(childRef => this.destroy(childRef));
78
+ }
79
+ this.store.delete(ref[REF_ID]);
80
+ }
81
+ }
82
+ module.exports = Refer;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.reload = exports.getCookies = exports.getUrl = exports.getTitle = exports.findElements = exports.findElement = exports.transformSelector = exports.setViewportSize = exports.getViewportSize = exports.childContext = exports.parentContext = exports.mainContext = exports.executeScript = void 0;
3
+ exports.executeUserFunction = exports.reload = exports.getCookies = exports.getUrl = exports.getTitle = exports.findElements = exports.findElement = exports.transformSelector = exports.setViewportSize = exports.getViewportSize = exports.childContext = exports.parentContext = exports.mainContext = exports.executeScript = void 0;
4
4
  function executeScript(context, script, arg) {
5
5
  let scriptToExecute;
6
6
  if (script.includes('dom-snapshot') || script.includes('dom-capture') || script.includes('dom-shared')) {
@@ -118,6 +118,14 @@ function reload() {
118
118
  });
119
119
  }
120
120
  exports.reload = reload;
121
+ async function executeUserFunction(fn) {
122
+ if (typeof fn !== 'function') {
123
+ console.error('Not a function:', fn);
124
+ throw new Error(`Not a function: ${JSON.stringify(fn)}`);
125
+ }
126
+ return fn();
127
+ }
128
+ exports.executeUserFunction = executeUserFunction;
121
129
  // export function takeScreenshot(page: Driver): Promise<Buffer>;
122
130
  // export function visit(page: Driver, url: string): Promise<void>; (??)
123
131
  // export function isStaleElementError(err: any): boolean;
@@ -54,7 +54,9 @@ function transformCypressCheckSettings(settings, refer) {
54
54
  ignoreCaret: settings.ignoreCaret,
55
55
  ignoreDisplacements: settings.ignoreDisplacements,
56
56
  fully: settings.fully,
57
- waitBeforeCapture: settings.waitBeforeCapture,
57
+ waitBeforeCapture: typeof settings.waitBeforeCapture === 'number'
58
+ ? settings.waitBeforeCapture
59
+ : settings.waitBeforeCapture && refer.ref(settings.waitBeforeCapture),
58
60
  lazyLoad: settings.lazyLoad,
59
61
  matchLevel: settings.matchLevel,
60
62
  useDom: settings.useDom,
@@ -26,7 +26,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
26
26
  exports.transformCypressConfig = void 0;
27
27
  const utils_1 = require("./utils");
28
28
  const utils = __importStar(require("@applitools/utils"));
29
- function transformCypressConfig(config) {
29
+ function transformCypressConfig(config, refer) {
30
30
  var _a, _b, _c, _d, _e, _f, _g, _h;
31
31
  return {
32
32
  open: {
@@ -85,10 +85,14 @@ function transformCypressConfig(config) {
85
85
  stitchMode: config.stitchMode,
86
86
  autProxy: config.autProxy,
87
87
  scrollRootElement: config.scrollRootElement,
88
- waitBeforeCapture: config.waitBeforeCapture,
88
+ waitBeforeCapture: typeof config.waitBeforeCapture === 'number'
89
+ ? config.waitBeforeCapture
90
+ : config.waitBeforeCapture && refer.ref(config.waitBeforeCapture),
89
91
  },
90
92
  screenshot: {
91
- waitBeforeCapture: config.waitBeforeCapture,
93
+ waitBeforeCapture: typeof config.waitBeforeCapture === 'number'
94
+ ? config.waitBeforeCapture
95
+ : config.waitBeforeCapture && refer.ref(config.waitBeforeCapture),
92
96
  autProxy: config.autProxy,
93
97
  scrollRootElement: config.scrollRootElement,
94
98
  hideScrollbars: config.hideScrollbars,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@applitools/eyes-cypress",
3
- "version": "3.50.3",
3
+ "version": "3.51.0",
4
4
  "homepage": "https://applitools.com/docs/api-ref/sdk-api/cypress/",
5
5
  "license": "SEE LICENSE IN LICENSE",
6
6
  "main": "./index.js",
@@ -54,11 +54,11 @@
54
54
  "setup": "run --top-level xvfb:setup"
55
55
  },
56
56
  "dependencies": {
57
- "@applitools/core": "4.32.2",
58
- "@applitools/eyes": "1.32.6",
57
+ "@applitools/core": "4.35.1",
58
+ "@applitools/eyes": "1.33.2",
59
59
  "@applitools/functional-commons": "1.6.0",
60
- "@applitools/logger": "2.1.1",
61
- "@applitools/utils": "1.7.8",
60
+ "@applitools/logger": "2.1.2",
61
+ "@applitools/utils": "1.8.0",
62
62
  "boxen": "5.1.2",
63
63
  "chalk": "3.0.0",
64
64
  "semver": "7.6.2",
@@ -1,7 +1,7 @@
1
1
  /* global Cypress,cy,after */
2
2
  'use strict'
3
3
  const spec = require('../../dist/browser/spec-driver')
4
- const Refer = require('./refer')
4
+ const Refer = require('../../dist/browser/refer')
5
5
  const Socket = require('./socket')
6
6
  const {socketCommands} = require('./socketCommands')
7
7
  const {TestResultsSummaryData: TestResultsSummary} = require('@applitools/eyes/dist/output/TestResultsSummary')
@@ -147,11 +147,14 @@ Cypress.Commands.add('eyesOpen', function (args = {}) {
147
147
 
148
148
  const appliConfFile = Cypress.config('appliConfFile')
149
149
  const mergedConfig = mergeCypressConfigs({globalConfig: appliConfFile, openConfig: {testName, ...args}})
150
- openAndGlobalConfig = transformCypressConfig({
151
- ...mergedConfig,
152
- shouldDoPostSpecTasks,
153
- isComponentTest: Cypress.config('isComponent'),
154
- })
150
+ openAndGlobalConfig = transformCypressConfig(
151
+ {
152
+ ...mergedConfig,
153
+ shouldDoPostSpecTasks,
154
+ isComponentTest: Cypress.config('isComponent'),
155
+ },
156
+ refer,
157
+ )
155
158
 
156
159
  eyes = await socket.request('EyesManager.openEyes', {manager, target, config: openAndGlobalConfig})
157
160
  })
@@ -3,29 +3,29 @@
3
3
  const uuid = require('uuid')
4
4
  const REF_ID = 'applitools-ref-id'
5
5
 
6
- // type RefType = 'cypress-driver' | 'element' | 'context' | 'driver'
6
+ type RefType = 'cypress-driver' | 'element' | 'context' | 'driver' | 'function'
7
7
 
8
- // type Ref = {
9
- // [REF_ID]: string
10
- // type?: RefType
11
- // }
8
+ type Ref = {
9
+ [REF_ID]: string
10
+ type?: RefType
11
+ }
12
12
 
13
13
  class Refer {
14
- // store: Map<string, any>
15
- // relation: Map<string, Set<Ref>>
14
+ store: Map<string, any>
15
+ relation: Map<string, Set<Ref>>
16
16
 
17
17
  constructor() {
18
18
  this.store = new Map()
19
19
  this.relation = new Map()
20
20
  }
21
21
 
22
- // isRef(ref: any): ref is Ref {
23
- isRef(ref) {
22
+ isRef(ref: any): ref is Ref {
23
+ // isRef(ref) {
24
24
  return Boolean(ref && ref[REF_ID])
25
25
  }
26
26
 
27
- // check(value: any): RefType | undefined {
28
- check(value) {
27
+ check(value: any): RefType | undefined {
28
+ // check(value) {
29
29
  if (!value) return
30
30
  if (value === '__CYPRESS_DRIVER__') {
31
31
  return 'cypress-driver'
@@ -35,11 +35,13 @@ class Refer {
35
35
  return 'context'
36
36
  } else if (value.constructor && value.constructor.name === 'Window') {
37
37
  return 'driver'
38
+ } else if (typeof value === 'function') {
39
+ return 'function'
38
40
  }
39
41
  }
40
42
 
41
- // ref(value: any, parentRef?: Ref) {
42
- ref(value, parentRef) {
43
+ ref(value: any, parentRef?: Ref) {
44
+ // ref(value, parentRef) {
43
45
  const refType = this.check(value)
44
46
  if (refType) {
45
47
  const ref = uuid.v4()
@@ -67,7 +69,7 @@ class Refer {
67
69
  deref(ref) {
68
70
  if (this.isRef(ref)) {
69
71
  const value = this.store.get(ref[REF_ID])
70
- return value === '__CYPRESS_DRIVER__' ? cy.state('document') : value
72
+ return value === '__CYPRESS_DRIVER__' ? (cy as any).state('document') : value
71
73
  } else {
72
74
  return ref
73
75
  }
@@ -49,6 +49,10 @@ function socketCommands(socket, refer) {
49
49
  socket.command('Driver.reload', async () => {
50
50
  await spec.reload()
51
51
  })
52
+
53
+ socket.command('Driver.executeUserFunction', fn => {
54
+ return spec.executeUserFunction(refer.deref(fn))
55
+ })
52
56
  }
53
57
 
54
58
  module.exports = {socketCommands}
@@ -120,6 +120,14 @@ export function reload(): Promise<void> {
120
120
  })
121
121
  }
122
122
 
123
+ export async function executeUserFunction(fn: any) {
124
+ if (typeof fn !== 'function') {
125
+ console.error('Not a function:', fn)
126
+ throw new Error(`Not a function: ${JSON.stringify(fn)}`)
127
+ }
128
+ return fn()
129
+ }
130
+
123
131
  // export function takeScreenshot(page: Driver): Promise<Buffer>;
124
132
 
125
133
  // export function visit(page: Driver, url: string): Promise<void>; (??)
@@ -50,7 +50,10 @@ export function transformCypressCheckSettings(
50
50
  ignoreCaret: settings.ignoreCaret,
51
51
  ignoreDisplacements: settings.ignoreDisplacements,
52
52
  fully: settings.fully,
53
- waitBeforeCapture: settings.waitBeforeCapture,
53
+ waitBeforeCapture:
54
+ typeof settings.waitBeforeCapture === 'number'
55
+ ? settings.waitBeforeCapture
56
+ : settings.waitBeforeCapture && refer.ref(settings.waitBeforeCapture),
54
57
  lazyLoad: settings.lazyLoad,
55
58
  matchLevel: settings.matchLevel,
56
59
  useDom: settings.useDom,
@@ -3,7 +3,7 @@ import type {SpecType, Config} from '@applitools/core'
3
3
  import {transformBrowsers, transformAccessibilityValidation} from './utils'
4
4
  import * as utils from '@applitools/utils'
5
5
 
6
- export function transformCypressConfig(config: appliConfFile): Config<SpecType, 'ufg'> {
6
+ export function transformCypressConfig(config: appliConfFile, refer): Config<SpecType, 'ufg'> {
7
7
  return {
8
8
  open: {
9
9
  apiKey: config.apiKey,
@@ -61,10 +61,16 @@ export function transformCypressConfig(config: appliConfFile): Config<SpecType,
61
61
  stitchMode: config.stitchMode,
62
62
  autProxy: config.autProxy,
63
63
  scrollRootElement: config.scrollRootElement,
64
- waitBeforeCapture: config.waitBeforeCapture,
64
+ waitBeforeCapture:
65
+ typeof config.waitBeforeCapture === 'number'
66
+ ? config.waitBeforeCapture
67
+ : config.waitBeforeCapture && refer.ref(config.waitBeforeCapture),
65
68
  },
66
69
  screenshot: {
67
- waitBeforeCapture: config.waitBeforeCapture,
70
+ waitBeforeCapture:
71
+ typeof config.waitBeforeCapture === 'number'
72
+ ? config.waitBeforeCapture
73
+ : config.waitBeforeCapture && refer.ref(config.waitBeforeCapture),
68
74
  autProxy: config.autProxy,
69
75
  scrollRootElement: config.scrollRootElement,
70
76
  hideScrollbars: config.hideScrollbars,
package/types/expose.d.ts CHANGED
@@ -244,7 +244,7 @@ export type CypressCheckSettings = {
244
244
  useSystemScreenshot?: boolean;
245
245
  hooks?: { beforeCaptureScreenshot: string; };
246
246
  timeout?: number;
247
- waitBeforeCapture?: number;
247
+ waitBeforeCapture?: number | (() => Promise<void>);
248
248
  lazyLoad?: boolean | { scrollLength?: number; waitingTime?: number; maxAmountToScroll?: number; };
249
249
  tag?: string;
250
250
  target?: "window" | "region";
@@ -358,6 +358,7 @@ export type CypressEyesConfig = {
358
358
  enablePatterns?: boolean;
359
359
  environmentName?: string;
360
360
  forceFullPageScreenshot?: boolean;
361
+ fully?: boolean;
361
362
  gitMergeBaseTimestamp?: string;
362
363
  latestCommitInfo?: { timestamp: string; sha: string; };
363
364
  hideCaret?: boolean;
@@ -394,7 +395,7 @@ export type CypressEyesConfig = {
394
395
  useDom?: boolean;
395
396
  viewportSize?: { width: number; height: number; };
396
397
  visualGridOptions?: Record<string, any>;
397
- waitBeforeCapture?: number;
398
+ waitBeforeCapture?: number | (() => Promise<void>);
398
399
  waitBeforeScreenshots?: number;
399
400
  browser?: MaybeArray<(({ name?: "chrome" | "chrome-one-version-back" | "chrome-two-versions-back" | "firefox" | "firefox-one-version-back" | "firefox-two-versions-back" | "ie" | "ie10" | "edge" | "edgechromium" | "edgelegacy" | "edgechromium-one-version-back" | "edgechromium-two-versions-back" | "safari" | "safari-earlyaccess" | "safari-one-version-back" | "safari-two-versions-back"; width: number; height: number; } | { chromeEmulationInfo: { deviceName: "iPhone 4" | "iPhone 5/SE" | "iPhone SE 3rd Gen" | "iPhone 6/7/8" | "iPhone 6/7/8 Plus" | "iPhone X" | "iPhone 13 Mini" | "iPhone 14 Plus" | "iPhone 14 Pro" | "iPhone 15 Pro" | "BlackBerry Z30" | "Nexus 4" | "Nexus 5" | "Nexus 5X" | "Nexus 6" | "Nexus 6P" | "Pixel 2" | "Pixel 2 XL" | "LG Optimus L70" | "Nokia N9" | "Nokia Lumia 520" | "Microsoft Lumia 550" | "Microsoft Lumia 950" | "Galaxy S3" | "Galaxy S III" | "Galaxy S5" | "Kindle Fire HDX" | "iPad Mini" | "iPad" | "iPad Pro" | "iPad 8th Gen" | "iPad 10th Gen" | "iPad Mini 4th Gen" | "iPad Mini 6th Gen" | "Blackberry PlayBook" | "Nexus 10" | "Nexus 7" | "Galaxy Note 3" | "Galaxy Note II" | "Galaxy Note 2" | "Galaxy S20" | "Galaxy S22" | "Galaxy S21" | "Galaxy S21 Ultra" | "Galaxy S22 Ultra" | "Laptop with touch" | "Laptop with HiDPI screen" | "Laptop with MDPI screen" | "iPhone XR" | "iPhone XS Max" | "iPhone XS" | "Samsung Galaxy A5" | "Galaxy A5" | "Samsung Galaxy S8" | "Galaxy S8" | "LG G6" | "iPad Air 2" | "iPad 6th Gen" | "iPhone 11" | "iPhone 11 Pro Max" | "iPhone 11 Pro" | "Galaxy S10" | "Galaxy S9 Plus" | "Galaxy S9" | "Galaxy S10 Plus" | "Galaxy S8 Plus" | "Galaxy Note 10" | "Galaxy Note 10 Plus" | "Galaxy Note 9" | "Galaxy Note 8" | "Galaxy Note 4" | "Galaxy Tab A SM-T510" | "Galaxy Tab A7 SM-T500" | "Galaxy Tab S8" | "Galaxy Tab A8" | "Galaxy S23" | "Galaxy S23 Ultra" | "Galaxy A52s" | "Pixel 3" | "Pixel 3 XL" | "Pixel 4" | "Pixel 4 XL" | "Pixel 5" | "iPad 7th Gen" | "OnePlus 7T" | "OnePlus 7T Pro" | "Galaxy Tab S7" | "Sony Xperia 10 II" | "Huawei Mate 50 Pro" | "Huawei Matepad 11" | "Huawei P30" | "Xiaomi Mi A3" | "Huawei P40" | "Xiaomi Redmi Note 8" | "Xiaomi Mi Poco X3 Pro" | "Xiaomi Poco X3"; screenOrientation?: ScreenOrientationPlain; }; } | { iosDeviceInfo: { deviceName: "iPhone 14 Plus" | "iPhone 14 Pro" | "iPhone 15 Pro" | "iPhone XR" | "iPhone 11" | "iPhone 11 Pro Max" | "iPhone 11 Pro" | "iPad (7th generation)" | "iPad (9th generation)" | "iPad (10th generation)" | "iPad mini (6th generation)" | "iPad Air (4th generation)" | "iPad Pro (12.9-inch) (3rd generation)" | "iPad Pro (11-inch) (4th generation)" | "iPhone SE (2nd generation)" | "iPhone SE (3rd generation)" | "iPhone Xs" | "iPhone 12" | "iPhone 12 mini" | "iPhone 12 Pro Max" | "iPhone 12 Pro" | "iPhone 13" | "iPhone 13 mini" | "iPhone 13 Pro Max" | "iPhone 13 Pro" | "iPhone 14" | "iPhone 14 Pro Max" | "iPhone 15" | "iPhone 15 Pro Max" | "iPhone 15 Plus" | "iPhone 16" | "iPhone 16 Pro Max" | "iPhone 16 Pro" | "iPhone 16 Plus"; iosVersion?: "latest" | "latest-1"; screenOrientation?: ScreenOrientationPlain; }; } | { iosDeviceInfo: { deviceName: "iPhone X" | "iPhone 14 Plus" | "iPhone 14 Pro" | "iPhone XR" | "iPhone 11" | "iPhone 11 Pro Max" | "iPhone 11 Pro" | "iPhone SE (2nd generation)" | "iPhone SE (3rd generation)" | "iPhone Xs" | "iPhone 12" | "iPhone 12 mini" | "iPhone 12 Pro Max" | "iPhone 12 Pro" | "iPhone 13" | "iPhone 13 mini" | "iPhone 13 Pro Max" | "iPhone 13 Pro" | "iPhone 14" | "iPhone 14 Pro Max" | "iPhone 8" | "iPhone 8 Plus" | "iPhone Xs Max"; }; })) | { deviceName: DeviceName; screenOrientation?: ScreenOrientationPlain; name?: string; }>;
400
401
  batchId?: string;
@@ -504,6 +505,7 @@ export type appliConfFile = {
504
505
  enablePatterns?: boolean;
505
506
  environmentName?: string;
506
507
  forceFullPageScreenshot?: boolean;
508
+ fully?: boolean;
507
509
  gitMergeBaseTimestamp?: string;
508
510
  latestCommitInfo?: { timestamp: string; sha: string; };
509
511
  hideCaret?: boolean;
@@ -540,7 +542,7 @@ export type appliConfFile = {
540
542
  useDom?: boolean;
541
543
  viewportSize?: { width: number; height: number; };
542
544
  visualGridOptions?: Record<string, any>;
543
- waitBeforeCapture?: number;
545
+ waitBeforeCapture?: number | (() => Promise<void>);
544
546
  waitBeforeScreenshots?: number;
545
547
  browser?: MaybeArray<(({ name?: "chrome" | "chrome-one-version-back" | "chrome-two-versions-back" | "firefox" | "firefox-one-version-back" | "firefox-two-versions-back" | "ie" | "ie10" | "edge" | "edgechromium" | "edgelegacy" | "edgechromium-one-version-back" | "edgechromium-two-versions-back" | "safari" | "safari-earlyaccess" | "safari-one-version-back" | "safari-two-versions-back"; width: number; height: number; } | { chromeEmulationInfo: { deviceName: "iPhone 4" | "iPhone 5/SE" | "iPhone SE 3rd Gen" | "iPhone 6/7/8" | "iPhone 6/7/8 Plus" | "iPhone X" | "iPhone 13 Mini" | "iPhone 14 Plus" | "iPhone 14 Pro" | "iPhone 15 Pro" | "BlackBerry Z30" | "Nexus 4" | "Nexus 5" | "Nexus 5X" | "Nexus 6" | "Nexus 6P" | "Pixel 2" | "Pixel 2 XL" | "LG Optimus L70" | "Nokia N9" | "Nokia Lumia 520" | "Microsoft Lumia 550" | "Microsoft Lumia 950" | "Galaxy S3" | "Galaxy S III" | "Galaxy S5" | "Kindle Fire HDX" | "iPad Mini" | "iPad" | "iPad Pro" | "iPad 8th Gen" | "iPad 10th Gen" | "iPad Mini 4th Gen" | "iPad Mini 6th Gen" | "Blackberry PlayBook" | "Nexus 10" | "Nexus 7" | "Galaxy Note 3" | "Galaxy Note II" | "Galaxy Note 2" | "Galaxy S20" | "Galaxy S22" | "Galaxy S21" | "Galaxy S21 Ultra" | "Galaxy S22 Ultra" | "Laptop with touch" | "Laptop with HiDPI screen" | "Laptop with MDPI screen" | "iPhone XR" | "iPhone XS Max" | "iPhone XS" | "Samsung Galaxy A5" | "Galaxy A5" | "Samsung Galaxy S8" | "Galaxy S8" | "LG G6" | "iPad Air 2" | "iPad 6th Gen" | "iPhone 11" | "iPhone 11 Pro Max" | "iPhone 11 Pro" | "Galaxy S10" | "Galaxy S9 Plus" | "Galaxy S9" | "Galaxy S10 Plus" | "Galaxy S8 Plus" | "Galaxy Note 10" | "Galaxy Note 10 Plus" | "Galaxy Note 9" | "Galaxy Note 8" | "Galaxy Note 4" | "Galaxy Tab A SM-T510" | "Galaxy Tab A7 SM-T500" | "Galaxy Tab S8" | "Galaxy Tab A8" | "Galaxy S23" | "Galaxy S23 Ultra" | "Galaxy A52s" | "Pixel 3" | "Pixel 3 XL" | "Pixel 4" | "Pixel 4 XL" | "Pixel 5" | "iPad 7th Gen" | "OnePlus 7T" | "OnePlus 7T Pro" | "Galaxy Tab S7" | "Sony Xperia 10 II" | "Huawei Mate 50 Pro" | "Huawei Matepad 11" | "Huawei P30" | "Xiaomi Mi A3" | "Huawei P40" | "Xiaomi Redmi Note 8" | "Xiaomi Mi Poco X3 Pro" | "Xiaomi Poco X3"; screenOrientation?: ScreenOrientationPlain; }; } | { iosDeviceInfo: { deviceName: "iPhone 14 Plus" | "iPhone 14 Pro" | "iPhone 15 Pro" | "iPhone XR" | "iPhone 11" | "iPhone 11 Pro Max" | "iPhone 11 Pro" | "iPad (7th generation)" | "iPad (9th generation)" | "iPad (10th generation)" | "iPad mini (6th generation)" | "iPad Air (4th generation)" | "iPad Pro (12.9-inch) (3rd generation)" | "iPad Pro (11-inch) (4th generation)" | "iPhone SE (2nd generation)" | "iPhone SE (3rd generation)" | "iPhone Xs" | "iPhone 12" | "iPhone 12 mini" | "iPhone 12 Pro Max" | "iPhone 12 Pro" | "iPhone 13" | "iPhone 13 mini" | "iPhone 13 Pro Max" | "iPhone 13 Pro" | "iPhone 14" | "iPhone 14 Pro Max" | "iPhone 15" | "iPhone 15 Pro Max" | "iPhone 15 Plus" | "iPhone 16" | "iPhone 16 Pro Max" | "iPhone 16 Pro" | "iPhone 16 Plus"; iosVersion?: "latest" | "latest-1"; screenOrientation?: ScreenOrientationPlain; }; } | { iosDeviceInfo: { deviceName: "iPhone X" | "iPhone 14 Plus" | "iPhone 14 Pro" | "iPhone XR" | "iPhone 11" | "iPhone 11 Pro Max" | "iPhone 11 Pro" | "iPhone SE (2nd generation)" | "iPhone SE (3rd generation)" | "iPhone Xs" | "iPhone 12" | "iPhone 12 mini" | "iPhone 12 Pro Max" | "iPhone 12 Pro" | "iPhone 13" | "iPhone 13 mini" | "iPhone 13 Pro Max" | "iPhone 13 Pro" | "iPhone 14" | "iPhone 14 Pro Max" | "iPhone 8" | "iPhone 8 Plus" | "iPhone Xs Max"; }; })) | { deviceName: DeviceName; screenOrientation?: ScreenOrientationPlain; name?: string; }>;
546
548
  batchId?: string;