@applitools/eyes-cypress 3.28.3 → 3.29.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.
Files changed (40) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/README.md +28 -2
  3. package/dist/browser/spec-driver.js +0 -8
  4. package/dist/expose.js +7 -0
  5. package/dist/plugin/concurrencyMsg.js +9 -0
  6. package/dist/plugin/config.js +66 -0
  7. package/dist/plugin/configParams.js +47 -0
  8. package/dist/plugin/errorDigest.js +74 -0
  9. package/dist/plugin/getErrorsAndDiffs.js +31 -0
  10. package/dist/plugin/handleTestResults.js +38 -0
  11. package/dist/plugin/hooks.js +43 -0
  12. package/dist/plugin/index.js +17 -0
  13. package/dist/plugin/isGlobalHooksSupported.js +10 -0
  14. package/dist/plugin/pluginExport.js +104 -0
  15. package/dist/plugin/server.js +117 -0
  16. package/dist/plugin/webSocket.js +129 -0
  17. package/index.js +3 -2
  18. package/package.json +37 -18
  19. package/src/browser/spec-driver.ts +1 -1
  20. package/src/expose.ts +71 -0
  21. package/src/plugin/{concurrencyMsg.js → concurrencyMsg.ts} +1 -1
  22. package/src/plugin/{config.js → config.ts} +6 -15
  23. package/src/plugin/{configParams.js → configParams.ts} +1 -3
  24. package/src/plugin/{errorDigest.js → errorDigest.ts} +34 -38
  25. package/src/plugin/{getErrorsAndDiffs.js → getErrorsAndDiffs.ts} +3 -8
  26. package/src/plugin/{handleTestResults.js → handleTestResults.ts} +17 -12
  27. package/src/plugin/hooks.ts +60 -0
  28. package/src/plugin/index.ts +37 -0
  29. package/src/plugin/isGlobalHooksSupported.ts +11 -0
  30. package/src/plugin/pluginExport.ts +118 -0
  31. package/src/plugin/{server.js → server.ts} +30 -33
  32. package/src/plugin/{webSocket.js → webSocket.ts} +34 -23
  33. package/src/setup/handlePlugin.js +21 -2
  34. package/src/setup/isPluginDefinedESM.js +5 -0
  35. package/index.d.ts +0 -86
  36. package/src/plugin/defaultPort.js +0 -1
  37. package/src/plugin/hooks.js +0 -41
  38. package/src/plugin/isGlobalHooksSupported.js +0 -13
  39. package/src/plugin/pluginExport.js +0 -94
  40. package/src/plugin/startPlugin.js +0 -15
@@ -0,0 +1,11 @@
1
+ const CYPRESS_SUPPORTED_VERSION = '6.2.0'
2
+ const CYPRESS_NO_FLAG_VERSION = '6.7.0'
3
+
4
+ export default function isGlobalHooksSupported(config: any) {
5
+ const {version, experimentalRunEvents} = config
6
+
7
+ return (
8
+ parseFloat(version) >= parseFloat(CYPRESS_NO_FLAG_VERSION) ||
9
+ (parseFloat(version) >= parseFloat(CYPRESS_SUPPORTED_VERSION) && !!experimentalRunEvents)
10
+ )
11
+ }
@@ -0,0 +1,118 @@
1
+ import isGlobalHooksSupported from './isGlobalHooksSupported'
2
+ // @ts-ignore
3
+ import {presult} from '@applitools/functional-commons'
4
+ import makeGlobalRunHooks from './hooks'
5
+ import {type EyesPluginConfig} from './'
6
+
7
+ export default function makePluginExport({startServer, eyesConfig}: any) {
8
+ return function pluginExport(pluginInitArgs: Cypress.ConfigOptions | NodeJS.Module) {
9
+ let eyesServer: any, pluginModuleExports: any, pluginExportsE2E: any, pluginExportsComponent: any
10
+ let pluginExports
11
+ if ((pluginInitArgs as NodeJS.Module).exports) {
12
+ const pluginAsNodeJSModule = pluginInitArgs as NodeJS.Module
13
+ pluginExports =
14
+ pluginAsNodeJSModule.exports && pluginAsNodeJSModule.exports.default
15
+ ? pluginAsNodeJSModule.exports.default
16
+ : pluginAsNodeJSModule.exports
17
+
18
+ if (pluginExports.component) {
19
+ pluginExportsComponent = pluginExports.component.setupNodeEvents
20
+ }
21
+ if (pluginExports.e2e) {
22
+ pluginExportsE2E = pluginExports.e2e.setupNodeEvents
23
+ }
24
+ if (!pluginExports.e2e && !pluginExports.component) {
25
+ pluginModuleExports = pluginExports
26
+ }
27
+ if (pluginExports?.component) {
28
+ pluginExports.component.setupNodeEvents = setupNodeEvents
29
+ }
30
+ if (pluginExports?.e2e) {
31
+ pluginExports.e2e.setupNodeEvents = setupNodeEvents
32
+ }
33
+ if (!pluginExports.component && !pluginExports.e2e) {
34
+ if (pluginAsNodeJSModule.exports.default) {
35
+ pluginAsNodeJSModule.exports.default = setupNodeEvents
36
+ } else {
37
+ pluginAsNodeJSModule.exports = setupNodeEvents
38
+ }
39
+ }
40
+ } else {
41
+ // this is required because we are currently support cypress < 10
42
+ // in the version before 10 the `e2e.setupNodeEvents` and `component.setupNodeEvents` were not supported
43
+ const pluginAsCypress10PluginOptions = pluginInitArgs as {e2e: {setupNodeEvents: any}; component: {setupNodeEvents: any}}
44
+ if (pluginAsCypress10PluginOptions.component) {
45
+ pluginExportsComponent = pluginAsCypress10PluginOptions.component.setupNodeEvents
46
+ pluginAsCypress10PluginOptions.component.setupNodeEvents = setupNodeEvents
47
+ }
48
+ if (pluginAsCypress10PluginOptions.e2e) {
49
+ pluginExportsE2E = pluginAsCypress10PluginOptions.e2e.setupNodeEvents
50
+ pluginAsCypress10PluginOptions.e2e.setupNodeEvents = setupNodeEvents
51
+ }
52
+ }
53
+
54
+ if (!(pluginInitArgs as NodeJS.Module).exports) {
55
+ return pluginInitArgs
56
+ }
57
+ return function getCloseServer() {
58
+ return eyesServer.close()
59
+ }
60
+
61
+ async function setupNodeEvents(
62
+ origOn: Cypress.PluginEvents,
63
+ cypressConfig: Cypress.PluginConfigOptions,
64
+ ): Promise<EyesPluginConfig> {
65
+ const {server, port, closeManager, closeBatches, closeUniversalServer} = await startServer()
66
+ eyesServer = server
67
+
68
+ const globalHooks: any = makeGlobalRunHooks({
69
+ closeManager,
70
+ closeBatches,
71
+ closeUniversalServer,
72
+ })
73
+
74
+ if (!pluginModuleExports) {
75
+ pluginModuleExports = cypressConfig.testingType === 'e2e' ? pluginExportsE2E : pluginExportsComponent
76
+ }
77
+
78
+ const isGlobalHookCalledFromUserHandlerMap = new Map()
79
+ eyesConfig.eyesIsGlobalHooksSupported = isGlobalHooksSupported(cypressConfig)
80
+ let moduleExportsResult = {}
81
+ // in case setupNodeEvents is not defined in cypress.config file
82
+ if (typeof pluginModuleExports === 'function') {
83
+ moduleExportsResult = await pluginModuleExports(onThatCallsUserDefinedHandler, cypressConfig)
84
+ }
85
+ if (eyesConfig.eyesIsGlobalHooksSupported) {
86
+ for (const [eventName, eventHandler] of Object.entries(globalHooks)) {
87
+ if (!isGlobalHookCalledFromUserHandlerMap.get(eventName)) {
88
+ origOn.call(this, eventName, eventHandler)
89
+ }
90
+ }
91
+ }
92
+
93
+ return Object.assign({}, eyesConfig, {eyesPort: port}, moduleExportsResult)
94
+
95
+ // This piece of code exists because at the point of writing, Cypress does not support multiple event handlers:
96
+ // https://github.com/cypress-io/cypress/issues/5240#issuecomment-948277554
97
+ // So we wrap Cypress' `on` function in order to wrap the user-defined handler. This way we can call our own handler
98
+ // in addition to the user's handler
99
+ function onThatCallsUserDefinedHandler(eventName: string, handler: any) {
100
+ const isRunEvent = eventName === 'before:run' || eventName === 'after:run'
101
+ let handlerToCall = handler
102
+ if (eyesConfig.eyesIsGlobalHooksSupported && isRunEvent) {
103
+ handlerToCall = handlerThatCallsUserDefinedHandler
104
+ isGlobalHookCalledFromUserHandlerMap.set(eventName, true)
105
+ }
106
+ return origOn.call(this, eventName, handlerToCall)
107
+
108
+ async function handlerThatCallsUserDefinedHandler(...args: any[]) {
109
+ const [err] = await presult(Promise.resolve(globalHooks[eventName].apply(this, args)))
110
+ await handler.apply(this, args)
111
+ if (err) {
112
+ throw err
113
+ }
114
+ }
115
+ }
116
+ }
117
+ }
118
+ }
@@ -1,38 +1,37 @@
1
- 'use strict'
2
- const connectSocket = require('./webSocket')
3
- const {makeServerProcess} = require('@applitools/eyes-universal')
4
- const handleTestResults = require('./handleTestResults')
5
- const path = require('path')
6
- const fs = require('fs')
7
- const semverLt = require('semver/functions/lt')
8
- const {Server: HttpsServer} = require('https')
9
- const {Server: WSServer} = require('ws')
10
- const which = require('which')
11
-
12
- function makeStartServer({logger}) {
1
+ import connectSocket, {type SocketWithUniversal} from './webSocket'
2
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
3
+ // @ts-ignore
4
+ import {makeServerProcess} from '@applitools/eyes-universal'
5
+ import handleTestResults from './handleTestResults'
6
+ import path from 'path'
7
+ import fs from 'fs'
8
+ import {lt as semverLt} from 'semver'
9
+ import {Server as HttpsServer} from 'https'
10
+ import {Server as WSServer} from 'ws'
11
+ import which from 'which'
12
+ import {type Logger} from '@applitools/logger'
13
+ import {AddressInfo} from 'net'
14
+ import {promisify} from 'util'
15
+
16
+ export default function makeStartServer({logger}: {logger: Logger}) {
13
17
  return async function startServer() {
14
- const key = fs.readFileSync(path.resolve(__dirname, '../pem/server.key'))
15
- const cert = fs.readFileSync(path.resolve(__dirname, '../pem/server.cert'))
16
- let port
17
-
18
+ const key = fs.readFileSync(path.resolve(__dirname, '../../src/pem/server.key'))
19
+ const cert = fs.readFileSync(path.resolve(__dirname, '../../src/pem/server.cert'))
18
20
  const https = new HttpsServer({
19
21
  key,
20
22
  cert,
21
23
  })
22
- await https.listen(0, err => {
23
- if (err) {
24
- logger.log('error starting plugin server', err)
25
- } else {
26
- logger.log(`plugin server running at port: ${https.address().port}`)
27
- port = https.address().port
28
- }
29
- })
24
+ await promisify(https.listen.bind(https))()
30
25
 
26
+ const port = (https.address() as AddressInfo).port
31
27
  const wss = new WSServer({server: https, path: '/eyes', maxPayload: 254 * 1024 * 1024})
32
28
 
33
29
  wss.on('close', () => https.close())
34
30
 
35
- const forkOptions = {
31
+ const forkOptions: {
32
+ detached: boolean
33
+ execPath?: string
34
+ } = {
36
35
  detached: true,
37
36
  }
38
37
 
@@ -53,13 +52,13 @@ function makeStartServer({logger}) {
53
52
  portResolutionMode: 'random',
54
53
  })
55
54
 
56
- const managers = []
57
- let socketWithUniversal
55
+ const managers: {manager: object; socketWithUniversal: SocketWithUniversal}[] = []
56
+ let socketWithUniversal: SocketWithUniversal
58
57
 
59
58
  wss.on('connection', socketWithClient => {
60
59
  socketWithUniversal = connectSocket(`ws://localhost:${universalPort}/eyes`)
61
60
 
62
- socketWithUniversal.setPassthroughListener(message => {
61
+ socketWithUniversal.setPassthroughListener((message: string) => {
63
62
  logger.log('<== ', message.toString().slice(0, 1000))
64
63
  const {name, payload} = JSON.parse(message)
65
64
  if (name === 'Core.makeManager') {
@@ -69,7 +68,7 @@ function makeStartServer({logger}) {
69
68
  socketWithClient.send(message.toString())
70
69
  })
71
70
 
72
- socketWithClient.on('message', message => {
71
+ socketWithClient.on('message', (message: string) => {
73
72
  const msg = JSON.parse(message)
74
73
  logger.log('==> ', message.toString().slice(0, 1000))
75
74
  if (msg.name === 'Core.makeSDK') {
@@ -134,13 +133,11 @@ function makeStartServer({logger}) {
134
133
  ),
135
134
  )
136
135
  }
137
- function closeBatches(settings) {
136
+ function closeBatches(settings: any) {
138
137
  if (socketWithUniversal)
139
- return socketWithUniversal.request('Core.closeBatches', {settings}).catch(err => {
138
+ return socketWithUniversal.request('Core.closeBatches', {settings}).catch((err: Error) => {
140
139
  logger.log('@@@', err)
141
140
  })
142
141
  }
143
142
  }
144
143
  }
145
-
146
- module.exports = makeStartServer
@@ -1,26 +1,39 @@
1
- const WebSocket = require('ws')
2
- const {v4: uuid} = require('uuid')
1
+ import WebSocket from 'ws'
2
+ import {v4 as uuid} from 'uuid'
3
+ import {type Socket} from 'net'
4
+
5
+ export type SocketWithUniversal = {
6
+ setPassthroughListener: (_listener: (_message: any) => void) => void
7
+ once(_type: any, _fn: any): any
8
+ on(_type: any, _fn: any): any
9
+ off(_type: any, _fn: any): any
10
+ disconnect(): void
11
+ ref(): () => boolean
12
+ unref(): () => boolean
13
+ send(_message: any): () => boolean
14
+ request(_name: string, _payload: any): any
15
+ }
3
16
 
4
- function connectSocket(url) {
5
- const socket = new WebSocket(url)
6
- let passthroughListener
17
+ export default function connectSocket(url: string): SocketWithUniversal {
18
+ const socket: WebSocket & {_socket?: Socket} = new WebSocket(url)
19
+ let passthroughListener: any
7
20
  const listeners = new Map()
8
- const queue = new Set()
21
+ const queue = new Set<any>()
9
22
  let isReady = false
10
23
 
11
24
  attach()
12
25
 
13
26
  function attach() {
14
- if (socket.readyState === WebSocket.CONNECTING) socket.on('open', () => attach(socket))
27
+ if (socket.readyState === WebSocket.CONNECTING) socket.on('open', () => attach())
15
28
  else if (socket.readyState === WebSocket.OPEN) {
16
29
  isReady = true
17
- queue.forEach(command => command())
30
+ queue.forEach((command: any) => command())
18
31
  queue.clear()
19
32
 
20
33
  socket.on('message', message => {
21
34
  const {name, key, payload} = deserialize(message)
22
- const fns = listeners.get(name)
23
- const keyListeners = key && listeners.get(`${name}/${key}`)
35
+ const fns: any[] = listeners.get(name)
36
+ const keyListeners: any[] = key && listeners.get(`${name}/${key}`)
24
37
  if (fns) fns.forEach(fn => fn(payload, key))
25
38
  if (keyListeners) keyListeners.forEach(fn => fn(payload, key))
26
39
 
@@ -39,18 +52,18 @@ function connectSocket(url) {
39
52
  queue.clear()
40
53
  }
41
54
 
42
- function setPassthroughListener(fn) {
55
+ function setPassthroughListener(fn: any) {
43
56
  passthroughListener = fn
44
57
  }
45
58
 
46
- function send(message) {
59
+ function send(message: string) {
47
60
  const command = () => socket.send(message)
48
61
  if (isReady) command()
49
62
  else queue.add(command)
50
63
  return () => queue.delete(command)
51
64
  }
52
65
 
53
- function on(type, fn) {
66
+ function on(type: string | {name: string; key: string}, fn: any) {
54
67
  const name = typeof type === 'string' ? type : `${type.name}/${type.key}`
55
68
  let fns = listeners.get(name)
56
69
  if (!fns) {
@@ -61,12 +74,12 @@ function connectSocket(url) {
61
74
  return () => off(name, fn)
62
75
  }
63
76
 
64
- function once(type, fn) {
65
- const off = on(type, (...args) => (fn(...args), off()))
77
+ function once(type: any, fn: any) {
78
+ const off = on(type, (...args: any[]) => (fn(...args), off()))
66
79
  return off
67
80
  }
68
81
 
69
- function off(name, fn) {
82
+ function off(name: string, fn: any) {
70
83
  if (!fn) return listeners.delete(name)
71
84
  const fns = listeners.get(name)
72
85
  if (!fns) return false
@@ -75,15 +88,15 @@ function connectSocket(url) {
75
88
  return existed
76
89
  }
77
90
 
78
- function emit(type, payload) {
91
+ function emit(type: any, payload: any) {
79
92
  return send(serialize(type, payload))
80
93
  }
81
94
 
82
- function request(name, payload) {
95
+ function request(name: string, payload: any) {
83
96
  return new Promise((resolve, reject) => {
84
97
  const key = uuid()
85
98
  emit({name, key}, payload)
86
- once({name, key}, response => {
99
+ once({name, key}, (response: any) => {
87
100
  if (response.error) return reject(response.error)
88
101
  return resolve(response.result)
89
102
  })
@@ -117,13 +130,11 @@ function connectSocket(url) {
117
130
  }
118
131
  }
119
132
 
120
- function serialize(type, payload) {
133
+ function serialize(type: any, payload: any) {
121
134
  const message = typeof type === 'string' ? {name: type, payload} : {name: type.name, key: type.key, payload}
122
135
  return JSON.stringify(message)
123
136
  }
124
137
 
125
- function deserialize(message) {
138
+ function deserialize(message: any) {
126
139
  return JSON.parse(message)
127
140
  }
128
-
129
- module.exports = connectSocket
@@ -1,16 +1,35 @@
1
1
  'use strict'
2
2
 
3
3
  const chalk = require('chalk')
4
+ const boxen = require('boxen')
4
5
  const {addEyesCypressPlugin} = require('./addEyesCypressPlugin')
5
6
  const isPluginDefined = require('./isPluginDefined')
7
+ const isPluginDefinedESM = require('./isPluginDefinedESM')
6
8
  const fs = require('fs')
7
9
 
8
10
  function handlePlugin(pluginsFilePath) {
9
11
  const fileContent = fs.readFileSync(pluginsFilePath, 'utf-8')
10
-
11
- if (!isPluginDefined(fileContent)) {
12
+ const isESMOrTS = fileContent.indexOf('module.export') === -1
13
+ if (!isESMOrTS && !isPluginDefined(fileContent)) {
12
14
  fs.writeFileSync(pluginsFilePath, addEyesCypressPlugin(fileContent))
13
15
  console.log(chalk.cyan('Plugins defined.'))
16
+ } else if (isESMOrTS && !isPluginDefinedESM(fileContent)) {
17
+ console.log(
18
+ boxen(
19
+ `
20
+ We detected that you are using TS or ESM syntax. Please configure the plugin as follows:
21
+
22
+ ${chalk.green.bold('import eyesPlugin from "@applitools/eyes-cypress"')}
23
+
24
+ export default ${chalk.green.bold('eyesPlugin(')}definedConfig({
25
+ //...
26
+ })${chalk.green.bold(')')}
27
+
28
+ For more information, visit Eyes-Cypress documentation https://www.npmjs.com/package/@applitools/eyes-cypress (manual configuration section)
29
+ `,
30
+ {padding: 1, borderColor: 'cyan'},
31
+ ),
32
+ )
14
33
  } else {
15
34
  console.log(chalk.cyan('Plugins already defined'))
16
35
  }
@@ -0,0 +1,5 @@
1
+ function isPluginDefinedTypeScript(content) {
2
+ return !!content.match(/from\s*['"]@applitools\/eyes-cypress['"]\s*/)
3
+ }
4
+
5
+ module.exports = isPluginDefinedTypeScript
package/index.d.ts DELETED
@@ -1,86 +0,0 @@
1
- /// <reference types="cypress" />
2
- import type * as api from '@applitools/eyes-api'
3
-
4
- type MaybeArray<T> = T | T[]
5
-
6
- type LegacyRegion = {left: number; top: number; width: number; height: number}
7
- type Selector = {selector: string; type?: 'css' | 'xpath', nodeType?: 'element' | 'shadow-root'} | 'string'
8
- type Element = HTMLElement | JQuery<HTMLElement>
9
- type ElementWithOptions = {element: Element, regionId?: string, padding?: any}
10
-
11
- interface CypressCheckSettings extends api.CheckSettingsAutomationPlain<Element, Selector>{
12
- tag?: CypressCheckSettings['name']
13
-
14
- target?: 'window' | 'region'
15
- selector?: Selector
16
- element?: Element
17
-
18
- ignore?: MaybeArray<NonNullable<CypressCheckSettings['ignoreRegions']>[number] | LegacyRegion | ElementWithOptions>
19
- layout?: MaybeArray<NonNullable<CypressCheckSettings['layoutRegions']>[number] | LegacyRegion| ElementWithOptions>
20
- content?: MaybeArray<NonNullable<CypressCheckSettings['contentRegions']>[number] | LegacyRegion| ElementWithOptions>
21
- strict?: MaybeArray<NonNullable<CypressCheckSettings['strictRegions']>[number] | LegacyRegion | ElementWithOptions>
22
- floating?: MaybeArray<NonNullable<CypressCheckSettings['floatingRegions']>[number] | ((ElementWithOptions | Selector | LegacyRegion) & {maxUpOffset?: number; maxDownOffset?: number; maxLeftOffset?: number; maxRightOffset?: number})>
23
- accessibility?: MaybeArray<NonNullable<CypressCheckSettings['accessibilityRegions']>[number] | ((ElementWithOptions | Selector | LegacyRegion) & {accessibilityType?: api.AccessibilityRegionTypePlain})>
24
- scriptHooks?: CypressCheckSettings['hooks']
25
- ignoreCaret?: boolean
26
- ignoreDisplacements?: boolean
27
- }
28
-
29
- interface CypressEyesConfig extends api.ConfigurationPlain<Element, Selector> {
30
- browser?: MaybeArray<NonNullable<CypressEyesConfig['browsersInfo']>[number] | {deviceName: string; screenOrientation?: api.ScreenOrientationPlain; name?: string}>
31
-
32
- batchId?: NonNullable<CypressEyesConfig['batch']>['id']
33
- batchName?: NonNullable<CypressEyesConfig['batch']>['name']
34
- batchSequence?: NonNullable<CypressEyesConfig['batch']>['sequenceName']
35
- notifyOnCompletion?: NonNullable<CypressEyesConfig['batch']>['notifyOnCompletion']
36
-
37
- envName?: CypressEyesConfig['environmentName']
38
-
39
- accessibilitySettings?: NonNullable<CypressEyesConfig['defaultMatchSettings']>['accessibilitySettings']
40
- }
41
-
42
- declare global {
43
- namespace Cypress {
44
- interface Chainable {
45
- /**
46
- * Create an Applitools test.
47
- * This will start a session with the Applitools server.
48
- * @example
49
- * cy.eyesOpen({ appName: 'My App' })
50
- */
51
- eyesOpen(config?: CypressEyesConfig): null
52
-
53
- /**
54
- * Generate a screenshot of the current page and add it to the Applitools Test.
55
- * @example
56
- * cy.eyesCheckWindow()
57
- *
58
- * OR
59
- *
60
- * cy.eyesCheckWindow({
61
- * target: 'region',
62
- * selector: '.my-element'
63
- * });
64
- */
65
- eyesCheckWindow(tag?: string): null
66
- eyesCheckWindow(settings?: CypressCheckSettings): null
67
-
68
- /**
69
- * Close the applitools test and check that all screenshots are valid.
70
- * @example cy.eyesClose()
71
- */
72
- eyesClose(): null
73
-
74
- /**
75
- * Returns an object with the applitools test results from a given test / test file. This should be called after close.
76
- * @example
77
- * after(() => {
78
- * cy.eyesGetAllTestResults().then(summary => {
79
- * console.log(summary)
80
- * })
81
- * })
82
- */
83
- eyesGetAllTestResults(): Chainable<api.TestResultsSummary>
84
- }
85
- }
86
- }
@@ -1 +0,0 @@
1
- module.exports = 7373
@@ -1,41 +0,0 @@
1
- 'use strict'
2
- const handleTestResults = require('./handleTestResults')
3
-
4
- function makeGlobalRunHooks({closeManager, closeBatches, closeUniversalServer}) {
5
- return {
6
- 'before:run': ({config}) => {
7
- if (!config.isTextTerminal) return
8
- },
9
-
10
- 'after:run': async ({config}) => {
11
- try {
12
- if (!config.isTextTerminal) return
13
- const summaries = await closeManager()
14
-
15
- let testResults
16
- for (const summary of summaries) {
17
- testResults = summary.results.map(({testResults}) => testResults)
18
- }
19
- if (!config.appliConfFile.dontCloseBatches) {
20
- await closeBatches({
21
- batchIds: [config.appliConfFile.batchId || config.appliConfFile.batch.id],
22
- serverUrl: config.appliConfFile.serverUrl,
23
- proxy: config.appliConfFile.proxy,
24
- apiKey: config.appliConfFile.apiKey,
25
- })
26
- }
27
-
28
- if (config.appliConfFile.tapDirPath) {
29
- await handleTestResults.handleBatchResultsFile(testResults, {
30
- tapDirPath: config.appliConfFile.tapDirPath,
31
- tapFileName: config.appliConfFile.tapFileName,
32
- })
33
- }
34
- } finally {
35
- await closeUniversalServer()
36
- }
37
- },
38
- }
39
- }
40
-
41
- module.exports = makeGlobalRunHooks
@@ -1,13 +0,0 @@
1
- const CYPRESS_SUPPORTED_VERSION = '6.2.0'
2
- const CYPRESS_NO_FLAG_VERSION = '6.7.0'
3
-
4
- function isGlobalHooksSupported(config) {
5
- const {version, experimentalRunEvents} = config
6
-
7
- return (
8
- parseFloat(version, 10) >= parseFloat(CYPRESS_NO_FLAG_VERSION, 10) ||
9
- (parseFloat(version, 10) >= parseFloat(CYPRESS_SUPPORTED_VERSION, 10) && !!experimentalRunEvents)
10
- )
11
- }
12
-
13
- module.exports = isGlobalHooksSupported
@@ -1,94 +0,0 @@
1
- 'use strict'
2
- const isGlobalHooksSupported = require('./isGlobalHooksSupported')
3
- const {presult} = require('@applitools/functional-commons')
4
- const makeGlobalRunHooks = require('./hooks')
5
-
6
- function makePluginExport({startServer, eyesConfig}) {
7
- return function pluginExport(pluginModule) {
8
- let eyesServer, pluginModuleExports, pluginExportsE2E, pluginExportsComponent
9
- const pluginExports =
10
- pluginModule.exports && pluginModule.exports.default ? pluginModule.exports.default : pluginModule.exports
11
-
12
- if (pluginExports.component) {
13
- pluginExportsComponent = pluginExports.component.setupNodeEvents
14
- }
15
- if (pluginExports.e2e) {
16
- pluginExportsE2E = pluginExports.e2e.setupNodeEvents
17
- }
18
- if (!pluginExports.e2e && !pluginExports.component) {
19
- pluginModuleExports = pluginExports
20
- }
21
-
22
- const setupNodeEvents = async function (...args) {
23
- const {server, port, closeManager, closeBatches, closeUniversalServer} = await startServer()
24
- eyesServer = server
25
-
26
- const globalHooks = makeGlobalRunHooks({closeManager, closeBatches, closeUniversalServer})
27
-
28
- const [origOn, config] = args
29
-
30
- if (!pluginModuleExports) {
31
- pluginModuleExports = config.testingType === 'e2e' ? pluginExportsE2E : pluginExportsComponent
32
- }
33
-
34
- const isGlobalHookCalledFromUserHandlerMap = new Map()
35
- eyesConfig.eyesIsGlobalHooksSupported = isGlobalHooksSupported(config)
36
- let moduleExportsResult = {}
37
- // in case setupNodeEvents is not defined in cypress.config file
38
- if (typeof pluginModuleExports === 'function') {
39
- moduleExportsResult = await pluginModuleExports(onThatCallsUserDefinedHandler, config)
40
- }
41
- if (eyesConfig.eyesIsGlobalHooksSupported) {
42
- for (const [eventName, eventHandler] of Object.entries(globalHooks)) {
43
- if (!isGlobalHookCalledFromUserHandlerMap.get(eventName)) {
44
- origOn.call(this, eventName, eventHandler)
45
- }
46
- }
47
- }
48
-
49
- return Object.assign({}, eyesConfig, {eyesPort: port}, moduleExportsResult)
50
-
51
- // This piece of code exists because at the point of writing, Cypress does not support multiple event handlers:
52
- // https://github.com/cypress-io/cypress/issues/5240#issuecomment-948277554
53
- // So we wrap Cypress' `on` function in order to wrap the user-defined handler. This way we can call our own handler
54
- // in addition to the user's handler
55
- function onThatCallsUserDefinedHandler(eventName, handler) {
56
- const isRunEvent = eventName === 'before:run' || eventName === 'after:run'
57
- let handlerToCall = handler
58
- if (eyesConfig.eyesIsGlobalHooksSupported && isRunEvent) {
59
- handlerToCall = handlerThatCallsUserDefinedHandler
60
- isGlobalHookCalledFromUserHandlerMap.set(eventName, true)
61
- }
62
- return origOn.call(this, eventName, handlerToCall)
63
-
64
- async function handlerThatCallsUserDefinedHandler() {
65
- const [err] = await presult(Promise.resolve(globalHooks[eventName].apply(this, arguments)))
66
- await handler.apply(this, arguments)
67
- if (err) {
68
- throw err
69
- }
70
- }
71
- }
72
- }
73
-
74
- if (pluginExports.component) {
75
- pluginExports.component.setupNodeEvents = setupNodeEvents
76
- }
77
- if (pluginExports.e2e) {
78
- pluginExports.e2e.setupNodeEvents = setupNodeEvents
79
- }
80
- if (!pluginExports.component && !pluginExports.e2e) {
81
- if (pluginModule.exports.default) {
82
- pluginModule.exports.default = setupNodeEvents
83
- } else {
84
- pluginModule.exports = setupNodeEvents
85
- }
86
- }
87
-
88
- return function getCloseServer() {
89
- return eyesServer.close()
90
- }
91
- }
92
- }
93
-
94
- module.exports = makePluginExport
@@ -1,15 +0,0 @@
1
- 'use strict'
2
- const makePluginExport = require('./pluginExport')
3
- const makeConfig = require('./config')
4
- const makeStartServer = require('./server')
5
- const {makeLogger} = require('@applitools/logger')
6
-
7
- const {config, eyesConfig} = makeConfig()
8
- const logger = makeLogger({level: config.showLogs ? 'info' : 'silent', label: 'eyes'})
9
-
10
- const startServer = makeStartServer({logger})
11
-
12
- module.exports = makePluginExport({
13
- startServer,
14
- eyesConfig: Object.assign({}, eyesConfig, {appliConfFile: config}),
15
- })