@applitools/eyes-cypress 3.26.0 → 3.26.3

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
@@ -8,6 +8,38 @@
8
8
 
9
9
 
10
10
 
11
+
12
+ ## 3.26.3 - 2022/6/17
13
+
14
+ ### Features
15
+ - Add special attribute for pseudo elements
16
+ - Add the ability for the SDK to lazy load the page prior to performing a check window
17
+ - Support padding for regions in the following region types - ignoreRegions, layoutRegions, strictRegions, contentRegions
18
+ - Allow configuration file to be loaded from ancestor directories
19
+ ### Bug fixes
20
+ - Fix rendering issues with Salesforce Lightning design system
21
+ - Fix issue that prevented self-signed certificates from working when connecting through a proxy server
22
+
23
+ ## 3.26.2 - 2022/6/8
24
+
25
+ ### Features
26
+ - add support for secure websocket
27
+ - Allowed `` values in custom properties
28
+ ### Bug fixes
29
+ - Fix incorrect test results when dealing with a page that contains CORS iframes
30
+ - Fixed broken links to enums implementation in the README.md
31
+ - Fix calling `waitBeforeCapture` when failed to set required viewport size
32
+
33
+ ## 3.26.1 - 2022/6/2
34
+
35
+ ### Features
36
+ - Improve type definitions
37
+ - Dorp support for Node.js versions <=12
38
+ ### Bug fixes
39
+ - Support `cy.eyesGetAllTestResults` in TypeScript
40
+ - Set EyesExceptions (such as new test, diffs exception and failed test exception) to exception property in TestResultsSummary
41
+ - Improve error message when failed to set viewport size
42
+
11
43
  ## 3.26.0 - 2022/5/19
12
44
 
13
45
  ### Features
package/README.md CHANGED
@@ -173,43 +173,66 @@ Applitools will take screenshots and perform the visual comparisons in the backg
173
173
  <br/>
174
174
 
175
175
  ### Index
176
- - [Commands](#Commands)
177
- - [Open](#Open)
178
- - [CheckWindow](#Check-window)
179
- - [tag](#tag)
180
- - [target](#target)
181
- - [fully](#fully)
182
- - [selector](#selector)
183
- - [region](#region)
184
- - [ignore](#ignore)
185
- - [floating](#floating)
186
- - [layout](#layout)
187
- - [strict](#strict)
188
- - [content](#content)
189
- - [accessibility](#accessibility)
190
- - [region in shadow DOM](#region-in-shadow-dom)
191
- - [scriptHooks](#scriptHooks)
192
- - [layoutBreakpoints](#layoutBreakpoints)
193
- - [sendDom](#sendDom)
194
- - [variationGroupId](#variationGroupId)
195
- - [waitBeforeCapture](#waitBeforeCapture)
196
- - [Close](#Close)
197
- - [GetAllTestResults](#GetAllTestResults)
198
- - [deletTestResults](#deleteTestResults)
199
- - [Concurrency](#Concurrency)
200
- - [Advanced configuration](#Advanced-configuration)
201
- - [Scoped configuration](#Here-are-the-available-configuration-properties)
202
- - [Global configuration](#global-configuration-properties)
203
- - [Examples](#Method-1-Arguments-for-cyeyesOpen)
204
- - [Arguments for `cy.eyesOpen`](#Method-1-Arguments-for-cyeyesOpen)
205
- - [Environment variables](#Method-2-Environment-variables)
206
- - [The `applitools.config.js` file](#Method-3-The-applitoolsconfigjs-file)
207
- - [Configuring the browser](#Configuring-the-browser)
208
- - [Device emulation](#Device-emulation)
209
- - [IDE Code Completion](#Intelligent-Code-Completion)
210
- - [Triple slash directives](#1-Triple-slash-directives)
211
- - [Reference type declarations via `tsconfig`](#2-Reference-type-declarations-via-tsconfig)
212
- - [Troubleshooting](#Troubleshooting)
176
+ - [Eyes-Cypress](#eyes-cypress)
177
+ - [Installation](#installation)
178
+ - [Install npm package](#install-npm-package)
179
+ - [Configure plugin and commands](#configure-plugin-and-commands)
180
+ - [Automatic configuration](#automatic-configuration)
181
+ - [Manual configuration](#manual-configuration)
182
+ - [1. Configure Eyes-Cypress plugin](#1-configure-eyes-cypress-plugin)
183
+ - [2. Configure custom commands](#2-configure-custom-commands)
184
+ - [3. (Optional) TypeScript configuration](#3-optional-typescript-configuration)
185
+ - [Applitools API key](#applitools-api-key)
186
+ - [Eyes server URL (optional)](#eyes-server-url-optional)
187
+ - [Usage](#usage)
188
+ - [Example](#example)
189
+ - [Best practice for using the SDK](#best-practice-for-using-the-sdk)
190
+ - [Index](#index)
191
+ - [Commands](#commands)
192
+ - [Open](#open)
193
+ - [Check window](#check-window)
194
+ - [Arguments to `cy.eyesCheckWindow`](#arguments-to-cyeyescheckwindow)
195
+ - [`tag`](#tag)
196
+ - [`target`](#target)
197
+ - [`fully`](#fully)
198
+ - [`selector`](#selector)
199
+ - [`region`](#region)
200
+ - [`element`](#element)
201
+ - [`ignore`](#ignore)
202
+ - [`floating`](#floating)
203
+ - [`layout`](#layout)
204
+ - [`strict`](#strict)
205
+ - [`content`](#content)
206
+ - [`accessibility`](#accessibility)
207
+ - [`region in shadow DOM`](#region-in-shadow-dom)
208
+ - [`scriptHooks`](#scripthooks)
209
+ - [`layoutBreakpoints`](#layoutbreakpoints)
210
+ - [`sendDom`](#senddom)
211
+ - [`variationGroupId`](#variationgroupid)
212
+ - [`waitBeforeCapture`](#waitbeforecapture)
213
+ - [`useDom`](#usedom)
214
+ - [`enablePatterns`](#enablepatterns)
215
+ - [`matchLevel`](#matchlevel)
216
+ - [`visualGridOptions`](#visualgridoptions)
217
+ - [Close](#close)
218
+ - [GetAllTestResults](#getalltestresults)
219
+ - [deleteTestResults](#deletetestresults)
220
+ - [Concurrency](#concurrency)
221
+ - [Advanced configuration](#advanced-configuration)
222
+ - [Here are the available configuration properties:](#here-are-the-available-configuration-properties)
223
+ - [Global configuration properties:](#global-configuration-properties)
224
+ - [Method 1: Arguments for `cy.eyesOpen`](#method-1-arguments-for-cyeyesopen)
225
+ - [Method 2: Environment variables](#method-2-environment-variables)
226
+ - [Method 3: The `applitools.config.js` file](#method-3-the-applitoolsconfigjs-file)
227
+ - [Configuring the browser](#configuring-the-browser)
228
+ - [Previous browser versions](#previous-browser-versions)
229
+ - [Getting a screenshot of multiple browsers in parallel](#getting-a-screenshot-of-multiple-browsers-in-parallel)
230
+ - [Device emulation](#device-emulation)
231
+ - [iOS device](#ios-device)
232
+ - [Intelligent Code Completion](#intelligent-code-completion)
233
+ - [There are two ways you can add Eyes-Cypress intelliSense to your tests:](#there-are-two-ways-you-can-add-eyes-cypress-intellisense-to-your-tests)
234
+ - [1. Triple slash directives](#1-triple-slash-directives)
235
+ - [2. Reference type declarations via `tsconfig`](#2-reference-type-declarations-via-tsconfig)
213
236
 
214
237
  <br/><hr/><br/>
215
238
 
@@ -827,7 +850,7 @@ cy.eyesOpen({
827
850
 
828
851
  Possible values for screen orientation are `landscape` and `portrait`, and if no value is specified, the default is `portrait`.
829
852
 
830
- The list of device names is available at https://github.com/applitools/eyes.sdk.javascript1/blob/master/packages/eyes-sdk-core/lib/config/DeviceName.js
853
+ The list of device names is available at https://github.com/applitools/eyes.sdk.javascript1/blob/master/packages/eyes-api/src/enums/DeviceName.ts
831
854
 
832
855
  In addition, it's possible to use chrome's device emulation with custom viewport sizes, pixel density and mobile mode, by passing `deviceScaleFactor` and `mobile` in addition to `width` and `height`. For example:
833
856
 
@@ -859,7 +882,7 @@ cy.eyesOpen({
859
882
  })
860
883
  ```
861
884
 
862
- The list of devices is available at https://github.com/applitools/eyes.sdk.javascript1/blob/master/packages/eyes-sdk-core/lib/config/IosDeviceName.js
885
+ The list of devices is available at https://github.com/applitools/eyes.sdk.javascript1/blob/master/packages/eyes-api/src/enums/IosDeviceName.ts
863
886
 
864
887
  Possible values for `iosVersion` are:
865
888
 
@@ -2,7 +2,6 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  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
- context = refreshContext(context);
6
5
  let scriptToExecute;
7
6
  if (script.includes('dom-snapshot') ||
8
7
  script.includes('dom-capture') ||
@@ -23,13 +22,20 @@ function mainContext() {
23
22
  }
24
23
  exports.mainContext = mainContext;
25
24
  function parentContext(context) {
26
- if (!context)
27
- return; // because Cypress doesn't support cross origin iframe, then childContext might return null, and then the input to parentContext might be null
25
+ // because Cypress doesn't support cross origin iframe, then childContext might return null, and then the input to parentContext might be null
26
+ if (!context) {
27
+ throw new Error('Context is not accessible');
28
+ }
29
+ ;
28
30
  return context === mainContext() ? context : context.defaultView.frameElement.ownerDocument;
29
31
  }
30
32
  exports.parentContext = parentContext;
31
33
  function childContext(_context, element) {
32
- return element.contentDocument; // null in case of cross origin iframe
34
+ if (element.contentDocument)
35
+ return element.contentDocument;
36
+ else {
37
+ throw new Error('Context is not accessible');
38
+ }
33
39
  }
34
40
  exports.childContext = childContext;
35
41
  function getViewportSize() {
@@ -55,7 +61,6 @@ function transformSelector(selector) {
55
61
  }
56
62
  exports.transformSelector = transformSelector;
57
63
  function findElement(context, selector, parent) {
58
- context = refreshContext(context);
59
64
  const eyesSelector = selector;
60
65
  const root = parent !== null && parent !== void 0 ? parent : context;
61
66
  const sel = typeof selector === 'string' ? selector : eyesSelector.selector;
@@ -68,7 +73,6 @@ function findElement(context, selector, parent) {
68
73
  }
69
74
  exports.findElement = findElement;
70
75
  function findElements(context, selector, parent) {
71
- context = refreshContext(context);
72
76
  const eyesSelector = selector;
73
77
  const root = parent !== null && parent !== void 0 ? parent : context;
74
78
  const sel = typeof selector === 'string' ? selector : eyesSelector.selector;
@@ -86,12 +90,10 @@ function findElements(context, selector, parent) {
86
90
  }
87
91
  exports.findElements = findElements;
88
92
  function getTitle(context) {
89
- context = refreshContext(context);
90
93
  return context.title;
91
94
  }
92
95
  exports.getTitle = getTitle;
93
96
  function getUrl(context) {
94
- context = refreshContext(context);
95
97
  return context.location.href;
96
98
  }
97
99
  exports.getUrl = getUrl;
@@ -100,11 +102,6 @@ function getCookies() {
100
102
  return Cypress.automation('get:cookies', {});
101
103
  }
102
104
  exports.getCookies = getCookies;
103
- // we need to method to reset the context in case the user called open before visit
104
- function refreshContext(context) {
105
- //@ts-ignore
106
- return (context && context.defaultView) ? context : cy.state('window').document;
107
- }
108
105
  // export function takeScreenshot(page: Driver): Promise<Buffer>;
109
106
  // export function visit(page: Driver, url: string): Promise<void>; (??)
110
107
  // export function isStaleElementError(err: any): boolean;
package/index.d.ts ADDED
@@ -0,0 +1,89 @@
1
+ /// <reference types="cypress" />
2
+
3
+ import type * as types from '@applitools/types'
4
+ import type * as api from '@applitools/eyes-api'
5
+
6
+ type MaybeArray<T> = T | T[]
7
+
8
+ type LegacyRegion = {left: number; top: number; width: number; height: number}
9
+ type Selector = {selector: string; type?: 'css' | 'xpath', nodeType?: 'element' | 'shadow-root'} | 'string'
10
+ type Element = HTMLElement | JQuery<HTMLElement>
11
+
12
+ interface CypressCheckSettings extends types.CheckSettings<Element, Selector> {
13
+ tag?: CypressCheckSettings['name']
14
+
15
+ target?: 'window' | 'region'
16
+ selector?: Selector
17
+ element?: Element
18
+
19
+ ignore?: MaybeArray<CypressCheckSettings['ignoreRegions'][number] | LegacyRegion>
20
+ layout?: MaybeArray<CypressCheckSettings['layoutRegions'][number] | LegacyRegion>
21
+ content?: MaybeArray<CypressCheckSettings['contentRegions'][number] | LegacyRegion>
22
+ strict?: MaybeArray<CypressCheckSettings['strictRegions'][number] | LegacyRegion>
23
+ floating?: MaybeArray<CypressCheckSettings['floatingRegions'][number] | (({element: Element} | Selector | LegacyRegion) & {maxUpOffset?: number; maxDownOffset?: number; maxLeftOffset?: number; maxRightOffset?: number})>
24
+ accessibility?: MaybeArray<CypressCheckSettings['accessibilityRegions'][number] | (({element: Element} | Selector | LegacyRegion) & {accessibilityType?: types.AccessibilityRegionType})>
25
+
26
+ scriptHooks?: CypressCheckSettings['hooks']
27
+ }
28
+
29
+ interface CypressEyesConfig extends types.EyesConfig<Element, Selector> {
30
+ browser?: MaybeArray<CypressEyesConfig['browsersInfo'][number] | {deviceName: string; screenOrientation?: types.ScreenOrientation; name?: string}>
31
+
32
+ batchId?: CypressEyesConfig['batch']['id']
33
+ batchName?: CypressEyesConfig['batch']['name']
34
+ batchSequence?: CypressEyesConfig['batch']['sequenceName']
35
+ notifyOnCompletion?: CypressEyesConfig['batch']['notifyOnCompletion']
36
+
37
+ envName?: CypressEyesConfig['environmentName']
38
+
39
+ ignoreCaret?: CypressEyesConfig['defaultMatchSettings']['ignoreCaret']
40
+ matchLevel?: CypressEyesConfig['defaultMatchSettings']['matchLevel']
41
+ accessibilitySettings?: CypressEyesConfig['defaultMatchSettings']['accessibilitySettings']
42
+ ignoreDisplacements?: CypressEyesConfig['defaultMatchSettings']['ignoreDisplacements']
43
+ }
44
+
45
+ declare global {
46
+ namespace Cypress {
47
+ interface Chainable {
48
+ /**
49
+ * Create an Applitools test.
50
+ * This will start a session with the Applitools server.
51
+ * @example
52
+ * cy.eyesOpen({ appName: 'My App' })
53
+ */
54
+ eyesOpen(config?: CypressEyesConfig): null
55
+
56
+ /**
57
+ * Generate a screenshot of the current page and add it to the Applitools Test.
58
+ * @example
59
+ * cy.eyesCheckWindow()
60
+ *
61
+ * OR
62
+ *
63
+ * cy.eyesCheckWindow({
64
+ * target: 'region',
65
+ * selector: '.my-element'
66
+ * });
67
+ */
68
+ eyesCheckWindow(tag?: string): null
69
+ eyesCheckWindow(settings?: CypressCheckSettings): null
70
+
71
+ /**
72
+ * Close the applitools test and check that all screenshots are valid.
73
+ * @example cy.eyesClose()
74
+ */
75
+ eyesClose(): null
76
+
77
+ /**
78
+ * Returns an object with the applitools test results from a given test / test file. This should be called after close.
79
+ * @example
80
+ * after(() => {
81
+ * cy.eyesGetAllTestResults().then(summary => {
82
+ * console.log(summary)
83
+ * })
84
+ * })
85
+ */
86
+ eyesGetAllTestResults(): Chainable<api.TestResultsSummary>
87
+ }
88
+ }
89
+ }
package/package.json CHANGED
@@ -1,77 +1,78 @@
1
1
  {
2
2
  "name": "@applitools/eyes-cypress",
3
- "version": "3.26.0",
4
- "main": "index.js",
3
+ "version": "3.26.3",
4
+ "repository": {
5
+ "type": "git",
6
+ "url": "git://github.com/applitools/eyes.sdk.javascript1.git",
7
+ "directory": "packages/eyes-cypress"
8
+ },
5
9
  "license": "SEE LICENSE IN LICENSE",
10
+ "aliases": [
11
+ "cypress",
12
+ "cy"
13
+ ],
14
+ "main": "index.js",
15
+ "types": "./index.d.ts",
6
16
  "bin": {
7
17
  "eyes-setup": "./bin/eyes-setup.js"
8
18
  },
19
+ "files": [
20
+ "src",
21
+ "dist",
22
+ "bin",
23
+ "index.js",
24
+ "commands.js",
25
+ "index.d.ts"
26
+ ],
9
27
  "scripts": {
28
+ "lint": "eslint \"**/*.js\"",
10
29
  "build": "tsc",
11
- "render": "run(){ npx cypress run --config integrationFolder=test/fixtures/testApp/cypress/render,pluginsFile=test/fixtures/testApp/cypress/plugins/index-render.js,supportFile=test/fixtures/testApp/cypress/support/index-run.js --env url=$1; }; run",
30
+ "generate:tests": "coverage-tests generate",
31
+ "test": "yarn test:unit && yarn test:it && yarn test:e2e && yarn test:ts && yarn test:coverage",
12
32
  "test:unit": "mocha --no-timeouts 'test/unit/**/*.test.js'",
13
33
  "test:it": "mocha --no-timeouts 'test/it/**/*.test.js'",
14
34
  "test:e2e": "mkdir -p test/fixtures/testAppCopies && mocha --no-timeouts 'test/e2e/**/*.test.js'",
15
35
  "test:ts:compile": "tsc --project test/e2e/ts/cypress",
16
36
  "test:ts:run": "cypress run --config-file test/e2e/ts/cypress-ts.json",
17
37
  "test:ts": "yarn test:ts:compile && yarn test:ts:run",
18
- "lint": "eslint \"**/*.js\"",
19
- "test": "yarn test:unit && yarn test:it && yarn test:e2e && yarn test:ts && yarn test:coverage",
38
+ "test:coverage": "yarn generate:tests && cd test/coverage/generic && unset APPLITOOLS_API_KEY && APPLITOOLS_BATCH_NAME='JS Coverage Tests: eyes-selenium' APPLITOOLS_BATCH_ID=$(uuidgen) cypress run",
20
39
  "cypress": "cypress open --config-file test/fixtures/cypress-play.json",
21
40
  "cypress:new": "node_modules/cypress-new/bin/cypress open --config-file test/fixtures/cypress-play.json",
22
41
  "cypress:run": "cypress run --config-file test/fixtures/cypress-play.json --spec=test/fixtures/testApp/cypress/integration-play/play.js",
23
42
  "cypress:run:new": "node_modules/cypress-new/bin/cypress run --config-file test/fixtures/cypress-play.json --spec=test/fixtures/testApp/cypress/integration-play/play.js",
24
43
  "cypress:play": "cd test/fixtures/testApp && cypress run --config integrationFolder=cypress/integration-play,pluginsFile=cypress/plugins/index-play.js,supportFile=cypress/support/index-run.js --spec=cypress/integration-play/play.js",
44
+ "render": "run(){ npx cypress run --config integrationFolder=test/fixtures/testApp/cypress/render,pluginsFile=test/fixtures/testApp/cypress/plugins/index-render.js,supportFile=test/fixtures/testApp/cypress/support/index-run.js --env url=$1; }; run",
45
+ "prepublish:setup": "sudo apt-get install xvfb",
46
+ "deps": "bongo deps",
25
47
  "preversion": "yarn build && bongo preversion --skip-deps --verifyPendingChanges",
26
48
  "version": "bongo version --withPendingChanges",
27
- "postversion": "bongo postversion --skip-release-notification",
28
- "deps": "bongo deps",
29
- "generate:tests": "coverage-tests generate",
30
- "test:coverage": "yarn generate:tests && cd test/coverage/generic && unset APPLITOOLS_API_KEY && APPLITOOLS_BATCH_NAME='JS Coverage Tests: eyes-selenium' APPLITOOLS_BATCH_ID=$(uuidgen) cypress run",
31
- "prepublish:setup": "sudo apt-get install xvfb"
32
- },
33
- "files": [
34
- "src",
35
- "dist",
36
- "bin",
37
- "index.js",
38
- "commands.js",
39
- "eyes-index.d.ts"
40
- ],
41
- "types": "./eyes-index.d.ts",
42
- "engines": {
43
- "node": ">=8.0.0"
49
+ "postversion": "bongo postversion --skip-release-notification"
44
50
  },
45
- "repository": {
46
- "type": "git",
47
- "url": "git://github.com/applitools/eyes.sdk.javascript1.git",
48
- "directory": "packages/eyes-cypress"
51
+ "husky": {
52
+ "hooks": {
53
+ "pre-push": "yarn bongo lint"
54
+ }
49
55
  },
50
56
  "dependencies": {
51
- "@applitools/dom-snapshot": "4.5.12",
52
- "@applitools/eyes-api": "1.4.1",
53
- "@applitools/eyes-universal": "2.5.15",
57
+ "@applitools/eyes-api": "1.7.0",
58
+ "@applitools/eyes-universal": "2.9.1",
54
59
  "@applitools/functional-commons": "1.6.0",
55
- "@applitools/logger": "1.1.5",
56
- "@applitools/visual-grid-client": "15.12.28",
57
- "body-parser": "1.19.0",
60
+ "@applitools/logger": "1.1.12",
61
+ "@applitools/visual-grid-client": "15.12.45",
58
62
  "chalk": "3.0.0",
59
- "cors": "2.8.5",
60
- "express": "4.17.1",
61
- "lodash.flatten": "4.4.0",
62
63
  "uuid": "8.3.2",
63
64
  "ws": "8.5.0"
64
65
  },
65
66
  "devDependencies": {
66
- "@applitools/bongo": "^2.1.0",
67
+ "@applitools/bongo": "^2.1.5",
67
68
  "@applitools/scripts": "1.1.0",
68
69
  "@applitools/sdk-coverage-tests": "^2.3.18",
69
70
  "@applitools/snaptdout": "1.0.1",
70
- "@applitools/test-server": "1.0.8",
71
- "@applitools/test-utils": "1.3.2",
72
- "@applitools/types": "^1.4.3",
73
- "@applitools/utils": "1.3.0",
74
- "@types/node": "17.0.13",
71
+ "@applitools/test-server": "1.1.1",
72
+ "@applitools/test-utils": "1.3.3",
73
+ "@applitools/types": "^1.5.3",
74
+ "@applitools/utils": "1.3.8",
75
+ "@types/node": "12",
75
76
  "@types/ws": "^8.2.2",
76
77
  "@typescript-eslint/eslint-plugin": "^5.10.2",
77
78
  "@typescript-eslint/parser": "^5.10.2",
@@ -93,9 +94,7 @@
93
94
  "prettier": "1.19.1",
94
95
  "typescript": "4.6.4"
95
96
  },
96
- "husky": {
97
- "hooks": {
98
- "pre-push": "yarn bongo lint"
99
- }
97
+ "engines": {
98
+ "node": ">=12.13.0"
100
99
  }
101
100
  }
@@ -110,7 +110,7 @@ Cypress.Commands.add('eyesOpen', function(args = {}) {
110
110
  const driver = refer.ref(cy.state('window').document);
111
111
 
112
112
  if (!connectedToUniversal) {
113
- socket.connect(`ws://localhost:${Cypress.config('eyesPort')}/eyes`);
113
+ socket.connect(`wss://localhost:${Cypress.config('eyesPort')}/eyes`);
114
114
  connectedToUniversal = true;
115
115
  socket.emit('Core.makeSDK', {
116
116
  name: 'eyes.cypress',
@@ -152,6 +152,7 @@ Cypress.Commands.add('eyesCheckWindow', (args = {}) =>
152
152
  if (isCurrentTestDisabled) return;
153
153
 
154
154
  setRootContext();
155
+ const driver = refer.ref(cy.state('window').document);
155
156
 
156
157
  Cypress.log({name: 'Eyes: check window'});
157
158
 
@@ -160,6 +161,7 @@ Cypress.Commands.add('eyesCheckWindow', (args = {}) =>
160
161
  return socket.request('Eyes.check', {
161
162
  eyes,
162
163
  settings: checkSettings,
164
+ driver,
163
165
  });
164
166
  }),
165
167
  );
@@ -4,7 +4,6 @@ export type Context = Document & {__applitoolsBrand?: never};
4
4
  export type Element = HTMLElement & {__applitoolsBrand?: never};
5
5
 
6
6
  export function executeScript(context: Context, script: string, arg: any): any {
7
- context = refreshContext(context)
8
7
 
9
8
  let scriptToExecute;
10
9
  if (
@@ -28,13 +27,20 @@ export function mainContext(): Context {
28
27
  }
29
28
 
30
29
  export function parentContext(context: Context): Context {
31
- if (!context) return; // because Cypress doesn't support cross origin iframe, then childContext might return null, and then the input to parentContext might be null
30
+ // because Cypress doesn't support cross origin iframe, then childContext might return null, and then the input to parentContext might be null
31
+ if (!context) {
32
+ throw new Error('Context is not accessible')
33
+ };
32
34
 
33
35
  return context === mainContext() ? context : context.defaultView.frameElement.ownerDocument
34
36
  }
35
37
 
36
38
  export function childContext(_context: Context, element: HTMLIFrameElement): Context {
37
- return element.contentDocument // null in case of cross origin iframe
39
+ if(element.contentDocument)
40
+ return element.contentDocument
41
+ else {
42
+ throw new Error('Context is not accessible')
43
+ }
38
44
  }
39
45
 
40
46
  export function getViewportSize(): Object {
@@ -60,7 +66,6 @@ export function transformSelector(selector: Selector): Selector {
60
66
  }
61
67
 
62
68
  export function findElement(context: Context, selector: Selector, parent?: Element) {
63
- context = refreshContext(context)
64
69
  const eyesSelector = (selector as EyesSelector)
65
70
  const root = parent ?? context
66
71
  const sel = typeof selector === 'string' ? selector : eyesSelector.selector
@@ -72,7 +77,6 @@ export function findElement(context: Context, selector: Selector, parent?: Eleme
72
77
  }
73
78
 
74
79
  export function findElements(context: Context, selector: Selector, parent: Element){
75
- context = refreshContext(context)
76
80
  const eyesSelector = (selector as EyesSelector)
77
81
  const root = parent ?? context
78
82
  const sel = typeof selector === 'string' ? selector : eyesSelector.selector
@@ -91,12 +95,10 @@ export function findElements(context: Context, selector: Selector, parent: Eleme
91
95
  }
92
96
 
93
97
  export function getTitle(context: Context): string {
94
- context = refreshContext(context)
95
98
  return context.title
96
99
  }
97
100
 
98
101
  export function getUrl(context: Context): string {
99
- context = refreshContext(context)
100
102
  return context.location.href
101
103
  }
102
104
 
@@ -105,11 +107,6 @@ export function getCookies(): Array<any> {
105
107
  return Cypress.automation('get:cookies', {})
106
108
  }
107
109
 
108
- // we need to method to reset the context in case the user called open before visit
109
- function refreshContext(context: Context) {
110
- //@ts-ignore
111
- return (context && context.defaultView) ? context : cy.state('window').document
112
- }
113
110
 
114
111
  // export function takeScreenshot(page: Driver): Promise<Buffer>;
115
112
 
@@ -1,11 +1,12 @@
1
1
  'use strict';
2
- const {configParams, ConfigUtils, TypeUtils} = require('@applitools/visual-grid-client');
2
+ const utils = require('@applitools/utils');
3
+ const {configParams, TypeUtils} = require('@applitools/visual-grid-client');
3
4
  const DEFAULT_TEST_CONCURRENCY = 5;
4
5
  const uuid = require('uuid');
5
6
 
6
7
  function makeConfig() {
7
- const config = ConfigUtils.getConfig({
8
- configParams: [
8
+ const config = utils.config.getConfig({
9
+ params: [
9
10
  ...configParams,
10
11
  'failCypressOnDiff',
11
12
  'tapDirPath',
@@ -1,21 +1,46 @@
1
1
  'use strict';
2
- const {makeHandler} = require('../../dist/plugin/handler');
3
2
  const connectSocket = require('./webSocket');
4
3
  const {makeServerProcess} = require('@applitools/eyes-universal');
5
4
  const {TestResults} = require('@applitools/visual-grid-client');
6
5
  const handleTestResults = require('./handleTestResults');
6
+ const path = require('path');
7
+ const fs = require('fs');
8
+ const {Server: HttpsServer} = require('https');
9
+ const {Server: WSServer} = require('ws');
7
10
 
8
11
  function makeStartServer({logger}) {
9
12
  return async function startServer() {
10
- const {server, port} = await makeHandler({singleton: false});
13
+ const key = fs.readFileSync(path.resolve(__dirname, '../pem/server.key'));
14
+ const cert = fs.readFileSync(path.resolve(__dirname, '../pem/server.cert'));
15
+ let port;
11
16
 
12
- const {port: universalPort, close: closeUniversalServer} = await makeServerProcess();
17
+ const https = new HttpsServer({
18
+ key,
19
+ cert,
20
+ });
21
+ await https.listen(0, err => {
22
+ if (err) {
23
+ logger.log('error starting plugin server', err);
24
+ } else {
25
+ logger.log(`plugin server running at port: ${https.address().port}`);
26
+ port = https.address().port;
27
+ }
28
+ });
29
+
30
+ const wss = new WSServer({server: https, path: '/eyes', maxPayload: 254 * 1024 * 1024});
31
+
32
+ wss.on('close', () => https.close());
33
+
34
+ const {port: universalPort, close: closeUniversalServer} = await makeServerProcess({
35
+ key: path.resolve(__dirname, '../pem/server.key'),
36
+ cert: path.resolve(__dirname, '../pem/server.cert'),
37
+ });
13
38
 
14
39
  const managers = [];
15
40
  let socketWithUniversal;
16
41
 
17
- server.on('connection', socketWithClient => {
18
- socketWithUniversal = connectSocket(`ws://localhost:${universalPort}/eyes`);
42
+ wss.on('connection', socketWithClient => {
43
+ socketWithUniversal = connectSocket(`wss://localhost:${universalPort}/eyes`);
19
44
 
20
45
  socketWithUniversal.setPassthroughListener(message => {
21
46
  logger.log('<== ', message.toString().slice(0, 1000));
@@ -69,7 +94,7 @@ function makeStartServer({logger}) {
69
94
  });
70
95
 
71
96
  return {
72
- server,
97
+ server: wss,
73
98
  port,
74
99
  closeManager,
75
100
  closeBatches,
@@ -6,12 +6,12 @@ function getFilePath(type, cypressConfig, cwd) {
6
6
  let filePath = {
7
7
  plugins: join('cypress', 'plugins', 'index.js'),
8
8
  support: join('cypress', 'support', 'index.js'),
9
- typeScript: join('cypress', 'support', 'eyes-index.d.ts'),
9
+ typeScript: join('cypress', 'support', 'index.d.ts'),
10
10
  }[type];
11
11
 
12
12
  if (type === 'typeScript' && cypressConfig && cypressConfig[`supportFile`]) {
13
13
  const supportDir = dirname(cypressConfig[`supportFile`]);
14
- filePath = resolve(supportDir, 'eyes-index.d.ts');
14
+ filePath = resolve(supportDir, 'index.d.ts');
15
15
  }
16
16
 
17
17
  filePath = (cypressConfig && cypressConfig[`${type}File`]) || filePath;
@@ -1,55 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.makeHandler = void 0;
4
- const http_1 = require("http");
5
- const ws_1 = require("ws");
6
- const { name, version } = require('../../package.json'); // TODO is the handshake needed at all?
7
- const TOKEN_HEADER = 'x-eyes-universal-token';
8
- const TOKEN = `${name}@${version}`;
9
- // TODO make default port 0 and return actual port
10
- async function makeHandler({ port = 31077, singleton = true, lazy = false } = {}) {
11
- const http = new http_1.Server();
12
- http.on('request', (request, response) => {
13
- if (request.url === '/handshake') {
14
- if (request.headers[TOKEN_HEADER] === TOKEN) {
15
- response.writeHead(200, { [TOKEN_HEADER]: TOKEN });
16
- }
17
- else {
18
- response.writeHead(400);
19
- }
20
- response.end();
21
- }
22
- });
23
- http.listen(port, 'localhost');
24
- return new Promise((resolve, reject) => {
25
- http.on('listening', () => {
26
- const ws = new ws_1.Server({ server: http, path: '/eyes' });
27
- ws.on('close', () => http.close());
28
- resolve({ server: ws, port });
29
- });
30
- http.on('error', async (err) => {
31
- if (!lazy && err.code === 'EADDRINUSE') {
32
- if (singleton && (await isHandshakable(port))) {
33
- return resolve({ port });
34
- }
35
- else {
36
- return resolve(await makeHandler({ port: port + 1, singleton }));
37
- }
38
- }
39
- reject(err);
40
- });
41
- });
42
- }
43
- exports.makeHandler = makeHandler;
44
- async function isHandshakable(port) {
45
- return new Promise(resolve => {
46
- const handshake = (0, http_1.request)(`http://localhost:${port}/handshake`, {
47
- headers: { [TOKEN_HEADER]: TOKEN },
48
- });
49
- handshake.on('response', ({ statusCode, headers }) => {
50
- resolve(statusCode === 200 && headers[TOKEN_HEADER] === TOKEN);
51
- });
52
- handshake.on('error', () => resolve(false));
53
- handshake.end();
54
- });
55
- }
package/eyes-index.d.ts DELETED
@@ -1,48 +0,0 @@
1
- /// <reference types="Cypress" />
2
- /// <reference types="@applitools/visual-grid-client" />
3
- import {TestResultsSummary} from '@applitools/eyes-api';
4
-
5
- declare global {
6
- namespace Cypress {
7
- interface Chainable {
8
- /**
9
- * Create an Applitools test.
10
- * This will start a session with the Applitools server.
11
- * @example
12
- * cy.eyesOpen({ appName: 'My App' })
13
- */
14
- eyesOpen(options?: Eyes.Open.Options): null // add isDisabled
15
-
16
- /**
17
- * Generate a screenshot of the current page and add it to the Applitools Test.
18
- * @example
19
- * cy.eyesCheckWindow()
20
- *
21
- * OR
22
- *
23
- * cy.eyesCheckWindow({
24
- * target: 'region',
25
- * selector: '.my-element'
26
- * });
27
- */
28
- eyesCheckWindow(config?: Eyes.Check.Options|String): null
29
-
30
- /**
31
- * Close the applitools test and check that all screenshots are valid.
32
- * @example cy.eyesClose()
33
- */
34
- eyesClose(): null
35
-
36
- /**
37
- * Returns an object with the applitools test results from a given test / test file. This should be called after close.
38
- * @example
39
- * after(() => {
40
- * cy.eyesGetAllTestResults().then(summary => {
41
- * console.log(summary)
42
- * })
43
- * })
44
- */
45
- eyesGetAllTestResults(): Chainable<TestResultsSummary>
46
- }
47
- }
48
- }
@@ -1,58 +0,0 @@
1
- import {Server as HTTPServer, request} from 'http'
2
- import {Server as WSServer} from 'ws'
3
-
4
- const {name, version} = require('../../package.json') // TODO is the handshake needed at all?
5
- const TOKEN_HEADER = 'x-eyes-universal-token'
6
- const TOKEN = `${name}@${version}`
7
-
8
- // TODO make default port 0 and return actual port
9
- export async function makeHandler({port = 31077, singleton = true, lazy = false} = {}): Promise<{
10
- server?: WSServer
11
- port: number
12
- }> {
13
- const http = new HTTPServer()
14
- http.on('request', (request, response) => {
15
- if (request.url === '/handshake') {
16
- if (request.headers[TOKEN_HEADER] === TOKEN) {
17
- response.writeHead(200, {[TOKEN_HEADER]: TOKEN})
18
- } else {
19
- response.writeHead(400)
20
- }
21
- response.end()
22
- }
23
- })
24
-
25
- http.listen(port, 'localhost')
26
-
27
- return new Promise((resolve, reject) => {
28
- http.on('listening', () => {
29
- const ws = new WSServer({server: http, path: '/eyes'})
30
- ws.on('close', () => http.close())
31
- resolve({server: ws, port})
32
- })
33
-
34
- http.on('error', async (err: Error & {code: string}) => {
35
- if (!lazy && err.code === 'EADDRINUSE') {
36
- if (singleton && (await isHandshakable(port))) {
37
- return resolve({port})
38
- } else {
39
- return resolve(await makeHandler({port: port + 1, singleton}))
40
- }
41
- }
42
- reject(err)
43
- })
44
- })
45
- }
46
-
47
- async function isHandshakable(port: number) {
48
- return new Promise(resolve => {
49
- const handshake = request(`http://localhost:${port}/handshake`, {
50
- headers: {[TOKEN_HEADER]: TOKEN},
51
- })
52
- handshake.on('response', ({statusCode, headers}) => {
53
- resolve(statusCode === 200 && headers[TOKEN_HEADER] === TOKEN)
54
- })
55
- handshake.on('error', () => resolve(false))
56
- handshake.end()
57
- })
58
- }