@applitools/eyes-cypress 3.24.0-beta.5 → 3.25.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 (44) hide show
  1. package/CHANGELOG.md +2191 -2195
  2. package/LICENSE +25 -25
  3. package/README.md +803 -782
  4. package/bin/eyes-setup.js +21 -21
  5. package/commands.js +2 -2
  6. package/dist/browser/spec-driver.js +110 -106
  7. package/dist/plugin/handler.js +55 -55
  8. package/eyes-index.d.ts +34 -34
  9. package/index.js +2 -2
  10. package/package.json +98 -97
  11. package/src/browser/commands.js +188 -188
  12. package/src/browser/eyesCheckMapping.js +104 -103
  13. package/src/browser/eyesOpenMapping.js +60 -60
  14. package/src/browser/makeSend.js +18 -18
  15. package/src/browser/refer.js +57 -57
  16. package/src/browser/sendRequest.js +16 -16
  17. package/src/browser/socket.js +144 -143
  18. package/src/browser/socketCommands.js +81 -81
  19. package/src/browser/spec-driver.ts +117 -111
  20. package/src/pem/server.cert +22 -22
  21. package/src/pem/server.key +27 -27
  22. package/src/plugin/concurrencyMsg.js +8 -8
  23. package/src/plugin/config.js +54 -54
  24. package/src/plugin/defaultPort.js +1 -1
  25. package/src/plugin/errorDigest.js +96 -96
  26. package/src/plugin/getErrorsAndDiffs.js +34 -34
  27. package/src/plugin/handleTestResults.js +35 -39
  28. package/src/plugin/handler.ts +58 -58
  29. package/src/plugin/hooks.js +51 -50
  30. package/src/plugin/isGlobalHooksSupported.js +13 -13
  31. package/src/plugin/pluginExport.js +60 -60
  32. package/src/plugin/server.js +98 -98
  33. package/src/plugin/startPlugin.js +15 -13
  34. package/src/plugin/webSocket.js +130 -130
  35. package/src/setup/addEyesCommands.js +24 -24
  36. package/src/setup/addEyesCypressPlugin.js +15 -15
  37. package/src/setup/getCypressConfig.js +16 -16
  38. package/src/setup/getFilePath.js +22 -22
  39. package/src/setup/handleCommands.js +23 -23
  40. package/src/setup/handlePlugin.js +23 -23
  41. package/src/setup/handleTypeScript.js +21 -21
  42. package/src/setup/isCommandsDefined.js +7 -7
  43. package/src/setup/isPluginDefined.js +7 -7
  44. package/test/fixtures/testAppCopies/.gitignore +1 -1
package/bin/eyes-setup.js CHANGED
@@ -1,21 +1,21 @@
1
- #!/usr/bin/env node
2
- 'use strict';
3
-
4
- const chalk = require('chalk');
5
- const handlePlugin = require('../src/setup/handlePlugin');
6
- const handleCommands = require('../src/setup/handleCommands');
7
- const handleTypeScript = require('../src/setup/handleTypeScript');
8
- const {version} = require('../package');
9
- const cwd = process.cwd();
10
-
11
- console.log(chalk.cyan('Setup eyes-cypress', version));
12
-
13
- try {
14
- handlePlugin(cwd);
15
- handleCommands(cwd);
16
- handleTypeScript(cwd);
17
- } catch (e) {
18
- console.log(chalk.red('Setup error:\n', e));
19
- }
20
-
21
- console.log(chalk.cyan('Setup done!'));
1
+ #!/usr/bin/env node
2
+ 'use strict';
3
+
4
+ const chalk = require('chalk');
5
+ const handlePlugin = require('../src/setup/handlePlugin');
6
+ const handleCommands = require('../src/setup/handleCommands');
7
+ const handleTypeScript = require('../src/setup/handleTypeScript');
8
+ const {version} = require('../package');
9
+ const cwd = process.cwd();
10
+
11
+ console.log(chalk.cyan('Setup eyes-cypress', version));
12
+
13
+ try {
14
+ handlePlugin(cwd);
15
+ handleCommands(cwd);
16
+ handleTypeScript(cwd);
17
+ } catch (e) {
18
+ console.log(chalk.red('Setup error:\n', e));
19
+ }
20
+
21
+ console.log(chalk.cyan('Setup done!'));
package/commands.js CHANGED
@@ -1,2 +1,2 @@
1
- 'use strict';
2
- require('./src/browser/commands');
1
+ 'use strict';
2
+ require('./src/browser/commands');
@@ -1,106 +1,110 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getCookies = exports.getUrl = exports.getTitle = exports.findElements = exports.findElement = exports.transformSelector = exports.setViewportSize = exports.getViewportSize = exports.childContext = exports.parentContext = exports.mainContext = exports.executeScript = void 0;
4
- function executeScript(context, script, arg) {
5
- context = refreshContext(context);
6
- let scriptToExecute;
7
- if (script.includes('dom-snapshot') ||
8
- script.includes('dom-capture') ||
9
- script.includes('dom-shared')) {
10
- scriptToExecute = script;
11
- }
12
- else {
13
- const prepScirpt = script.replace('function(arg)', 'function func(arg)');
14
- scriptToExecute = prepScirpt.concat(' return func(arg)');
15
- }
16
- const executor = new context.defaultView.Function('arg', scriptToExecute);
17
- return executor(arg);
18
- }
19
- exports.executeScript = executeScript;
20
- function mainContext() {
21
- //@ts-ignore
22
- return cy.state('window').document;
23
- }
24
- exports.mainContext = mainContext;
25
- function parentContext(context) {
26
- if (!context)
27
- return; // because Cypress doesn't support cross origin iframe, then childContext might return null, and then the input to parentContext might be null
28
- return context === mainContext() ? context : context.defaultView.frameElement.ownerDocument;
29
- }
30
- exports.parentContext = parentContext;
31
- function childContext(_context, element) {
32
- return element.contentDocument; // null in case of cross origin iframe
33
- }
34
- exports.childContext = childContext;
35
- function getViewportSize() {
36
- //@ts-ignore
37
- const currWindow = cy.state('window');
38
- const viewportSize = {
39
- width: Math.max(currWindow.document.documentElement.clientWidth || 0, currWindow.innerWidth || 0),
40
- height: Math.max(currWindow.document.documentElement.clientHeight || 0, currWindow.innerHeight || 0)
41
- };
42
- return viewportSize;
43
- }
44
- exports.getViewportSize = getViewportSize;
45
- function setViewportSize(vs) {
46
- //@ts-ignore
47
- Cypress.action('cy:viewport:changed', { viewportWidth: vs.size.width, viewportHeight: vs.size.height });
48
- }
49
- exports.setViewportSize = setViewportSize;
50
- function transformSelector(selector) {
51
- if (selector.hasOwnProperty('selector') && (!selector.hasOwnProperty('type') || selector.type === 'css')) {
52
- return selector.selector;
53
- }
54
- return selector;
55
- }
56
- exports.transformSelector = transformSelector;
57
- function findElement(context, selector, parent) {
58
- context = refreshContext(context);
59
- const eyesSelector = selector;
60
- const root = parent !== null && parent !== void 0 ? parent : context;
61
- const sel = typeof selector === 'string' ? selector : eyesSelector.selector;
62
- if (typeof selector !== 'string' && eyesSelector.type === 'xpath') {
63
- return context.evaluate(sel, context, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
64
- }
65
- else {
66
- return root.querySelector(sel);
67
- }
68
- }
69
- exports.findElement = findElement;
70
- function findElements(context, selector, parent) {
71
- context = refreshContext(context);
72
- const eyesSelector = selector;
73
- const root = parent !== null && parent !== void 0 ? parent : context;
74
- const sel = typeof selector === 'string' ? selector : eyesSelector.selector;
75
- if (typeof selector !== 'string' && eyesSelector.type === 'xpath') {
76
- // TODO return multiple
77
- return context.evaluate(sel, context, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
78
- }
79
- else {
80
- return root.querySelectorAll(sel);
81
- }
82
- }
83
- exports.findElements = findElements;
84
- function getTitle(context) {
85
- context = refreshContext(context);
86
- return context.title;
87
- }
88
- exports.getTitle = getTitle;
89
- function getUrl(context) {
90
- context = refreshContext(context);
91
- return context.location.href;
92
- }
93
- exports.getUrl = getUrl;
94
- function getCookies() {
95
- //@ts-ignore
96
- return Cypress.automation('get:cookies', {});
97
- }
98
- exports.getCookies = getCookies;
99
- // we need to method to reset the context in case the user called open before visit
100
- function refreshContext(context) {
101
- //@ts-ignore
102
- return (context && context.defaultView) ? context : cy.state('window').document;
103
- }
104
- // export function takeScreenshot(page: Driver): Promise<Buffer>;
105
- // export function visit(page: Driver, url: string): Promise<void>; (??)
106
- // export function isStaleElementError(err: any): boolean;
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getCookies = exports.getUrl = exports.getTitle = exports.findElements = exports.findElement = exports.transformSelector = exports.setViewportSize = exports.getViewportSize = exports.childContext = exports.parentContext = exports.mainContext = exports.executeScript = void 0;
4
+ function executeScript(context, script, arg) {
5
+ context = refreshContext(context);
6
+ let scriptToExecute;
7
+ if (script.includes('dom-snapshot') ||
8
+ script.includes('dom-capture') ||
9
+ script.includes('dom-shared')) {
10
+ scriptToExecute = script;
11
+ }
12
+ else {
13
+ const prepScirpt = script.replace('function(arg)', 'function func(arg)');
14
+ scriptToExecute = prepScirpt.concat(' return func(arg)');
15
+ }
16
+ const executor = new context.defaultView.Function('arg', scriptToExecute);
17
+ return executor(arg);
18
+ }
19
+ exports.executeScript = executeScript;
20
+ function mainContext() {
21
+ //@ts-ignore
22
+ return cy.state('window').document;
23
+ }
24
+ exports.mainContext = mainContext;
25
+ function parentContext(context) {
26
+ if (!context)
27
+ return; // because Cypress doesn't support cross origin iframe, then childContext might return null, and then the input to parentContext might be null
28
+ return context === mainContext() ? context : context.defaultView.frameElement.ownerDocument;
29
+ }
30
+ exports.parentContext = parentContext;
31
+ function childContext(_context, element) {
32
+ return element.contentDocument; // null in case of cross origin iframe
33
+ }
34
+ exports.childContext = childContext;
35
+ function getViewportSize() {
36
+ //@ts-ignore
37
+ const currWindow = cy.state('window');
38
+ const viewportSize = {
39
+ width: Math.max(currWindow.document.documentElement.clientWidth || 0, currWindow.innerWidth || 0),
40
+ height: Math.max(currWindow.document.documentElement.clientHeight || 0, currWindow.innerHeight || 0)
41
+ };
42
+ return viewportSize;
43
+ }
44
+ exports.getViewportSize = getViewportSize;
45
+ function setViewportSize(vs) {
46
+ //@ts-ignore
47
+ Cypress.action('cy:viewport:changed', { viewportWidth: vs.size.width, viewportHeight: vs.size.height });
48
+ }
49
+ exports.setViewportSize = setViewportSize;
50
+ function transformSelector(selector) {
51
+ if (selector.hasOwnProperty('selector') && (!selector.hasOwnProperty('type') || selector.type === 'css')) {
52
+ return selector.selector;
53
+ }
54
+ return selector;
55
+ }
56
+ exports.transformSelector = transformSelector;
57
+ function findElement(context, selector, parent) {
58
+ context = refreshContext(context);
59
+ const eyesSelector = selector;
60
+ const root = parent !== null && parent !== void 0 ? parent : context;
61
+ const sel = typeof selector === 'string' ? selector : eyesSelector.selector;
62
+ if (typeof selector !== 'string' && eyesSelector.type === 'xpath') {
63
+ return context.evaluate(sel, context, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
64
+ }
65
+ else {
66
+ return root.querySelector(sel);
67
+ }
68
+ }
69
+ exports.findElement = findElement;
70
+ function findElements(context, selector, parent) {
71
+ context = refreshContext(context);
72
+ const eyesSelector = selector;
73
+ const root = parent !== null && parent !== void 0 ? parent : context;
74
+ const sel = typeof selector === 'string' ? selector : eyesSelector.selector;
75
+ if (typeof selector !== 'string' && eyesSelector.type === 'xpath') {
76
+ const results = [];
77
+ const queryResult = document.evaluate(sel, context, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
78
+ for (let i = 0; i < queryResult.snapshotLength; i++) {
79
+ results.push(queryResult.snapshotItem(i));
80
+ }
81
+ return results;
82
+ }
83
+ else {
84
+ return root.querySelectorAll(sel);
85
+ }
86
+ }
87
+ exports.findElements = findElements;
88
+ function getTitle(context) {
89
+ context = refreshContext(context);
90
+ return context.title;
91
+ }
92
+ exports.getTitle = getTitle;
93
+ function getUrl(context) {
94
+ context = refreshContext(context);
95
+ return context.location.href;
96
+ }
97
+ exports.getUrl = getUrl;
98
+ function getCookies() {
99
+ //@ts-ignore
100
+ return Cypress.automation('get:cookies', {});
101
+ }
102
+ exports.getCookies = getCookies;
103
+ // we need to method to reset the context in case the user called open before visit
104
+ function refreshContext(context) {
105
+ //@ts-ignore
106
+ return (context && context.defaultView) ? context : cy.state('window').document;
107
+ }
108
+ // export function takeScreenshot(page: Driver): Promise<Buffer>;
109
+ // export function visit(page: Driver, url: string): Promise<void>; (??)
110
+ // export function isStaleElementError(err: any): boolean;
@@ -1,55 +1,55 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.makeHandler = void 0;
4
- const http_1 = require("http");
5
- const ws_1 = require("ws");
6
- const { name, version } = require('../../package.json'); // TODO is the handshake needed at all?
7
- const TOKEN_HEADER = 'x-eyes-universal-token';
8
- const TOKEN = `${name}@${version}`;
9
- // TODO make default port 0 and return actual port
10
- async function makeHandler({ port = 31077, singleton = true, lazy = false } = {}) {
11
- const http = new http_1.Server();
12
- http.on('request', (request, response) => {
13
- if (request.url === '/handshake') {
14
- if (request.headers[TOKEN_HEADER] === TOKEN) {
15
- response.writeHead(200, { [TOKEN_HEADER]: TOKEN });
16
- }
17
- else {
18
- response.writeHead(400);
19
- }
20
- response.end();
21
- }
22
- });
23
- http.listen(port, 'localhost');
24
- return new Promise((resolve, reject) => {
25
- http.on('listening', () => {
26
- const ws = new ws_1.Server({ server: http, path: '/eyes' });
27
- ws.on('close', () => http.close());
28
- resolve({ server: ws, port });
29
- });
30
- http.on('error', async (err) => {
31
- if (!lazy && err.code === 'EADDRINUSE') {
32
- if (singleton && (await isHandshakable(port))) {
33
- return resolve({ port });
34
- }
35
- else {
36
- return resolve(await makeHandler({ port: port + 1, singleton }));
37
- }
38
- }
39
- reject(err);
40
- });
41
- });
42
- }
43
- exports.makeHandler = makeHandler;
44
- async function isHandshakable(port) {
45
- return new Promise(resolve => {
46
- const handshake = http_1.request(`http://localhost:${port}/handshake`, {
47
- headers: { [TOKEN_HEADER]: TOKEN },
48
- });
49
- handshake.on('response', ({ statusCode, headers }) => {
50
- resolve(statusCode === 200 && headers[TOKEN_HEADER] === TOKEN);
51
- });
52
- handshake.on('error', () => resolve(false));
53
- handshake.end();
54
- });
55
- }
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.makeHandler = void 0;
4
+ const http_1 = require("http");
5
+ const ws_1 = require("ws");
6
+ const { name, version } = require('../../package.json'); // TODO is the handshake needed at all?
7
+ const TOKEN_HEADER = 'x-eyes-universal-token';
8
+ const TOKEN = `${name}@${version}`;
9
+ // TODO make default port 0 and return actual port
10
+ async function makeHandler({ port = 31077, singleton = true, lazy = false } = {}) {
11
+ const http = new http_1.Server();
12
+ http.on('request', (request, response) => {
13
+ if (request.url === '/handshake') {
14
+ if (request.headers[TOKEN_HEADER] === TOKEN) {
15
+ response.writeHead(200, { [TOKEN_HEADER]: TOKEN });
16
+ }
17
+ else {
18
+ response.writeHead(400);
19
+ }
20
+ response.end();
21
+ }
22
+ });
23
+ http.listen(port, 'localhost');
24
+ return new Promise((resolve, reject) => {
25
+ http.on('listening', () => {
26
+ const ws = new ws_1.Server({ server: http, path: '/eyes' });
27
+ ws.on('close', () => http.close());
28
+ resolve({ server: ws, port });
29
+ });
30
+ http.on('error', async (err) => {
31
+ if (!lazy && err.code === 'EADDRINUSE') {
32
+ if (singleton && (await isHandshakable(port))) {
33
+ return resolve({ port });
34
+ }
35
+ else {
36
+ return resolve(await makeHandler({ port: port + 1, singleton }));
37
+ }
38
+ }
39
+ reject(err);
40
+ });
41
+ });
42
+ }
43
+ exports.makeHandler = makeHandler;
44
+ async function isHandshakable(port) {
45
+ return new Promise(resolve => {
46
+ const handshake = http_1.request(`http://localhost:${port}/handshake`, {
47
+ headers: { [TOKEN_HEADER]: TOKEN },
48
+ });
49
+ handshake.on('response', ({ statusCode, headers }) => {
50
+ resolve(statusCode === 200 && headers[TOKEN_HEADER] === TOKEN);
51
+ });
52
+ handshake.on('error', () => resolve(false));
53
+ handshake.end();
54
+ });
55
+ }
package/eyes-index.d.ts CHANGED
@@ -1,34 +1,34 @@
1
- /// <reference types="Cypress" />
2
- /// <reference types="@applitools/visual-grid-client" />
3
-
4
- declare namespace Cypress {
5
- interface Chainable {
6
- /**
7
- * Create an Applitools test.
8
- * This will start a session with the Applitools server.
9
- * @example
10
- * cy.eyesOpen({ appName: 'My App' })
11
- */
12
- eyesOpen(options?: Eyes.Open.Options): null // add isDisabled
13
-
14
- /**
15
- * Generate a screenshot of the current page and add it to the Applitools Test.
16
- * @example
17
- * cy.eyesCheckWindow()
18
- *
19
- * OR
20
- *
21
- * cy.eyesCheckWindow({
22
- * target: 'region',
23
- * selector: '.my-element'
24
- * });
25
- */
26
- eyesCheckWindow(config?: Eyes.Check.Options|String): null
27
-
28
- /**
29
- * Close the applitools test and check that all screenshots are valid.
30
- * @example cy.eyesClose()
31
- */
32
- eyesClose(): null
33
- }
34
- }
1
+ /// <reference types="Cypress" />
2
+ /// <reference types="@applitools/visual-grid-client" />
3
+
4
+ declare namespace Cypress {
5
+ interface Chainable {
6
+ /**
7
+ * Create an Applitools test.
8
+ * This will start a session with the Applitools server.
9
+ * @example
10
+ * cy.eyesOpen({ appName: 'My App' })
11
+ */
12
+ eyesOpen(options?: Eyes.Open.Options): null // add isDisabled
13
+
14
+ /**
15
+ * Generate a screenshot of the current page and add it to the Applitools Test.
16
+ * @example
17
+ * cy.eyesCheckWindow()
18
+ *
19
+ * OR
20
+ *
21
+ * cy.eyesCheckWindow({
22
+ * target: 'region',
23
+ * selector: '.my-element'
24
+ * });
25
+ */
26
+ eyesCheckWindow(config?: Eyes.Check.Options|String): null
27
+
28
+ /**
29
+ * Close the applitools test and check that all screenshots are valid.
30
+ * @example cy.eyesClose()
31
+ */
32
+ eyesClose(): null
33
+ }
34
+ }
package/index.js CHANGED
@@ -1,2 +1,2 @@
1
- 'use strict';
2
- module.exports = require('./src/plugin/startPlugin');
1
+ 'use strict';
2
+ module.exports = require('./src/plugin/startPlugin');