@applitools/eyes-cypress 3.50.3 → 3.52.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,135 @@
1
1
  # Changelog
2
2
 
3
+ ## [3.52.0](https://github.com/Applitools-Dev/sdk/compare/js/eyes-cypress@3.51.0...js/eyes-cypress@3.52.0) (2025-04-17)
4
+
5
+
6
+ ### Features
7
+
8
+ * height layout breakpoints ([#2801](https://github.com/Applitools-Dev/sdk/issues/2801)) ([819e241](https://github.com/Applitools-Dev/sdk/commit/819e2418f1fd93220a07dfbcf1157ffcf4995dd7))
9
+
10
+
11
+ ### Bug Fixes
12
+
13
+ * simplify sandbox creation and ensure cleanup after execution ([#2869](https://github.com/Applitools-Dev/sdk/issues/2869)) ([72c5e01](https://github.com/Applitools-Dev/sdk/commit/72c5e01307f6abd83fab365a7e235124caae0694))
14
+
15
+
16
+ ### Performance Improvements
17
+
18
+ * cachify http agent ([#2466](https://github.com/Applitools-Dev/sdk/issues/2466)) ([bc2f4a1](https://github.com/Applitools-Dev/sdk/commit/bc2f4a1fae3c379f061c9199edf4c5257769fb44))
19
+
20
+
21
+ ### Dependencies
22
+
23
+ * @applitools/dom-snapshot bumped to 4.11.18
24
+ #### Bug Fixes
25
+
26
+ * simplify sandbox creation and ensure cleanup after execution ([#2869](https://github.com/Applitools-Dev/sdk/issues/2869)) ([72c5e01](https://github.com/Applitools-Dev/sdk/commit/72c5e01307f6abd83fab365a7e235124caae0694))
27
+
28
+
29
+
30
+ * @applitools/snippets bumped to 2.6.5
31
+ #### Performance Improvements
32
+
33
+ * cachify http agent ([#2466](https://github.com/Applitools-Dev/sdk/issues/2466)) ([bc2f4a1](https://github.com/Applitools-Dev/sdk/commit/bc2f4a1fae3c379f061c9199edf4c5257769fb44))
34
+ * @applitools/driver bumped to 1.21.1
35
+ #### Bug Fixes
36
+
37
+ * executePoll error logging FLD-2870 ([#2890](https://github.com/Applitools-Dev/sdk/issues/2890)) ([a8ff720](https://github.com/Applitools-Dev/sdk/commit/a8ff720efafacabe2023282748a6d8a0f1b3ff73))
38
+
39
+
40
+
41
+ * @applitools/spec-driver-webdriver bumped to 1.2.2
42
+ #### Performance Improvements
43
+
44
+ * cachify http agent ([#2466](https://github.com/Applitools-Dev/sdk/issues/2466)) ([bc2f4a1](https://github.com/Applitools-Dev/sdk/commit/bc2f4a1fae3c379f061c9199edf4c5257769fb44))
45
+
46
+
47
+
48
+ * @applitools/spec-driver-selenium bumped to 1.5.98
49
+ #### Performance Improvements
50
+
51
+ * cachify http agent ([#2466](https://github.com/Applitools-Dev/sdk/issues/2466)) ([bc2f4a1](https://github.com/Applitools-Dev/sdk/commit/bc2f4a1fae3c379f061c9199edf4c5257769fb44))
52
+
53
+
54
+
55
+ * @applitools/spec-driver-puppeteer bumped to 1.4.27
56
+ #### Performance Improvements
57
+
58
+ * cachify http agent ([#2466](https://github.com/Applitools-Dev/sdk/issues/2466)) ([bc2f4a1](https://github.com/Applitools-Dev/sdk/commit/bc2f4a1fae3c379f061c9199edf4c5257769fb44))
59
+
60
+
61
+
62
+ * @applitools/screenshoter bumped to 3.11.1
63
+ #### Performance Improvements
64
+
65
+ * cachify http agent ([#2466](https://github.com/Applitools-Dev/sdk/issues/2466)) ([bc2f4a1](https://github.com/Applitools-Dev/sdk/commit/bc2f4a1fae3c379f061c9199edf4c5257769fb44))
66
+
67
+
68
+
69
+ * @applitools/nml-client bumped to 1.9.1
70
+ #### Performance Improvements
71
+
72
+ * cachify http agent ([#2466](https://github.com/Applitools-Dev/sdk/issues/2466)) ([bc2f4a1](https://github.com/Applitools-Dev/sdk/commit/bc2f4a1fae3c379f061c9199edf4c5257769fb44))
73
+
74
+
75
+
76
+ * @applitools/tunnel-client bumped to 1.6.5
77
+ #### Bug Fixes
78
+
79
+ * enhance error messages in tunnel client ([cab26e6](https://github.com/Applitools-Dev/sdk/commit/cab26e6e3d56fa3cbabaa1a9c68de13046b8f57e))
80
+ * @applitools/ufg-client bumped to 1.16.9
81
+ #### Bug Fixes
82
+
83
+ * basic auth protected resources | FLD-2761 | FMRI-120 ([#2444](https://github.com/Applitools-Dev/sdk/issues/2444)) ([b48cf49](https://github.com/Applitools-Dev/sdk/commit/b48cf49dec50bbf1ed2ba111608a48cf09962565))
84
+
85
+
86
+ #### Performance Improvements
87
+
88
+ * cachify http agent ([#2466](https://github.com/Applitools-Dev/sdk/issues/2466)) ([bc2f4a1](https://github.com/Applitools-Dev/sdk/commit/bc2f4a1fae3c379f061c9199edf4c5257769fb44))
89
+ * @applitools/ec-client bumped to 1.10.9
90
+ #### Performance Improvements
91
+
92
+ * cachify http agent ([#2466](https://github.com/Applitools-Dev/sdk/issues/2466)) ([bc2f4a1](https://github.com/Applitools-Dev/sdk/commit/bc2f4a1fae3c379f061c9199edf4c5257769fb44))
93
+
94
+
95
+
96
+ * @applitools/core bumped to 4.37.0
97
+ #### Features
98
+
99
+ * height layout breakpoints ([#2801](https://github.com/Applitools-Dev/sdk/issues/2801)) ([819e241](https://github.com/Applitools-Dev/sdk/commit/819e2418f1fd93220a07dfbcf1157ffcf4995dd7))
100
+
101
+
102
+
103
+ * @applitools/eyes bumped to 1.34.0
104
+ #### Features
105
+
106
+ * height layout breakpoints ([#2801](https://github.com/Applitools-Dev/sdk/issues/2801)) ([819e241](https://github.com/Applitools-Dev/sdk/commit/819e2418f1fd93220a07dfbcf1157ffcf4995dd7))
107
+
108
+
109
+ #### Bug Fixes
110
+
111
+ * add checks for undefined regions in CheckSettings | AD-9042 ([#2868](https://github.com/Applitools-Dev/sdk/issues/2868)) ([0f7c991](https://github.com/Applitools-Dev/sdk/commit/0f7c9913d64e0535ba5ffe632923a3bf440be65f))
112
+
113
+
114
+
115
+
116
+ ## [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)
117
+
118
+
119
+ ### Features
120
+
121
+ * allow sending callback functions to waitBeforeCapture ([#2780](https://github.com/Applitools-Dev/sdk/issues/2780)) ([4caa2e8](https://github.com/Applitools-Dev/sdk/commit/4caa2e8ae055d3dd48164eeceaa4c691eeadcdd4))
122
+
123
+
124
+ ### Dependencies
125
+
126
+ * @applitools/core bumped to 4.35.1
127
+ #### Bug Fixes
128
+
129
+ * dummy ([9b8ffef](https://github.com/Applitools-Dev/sdk/commit/9b8ffef6277015a9073caf50f5dc5741986fbf07))
130
+ * @applitools/eyes bumped to 1.33.2
131
+
132
+
3
133
  ## [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
134
 
5
135
 
package/README.md CHANGED
@@ -1,12 +1,147 @@
1
- <div align="center">
1
+ ## Applitools Eyes SDK for [Cypress](https://www.cypress.io/)
2
2
 
3
- ![Applitools Eyes](https://i.ibb.co/3hWJK68/applitools-eyes-logo.png)
4
- ### Applitools Eyes SDK for [Cypress](https://www.cypress.io/)
5
- [![npm](https://img.shields.io/npm/v/@applitools/eyes-cypress.svg?style=for-the-badge)](https://www.npmjs.com/package/@applitools/eyes-cypress)
3
+ The Cypress SDK allows you to leverage the Applitools [Ultrafast Grid](/concepts/test-execution/ultrafast-grid) to automatically run tests across all major browsers.
6
4
 
7
- </div>
8
- <br/>
5
+ For general information about working with Cypress, see [Cypress Testing Framework](https://applitools.com/learn/frameworks/cypress-testing/) on the Applitools website.
9
6
 
10
- ## Resources
11
- - [Quick start](https://applitools.com/tutorials/quickstart/web/cypress)
12
- - [API reference](https://applitools.com/docs/api-ref/sdk-api/cypress/)
7
+ ## Installing Eyes Cypress
8
+
9
+ Run the following
10
+ ```bash
11
+ npm i --save @applitools/eyes-cypress
12
+ ```
13
+
14
+ or
15
+ ```bash
16
+ yarn add @applitools/eyes-cypress
17
+ ```
18
+
19
+
20
+ ## Setting up the project
21
+
22
+ On the project, run the following:
23
+
24
+ ```bash
25
+ npx eyes-setup
26
+ ```
27
+
28
+ ### Modifying the configuration file
29
+
30
+ If `npx eyes-setup` did not run successfully, modify the configuration file as follows:
31
+
32
+ #### Cypress version 10 or later
33
+
34
+ Add the following to the `cypress.config.js` file:
35
+
36
+ ```js
37
+ const { defineConfig } = require('cypress')
38
+ const eyesPlugin = require('@applitools/eyes-cypress')
39
+ module.exports = eyesPlugin(defineConfig({
40
+ // the e2e or component configuration
41
+ e2e: {
42
+ setupNodeEvents(on, config) {
43
+ }
44
+ }
45
+ }))
46
+ ```
47
+
48
+ #### Cypress version earlier than version 10:
49
+
50
+ In the `pluginsFile` file, add the following **after** the definition of `module.exports`:
51
+
52
+ ```js
53
+ require('@applitools/eyes-cypress')(module)
54
+ ```
55
+
56
+ ### IntelliSense code completion
57
+
58
+ You can add Eyes-Cypress IntelliSense to your tests using one of the following methods:
59
+
60
+ * [Triple slash directives](#slash)
61
+ * [Reference type declarations via `tsconfig`](#reference)
62
+
63
+
64
+ ### Triple slash directives {#slash}
65
+
66
+ The simplest way to see IntelliSense when typing an Eyes-Cypress command is to add a [triple-slash](https://www.typescriptlang.org/docs/handbook/triple-slash-directives.html) directive to the head of your JavaScript or TypeScript testing file. This will turn the IntelliSense on a per file basis:
67
+
68
+ ```
69
+ /// <reference types="@applitools/eyes-cypress" />
70
+ ```
71
+
72
+ ### Reference type declarations via `tsconfig` {#reference}
73
+
74
+ Eyes-Cypress ships with official type declarations for TypeScript. This allows you to add eyes commands to your TypeScript tests.
75
+ If you do not have TypeScript, for example you use JavaScript, you can add IntelliSense declarations to the project using one of the following:
76
+
77
+ - Add the path to your [`tsconfig`](https://www.typescriptlang.org/docs/handbook/tsconfig-json.html) file:
78
+
79
+ ```json
80
+ {
81
+ "compileroptions": {
82
+ "types": ["@applitools/eyes-cypress", "cypress", "node"]
83
+ }
84
+ }
85
+ ```
86
+
87
+ - In the `cypress/support` folder, create a file `index.d.ts` that contains:
88
+ ```js
89
+ import "@applitools/eyes-cypress"
90
+ ```
91
+
92
+ Normally, this is `cypress/plugins/index.js`. For details, see the [Cypress documentation](https://docs.cypress.io/guides/references/configuration.html#Folders-Files).
93
+
94
+
95
+
96
+ #### Configure custom commands manually
97
+
98
+ Eyes-Cypress exposes new commands to your tests. This means that additional methods will be available on the `cy` object.
99
+ If `npx eyes-setup` does not work, you need to configure these custom commands. As with the plugin, there is no automatic way to configure this in Cypress, so you need to manually add the following code to your `supportFile`:
100
+
101
+ ```js
102
+ import '@applitools/eyes-cypress/commands'
103
+ ```
104
+
105
+ ### Entering the Applitools API key{#API}
106
+
107
+ To authenticate via the Applitools server and run tests, you need to set the environment variable `APPLITOOLS_API_KEY` to the API key provided from Applitools Eyes. For details how to retrieve your API key, see [the Applitools documentation](/getting-started/retrieve-api-key).
108
+
109
+
110
+ #### Entering the API Key on Linux or a Mac
111
+
112
+ ```bash
113
+ export APPLITOOLS_API_KEY=<API_key>
114
+ npx cypress open
115
+ ```
116
+
117
+ #### Entering the API Key on Windows
118
+
119
+ ```bash
120
+ set APPLITOOLS_API_KEY=<API_key>
121
+ npx cypress open
122
+ ```
123
+
124
+ ### Eyes server URL {#URL}
125
+
126
+ If the Eyes server is not deployed in `https://eyes.applitools.com`, you need to set the Server URL in the environment variable `APPLITOOLS_SERVER_URL` before running tests.
127
+
128
+ The server URL of your Applitools Eyes dashboard is in the format `https://<MY_COMPANY>.applitools.com`
129
+
130
+ #### Entering the server URL on Linux or a Mac
131
+
132
+ ```bash
133
+ export APPLITOOLS_SERVER_URL=<YOUR_SERVER_URL>
134
+ ```
135
+
136
+ #### Entering the server URL on Windows
137
+
138
+ ```bash
139
+ set APPLITOOLS_SERVER_URL=<YOUR_SERVER_URL>
140
+ ```
141
+ ## Further information
142
+
143
+ For further information, see:
144
+
145
+ * [Quickstart](https://applitools.com/tutorials/sdks/cypress/quickstart)
146
+ * [Overview](https://applitools.com/tutorials/sdks/cypress)
147
+ * [Changelog](https://applitools.com/tutorials/sdks/cypress/changelog)
@@ -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.52.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.37.0",
58
+ "@applitools/eyes": "1.34.0",
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
@@ -237,14 +237,14 @@ export type CypressCheckSettings = {
237
237
  scrollRootElement?: Element | (Selector | { selector: Selector; type?: string; shadow?: EyesSelector<Selector>; frame?: EyesSelector<Selector>; });
238
238
  fully?: boolean;
239
239
  disableBrowserFetching?: boolean;
240
- layoutBreakpoints?: boolean | Array<number> | { breakpoints: boolean | Array<number>; reload?: boolean; };
240
+ layoutBreakpoints?: boolean | Array<number> | { breakpoints: boolean | Array<number>; reload?: boolean; } | { breakpoints: boolean; heightBreakpoints: boolean; reload?: boolean; };
241
241
  visualGridOptions?: { [key: string]: any; };
242
242
  ufgOptions?: { [key: string]: any; };
243
243
  nmgOptions?: { [key: string]: any; };
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;