@applitools/eyes-cypress 3.29.1 → 3.30.1
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 +15 -0
- package/README.md +34 -10
- package/dist/plugin/hooks.js +4 -4
- package/dist/plugin/pluginExport.js +3 -3
- package/dist/plugin/server.js +8 -9
- package/package.json +18 -22
- package/src/browser/commands.js +43 -30
- package/src/browser/eyesCheckMapping.js +75 -37
- package/src/browser/eyesOpenMapping.js +21 -27
- package/src/expose.ts +5 -3
- package/src/plugin/hooks.ts +10 -5
- package/src/plugin/index.ts +1 -0
- package/src/plugin/pluginExport.ts +10 -3
- package/src/plugin/server.ts +25 -12
- package/src/setup/handlePlugin.js +1 -1
- package/types/expose.d.ts +53 -52
|
@@ -14,8 +14,6 @@ const batchPropertiesRetriever = (args, appliConfFile) => {
|
|
|
14
14
|
}
|
|
15
15
|
}
|
|
16
16
|
function eyesOpenMapValues({args, appliConfFile, testName, shouldUseBrowserHooks}) {
|
|
17
|
-
let browsersInfo = args.browser || appliConfFile.browser
|
|
18
|
-
let accessibilitySettings = args.accessibilityValidation || appliConfFile.accessibilityValidation
|
|
19
17
|
const batchProperties = batchPropertiesRetriever(args, appliConfFile)
|
|
20
18
|
const batch = {
|
|
21
19
|
id: batchProperties('batchId', 'id'),
|
|
@@ -45,18 +43,7 @@ function eyesOpenMapValues({args, appliConfFile, testName, shouldUseBrowserHooks
|
|
|
45
43
|
'batchSequenceName',
|
|
46
44
|
]
|
|
47
45
|
|
|
48
|
-
if (browsersInfo) {
|
|
49
|
-
if (Array.isArray(browsersInfo)) {
|
|
50
|
-
for (const [index, value] of browsersInfo.entries()) {
|
|
51
|
-
browsersInfo[index] = fillDefaultBrowserName(value)
|
|
52
|
-
}
|
|
53
|
-
} else {
|
|
54
|
-
browsersInfo = [fillDefaultBrowserName(browsersInfo)]
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
|
|
58
46
|
const defaultMatchSettings = {
|
|
59
|
-
accessibilitySettings,
|
|
60
47
|
matchLevel: args.matchLevel || appliConfFile.matchLevel,
|
|
61
48
|
ignoreCaret: args.ignoreCaret || appliConfFile.ignoreCaret,
|
|
62
49
|
useDom: args.useDom || appliConfFile.useDom,
|
|
@@ -75,27 +62,34 @@ function eyesOpenMapValues({args, appliConfFile, testName, shouldUseBrowserHooks
|
|
|
75
62
|
}
|
|
76
63
|
|
|
77
64
|
const mappedArgs = {
|
|
65
|
+
...defaultMatchSettings,
|
|
78
66
|
...args,
|
|
79
|
-
browsersInfo,
|
|
80
|
-
defaultMatchSettings,
|
|
81
67
|
batch,
|
|
82
68
|
}
|
|
69
|
+
if (typeof args.viewportSize !== 'undefined' || typeof args.environment !== 'undefined') {
|
|
70
|
+
mappedArgs.environment = {viewportSize: args.viewportSize, ...args.environment}
|
|
71
|
+
}
|
|
83
72
|
|
|
84
|
-
return Object.assign({testName,
|
|
73
|
+
return Object.assign({testName, keepBatchOpen: !shouldUseBrowserHooks}, appliConfFileCopy, mappedArgs)
|
|
85
74
|
}
|
|
86
75
|
|
|
87
|
-
function
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
76
|
+
function eyesOpenToCheckMapValues(args) {
|
|
77
|
+
const {browser, waitBeforeCapture, layoutBreakpoints, accessibilityValidation} = args
|
|
78
|
+
|
|
79
|
+
const openToCheckSettingsArgs = {
|
|
80
|
+
browser,
|
|
81
|
+
waitBeforeCapture,
|
|
82
|
+
layoutBreakpoints,
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
if (accessibilityValidation) {
|
|
86
|
+
const {level, guidelinesVersion} = accessibilityValidation
|
|
87
|
+
openToCheckSettingsArgs.accessibilitySettings = {
|
|
88
|
+
level,
|
|
89
|
+
version: guidelinesVersion,
|
|
94
90
|
}
|
|
95
|
-
return browser
|
|
96
|
-
} else {
|
|
97
|
-
return browser
|
|
98
91
|
}
|
|
92
|
+
return openToCheckSettingsArgs
|
|
99
93
|
}
|
|
100
94
|
|
|
101
|
-
module.exports = {eyesOpenMapValues}
|
|
95
|
+
module.exports = {eyesOpenMapValues, eyesOpenToCheckMapValues}
|
package/src/expose.ts
CHANGED
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
**/
|
|
9
9
|
/// <reference types="cypress" />
|
|
10
10
|
import type * as api from '@applitools/eyes-api'
|
|
11
|
+
import type * as core from '@applitools/core'
|
|
11
12
|
import {type EyesSelector, type TestResultsStatus} from '@applitools/eyes-api'
|
|
12
13
|
|
|
13
14
|
export type {EyesSelector, TestResultsStatus}
|
|
@@ -15,11 +16,12 @@ export type {EyesSelector, TestResultsStatus}
|
|
|
15
16
|
type MaybeArray<T> = T | T[]
|
|
16
17
|
|
|
17
18
|
type LegacyRegion = {left: number; top: number; width: number; height: number}
|
|
18
|
-
type Selector = {selector: string; type?: 'css' | 'xpath'; nodeType?: 'element' | 'shadow-root'} |
|
|
19
|
+
type Selector = {selector: string; type?: 'css' | 'xpath'; nodeType?: 'element' | 'shadow-root'} | string
|
|
19
20
|
type Element = HTMLElement | JQuery<HTMLElement>
|
|
20
21
|
type ElementWithOptions = {element: Element; regionId?: string; padding?: any}
|
|
22
|
+
type SpecType = core.SpecType<unknown, unknown, Element, Selector>
|
|
21
23
|
|
|
22
|
-
export type CypressCheckSettings = api.CheckSettingsAutomationPlain<
|
|
24
|
+
export type CypressCheckSettings = api.CheckSettingsAutomationPlain<SpecType> & {
|
|
23
25
|
tag?: CypressCheckSettings['name']
|
|
24
26
|
|
|
25
27
|
target?: 'window' | 'region'
|
|
@@ -47,7 +49,7 @@ export type CypressCheckSettings = api.CheckSettingsAutomationPlain<Element, Sel
|
|
|
47
49
|
ignoreCaret?: boolean
|
|
48
50
|
ignoreDisplacements?: boolean
|
|
49
51
|
}
|
|
50
|
-
export type CypressEyesConfig = api.ConfigurationPlain<
|
|
52
|
+
export type CypressEyesConfig = api.ConfigurationPlain<SpecType> & {
|
|
51
53
|
browser?: MaybeArray<
|
|
52
54
|
| NonNullable<CypressEyesConfig['browsersInfo']>[number]
|
|
53
55
|
| {deviceName: string; screenOrientation?: api.ScreenOrientationPlain; name?: string}
|
package/src/plugin/hooks.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import handleTestResults from './handleTestResults'
|
|
2
|
+
import {type StartServerReturn} from './server'
|
|
2
3
|
export type EyesCypressAction = 'before:run' | 'after:run'
|
|
3
4
|
|
|
4
5
|
declare global {
|
|
@@ -9,7 +10,7 @@ declare global {
|
|
|
9
10
|
dontCloseBatches: boolean
|
|
10
11
|
batch: any
|
|
11
12
|
serverUrl: string
|
|
12
|
-
proxy:
|
|
13
|
+
proxy: any // TODO: add proxy type
|
|
13
14
|
apiKey: string
|
|
14
15
|
batchId: string
|
|
15
16
|
tapDirPath: string
|
|
@@ -19,7 +20,11 @@ declare global {
|
|
|
19
20
|
}
|
|
20
21
|
}
|
|
21
22
|
|
|
22
|
-
export default function makeGlobalRunHooks({
|
|
23
|
+
export default function makeGlobalRunHooks({
|
|
24
|
+
closeManager,
|
|
25
|
+
closeBatches,
|
|
26
|
+
closeUniversalServer,
|
|
27
|
+
}: Omit<StartServerReturn, 'server' | 'port'>): {
|
|
23
28
|
'after:run': (results: CypressCommandLine.CypressRunResult) => void | Promise<void>
|
|
24
29
|
'before:run': (runDetails: Cypress.BeforeRunDetails) => void | Promise<void>
|
|
25
30
|
} {
|
|
@@ -35,11 +40,11 @@ export default function makeGlobalRunHooks({closeManager, closeBatches, closeUni
|
|
|
35
40
|
|
|
36
41
|
let testResults
|
|
37
42
|
for (const summary of summaries) {
|
|
38
|
-
testResults = summary.results.map(({
|
|
43
|
+
testResults = summary.results.map(({result}: any) => result)
|
|
39
44
|
}
|
|
40
45
|
if (!config.appliConfFile.dontCloseBatches) {
|
|
41
46
|
await closeBatches({
|
|
42
|
-
|
|
47
|
+
batchId: config.appliConfFile.batchId || config.appliConfFile.batch.id,
|
|
43
48
|
serverUrl: config.appliConfFile.serverUrl,
|
|
44
49
|
proxy: config.appliConfFile.proxy,
|
|
45
50
|
apiKey: config.appliConfFile.apiKey,
|
|
@@ -47,7 +52,7 @@ export default function makeGlobalRunHooks({closeManager, closeBatches, closeUni
|
|
|
47
52
|
}
|
|
48
53
|
|
|
49
54
|
if (config.appliConfFile.tapDirPath) {
|
|
50
|
-
|
|
55
|
+
handleTestResults.handleBatchResultsFile(testResults, {
|
|
51
56
|
tapDirPath: config.appliConfFile.tapDirPath,
|
|
52
57
|
tapFileName: config.appliConfFile.tapFileName,
|
|
53
58
|
})
|
package/src/plugin/index.ts
CHANGED
|
@@ -3,8 +3,15 @@ import isGlobalHooksSupported from './isGlobalHooksSupported'
|
|
|
3
3
|
import {presult} from '@applitools/functional-commons'
|
|
4
4
|
import makeGlobalRunHooks from './hooks'
|
|
5
5
|
import {type EyesPluginConfig} from './'
|
|
6
|
+
import {type StartServerReturn} from './server'
|
|
6
7
|
|
|
7
|
-
export default function makePluginExport({
|
|
8
|
+
export default function makePluginExport({
|
|
9
|
+
startServer,
|
|
10
|
+
eyesConfig,
|
|
11
|
+
}: {
|
|
12
|
+
startServer: (options?: Cypress.PluginConfigOptions) => Promise<StartServerReturn>
|
|
13
|
+
eyesConfig: EyesPluginConfig
|
|
14
|
+
}) {
|
|
8
15
|
return function pluginExport(pluginInitArgs: Cypress.ConfigOptions | NodeJS.Module) {
|
|
9
16
|
let eyesServer: any, pluginModuleExports: any, pluginExportsE2E: any, pluginExportsComponent: any
|
|
10
17
|
let pluginExports
|
|
@@ -55,14 +62,14 @@ export default function makePluginExport({startServer, eyesConfig}: any) {
|
|
|
55
62
|
return pluginInitArgs
|
|
56
63
|
}
|
|
57
64
|
return function getCloseServer() {
|
|
58
|
-
return eyesServer.close()
|
|
65
|
+
return new Promise<void>(res => eyesServer.close(() => res()))
|
|
59
66
|
}
|
|
60
67
|
|
|
61
68
|
async function setupNodeEvents(
|
|
62
69
|
origOn: Cypress.PluginEvents,
|
|
63
70
|
cypressConfig: Cypress.PluginConfigOptions,
|
|
64
71
|
): Promise<EyesPluginConfig> {
|
|
65
|
-
const {server, port, closeManager, closeBatches, closeUniversalServer} = await startServer()
|
|
72
|
+
const {server, port, closeManager, closeBatches, closeUniversalServer} = await startServer(cypressConfig)
|
|
66
73
|
eyesServer = server
|
|
67
74
|
|
|
68
75
|
const globalHooks: any = makeGlobalRunHooks({
|
package/src/plugin/server.ts
CHANGED
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
import connectSocket, {type SocketWithUniversal} from './webSocket'
|
|
2
|
-
|
|
3
|
-
// @ts-ignore
|
|
4
|
-
import {makeServerProcess} from '@applitools/eyes-universal'
|
|
2
|
+
import {type CloseBatchSettings, makeCoreServerProcess} from '@applitools/core'
|
|
5
3
|
import handleTestResults from './handleTestResults'
|
|
6
4
|
import path from 'path'
|
|
7
5
|
import fs from 'fs'
|
|
@@ -12,9 +10,16 @@ import which from 'which'
|
|
|
12
10
|
import {type Logger} from '@applitools/logger'
|
|
13
11
|
import {AddressInfo} from 'net'
|
|
14
12
|
import {promisify} from 'util'
|
|
13
|
+
export type StartServerReturn = {
|
|
14
|
+
server: Omit<SocketWithUniversal, 'disconnect' | 'ref' | 'unref' | 'send' | 'request' | 'setPassthroughListener'>
|
|
15
|
+
port: number
|
|
16
|
+
closeManager: () => Promise<any[]>
|
|
17
|
+
closeBatches: (settings: CloseBatchSettings | CloseBatchSettings[]) => Promise<void>
|
|
18
|
+
closeUniversalServer: () => void
|
|
19
|
+
}
|
|
15
20
|
|
|
16
21
|
export default function makeStartServer({logger}: {logger: Logger}) {
|
|
17
|
-
return async function startServer() {
|
|
22
|
+
return async function startServer(options?: Cypress.PluginConfigOptions): Promise<StartServerReturn> {
|
|
18
23
|
const key = fs.readFileSync(path.resolve(__dirname, '../../src/pem/server.key'))
|
|
19
24
|
const cert = fs.readFileSync(path.resolve(__dirname, '../../src/pem/server.cert'))
|
|
20
25
|
const https = new HttpsServer({
|
|
@@ -40,11 +45,22 @@ export default function makeStartServer({logger}: {logger: Logger}) {
|
|
|
40
45
|
// `cypress` version below `7.0.0` has an old Electron version which not support async shell process.
|
|
41
46
|
// By passing `execPath` with the node process cwd it will switch the `node` process to be the like the OS have
|
|
42
47
|
// and will not use the unsupported `Cypress Helper.app` with the not supported shell process Electron
|
|
43
|
-
|
|
48
|
+
const isCypressVersionBelow7 = semverLt(cypressVersion, '7.0.0')
|
|
49
|
+
|
|
50
|
+
// `nodeVersion` property set the way the `node` process will be executed
|
|
51
|
+
// if set to `system` it will use the `node` process that the OS have
|
|
52
|
+
// if set to `bundled` it will use the `node` process that the `Cypress Helper.app` have
|
|
53
|
+
//
|
|
54
|
+
// [doc link](https://docs.cypress.io/guides/references/configuration#Node-version)
|
|
55
|
+
//
|
|
56
|
+
// this is why if `nodeVersion` exits and not set to `system` we need to tell to the `universal` server the `execPath` to `node`
|
|
57
|
+
const isNodeVersionSystem = !!options?.nodeVersion && options.nodeVersion !== 'system'
|
|
58
|
+
|
|
59
|
+
if (isCypressVersionBelow7 || isNodeVersionSystem) {
|
|
44
60
|
forkOptions.execPath = await which('node')
|
|
45
61
|
}
|
|
46
62
|
|
|
47
|
-
const {port: universalPort, close: closeUniversalServer} = await
|
|
63
|
+
const {port: universalPort, close: closeUniversalServer} = await makeCoreServerProcess({
|
|
48
64
|
idleTimeout: 0,
|
|
49
65
|
shutdownMode: 'stdin',
|
|
50
66
|
forkOptions,
|
|
@@ -126,16 +142,13 @@ export default function makeStartServer({logger}: {logger: Logger}) {
|
|
|
126
142
|
function closeManager() {
|
|
127
143
|
return Promise.all(
|
|
128
144
|
managers.map(({manager, socketWithUniversal}) =>
|
|
129
|
-
socketWithUniversal.request('EyesManager.
|
|
130
|
-
manager,
|
|
131
|
-
throwErr: false,
|
|
132
|
-
}),
|
|
145
|
+
socketWithUniversal.request('EyesManager.getResults', {manager, settings: {throwErr: false}}),
|
|
133
146
|
),
|
|
134
147
|
)
|
|
135
148
|
}
|
|
136
|
-
function closeBatches(settings:
|
|
149
|
+
function closeBatches(settings: CloseBatchSettings | CloseBatchSettings[]) {
|
|
137
150
|
if (socketWithUniversal)
|
|
138
|
-
return socketWithUniversal.request('Core.
|
|
151
|
+
return socketWithUniversal.request('Core.closeBatch', {settings}).catch((err: Error) => {
|
|
139
152
|
logger.log('@@@', err)
|
|
140
153
|
})
|
|
141
154
|
}
|
|
@@ -25,7 +25,7 @@ export default ${chalk.green.bold('eyesPlugin(')}definedConfig({
|
|
|
25
25
|
//...
|
|
26
26
|
})${chalk.green.bold(')')}
|
|
27
27
|
|
|
28
|
-
For more information, visit Eyes-Cypress documentation https://
|
|
28
|
+
For more information, visit Eyes-Cypress documentation https://applitools.com/docs/api-ref/sdk-api/cypress/typescript
|
|
29
29
|
`,
|
|
30
30
|
{padding: 1, borderColor: 'cyan'},
|
|
31
31
|
),
|