@applitools/eyes-cypress 3.22.6 → 3.23.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 CHANGED
@@ -2,6 +2,31 @@
2
2
 
3
3
  ## Unreleased
4
4
 
5
+
6
+ ## 3.23.1 - 2021/11/15
7
+
8
+ - fix types for region inside shadow
9
+ - updated to @applitools/visual-grid-client@15.8.45 (from 15.8.44)
10
+
11
+ ## 3.23.0 - 2021/11/11
12
+
13
+ - support waitBeforeCapture
14
+ - updated to @applitools/visual-grid-client@15.8.44 (from 15.8.43)
15
+
16
+ ## 3.22.8 - 2021/11/9
17
+
18
+ - fix not calling the global hooks before:run and after:run at all, unless the user also called them in his plugins file.
19
+ - fix not calling the browser hooks for Cypress versions < 6.2.0 (where global hooks are not supported).
20
+
21
+ ## 3.22.7 - 2021/11/7
22
+
23
+ - replace legacy logger construction with new
24
+ - Support running user defined run hooks in Cypress
25
+ - Fix cypress tests not being cleaned up
26
+ - Fix duplicate batch start/end events in cypress
27
+ - updated to @applitools/dom-snapshot@4.5.10 (from 4.5.9)
28
+ - updated to @applitools/visual-grid-client@15.8.43 (from 15.8.36)
29
+
5
30
  ## 3.22.6 - 2021/10/18
6
31
 
7
32
  - updated to @applitools/dom-snapshot@4.5.9 (from 4.5.8)
package/README.md CHANGED
@@ -192,6 +192,7 @@ Applitools will take screenshots and perform the visual comparisons in the backg
192
192
  - [layoutBreakpoints](#layoutBreakpoints)
193
193
  - [sendDom](#sendDom)
194
194
  - [variationGroupId](#variationGroupId)
195
+ - [waitBeforeCapture](#waitBeforeCapture)
195
196
  - [Close](#Close)
196
197
  - [Concurrency](#Concurrency)
197
198
  - [Advanced configuration](#Advanced-configuration)
@@ -449,6 +450,20 @@ cy.eyesCheckWindow({variationGroupId: 'Login screen variation #1'})
449
450
 
450
451
  For more information, visit our documentation page: https://applitools.com/docs/features/baseline-variations-groups.html
451
452
 
453
+ ##### `waitBeforeCapture`
454
+
455
+ A parameter that is set to wait a certain amount of milliseconds before capturing the pages snapshot. This will also apply between page resizes when using `layoutBreakpoints`.
456
+
457
+ ```
458
+ cy.eyesOpen({
459
+ waitBeforeCapture: 1000
460
+ // ...
461
+ })
462
+
463
+ cy.eyesCheckWindow({
464
+ waitBeforeCapture: 1000
465
+ })
466
+ ```
452
467
 
453
468
  ##### `useDom`
454
469
 
@@ -544,6 +559,7 @@ The list above is also the order of precedence, which means that if you pass a p
544
559
  | `accessibilityValidation` | undefined | An object that specifies the accessibility level and guidelines version to use for the screenshots. Possible values for **level** are `None`, `AA` and `AAA`, and possible values for **guidelinesVersion** are `WCAG_2_0` and `WCAG_2_1`. For example: `{level: 'AA', guidelinesVersion: 'WCAG_2_0'}`|
545
560
  | `visualGridOptions` | undefined | An object that specifies options to configure renderings on the Ultrafast grid. See more information [here](#visualgridoptions) |
546
561
  |`layoutBreakpoints`| undefined | When set to `true`, a snapshot of the DOM will be taken once for each browser/device size in the `browser` configuration. For optimization purposes, an array of numbers can be passed. The DOM snapshot will be taken once for every **width** in the array. For more information, see [layoutBreakpoints](#layoutBreakpoints)|
562
+ |`waitBeforeCapture`| 100 | A parameter that is set to wait a certain amount of milliseconds before capturing the pages snapshot. This will also apply between page resizes when using `layoutBreakpoints`.
547
563
 
548
564
  ### Global configuration properties:
549
565
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@applitools/eyes-cypress",
3
- "version": "3.22.6",
3
+ "version": "3.23.1",
4
4
  "main": "index.js",
5
5
  "license": "SEE LICENSE IN LICENSE",
6
6
  "bin": {
@@ -35,12 +35,14 @@
35
35
  },
36
36
  "repository": {
37
37
  "type": "git",
38
- "url": "git://github.com/applitools/eyes.sdk.javascript1.git"
38
+ "url": "git://github.com/applitools/eyes.sdk.javascript1.git",
39
+ "directory": "packages/eyes-cypress"
39
40
  },
40
41
  "dependencies": {
41
- "@applitools/dom-snapshot": "4.5.9",
42
+ "@applitools/dom-snapshot": "4.5.10",
42
43
  "@applitools/functional-commons": "1.6.0",
43
- "@applitools/visual-grid-client": "15.8.36",
44
+ "@applitools/logger": "1.0.5",
45
+ "@applitools/visual-grid-client": "15.8.45",
44
46
  "body-parser": "1.19.0",
45
47
  "chalk": "3.0.0",
46
48
  "cors": "2.8.5",
@@ -49,10 +51,10 @@
49
51
  },
50
52
  "devDependencies": {
51
53
  "@applitools/scripts": "^1.0.1",
52
- "@applitools/sdk-release-kit": "0.13.3",
53
- "@applitools/sdk-shared": "0.9.6",
54
+ "@applitools/sdk-release-kit": "0.13.4",
55
+ "@applitools/sdk-shared": "0.9.9",
54
56
  "@applitools/snaptdout": "1.0.1",
55
- "@applitools/test-server": "1.0.5",
57
+ "@applitools/test-server": "1.0.7",
56
58
  "chai": "^4.2.0",
57
59
  "chai-spies": "^1.0.0",
58
60
  "cookie-parser": "^1.4.4",
@@ -18,7 +18,13 @@ function getGlobalConfigProperty(prop) {
18
18
  const shouldParse = ['eyesBrowser', 'eyesLayoutBreakpoints'];
19
19
  return property ? (shouldParse.includes(prop) ? JSON.parse(property) : property) : undefined;
20
20
  }
21
- if (!getGlobalConfigProperty('eyesIsDisabled') && getGlobalConfigProperty('eyesLegacyHooks')) {
21
+
22
+ const shouldUseBrowserHooks =
23
+ !getGlobalConfigProperty('eyesIsDisabled') &&
24
+ (getGlobalConfigProperty('isInteractive') ||
25
+ !getGlobalConfigProperty('eyesIsGlobalHooksSupported'));
26
+
27
+ if (shouldUseBrowserHooks) {
22
28
  const batchEnd = poll(() => {
23
29
  return sendRequest({command: 'batchEnd'});
24
30
  });
@@ -94,6 +100,7 @@ Cypress.Commands.add('eyesCheckWindow', args => {
94
100
  const globalArgs = {
95
101
  browser: getGlobalConfigProperty('eyesBrowser'),
96
102
  layoutBreakpoints: getGlobalConfigProperty('eyesLayoutBreakpoints'),
103
+ waitBeforeCapture: getGlobalConfigProperty('eyesWaitBeforeCapture'),
97
104
  };
98
105
 
99
106
  const browser = eyesOpenArgs.browser || globalArgs.browser || defaultBrowser;
@@ -102,7 +109,12 @@ Cypress.Commands.add('eyesCheckWindow', args => {
102
109
  (eyesOpenArgs && eyesOpenArgs.layoutBreakpoints) ||
103
110
  globalArgs.layoutBreakpoints;
104
111
 
105
- const checkArgs = {layoutBreakpoints, browser};
112
+ const waitBeforeCapture =
113
+ (args && args.waitBeforeCapture) ||
114
+ (eyesOpenArgs && eyesOpenArgs.waitBeforeCapture) ||
115
+ globalArgs.waitBeforeCapture;
116
+
117
+ const checkArgs = {layoutBreakpoints, browser, waitBeforeCapture};
106
118
  if (typeof args === 'object') {
107
119
  Object.assign(checkArgs, args);
108
120
  } else {
@@ -21,11 +21,17 @@ function makeEyesCheckWindow({sendRequest, processPage, domSnapshotOptions, cypr
21
21
  function takeDomSnapshots(options) {
22
22
  const browser = args.browser;
23
23
  const breakpoints = args.layoutBreakpoints;
24
+ const waitBeforeCapture = args.waitBeforeCapture ? args.waitBeforeCapture : 100;
24
25
  const browsers = Array.isArray(browser) ? browser : [browser];
25
26
 
26
27
  if (!breakpoints) {
27
28
  //console.log('no breakpoints, taking single dom snapshot');
28
- return takeDomSnapshot(options);
29
+ return cypress
30
+ .wrap({}, {log: false})
31
+ .wait(waitBeforeCapture)
32
+ .then(() => {
33
+ return takeDomSnapshot(options);
34
+ });
29
35
  }
30
36
 
31
37
  return browsers
@@ -52,7 +58,7 @@ function makeEyesCheckWindow({sendRequest, processPage, domSnapshotOptions, cypr
52
58
  // console.log(`taking dom snapshot for width ${requiredWidth}`);
53
59
  cypress
54
60
  .viewport(Number(requiredWidth), height, {log: false})
55
- .wait(300, {log: false})
61
+ .wait(waitBeforeCapture, {log: false})
56
62
  .then({log: false, timeout: 900000}, () => {
57
63
  return takeDomSnapshot(options).then(snapshot => {
58
64
  browsersInfo.forEach(({index}) => (snapshots[index] = snapshot));
@@ -42,8 +42,8 @@ function makeConfig() {
42
42
  eyesFailCypressOnDiff:
43
43
  config.failCypressOnDiff === undefined ? true : !!config.failCypressOnDiff,
44
44
  eyesDisableBrowserFetching: !!config.disableBrowserFetching,
45
- eyesLegacyHooks: true,
46
45
  eyesTestConcurrency: config.testConcurrency || DEFAULT_TEST_CONCURRENCY,
46
+ eyesWaitBeforeCapture: config.waitBeforeCapture,
47
47
  };
48
48
 
49
49
  return {config, eyesConfig};
@@ -4,41 +4,39 @@ const makeHandleBatchResultsFile = require('./makeHandleBatchResultsFile');
4
4
  const getErrorsAndDiffs = require('./getErrorsAndDiffs');
5
5
  const processCloseAndAbort = require('./processCloseAndAbort');
6
6
  const errorDigest = require('./errorDigest');
7
- const {tests} = require('./runningTests');
7
+ const runningTests = require('./runningTests');
8
8
 
9
- function setGlobalRunHooks(on, {visualGridClient, logger, eyesConfig}) {
9
+ function makeGlobalRunHooks({visualGridClient, logger}) {
10
10
  let waitForBatch;
11
11
 
12
- on('before:run', ({config}) => {
13
- const {isTextTerminal, eyesTestConcurrency: testConcurrency} = config;
14
- // ugly but neccessary here - as this is the only place that cypress exposes the run mode on config
15
- if (!isTextTerminal) return;
16
- eyesConfig.eyesLegacyHooks = false;
12
+ return {
13
+ 'before:run': ({config}) => {
14
+ const {isTextTerminal, eyesTestConcurrency: testConcurrency} = config;
15
+ if (!config.isTextTerminal) return;
17
16
 
18
- waitForBatch = makeWaitForBatch({
19
- logger: (logger.extend && logger.extend('waitForBatch')) || console,
20
- testConcurrency,
21
- processCloseAndAbort,
22
- getErrorsAndDiffs,
23
- errorDigest,
24
- isInteractive: !isTextTerminal,
25
- handleBatchResultsFile: makeHandleBatchResultsFile(config),
26
- });
27
- });
17
+ waitForBatch = makeWaitForBatch({
18
+ logger: (logger.extend && logger.extend('waitForBatch')) || console,
19
+ testConcurrency,
20
+ processCloseAndAbort,
21
+ getErrorsAndDiffs,
22
+ errorDigest,
23
+ isInteractive: !isTextTerminal,
24
+ handleBatchResultsFile: makeHandleBatchResultsFile(config),
25
+ });
26
+ },
28
27
 
29
- on('after:run', async ({config}) => {
30
- if (!config.isTextTerminal) return;
28
+ 'after:run': async ({config}) => {
29
+ if (!config.isTextTerminal) return;
31
30
 
32
- try {
33
- // we rely on the fact that `runningTests.reset()` wasn't called
34
- // so that tests that were added in `open` are available here (through `tests` in `runningTests.js`)
35
- await waitForBatch(tests, visualGridClient.closeBatch);
36
- } catch (e) {
37
- if (!!config.eyesFailCypressOnDiff) {
38
- throw e;
31
+ try {
32
+ await waitForBatch(runningTests.tests, visualGridClient.closeBatch);
33
+ } catch (e) {
34
+ if (!!config.eyesFailCypressOnDiff) {
35
+ throw e;
36
+ }
39
37
  }
40
- }
41
- });
38
+ },
39
+ };
42
40
  }
43
41
 
44
- module.exports = setGlobalRunHooks;
42
+ module.exports = makeGlobalRunHooks;
@@ -1,7 +1,7 @@
1
1
  const CYPRESS_SUPPORTED_VERSION = '6.2.0';
2
2
  const CYPRESS_NO_FLAG_VERSION = '6.7.0';
3
3
 
4
- function shouldSetGlobalHooks(config) {
4
+ function isGlobalHooksSupported(config) {
5
5
  const {version, experimentalRunEvents} = config;
6
6
 
7
7
  return (
@@ -10,4 +10,4 @@ function shouldSetGlobalHooks(config) {
10
10
  );
11
11
  }
12
12
 
13
- module.exports = shouldSetGlobalHooks;
13
+ module.exports = isGlobalHooksSupported;
@@ -1,22 +1,48 @@
1
1
  'use strict';
2
- const setGlobalRunHooks = require('./hooks');
3
- const shouldSetGlobalHooks = require('./shouldSetGlobalHooks');
2
+ const isGlobalHooksSupported = require('./isGlobalHooksSupported');
3
+ const {presult} = require('@applitools/functional-commons');
4
4
 
5
- function makePluginExport({startServer, eyesConfig, visualGridClient, logger}) {
5
+ function makePluginExport({startServer, eyesConfig, globalHooks}) {
6
6
  return function pluginExport(pluginModule) {
7
7
  let closeEyesServer;
8
8
  const pluginModuleExports = pluginModule.exports;
9
- pluginModule.exports = async (...args) => {
9
+ pluginModule.exports = async function(...args) {
10
10
  const {eyesPort, closeServer} = await startServer();
11
11
  closeEyesServer = closeServer;
12
- const moduleExportsResult = await pluginModuleExports(...args);
13
- const [on, config] = args;
14
-
15
- if (shouldSetGlobalHooks({...config, ...eyesConfig})) {
16
- setGlobalRunHooks(on, {visualGridClient, logger, eyesConfig});
12
+ const [origOn, config] = args;
13
+ let isGlobalHookCalledFromUserHandler = false;
14
+ eyesConfig.eyesIsGlobalHooksSupported = isGlobalHooksSupported(config);
15
+ const moduleExportsResult = await pluginModuleExports(onThatCallsUserDefinedHandler, config);
16
+ if (eyesConfig.eyesIsGlobalHooksSupported && !isGlobalHookCalledFromUserHandler) {
17
+ for (const [eventName, eventHandler] of Object.entries(globalHooks)) {
18
+ origOn.call(this, eventName, eventHandler);
19
+ }
17
20
  }
18
-
19
21
  return Object.assign({}, eyesConfig, {eyesPort}, moduleExportsResult);
22
+
23
+ // This piece of code exists because at the point of writing, Cypress does not support multiple event handlers:
24
+ // https://github.com/cypress-io/cypress/issues/5240#issuecomment-948277554
25
+ // So we wrap Cypress' `on` function in order to wrap the user-defined handler. This way we can call our own handler
26
+ // in addition to the user's handler
27
+ function onThatCallsUserDefinedHandler(eventName, handler) {
28
+ const isRunEvent = eventName === 'before:run' || eventName === 'after:run';
29
+ let handlerToCall = handler;
30
+ if (eyesConfig.eyesIsGlobalHooksSupported && isRunEvent) {
31
+ handlerToCall = handlerThatCallsUserDefinedHandler;
32
+ isGlobalHookCalledFromUserHandler = true;
33
+ }
34
+ return origOn.call(this, eventName, handlerToCall);
35
+
36
+ async function handlerThatCallsUserDefinedHandler() {
37
+ const [err] = await presult(
38
+ Promise.resolve(globalHooks[eventName].apply(this, arguments)),
39
+ );
40
+ await handler.apply(this, arguments);
41
+ if (err) {
42
+ throw err;
43
+ }
44
+ }
45
+ }
20
46
  };
21
47
  return function getCloseServer() {
22
48
  return closeEyesServer;
@@ -9,8 +9,10 @@ const runningTests = {
9
9
  this.tests = [];
10
10
  },
11
11
  async abortTests() {
12
+ const tests = this.tests;
13
+ this.reset();
12
14
  return Promise.all(
13
- this.tests.map(async test => {
15
+ tests.map(async test => {
14
16
  if (test.closePromise) {
15
17
  // this condition doesn't really happen in the code, but it's here for purity. This is used in handlers' batchStart in order to cleanup the state in case a zombie open was called.
16
18
  await test.closePromise;
@@ -1,5 +1,6 @@
1
1
  'use strict';
2
- const {makeVisualGridClient, Logger} = require('@applitools/visual-grid-client');
2
+ const {makeVisualGridClient} = require('@applitools/visual-grid-client');
3
+ const {makeLogger} = require('@applitools/logger');
3
4
  const makeStartServer = require('./server');
4
5
  const makePluginExport = require('./pluginExport');
5
6
  const {startApp} = require('./app');
@@ -8,13 +9,12 @@ const processCloseAndAbort = require('./processCloseAndAbort');
8
9
  const errorDigest = require('./errorDigest');
9
10
  const makeHandlers = require('./handlers');
10
11
  const makeConfig = require('./config');
12
+ const makeGlobalRunHooks = require('./hooks');
11
13
 
12
14
  const {config, eyesConfig} = makeConfig();
13
- const logger = new Logger(config.showLogs, 'eyes');
15
+ const logger = makeLogger({level: config.showLogs ? 'info' : 'silent', label: 'eyes'});
14
16
 
15
- const visualGridClient = makeVisualGridClient(
16
- Object.assign(config, {logger: (logger.extend && logger.extend('vgc')) || logger}),
17
- );
17
+ const visualGridClient = makeVisualGridClient({...config, logger: logger.extend('vgc')});
18
18
 
19
19
  const handlers = makeHandlers({
20
20
  logger,
@@ -25,8 +25,10 @@ const handlers = makeHandlers({
25
25
  errorDigest,
26
26
  });
27
27
 
28
+ const globalHooks = makeGlobalRunHooks({visualGridClient, logger});
29
+
28
30
  const app = startApp({handlers, logger});
29
31
  const startServer = makeStartServer({app, logger});
30
32
  logger.log('eyes-cypress plugin running with config:', config);
31
33
 
32
- module.exports = makePluginExport({startServer, eyesConfig, visualGridClient, logger});
34
+ module.exports = makePluginExport({startServer, eyesConfig, globalHooks});