@applitools/eyes-cypress 3.36.2 → 3.37.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,151 @@
1
1
  # Changelog
2
2
 
3
+ ## [3.37.0](https://github.com/applitools/eyes.sdk.javascript1/compare/js/eyes-cypress@3.36.2...js/eyes-cypress@3.37.0) (2023-08-18)
4
+
5
+
6
+ ### Features
7
+
8
+ * add the option to fail on diffs after all spec files ([#1844](https://github.com/applitools/eyes.sdk.javascript1/issues/1844)) ([ca2510d](https://github.com/applitools/eyes.sdk.javascript1/commit/ca2510d094a921c9561b9b9e9094d763a6abce2f))
9
+
10
+
11
+ ### Dependencies
12
+
13
+ * @applitools/utils bumped to 1.5.1
14
+ #### Code Refactoring
15
+
16
+ * refactored spec driver interface ([#1839](https://github.com/applitools/eyes.sdk.javascript1/issues/1839)) ([aa49ec2](https://github.com/applitools/eyes.sdk.javascript1/commit/aa49ec2a7d14b8529acc3a8a4c2baecfa113d98a))
17
+ * @applitools/logger bumped to 2.0.8
18
+ #### Code Refactoring
19
+
20
+ * refactored spec driver interface ([#1839](https://github.com/applitools/eyes.sdk.javascript1/issues/1839)) ([aa49ec2](https://github.com/applitools/eyes.sdk.javascript1/commit/aa49ec2a7d14b8529acc3a8a4c2baecfa113d98a))
21
+
22
+
23
+
24
+ * @applitools/socket bumped to 1.1.8
25
+ #### Code Refactoring
26
+
27
+ * refactored spec driver interface ([#1839](https://github.com/applitools/eyes.sdk.javascript1/issues/1839)) ([aa49ec2](https://github.com/applitools/eyes.sdk.javascript1/commit/aa49ec2a7d14b8529acc3a8a4c2baecfa113d98a))
28
+
29
+
30
+
31
+ * @applitools/req bumped to 1.5.3
32
+ #### Code Refactoring
33
+
34
+ * refactored spec driver interface ([#1839](https://github.com/applitools/eyes.sdk.javascript1/issues/1839)) ([aa49ec2](https://github.com/applitools/eyes.sdk.javascript1/commit/aa49ec2a7d14b8529acc3a8a4c2baecfa113d98a))
35
+
36
+
37
+
38
+ * @applitools/image bumped to 1.1.3
39
+ #### Code Refactoring
40
+
41
+ * refactored spec driver interface ([#1839](https://github.com/applitools/eyes.sdk.javascript1/issues/1839)) ([aa49ec2](https://github.com/applitools/eyes.sdk.javascript1/commit/aa49ec2a7d14b8529acc3a8a4c2baecfa113d98a))
42
+
43
+
44
+
45
+ * @applitools/snippets bumped to 2.4.23
46
+ #### Code Refactoring
47
+
48
+ * refactored spec driver interface ([#1839](https://github.com/applitools/eyes.sdk.javascript1/issues/1839)) ([aa49ec2](https://github.com/applitools/eyes.sdk.javascript1/commit/aa49ec2a7d14b8529acc3a8a4c2baecfa113d98a))
49
+ * @applitools/spec-driver-webdriver bumped to 1.0.42
50
+ #### Code Refactoring
51
+
52
+ * refactored spec driver interface ([#1839](https://github.com/applitools/eyes.sdk.javascript1/issues/1839)) ([aa49ec2](https://github.com/applitools/eyes.sdk.javascript1/commit/aa49ec2a7d14b8529acc3a8a4c2baecfa113d98a))
53
+
54
+
55
+
56
+ * @applitools/spec-driver-selenium bumped to 1.5.56
57
+ #### Code Refactoring
58
+
59
+ * refactored spec driver interface ([#1839](https://github.com/applitools/eyes.sdk.javascript1/issues/1839)) ([aa49ec2](https://github.com/applitools/eyes.sdk.javascript1/commit/aa49ec2a7d14b8529acc3a8a4c2baecfa113d98a))
60
+
61
+
62
+
63
+ * @applitools/spec-driver-puppeteer bumped to 1.1.73
64
+ #### Code Refactoring
65
+
66
+ * refactored spec driver interface ([#1839](https://github.com/applitools/eyes.sdk.javascript1/issues/1839)) ([aa49ec2](https://github.com/applitools/eyes.sdk.javascript1/commit/aa49ec2a7d14b8529acc3a8a4c2baecfa113d98a))
67
+
68
+
69
+
70
+ * @applitools/driver bumped to 1.13.5
71
+ #### Bug Fixes
72
+
73
+ * optimize driver usage in close ([#1867](https://github.com/applitools/eyes.sdk.javascript1/issues/1867)) ([60dff6b](https://github.com/applitools/eyes.sdk.javascript1/commit/60dff6b160e69d3893c91a1125d668fa18b43072))
74
+
75
+
76
+ #### Code Refactoring
77
+
78
+ * refactored spec driver interface ([#1839](https://github.com/applitools/eyes.sdk.javascript1/issues/1839)) ([aa49ec2](https://github.com/applitools/eyes.sdk.javascript1/commit/aa49ec2a7d14b8529acc3a8a4c2baecfa113d98a))
79
+
80
+
81
+
82
+ * @applitools/screenshoter bumped to 3.8.8
83
+ #### Code Refactoring
84
+
85
+ * refactored spec driver interface ([#1839](https://github.com/applitools/eyes.sdk.javascript1/issues/1839)) ([aa49ec2](https://github.com/applitools/eyes.sdk.javascript1/commit/aa49ec2a7d14b8529acc3a8a4c2baecfa113d98a))
86
+
87
+
88
+
89
+ * @applitools/nml-client bumped to 1.5.8
90
+ #### Code Refactoring
91
+
92
+ * refactored spec driver interface ([#1839](https://github.com/applitools/eyes.sdk.javascript1/issues/1839)) ([aa49ec2](https://github.com/applitools/eyes.sdk.javascript1/commit/aa49ec2a7d14b8529acc3a8a4c2baecfa113d98a))
93
+
94
+
95
+
96
+ * @applitools/tunnel-client bumped to 1.2.0
97
+ #### Features
98
+
99
+ * replace and destroy tunnels by tunnel id ([#1878](https://github.com/applitools/eyes.sdk.javascript1/issues/1878)) ([22bcc15](https://github.com/applitools/eyes.sdk.javascript1/commit/22bcc15b31457e3da56cdb6f73bee3dcb7e051a1))
100
+
101
+
102
+ #### Code Refactoring
103
+
104
+ * refactored spec driver interface ([#1839](https://github.com/applitools/eyes.sdk.javascript1/issues/1839)) ([aa49ec2](https://github.com/applitools/eyes.sdk.javascript1/commit/aa49ec2a7d14b8529acc3a8a4c2baecfa113d98a))
105
+
106
+
107
+
108
+ * @applitools/ufg-client bumped to 1.7.1
109
+ #### Code Refactoring
110
+
111
+ * refactored spec driver interface ([#1839](https://github.com/applitools/eyes.sdk.javascript1/issues/1839)) ([aa49ec2](https://github.com/applitools/eyes.sdk.javascript1/commit/aa49ec2a7d14b8529acc3a8a4c2baecfa113d98a))
112
+
113
+
114
+
115
+ * @applitools/ec-client bumped to 1.7.5
116
+ #### Code Refactoring
117
+
118
+ * refactored spec driver interface ([#1839](https://github.com/applitools/eyes.sdk.javascript1/issues/1839)) ([aa49ec2](https://github.com/applitools/eyes.sdk.javascript1/commit/aa49ec2a7d14b8529acc3a8a4c2baecfa113d98a))
119
+
120
+
121
+
122
+ * @applitools/core-base bumped to 1.5.1
123
+ #### Code Refactoring
124
+
125
+ * refactored spec driver interface ([#1839](https://github.com/applitools/eyes.sdk.javascript1/issues/1839)) ([aa49ec2](https://github.com/applitools/eyes.sdk.javascript1/commit/aa49ec2a7d14b8529acc3a8a4c2baecfa113d98a))
126
+
127
+
128
+
129
+ * @applitools/core bumped to 3.9.1
130
+ #### Bug Fixes
131
+
132
+ * optimize driver usage in close ([#1867](https://github.com/applitools/eyes.sdk.javascript1/issues/1867)) ([60dff6b](https://github.com/applitools/eyes.sdk.javascript1/commit/60dff6b160e69d3893c91a1125d668fa18b43072))
133
+
134
+
135
+ #### Code Refactoring
136
+
137
+ * refactored spec driver interface ([#1839](https://github.com/applitools/eyes.sdk.javascript1/issues/1839)) ([aa49ec2](https://github.com/applitools/eyes.sdk.javascript1/commit/aa49ec2a7d14b8529acc3a8a4c2baecfa113d98a))
138
+
139
+
140
+
141
+ * @applitools/eyes bumped to 1.7.3
142
+ #### Code Refactoring
143
+
144
+ * refactored spec driver interface ([#1839](https://github.com/applitools/eyes.sdk.javascript1/issues/1839)) ([aa49ec2](https://github.com/applitools/eyes.sdk.javascript1/commit/aa49ec2a7d14b8529acc3a8a4c2baecfa113d98a))
145
+
146
+
147
+
148
+
3
149
  ## [3.36.2](https://github.com/applitools/eyes.sdk.javascript1/compare/js/eyes-cypress@3.36.1...js/eyes-cypress@3.36.2) (2023-08-10)
4
150
 
5
151
 
@@ -43,7 +43,7 @@ function transformCypressConfig(config) {
43
43
  sequenceName: (_e = config.batchSequenceName) !== null && _e !== void 0 ? _e : (_f = config.batch) === null || _f === void 0 ? void 0 : _f.sequenceName,
44
44
  notifyOnCompletion: (_g = config.notifyOnCompletion) !== null && _g !== void 0 ? _g : (_h = config.batch) === null || _h === void 0 ? void 0 : _h.notifyOnCompletion,
45
45
  },
46
- keepBatchOpen: !config.shouldUseBrowserHooks,
46
+ keepBatchOpen: !config.shouldDoPostSpecTasks,
47
47
  environmentName: config.envName,
48
48
  baselineBranchName: config.baselineBranchName,
49
49
  branchName: config.branchName,
@@ -16,7 +16,7 @@ function printTestResults(testResultsArr) {
16
16
  if (!testResultsArr.testResults)
17
17
  return;
18
18
  const { passed, failed, diffs } = (0, getErrorsAndDiffs_1.default)(testResultsArr.testResults);
19
- if ((failed.length || diffs.length) && !!testResultsArr.resultConfig.eyesFailCypressOnDiff) {
19
+ if ((failed.length || diffs.length) && !!testResultsArr.resultConfig.shouldThrowError) {
20
20
  throw new Error((0, errorDigest_1.default)({
21
21
  passed,
22
22
  failed,
@@ -4,7 +4,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  const handleTestResults_1 = __importDefault(require("./handleTestResults"));
7
- function makeGlobalRunHooks({ closeManager, closeBatches, closeUniversalServer, }) {
7
+ function makeGlobalRunHooks({ closeManagers, closeBatches, closeUniversalServer, }) {
8
8
  return {
9
9
  'before:run': ({ config }) => {
10
10
  if (!config.isTextTerminal)
@@ -14,11 +14,8 @@ function makeGlobalRunHooks({ closeManager, closeBatches, closeUniversalServer,
14
14
  try {
15
15
  if (!config.isTextTerminal)
16
16
  return;
17
- const summaries = await closeManager();
18
- let testResults;
19
- for (const summary of summaries) {
20
- testResults = summary.results.map(({ result }) => result);
21
- }
17
+ const summaries = await closeManagers();
18
+ const testResults = summaries.map(({ results }) => results.map(({ result }) => result)).flat();
22
19
  if (!config.appliConfFile.dontCloseBatches) {
23
20
  await closeBatches({
24
21
  batchId: config.appliConfFile.batchId || config.appliConfFile.batch.id,
@@ -33,6 +30,17 @@ function makeGlobalRunHooks({ closeManager, closeBatches, closeUniversalServer,
33
30
  tapFileName: config.appliConfFile.tapFileName,
34
31
  });
35
32
  }
33
+ const resultConfig = {
34
+ showLogs: config.appliConfFile.showLogs,
35
+ shouldThrowError: config.appliConfFile.failCypressAfterAllSpecs,
36
+ };
37
+ if (config.appliConfFile.failCypressAfterAllSpecs) {
38
+ // we want to throw an exception in case we have a least one test with diffs
39
+ // we create a runner per spec file, therefore we could have multiple summeries
40
+ for (const summary of summaries) {
41
+ handleTestResults_1.default.printTestResults({ testResults: summary.results.map(({ result }) => result), resultConfig });
42
+ }
43
+ }
36
44
  }
37
45
  finally {
38
46
  await closeUniversalServer();
@@ -61,10 +61,10 @@ function makePluginExport({ startServer, eyesConfig, }) {
61
61
  return new Promise(res => eyesServer.close(() => res()));
62
62
  };
63
63
  async function setupNodeEvents(origOn, cypressConfig) {
64
- const { server, port, closeManager, closeBatches, closeUniversalServer } = await startServer(cypressConfig);
64
+ const { server, port, closeManagers, closeBatches, closeUniversalServer } = await startServer(cypressConfig);
65
65
  eyesServer = server;
66
66
  const globalHooks = (0, hooks_1.default)({
67
- closeManager,
67
+ closeManagers,
68
68
  closeBatches,
69
69
  closeUniversalServer,
70
70
  });
@@ -85,11 +85,11 @@ function makeStartServer({ logger, eyesConfig }) {
85
85
  return {
86
86
  server: wss,
87
87
  port,
88
- closeManager,
88
+ closeManagers,
89
89
  closeBatches,
90
90
  closeUniversalServer,
91
91
  };
92
- function closeManager() {
92
+ function closeManagers() {
93
93
  return Promise.all(managers.map(({ manager, socketWithUniversal }) => socketWithUniversal.request('EyesManager.getResults', {
94
94
  manager,
95
95
  settings: { throwErr: false, removeDuplicateTests: eyesConfig.eyesRemoveDuplicateTests },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@applitools/eyes-cypress",
3
- "version": "3.36.2",
3
+ "version": "3.37.0",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "git://github.com/applitools/eyes.sdk.javascript1.git",
@@ -42,7 +42,7 @@
42
42
  "cypress12": "../../node_modules/cypress12/bin/cypress",
43
43
  "test:ts:run:12": "yarn cypress12 run --project ./test/e2e/ts --config-file ./cypress-12.config.ts",
44
44
  "test:ts:run": "yarn cypress$APPLITOOLS_FRAMEWORK_VERSION run --project ./test/e2e/ts --config-file ./cypress-$APPLITOOLS_FRAMEWORK_VERSION.config.ts",
45
- "test:coverage": "cd test/coverage && yarn && APPLITOOLS_BATCH_NAME='JS Coverage Tests: eyes-cypress' APPLITOOLS_BATCH_ID=$(uuidgen) npx cypress run",
45
+ "test:coverage": "cd test/generic && yarn && APPLITOOLS_BATCH_NAME='JS Coverage Tests: eyes-cypress' APPLITOOLS_BATCH_ID=$(uuidgen) npx cypress run",
46
46
  "test:e2e": "mkdir -p test/fixtures/testAppCopies && run --top-level mocha --no-timeouts 'test/e2e/**/*.test.js'",
47
47
  "test:components": "cd test/components && yarn && npx cypress run --component",
48
48
  "cypress": "cypress open --config-file test/fixtures/cypress-play.json",
@@ -54,11 +54,11 @@
54
54
  "setup": "run --top-level xvfb:setup"
55
55
  },
56
56
  "dependencies": {
57
- "@applitools/core": "3.9.0",
58
- "@applitools/eyes": "1.7.2",
57
+ "@applitools/core": "3.9.1",
58
+ "@applitools/eyes": "1.7.3",
59
59
  "@applitools/functional-commons": "1.6.0",
60
- "@applitools/logger": "2.0.7",
61
- "@applitools/utils": "1.5.0",
60
+ "@applitools/logger": "2.0.8",
61
+ "@applitools/utils": "1.5.1",
62
62
  "boxen": "5.1.2",
63
63
  "chalk": "3.0.0",
64
64
  "semver": "7.3.8",
@@ -67,8 +67,8 @@
67
67
  },
68
68
  "devDependencies": {
69
69
  "@applitools/api-extractor": "^1.2.21",
70
- "@applitools/bongo": "^5.4.3",
71
- "@applitools/generic": "^3.3.8",
70
+ "@applitools/bongo": "^5.6.1",
71
+ "@applitools/generic": "^3.3.9",
72
72
  "@applitools/snaptdout": "1.0.1",
73
73
  "@applitools/test-server": "^1.2.2",
74
74
  "@applitools/test-utils": "^1.5.17",
@@ -89,7 +89,9 @@
89
89
  "mocha": "^10.2.0",
90
90
  "morgan": "1.9.1",
91
91
  "ncp": "2.0.0",
92
- "node-fetch": "2.6.0"
92
+ "node-fetch": "2.6.0",
93
+ "strip-ansi": "^6.0.1",
94
+ "typescript": "^5.1.6"
93
95
  },
94
96
  "engines": {
95
97
  "node": ">=12.13.0"
@@ -41,10 +41,15 @@ function getGlobalConfigProperty(prop) {
41
41
  return property ? (shouldParse.includes(prop) ? JSON.parse(property) : property) : undefined
42
42
  }
43
43
 
44
- const shouldUseBrowserHooks =
44
+ // tasks = tapFile and closeBatch
45
+ const shouldDoPostSpecTasks =
45
46
  !getGlobalConfigProperty('eyesIsDisabled') &&
46
47
  (getGlobalConfigProperty('isInteractive') || !getGlobalConfigProperty('eyesIsGlobalHooksSupported'))
47
48
 
49
+ const shouldCallAfterHook =
50
+ (shouldDoPostSpecTasks || Cypress.config('eyesFailCypressOnDiff')) &&
51
+ !Cypress.config('appliConfFile').failCypressAfterAllSpecs
52
+
48
53
  Cypress.Commands.add('eyesGetAllTestResults', () => {
49
54
  Cypress.log({name: 'Eyes: getAllTestResults'})
50
55
  return cy.then({timeout: 86400000}, async () => {
@@ -66,7 +71,7 @@ Cypress.Commands.add('eyesGetResults', (args = {}) => {
66
71
  })
67
72
  })
68
73
 
69
- if (shouldUseBrowserHooks || Cypress.config('eyesFailCypressOnDiff')) {
74
+ if (shouldCallAfterHook) {
70
75
  after(() => {
71
76
  if (!manager) return
72
77
  return cy.then({timeout: 86400000}, async () => {
@@ -76,11 +81,11 @@ if (shouldUseBrowserHooks || Cypress.config('eyesFailCypressOnDiff')) {
76
81
  }
77
82
  const resultConfig = {
78
83
  showLogs: Cypress.config('appliConfFile').showLogs,
79
- eyesFailCypressOnDiff: Cypress.config('eyesFailCypressOnDiff'),
84
+ shouldThrowError: Cypress.config('eyesFailCypressOnDiff'),
80
85
  isTextTerminal: Cypress.config('isTextTerminal'),
81
86
  tapDirPath: Cypress.config('appliConfFile').tapDirPath,
82
87
  tapFileName: Cypress.config('appliConfFile').tapFileName,
83
- shouldCreateTapFile: shouldUseBrowserHooks,
88
+ shouldCreateTapFile: shouldDoPostSpecTasks,
84
89
  }
85
90
 
86
91
  const summary = await getSummary()
@@ -140,7 +145,7 @@ Cypress.Commands.add('eyesOpen', function (args = {}) {
140
145
  const mergedConfig = mergeCypressConfigs({globalConfig: appliConfFile, openConfig: {testName, ...args}})
141
146
  openAndGlobalConfig = transformCypressConfig({
142
147
  ...mergedConfig,
143
- shouldUseBrowserHooks,
148
+ shouldDoPostSpecTasks,
144
149
  isComponentTest: Cypress.config('isComponent'),
145
150
  })
146
151
 
@@ -1,9 +1,9 @@
1
- import type {CypressEyesConfig} from '../expose'
1
+ import type {appliConfFile} from '../expose'
2
2
  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: CypressEyesConfig): Config<SpecType, 'ufg'> {
6
+ export function transformCypressConfig(config: appliConfFile): Config<SpecType, 'ufg'> {
7
7
  return {
8
8
  open: {
9
9
  apiKey: config.apiKey,
@@ -19,7 +19,7 @@ export function transformCypressConfig(config: CypressEyesConfig): Config<SpecTy
19
19
  sequenceName: config.batchSequenceName ?? config.batch?.sequenceName,
20
20
  notifyOnCompletion: config.notifyOnCompletion ?? config.batch?.notifyOnCompletion,
21
21
  },
22
- keepBatchOpen: !config.shouldUseBrowserHooks,
22
+ keepBatchOpen: !config.shouldDoPostSpecTasks,
23
23
  environmentName: config.envName,
24
24
  baselineBranchName: config.baselineBranchName,
25
25
  branchName: config.branchName,
package/src/expose.ts CHANGED
@@ -89,11 +89,16 @@ export type CypressEyesConfig = api.ConfigurationPlain<SpecType> & {
89
89
  scriptHooks?: {
90
90
  beforeCaptureScreenshot: string
91
91
  }
92
- saveNewTests?: boolean
93
- /** @internal */
94
- shouldUseBrowserHooks?: boolean
95
- /* @internal */
92
+ }
93
+
94
+ export type appliConfFile = CypressEyesConfig & {
95
+ failCypressAfterAllSpecs?: boolean
96
+ tapDirPath?: string
97
+ tapFileName?: string
98
+ showLogs?: boolean
99
+ shouldDoPostSpecTasks?: boolean
96
100
  isComponentTest?: boolean
101
+ saveNewTests?: boolean
97
102
  }
98
103
 
99
104
  export type CypressTestResultsSummary = api.TestResultsSummary
@@ -11,7 +11,7 @@ function printTestResults(testResultsArr: any) {
11
11
  })
12
12
  if (!testResultsArr.testResults) return
13
13
  const {passed, failed, diffs} = getErrorsAndDiffs(testResultsArr.testResults)
14
- if ((failed.length || diffs.length) && !!testResultsArr.resultConfig.eyesFailCypressOnDiff) {
14
+ if ((failed.length || diffs.length) && !!testResultsArr.resultConfig.shouldThrowError) {
15
15
  throw new Error(
16
16
  errorDigest({
17
17
  passed,
@@ -1,27 +1,19 @@
1
1
  import handleTestResults from './handleTestResults'
2
2
  import {type StartServerReturn} from './server'
3
3
  export type EyesCypressAction = 'before:run' | 'after:run'
4
+ import type {appliConfFile} from '../expose'
4
5
 
5
6
  declare global {
6
7
  // eslint-disable-next-line @typescript-eslint/no-namespace
7
8
  namespace Cypress {
8
9
  interface ResolvedConfigOptions {
9
- appliConfFile: {
10
- dontCloseBatches: boolean
11
- batch: any
12
- serverUrl: string
13
- proxy: any // TODO: add proxy type
14
- apiKey: string
15
- batchId: string
16
- tapDirPath: string
17
- tapFileName: string
18
- }
10
+ appliConfFile: appliConfFile
19
11
  }
20
12
  }
21
13
  }
22
14
 
23
15
  export default function makeGlobalRunHooks({
24
- closeManager,
16
+ closeManagers,
25
17
  closeBatches,
26
18
  closeUniversalServer,
27
19
  }: Omit<StartServerReturn, 'server' | 'port'>): {
@@ -36,12 +28,10 @@ export default function makeGlobalRunHooks({
36
28
  'after:run': async ({config}: CypressCommandLine.CypressRunResult) => {
37
29
  try {
38
30
  if (!(config as Cypress.Config).isTextTerminal) return
39
- const summaries = await closeManager()
31
+ const summaries = await closeManagers()
32
+
33
+ const testResults = summaries.map(({results}) => results.map(({result}) => result)).flat()
40
34
 
41
- let testResults
42
- for (const summary of summaries) {
43
- testResults = summary.results.map(({result}: any) => result)
44
- }
45
35
  if (!config.appliConfFile.dontCloseBatches) {
46
36
  await closeBatches({
47
37
  batchId: config.appliConfFile.batchId || config.appliConfFile.batch.id,
@@ -57,6 +47,17 @@ export default function makeGlobalRunHooks({
57
47
  tapFileName: config.appliConfFile.tapFileName,
58
48
  })
59
49
  }
50
+ const resultConfig = {
51
+ showLogs: config.appliConfFile.showLogs,
52
+ shouldThrowError: config.appliConfFile.failCypressAfterAllSpecs,
53
+ }
54
+ if (config.appliConfFile.failCypressAfterAllSpecs) {
55
+ // we want to throw an exception in case we have a least one test with diffs
56
+ // we create a runner per spec file, therefore we could have multiple summeries
57
+ for (const summary of summaries) {
58
+ handleTestResults.printTestResults({testResults: summary.results.map(({result}) => result), resultConfig})
59
+ }
60
+ }
60
61
  } finally {
61
62
  await closeUniversalServer()
62
63
  }
@@ -72,11 +72,11 @@ export default function makePluginExport({
72
72
  origOn: Cypress.PluginEvents,
73
73
  cypressConfig: Cypress.PluginConfigOptions,
74
74
  ): Promise<EyesPluginConfig> {
75
- const {server, port, closeManager, closeBatches, closeUniversalServer} = await startServer(cypressConfig)
75
+ const {server, port, closeManagers, closeBatches, closeUniversalServer} = await startServer(cypressConfig)
76
76
  eyesServer = server
77
77
 
78
78
  const globalHooks: any = makeGlobalRunHooks({
79
- closeManager,
79
+ closeManagers,
80
80
  closeBatches,
81
81
  closeUniversalServer,
82
82
  })
@@ -14,7 +14,7 @@ import {extractEnvironment} from '../plugin/extractEnvironment'
14
14
  export type StartServerReturn = {
15
15
  server: Omit<SocketWithUniversal, 'disconnect' | 'ref' | 'unref' | 'send' | 'request' | 'setPassthroughListener'>
16
16
  port: number
17
- closeManager: () => Promise<any[]>
17
+ closeManagers: () => Promise<any[]>
18
18
  closeBatches: (settings: CloseBatchSettings | CloseBatchSettings[]) => Promise<void>
19
19
  closeUniversalServer: () => void
20
20
  }
@@ -103,12 +103,12 @@ export default function makeStartServer({logger, eyesConfig}: {logger: Logger; e
103
103
  return {
104
104
  server: wss,
105
105
  port,
106
- closeManager,
106
+ closeManagers,
107
107
  closeBatches,
108
108
  closeUniversalServer,
109
109
  }
110
110
 
111
- function closeManager() {
111
+ function closeManagers() {
112
112
  return Promise.all(
113
113
  managers.map(({manager, socketWithUniversal}) =>
114
114
  socketWithUniversal.request('EyesManager.getResults', {
package/types/expose.d.ts CHANGED
@@ -84,8 +84,8 @@ export type Element = HTMLElement | JQuery;
84
84
  export type ElementWithOptions = { element: Element; regionId?: string; padding?: any; };
85
85
  export type SelectorWithOptions = { region: Selector; regionId?: string; padding?: number | LegacyRegion; };
86
86
  export type AccessibilityValidation = { level?: "AA" | "AAA"; guidelinesVersion?: "WCAG_2_0" | "WCAG_2_1"; };
87
- export type FloatingRegion = ((LegacyRegion | Selector | ElementWithOptions | SelectorWithOptions) & { maxUpOffset?: number; maxDownOffset?: number; maxLeftOffset?: number; maxRightOffset?: number; }) | Array<(LegacyRegion | Selector | ElementWithOptions | SelectorWithOptions) & { maxUpOffset?: number; maxDownOffset?: number; maxLeftOffset?: number; maxRightOffset?: number; }>;
88
- export type accessibilityRegion = ((LegacyRegion | Selector | ElementWithOptions) & { accessibilityType?: "IgnoreContrast" | "RegularText" | "LargeText" | "BoldText" | "GraphicalObject"; }) | { region: { selector: Selector; accessibilityType: "IgnoreContrast" | "RegularText" | "LargeText" | "BoldText" | "GraphicalObject"; }; regionId?: string; padding?: number | LegacyRegion; } | Array<((LegacyRegion | Selector | ElementWithOptions) & { accessibilityType?: "IgnoreContrast" | "RegularText" | "LargeText" | "BoldText" | "GraphicalObject"; }) | { region: { selector: Selector; accessibilityType: "IgnoreContrast" | "RegularText" | "LargeText" | "BoldText" | "GraphicalObject"; }; regionId?: string; padding?: number | LegacyRegion; }>;
87
+ export type FloatingRegion = ((Selector | LegacyRegion | ElementWithOptions | SelectorWithOptions) & { maxUpOffset?: number; maxDownOffset?: number; maxLeftOffset?: number; maxRightOffset?: number; }) | Array<(Selector | LegacyRegion | ElementWithOptions | SelectorWithOptions) & { maxUpOffset?: number; maxDownOffset?: number; maxLeftOffset?: number; maxRightOffset?: number; }>;
88
+ export type accessibilityRegion = ((Selector | LegacyRegion | ElementWithOptions) & { accessibilityType?: "IgnoreContrast" | "RegularText" | "LargeText" | "BoldText" | "GraphicalObject"; }) | { region: { selector: Selector; accessibilityType: "IgnoreContrast" | "RegularText" | "LargeText" | "BoldText" | "GraphicalObject"; }; regionId?: string; padding?: number | LegacyRegion; } | Array<((Selector | LegacyRegion | ElementWithOptions) & { accessibilityType?: "IgnoreContrast" | "RegularText" | "LargeText" | "BoldText" | "GraphicalObject"; }) | { region: { selector: Selector; accessibilityType: "IgnoreContrast" | "RegularText" | "LargeText" | "BoldText" | "GraphicalObject"; }; regionId?: string; padding?: number | LegacyRegion; }>;
89
89
  export type CypressCheckSettings = {
90
90
  name?: string;
91
91
  region?: LegacyRegion;
@@ -205,10 +205,10 @@ export type CypressCheckSettings = {
205
205
  target?: "window" | "region";
206
206
  selector?: Selector;
207
207
  element?: Element;
208
- ignore?: MaybeArray<string | LegacyRegion | { selector: string; type?: "css" | "xpath"; nodeType?: "element" | "shadow-root"; } | Element | ElementWithOptions | SelectorWithOptions>;
209
- layout?: MaybeArray<string | LegacyRegion | { selector: string; type?: "css" | "xpath"; nodeType?: "element" | "shadow-root"; } | Element | ElementWithOptions | SelectorWithOptions>;
210
- content?: MaybeArray<string | LegacyRegion | { selector: string; type?: "css" | "xpath"; nodeType?: "element" | "shadow-root"; } | Element | ElementWithOptions | SelectorWithOptions>;
211
- strict?: MaybeArray<string | LegacyRegion | { selector: string; type?: "css" | "xpath"; nodeType?: "element" | "shadow-root"; } | Element | ElementWithOptions | SelectorWithOptions>;
208
+ ignore?: MaybeArray<string | Element | { selector: string; type?: "css" | "xpath"; nodeType?: "element" | "shadow-root"; } | LegacyRegion | ElementWithOptions | SelectorWithOptions>;
209
+ layout?: MaybeArray<string | Element | { selector: string; type?: "css" | "xpath"; nodeType?: "element" | "shadow-root"; } | LegacyRegion | ElementWithOptions | SelectorWithOptions>;
210
+ content?: MaybeArray<string | Element | { selector: string; type?: "css" | "xpath"; nodeType?: "element" | "shadow-root"; } | LegacyRegion | ElementWithOptions | SelectorWithOptions>;
211
+ strict?: MaybeArray<string | Element | { selector: string; type?: "css" | "xpath"; nodeType?: "element" | "shadow-root"; } | LegacyRegion | ElementWithOptions | SelectorWithOptions>;
212
212
  floating?: FloatingRegion;
213
213
  accessibility?: accessibilityRegion;
214
214
  scriptHooks?: { beforeCaptureScreenshot: string; };
@@ -354,6 +354,152 @@ export type CypressEyesConfig = {
354
354
  useDom?: boolean;
355
355
  enablePatterns?: boolean;
356
356
  scriptHooks?: { beforeCaptureScreenshot: string; };
357
+ };
358
+ export type appliConfFile = {
359
+ debugScreenshots?: { save: boolean; path?: string; prefix?: string; };
360
+ agentId?: string;
361
+ apiKey?: string;
362
+ serverUrl?: string;
363
+ proxy?: { url: string; username?: string; password?: string; };
364
+ autProxy?: {
365
+ url: string;
366
+ username?: string;
367
+ password?: string;
368
+ mode?: "Allow" | "Block";
369
+ domains?: Array<string>;
370
+ };
371
+ isDisabled?: boolean;
372
+ connectionTimeout?: number;
373
+ removeSession?: boolean;
374
+ appName?: string;
375
+ testName?: string;
376
+ displayName?: string;
377
+ viewportSize?: { width: number; height: number; };
378
+ sessionType?: "SEQUENTIAL" | "PROGRESSION";
379
+ properties?: Array<{ name: string; value: string; }>;
380
+ batch?: {
381
+ id?: string;
382
+ name?: string;
383
+ sequenceName?: string;
384
+ startedAt?: string | Date;
385
+ notifyOnCompletion?: boolean;
386
+ properties?: Array<{ name: string; value: string; }>;
387
+ };
388
+ defaultMatchSettings?: {
389
+ exact?: { minDiffIntensity: number; minDiffWidth: number; minDiffHeight: number; matchThreshold: number; };
390
+ matchLevel?: "None" | "Layout1" | "Layout" | "Layout2" | "Content" | "IgnoreColors" | "Strict" | "Exact";
391
+ ignoreCaret?: boolean;
392
+ useDom?: boolean;
393
+ enablePatterns?: boolean;
394
+ ignoreDisplacements?: boolean;
395
+ ignoreRegions?: Array<{
396
+ x: number;
397
+ y: number;
398
+ width: number;
399
+ height: number;
400
+ }>;
401
+ layoutRegions?: Array<{
402
+ x: number;
403
+ y: number;
404
+ width: number;
405
+ height: number;
406
+ }>;
407
+ strictRegions?: Array<{
408
+ x: number;
409
+ y: number;
410
+ width: number;
411
+ height: number;
412
+ }>;
413
+ contentRegions?: Array<{
414
+ x: number;
415
+ y: number;
416
+ width: number;
417
+ height: number;
418
+ }>;
419
+ floatingRegions?: Array<{
420
+ x: number;
421
+ y: number;
422
+ width: number;
423
+ height: number;
424
+ } | {
425
+ region: {
426
+ x: number;
427
+ y: number;
428
+ width: number;
429
+ height: number;
430
+ };
431
+ maxUpOffset?: number;
432
+ maxDownOffset?: number;
433
+ maxLeftOffset?: number;
434
+ maxRightOffset?: number;
435
+ }>;
436
+ accessibilityRegions?: Array<{
437
+ x: number;
438
+ y: number;
439
+ width: number;
440
+ height: number;
441
+ } | { region: {
442
+ x: number;
443
+ y: number;
444
+ width: number;
445
+ height: number;
446
+ }; type?: "IgnoreContrast" | "RegularText" | "LargeText" | "BoldText" | "GraphicalObject"; }>;
447
+ accessibilitySettings?: AccessibilityValidation;
448
+ };
449
+ hostApp?: string;
450
+ hostOS?: string;
451
+ hostAppInfo?: string;
452
+ hostOSInfo?: string;
453
+ deviceInfo?: string;
454
+ baselineEnvName?: string;
455
+ environmentName?: string;
456
+ branchName?: string;
457
+ parentBranchName?: string;
458
+ baselineBranchName?: string;
459
+ compareWithParentBranch?: boolean;
460
+ ignoreBaseline?: boolean;
461
+ ignoreGitMergeBase?: boolean;
462
+ saveFailedTests?: boolean;
463
+ saveNewTests?: boolean;
464
+ saveDiffs?: boolean;
465
+ dontCloseBatches?: boolean;
466
+ sendDom?: boolean;
467
+ matchTimeout?: number;
468
+ forceFullPageScreenshot?: boolean;
469
+ waitBeforeScreenshots?: number;
470
+ stitchMode?: "Scroll" | "CSS" | "Resize";
471
+ hideScrollbars?: boolean;
472
+ hideCaret?: boolean;
473
+ stitchOverlap?: number;
474
+ scrollRootElement?: Element | EyesSelector<Selector>;
475
+ cut?: { top: number; right: number; bottom: number; left: number; } | { x: number; y: number; width: number; height: number; };
476
+ rotation?: 0 | 270 | -270 | 180 | -180 | 90 | -90;
477
+ scaleRatio?: number;
478
+ concurrentSessions?: number;
479
+ browsersInfo?: Array<{ 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: "Blackberry PlayBook" | "BlackBerry Z30" | "Galaxy A5" | "Galaxy Note 10" | "Galaxy Note 10 Plus" | "Galaxy Note 2" | "Galaxy Note 3" | "Galaxy Note 4" | "Galaxy Note 8" | "Galaxy Note 9" | "Galaxy S3" | "Galaxy S5" | "Galaxy S8" | "Galaxy S8 Plus" | "Galaxy S9" | "Galaxy S9 Plus" | "Galaxy S10" | "Galaxy S10 Plus" | "Galaxy S20" | "Galaxy S21" | "Galaxy S21 Ultra" | "Galaxy S22" | "Galaxy S22 Ultra" | "Galaxy Tab S7" | "iPad" | "iPad 6th Gen" | "iPad 7th Gen" | "iPad Air 2" | "iPad Mini" | "iPad Pro" | "iPhone 11" | "iPhone 11 Pro" | "iPhone 11 Pro Max" | "iPhone 4" | "iPhone 5/SE" | "iPhone 6/7/8" | "iPhone 6/7/8 Plus" | "iPhone X" | "iPhone XR" | "iPhone XS" | "iPhone XS Max" | "Kindle Fire HDX" | "Laptop with HiDPI screen" | "Laptop with MDPI screen" | "Laptop with touch" | "LG G6" | "LG Optimus L70" | "Microsoft Lumia 550" | "Microsoft Lumia 950" | "Nexus 10" | "Nexus 4" | "Nexus 5" | "Nexus 5X" | "Nexus 6" | "Nexus 6P" | "Nexus 7" | "Nokia Lumia 520" | "Nokia N9" | "OnePlus 7T" | "OnePlus 7T Pro" | "Pixel 2" | "Pixel 2 XL" | "Pixel 3" | "Pixel 3 XL" | "Pixel 4" | "Pixel 4 XL" | "Pixel 5" | "Sony Xperia 10 II" | "Huawei Mate 50 Pro" | "Huawei Matepad 11"; screenOrientation?: ScreenOrientationPlain; }; } | { iosDeviceInfo: { deviceName: "iPhone 11" | "iPhone 11 Pro" | "iPhone 11 Pro Max" | "iPhone X" | "iPhone XR" | "iPhone 14 Pro Max" | "iPhone 14" | "iPhone 13 Pro Max" | "iPhone 13 Pro" | "iPhone 13" | "iPhone 12 Pro Max" | "iPhone 12 Pro" | "iPhone 12" | "iPhone 12 mini" | "iPhone Xs" | "iPhone 8" | "iPhone 8 Plus" | "iPhone 7" | "iPhone SE (1st generation)" | "iPad Pro (12.9-inch) (3rd generation)" | "iPad Pro (11-inch) (4th generation)" | "iPad (7th generation)" | "iPad (9th generation)" | "iPad Air (2nd generation)" | "iPad Air (4th generation)"; iosVersion?: "latest" | "latest-1"; screenOrientation?: ScreenOrientationPlain; }; } | { androidDeviceInfo: { deviceName: "Galaxy Note 10" | "Galaxy Note 10 Plus" | "Galaxy S10" | "Galaxy S10 Plus" | "Galaxy S20" | "Galaxy S21" | "Galaxy S21 Ultra" | "Galaxy S22" | "Galaxy Tab S7" | "Pixel 3 XL" | "Pixel 4" | "Pixel 4 XL" | "Pixel 5" | "Sony Xperia 10 II" | "Pixel 6" | "Galaxy S20 Plus" | "Galaxy S21 Plus" | "Galaxy S22 Plus" | "Galaxy Tab S8" | "Xiaomi Redmi Note 10 JE" | "Xiaomi Redmi Note 11" | "Xiaomi Redmi Note 11 Pro" | "Sony Xperia 1 II" | "Sony Xperia Ace II" | "Huawei P30 Lite"; version?: "latest" | "latest-1"; screenOrientation?: ScreenOrientationPlain; }; }>;
480
+ visualGridOptions?: Record<string, any>;
481
+ layoutBreakpoints?: boolean | Array<number> | { breakpoints: boolean | Array<number>; reload?: boolean; };
482
+ disableBrowserFetching?: boolean;
483
+ waitBeforeCapture?: number;
484
+ 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: "Blackberry PlayBook" | "BlackBerry Z30" | "Galaxy A5" | "Galaxy Note 10" | "Galaxy Note 10 Plus" | "Galaxy Note 2" | "Galaxy Note 3" | "Galaxy Note 4" | "Galaxy Note 8" | "Galaxy Note 9" | "Galaxy S3" | "Galaxy S5" | "Galaxy S8" | "Galaxy S8 Plus" | "Galaxy S9" | "Galaxy S9 Plus" | "Galaxy S10" | "Galaxy S10 Plus" | "Galaxy S20" | "Galaxy S21" | "Galaxy S21 Ultra" | "Galaxy S22" | "Galaxy S22 Ultra" | "Galaxy Tab S7" | "iPad" | "iPad 6th Gen" | "iPad 7th Gen" | "iPad Air 2" | "iPad Mini" | "iPad Pro" | "iPhone 11" | "iPhone 11 Pro" | "iPhone 11 Pro Max" | "iPhone 4" | "iPhone 5/SE" | "iPhone 6/7/8" | "iPhone 6/7/8 Plus" | "iPhone X" | "iPhone XR" | "iPhone XS" | "iPhone XS Max" | "Kindle Fire HDX" | "Laptop with HiDPI screen" | "Laptop with MDPI screen" | "Laptop with touch" | "LG G6" | "LG Optimus L70" | "Microsoft Lumia 550" | "Microsoft Lumia 950" | "Nexus 10" | "Nexus 4" | "Nexus 5" | "Nexus 5X" | "Nexus 6" | "Nexus 6P" | "Nexus 7" | "Nokia Lumia 520" | "Nokia N9" | "OnePlus 7T" | "OnePlus 7T Pro" | "Pixel 2" | "Pixel 2 XL" | "Pixel 3" | "Pixel 3 XL" | "Pixel 4" | "Pixel 4 XL" | "Pixel 5" | "Sony Xperia 10 II" | "Huawei Mate 50 Pro" | "Huawei Matepad 11"; screenOrientation?: ScreenOrientationPlain; }; } | { iosDeviceInfo: { deviceName: "iPhone 11" | "iPhone 11 Pro" | "iPhone 11 Pro Max" | "iPhone X" | "iPhone XR" | "iPhone 14 Pro Max" | "iPhone 14" | "iPhone 13 Pro Max" | "iPhone 13 Pro" | "iPhone 13" | "iPhone 12 Pro Max" | "iPhone 12 Pro" | "iPhone 12" | "iPhone 12 mini" | "iPhone Xs" | "iPhone 8" | "iPhone 8 Plus" | "iPhone 7" | "iPhone SE (1st generation)" | "iPad Pro (12.9-inch) (3rd generation)" | "iPad Pro (11-inch) (4th generation)" | "iPad (7th generation)" | "iPad (9th generation)" | "iPad Air (2nd generation)" | "iPad Air (4th generation)"; iosVersion?: "latest" | "latest-1"; screenOrientation?: ScreenOrientationPlain; }; } | { androidDeviceInfo: { deviceName: "Galaxy Note 10" | "Galaxy Note 10 Plus" | "Galaxy S10" | "Galaxy S10 Plus" | "Galaxy S20" | "Galaxy S21" | "Galaxy S21 Ultra" | "Galaxy S22" | "Galaxy Tab S7" | "Pixel 3 XL" | "Pixel 4" | "Pixel 4 XL" | "Pixel 5" | "Sony Xperia 10 II" | "Pixel 6" | "Galaxy S20 Plus" | "Galaxy S21 Plus" | "Galaxy S22 Plus" | "Galaxy Tab S8" | "Xiaomi Redmi Note 10 JE" | "Xiaomi Redmi Note 11" | "Xiaomi Redmi Note 11 Pro" | "Sony Xperia 1 II" | "Sony Xperia Ace II" | "Huawei P30 Lite"; version?: "latest" | "latest-1"; screenOrientation?: ScreenOrientationPlain; }; } | { deviceName: DeviceName; screenOrientation?: ScreenOrientationPlain; name?: string; }>;
485
+ batchId?: string;
486
+ batchName?: string;
487
+ batchSequence?: string;
488
+ notifyOnCompletion?: boolean;
489
+ batchSequenceName?: string;
490
+ envName?: string;
491
+ accessibilityValidation?: AccessibilityValidation;
492
+ matchLevel?: "None" | "Layout1" | "Layout" | "Layout2" | "Content" | "IgnoreColors" | "Strict" | "Exact";
493
+ ignoreCaret?: boolean;
494
+ ignoreDisplacements?: boolean;
495
+ useDom?: boolean;
496
+ enablePatterns?: boolean;
497
+ scriptHooks?: { beforeCaptureScreenshot: string; };
498
+ failCypressAfterAllSpecs?: boolean;
499
+ tapDirPath?: string;
500
+ tapFileName?: string;
501
+ showLogs?: boolean;
502
+ shouldDoPostSpecTasks?: boolean;
357
503
  isComponentTest?: boolean;
358
504
  };
359
505
  export type CypressTestResultsSummary = { getAllResults(): Array<{ getTestResults(): {