@applitools/eyes-cypress 3.27.5 → 3.27.7

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
@@ -10,6 +10,24 @@
10
10
 
11
11
 
12
12
 
13
+
14
+ ## 3.27.7 - 2022/11/17
15
+
16
+ ### Features
17
+ - Added new selector extensions `child` and `fallback`
18
+ - Use user agent metadata to improve browser environment detection logic
19
+ - Use APPLITOOLS_CONCURRENCY env variable to specify concurrency
20
+ ### Bug fixes
21
+ - Support parallel run of multiple `Cypress` instances
22
+ - Add support for regionId and padding for accessibility and floating regions
23
+
24
+ ## 3.27.6 - 2022/10/28
25
+
26
+ ### Features
27
+ - Add support for componenet testing and cypress config ts file
28
+ ### Bug fixes
29
+ - Fixed issue with universal not working in cypress@6
30
+
13
31
  ## 3.27.5 - 2022/10/20
14
32
 
15
33
  ### Features
package/README.md CHANGED
@@ -70,13 +70,13 @@ Add this file to your project with either:
70
70
  1. Adding the path to your [tsconfig](https://www.typescriptlang.org/docs/handbook/tsconfig-json.html) file:
71
71
  ```
72
72
  {
73
- "files": ["./node_modules/@applitools/eyes-cypress/eyes-index.d.ts"],
73
+ "files": ["./node_modules/@applitools/eyes-cypress/index.d.ts"],
74
74
  ...
75
75
  }
76
76
  ```
77
77
  2. Copying the file to to your [cypress/support/](https://docs.cypress.io/guides/core-concepts/writing-and-organizing-tests.html#Folder-Structure) dir:
78
78
  ```
79
- cp node_modules/@applitools/eyes-cypress/eyes-index.d.ts ./cypress/support/
79
+ cp node_modules/@applitools/eyes-cypress/index.d.ts ./cypress/support/
80
80
  ```
81
81
  ### Applitools API key
82
82
 
@@ -505,7 +505,24 @@ cy.get('some-region').then(el => {
505
505
  // will add padding of 20px to all JQuery elements at the top, button, right and left of the region
506
506
  ignore: {element: el, padding: 20},
507
507
  // will add padding for a DOM element on the top of the region
508
- content: {element: el[0], padding: {top:10}}
508
+ content: {element: el[0], padding: {top:10}},
509
+ accessibility: {
510
+ region: {
511
+ accessibilityType: 'LargeText',
512
+ selector: 'accessibilityRegion',
513
+ },
514
+ padding: {left: 5},
515
+ },
516
+ floating:{
517
+ region: {
518
+ selector: 'floatingRegion',
519
+ },
520
+ maxDownOffset: 3,
521
+ maxLeftOffset: 20,
522
+ maxRightOffset: 30,
523
+ maxUpOffset: 3,
524
+ padding: {top: 20},
525
+ },
509
526
  })
510
527
 
511
528
  })
@@ -662,10 +679,27 @@ cy.get('.region.two:nth-child(2)').then(el => {
662
679
  cy.eyesCheckWindow({
663
680
  fully: false,
664
681
  ignore: [
665
- {region: {type: 'css', selector: '.region.three:nth-child(3n)'}, regionId: 'region3'},
666
- {type: 'xpath', selector: '//div[@class="region one"][3]'},
682
+ {region: {type: 'css', selector: 'ignore1'}, regionId: 'region3'},
683
+ {type: 'xpath', selector: 'ignore2'},
667
684
  {element: el, regionId: 'my-region-id'},
668
685
  ],
686
+ accessibility: [{
687
+ region: {
688
+ accessibilityType: 'LargeText',
689
+ selector: 'accessibilityRegion',
690
+ },
691
+ regionId: 'accesibility-regionId',
692
+ },],
693
+ floating: [{
694
+ region: {
695
+ selector: 'floatingRegion',
696
+ },
697
+ maxDownOffset: 3,
698
+ maxLeftOffset: 20,
699
+ maxRightOffset: 30,
700
+ maxUpOffset: 3,
701
+ regionId: 'floating-regionId',
702
+ }]
669
703
  });
670
704
  })
671
705
  ```
package/index.d.ts CHANGED
@@ -7,7 +7,7 @@ type LegacyRegion = {left: number; top: number; width: number; height: number}
7
7
  type Selector = {selector: string; type?: 'css' | 'xpath', nodeType?: 'element' | 'shadow-root'} | 'string'
8
8
  type Element = HTMLElement | JQuery<HTMLElement>
9
9
 
10
- interface CypressCheckSettings extends api.CheckSettingsPlain<Element, Selector>{
10
+ interface CypressCheckSettings extends api.CheckSettingsAutomationPlain<Element, Selector>{
11
11
  tag?: CypressCheckSettings['name']
12
12
 
13
13
  target?: 'window' | 'region'
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@applitools/eyes-cypress",
3
- "version": "3.27.5",
3
+ "version": "3.27.7",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "git://github.com/applitools/eyes.sdk.javascript1.git",
@@ -28,7 +28,7 @@
28
28
  "lint": "eslint \"**/*.js\"",
29
29
  "build": "tsc",
30
30
  "generate:tests": "coverage-tests generate",
31
- "test": "yarn test:unit && yarn test:it && yarn test:e2e && yarn test:ts && yarn test:coverage",
31
+ "test": "yarn test:unit && yarn test:it && yarn test:e2e && yarn test:ts && yarn test:components && yarn test:coverage",
32
32
  "test:sanity": "yarn test:unit && yarn test:it && yarn test:ts",
33
33
  "test:unit": "mocha --no-timeouts 'test/unit/**/*.test.js'",
34
34
  "test:it": "yarn build && mocha --no-timeouts 'test/it/**/*.test.js'",
@@ -37,6 +37,7 @@
37
37
  "test:ts:run": "cypress run --config-file test/e2e/ts/cypress-ts.json",
38
38
  "test:coverage": "yarn generate:tests && cd test/coverage/generic && yarn && unset APPLITOOLS_API_KEY && APPLITOOLS_BATCH_NAME='JS Coverage Tests: eyes-cypress' APPLITOOLS_BATCH_ID=$(uuidgen) npx cypress run",
39
39
  "test:e2e": "mkdir -p test/fixtures/testAppCopies && mocha --no-timeouts 'test/e2e/**/*.test.js'",
40
+ "test:components": "cd test/components && yarn && npx cypress run --component",
40
41
  "cypress": "cypress open --config-file test/fixtures/cypress-play.json",
41
42
  "cypress:new": "cd test/play && yarn && npx cypress open",
42
43
  "cypress:run": "cypress run --config-file test/fixtures/cypress-play.json --spec=test/fixtures/testApp/cypress/integration-play/play.js",
@@ -55,25 +56,27 @@
55
56
  }
56
57
  },
57
58
  "dependencies": {
58
- "@applitools/core": "1.2.1",
59
- "@applitools/eyes-api": "1.9.0",
60
- "@applitools/eyes-universal": "2.16.6",
59
+ "@applitools/core": "1.2.12",
60
+ "@applitools/eyes-api": "1.10.4",
61
+ "@applitools/eyes-universal": "2.17.2",
61
62
  "@applitools/functional-commons": "1.6.0",
62
- "@applitools/logger": "1.1.27",
63
+ "@applitools/logger": "1.1.30",
63
64
  "chalk": "3.0.0",
64
- "semver": "7.3.7",
65
+ "semver": "7.3.8",
65
66
  "uuid": "8.3.2",
67
+ "which": "2.0.2",
66
68
  "ws": "8.5.0"
67
69
  },
68
70
  "devDependencies": {
69
71
  "@applitools/bongo": "^2.2.0",
70
72
  "@applitools/scripts": "1.2.0",
71
- "@applitools/sdk-coverage-tests": "^2.3.20",
73
+ "@applitools/sdk-coverage-tests": "^2.7.8",
72
74
  "@applitools/snaptdout": "1.0.1",
73
- "@applitools/test-server": "1.1.6",
75
+ "@applitools/test-server": "1.1.10",
74
76
  "@applitools/test-utils": "1.5.2",
75
- "@applitools/utils": "1.3.13",
77
+ "@applitools/utils": "1.3.16",
76
78
  "@types/node": "12",
79
+ "@types/which": "^2.0.1",
77
80
  "@types/ws": "^8.2.2",
78
81
  "@typescript-eslint/eslint-plugin": "^5.10.2",
79
82
  "@typescript-eslint/parser": "^5.10.2",
@@ -119,6 +119,10 @@ function eyesCheckMapValues({args, refer}) {
119
119
  resRegions = [...resRegions, ...refElements(region)];
120
120
  }
121
121
  } else {
122
+ if (region.selector && !region.type) {
123
+ region.region = region.selector;
124
+ delete region.selector;
125
+ }
122
126
  resRegions.push(region);
123
127
  }
124
128
  }
@@ -141,6 +145,10 @@ function eyesCheckMapValues({args, refer}) {
141
145
  for (const element of elements) {
142
146
  accessibility.push(Object.assign({}, accessabilityRegion, {region: element}));
143
147
  }
148
+ } else if (region.hasOwnProperty('region')) {
149
+ region.type = region.region.accessibilityType;
150
+ delete region.region.accessibilityType;
151
+ accessibility.push(region);
144
152
  } else {
145
153
  accessabilityRegion.region = {
146
154
  y: region.top,
@@ -174,6 +182,8 @@ function eyesCheckMapValues({args, refer}) {
174
182
  for (const element of elements) {
175
183
  floating.push(Object.assign({}, floatingRegion, {region: element}));
176
184
  }
185
+ } else if (region.hasOwnProperty('region')) {
186
+ floating.push(region);
177
187
  } else {
178
188
  floatingRegion.region = {
179
189
  y: region.top,
@@ -5,10 +5,22 @@ const makeGlobalRunHooks = require('./hooks');
5
5
 
6
6
  function makePluginExport({startServer, eyesConfig}) {
7
7
  return function pluginExport(pluginModule) {
8
- let eyesServer;
9
- const pluginModuleExports = pluginModule.exports.e2e
10
- ? pluginModule.exports.e2e.setupNodeEvents
11
- : pluginModule.exports;
8
+ let eyesServer, pluginModuleExports, pluginExportsE2E, pluginExportsComponent;
9
+ const pluginExports =
10
+ pluginModule.exports && pluginModule.exports.default
11
+ ? pluginModule.exports.default
12
+ : pluginModule.exports;
13
+
14
+ if (pluginExports.component) {
15
+ pluginExportsComponent = pluginExports.component.setupNodeEvents;
16
+ }
17
+ if (pluginExports.e2e) {
18
+ pluginExportsE2E = pluginExports.e2e.setupNodeEvents;
19
+ }
20
+ if (!pluginExports.e2e && !pluginExports.component) {
21
+ pluginModuleExports = pluginExports;
22
+ }
23
+
12
24
  const setupNodeEvents = async function(...args) {
13
25
  const {server, port, closeManager, closeBatches, closeUniversalServer} = await startServer();
14
26
  eyesServer = server;
@@ -16,9 +28,19 @@ function makePluginExport({startServer, eyesConfig}) {
16
28
  const globalHooks = makeGlobalRunHooks({closeManager, closeBatches, closeUniversalServer});
17
29
 
18
30
  const [origOn, config] = args;
31
+
32
+ if (!pluginModuleExports) {
33
+ pluginModuleExports =
34
+ config.testingType === 'e2e' ? pluginExportsE2E : pluginExportsComponent;
35
+ }
36
+
19
37
  const isGlobalHookCalledFromUserHandlerMap = new Map();
20
38
  eyesConfig.eyesIsGlobalHooksSupported = isGlobalHooksSupported(config);
21
- const moduleExportsResult = await pluginModuleExports(onThatCallsUserDefinedHandler, config);
39
+ let moduleExportsResult = {};
40
+ // in case setupNodeEvents is not defined in cypress.config file
41
+ if (typeof pluginModuleExports === 'function') {
42
+ moduleExportsResult = await pluginModuleExports(onThatCallsUserDefinedHandler, config);
43
+ }
22
44
  if (eyesConfig.eyesIsGlobalHooksSupported) {
23
45
  for (const [eventName, eventHandler] of Object.entries(globalHooks)) {
24
46
  if (!isGlobalHookCalledFromUserHandlerMap.get(eventName)) {
@@ -53,11 +75,21 @@ function makePluginExport({startServer, eyesConfig}) {
53
75
  }
54
76
  }
55
77
  };
56
- if (pluginModule.exports.e2e) {
57
- pluginModule.exports.e2e.setupNodeEvents = setupNodeEvents;
58
- } else {
59
- pluginModule.exports = setupNodeEvents;
78
+
79
+ if (pluginExports.component) {
80
+ pluginExports.component.setupNodeEvents = setupNodeEvents;
81
+ }
82
+ if (pluginExports.e2e) {
83
+ pluginExports.e2e.setupNodeEvents = setupNodeEvents;
60
84
  }
85
+ if (!pluginExports.component && !pluginExports.e2e) {
86
+ if (pluginModule.exports.default) {
87
+ pluginModule.exports.default = setupNodeEvents;
88
+ } else {
89
+ pluginModule.exports = setupNodeEvents;
90
+ }
91
+ }
92
+
61
93
  return function getCloseServer() {
62
94
  return eyesServer.close();
63
95
  };
@@ -4,8 +4,10 @@ const {makeServerProcess} = require('@applitools/eyes-universal');
4
4
  const handleTestResults = require('./handleTestResults');
5
5
  const path = require('path');
6
6
  const fs = require('fs');
7
+ const semverLt = require('semver/functions/lt');
7
8
  const {Server: HttpsServer} = require('https');
8
9
  const {Server: WSServer} = require('ws');
10
+ const which = require('which');
9
11
 
10
12
  function makeStartServer({logger}) {
11
13
  return async function startServer() {
@@ -30,19 +32,32 @@ function makeStartServer({logger}) {
30
32
 
31
33
  wss.on('close', () => https.close());
32
34
 
35
+ const forkOptions = {
36
+ detached: true,
37
+ };
38
+
39
+ const cypressVersion = require('cypress/package.json').version;
40
+
41
+ // `cypress` version below `7.0.0` has an old Electron version which not support async shell process.
42
+ // By passing `execPath` with the node process cwd it will switch the `node` process to be the like the OS have
43
+ // and will not use the unsupported `Cypress Helper.app` with the not supported shell process Electron
44
+ if (semverLt(cypressVersion, '7.0.0')) {
45
+ forkOptions.execPath = await which('node');
46
+ }
47
+
33
48
  const {port: universalPort, close: closeUniversalServer} = await makeServerProcess({
34
- key: path.resolve(__dirname, '../pem/server.key'),
35
- cert: path.resolve(__dirname, '../pem/server.cert'),
36
- detached: false,
37
49
  idleTimeout: 0,
38
50
  shutdownMode: 'stdin',
51
+ forkOptions,
52
+ singleton: false,
53
+ portResolutionMode: 'random',
39
54
  });
40
55
 
41
56
  const managers = [];
42
57
  let socketWithUniversal;
43
58
 
44
59
  wss.on('connection', socketWithClient => {
45
- socketWithUniversal = connectSocket(`wss://localhost:${universalPort}/eyes`);
60
+ socketWithUniversal = connectSocket(`ws://localhost:${universalPort}/eyes`);
46
61
 
47
62
  socketWithUniversal.setPassthroughListener(message => {
48
63
  logger.log('<== ', message.toString().slice(0, 1000));
@@ -12,8 +12,13 @@ function getCypressPaths({cwd, isCypress10}) {
12
12
  }
13
13
 
14
14
  function getCypressPaths10AndAbove(cwd) {
15
- const cypressConfigPath = path.resolve(cwd, 'cypress.config.js');
16
- if (fs.existsSync(cypressConfigPath)) {
15
+ const cypressConfigPath = fs.existsSync(path.resolve(cwd, 'cypress.config.js'))
16
+ ? path.resolve(cwd, 'cypress.config.js')
17
+ : fs.existsSync(path.resolve(cwd, 'cypress.config.ts'))
18
+ ? path.resolve(cwd, 'cypress.config.ts')
19
+ : undefined;
20
+
21
+ if (cypressConfigPath) {
17
22
  const configContent = fs.readFileSync(cypressConfigPath, 'utf-8');
18
23
  const supportFilePath = getSupportFilePathFromCypress10Config({cwd, configContent});
19
24
  const typeScriptFilePath = supportFilePath
@@ -27,7 +32,7 @@ function getCypressPaths10AndAbove(cwd) {
27
32
  };
28
33
  } else {
29
34
  throw new Error(
30
- `No configuration file found at ${cypressConfigPath}. This is usually caused by setting up Eyes before setting up Cypress. Please run "npx cypress open" first.`,
35
+ `No configuration file found at ${cwd}. This is usually caused by setting up Eyes before setting up Cypress. Please run "npx cypress open" first.`,
31
36
  );
32
37
  }
33
38
  }
@@ -45,6 +50,8 @@ function getSupportFilePathFromCypress10Config({cwd, configContent}) {
45
50
  supportFilePath = path.resolve(cwd, 'cypress/support/e2e.ts');
46
51
  } else if (fs.existsSync(path.resolve(cwd, 'cypress/support/component.js'))) {
47
52
  supportFilePath = path.resolve(cwd, 'cypress/support/component.js');
53
+ } else if (fs.existsSync(path.resolve(cwd, 'cypress/support/component.ts'))) {
54
+ supportFilePath = path.resolve(cwd, 'cypress/support/component.ts');
48
55
  }
49
56
  }
50
57
  return supportFilePath;