@o3r/testing 11.1.0-prerelease.8 → 11.1.0-rc.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 (42) hide show
  1. package/core/helpers.d.ts.map +1 -1
  2. package/core/playwright/element.js +2 -2
  3. package/core/playwright/element.js.map +1 -1
  4. package/core/protractor/utils.js +1 -2
  5. package/core/protractor/utils.js.map +1 -1
  6. package/kassette/update-dates-in-mocks.js +1 -2
  7. package/kassette/update-dates-in-mocks.js.map +1 -1
  8. package/localization/localization-mock.js +2 -2
  9. package/localization/localization-mock.js.map +1 -1
  10. package/mocks/mock-component-generator.js +1 -2
  11. package/mocks/mock-component-generator.js.map +1 -1
  12. package/package.json +42 -42
  13. package/schematics/fixture-to-component/index.js +2 -2
  14. package/schematics/fixture-to-component/index.js.map +1 -1
  15. package/schematics/ng-add/fixture/index.js +1 -2
  16. package/schematics/ng-add/fixture/index.js.map +1 -1
  17. package/schematics/ng-add/playwright/index.js +1 -2
  18. package/schematics/ng-add/playwright/index.js.map +1 -1
  19. package/schematics/ng-update/v9-0/localization-imports/localization-imports.js +1 -2
  20. package/schematics/ng-update/v9-0/localization-imports/localization-imports.js.map +1 -1
  21. package/schematics/ng-update/v9-0/throw-on-undefined/throw-on-undefined.js +1 -2
  22. package/schematics/ng-update/v9-0/throw-on-undefined/throw-on-undefined.js.map +1 -1
  23. package/store/testable-select.js +5 -6
  24. package/store/testable-select.js.map +1 -1
  25. package/store/typings.js +1 -2
  26. package/store/typings.js.map +1 -1
  27. package/tools/path-replacement/path-replacement.js +1 -2
  28. package/tools/path-replacement/path-replacement.js.map +1 -1
  29. package/tools/protractor/fetch-manager/_fetch-manager.d.ts +1 -0
  30. package/tools/protractor/fetch-manager/_fetch-manager.d.ts.map +1 -0
  31. package/tools/protractor/fetch-manager/_fetch-manager.js +127 -0
  32. package/tools/protractor/fetch-manager/_fetch-manager.js.map +1 -0
  33. package/tools/protractor/fetch-manager/utils.js +3 -4
  34. package/tools/protractor/fetch-manager/utils.js.map +1 -1
  35. package/tools/protractor/post-message-interceptor/_post-message-interceptor.d.ts +5 -0
  36. package/tools/protractor/post-message-interceptor/_post-message-interceptor.d.ts.map +1 -0
  37. package/tools/protractor/post-message-interceptor/_post-message-interceptor.js +157 -0
  38. package/tools/protractor/post-message-interceptor/_post-message-interceptor.js.map +1 -0
  39. package/visual-test/utils.js +3 -4
  40. package/visual-test/utils.js.map +1 -1
  41. package/visual-test/visual-test.js +6 -6
  42. package/visual-test/visual-test.js.map +1 -1
package/store/typings.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.isSelectorSpyCall = void 0;
3
+ exports.isSelectorSpyCall = isSelectorSpyCall;
4
4
  /**
5
5
  * Identifies if spy is a spyResult or spyCall
6
6
  * @param spy
@@ -8,5 +8,4 @@ exports.isSelectorSpyCall = void 0;
8
8
  function isSelectorSpyCall(spy) {
9
9
  return typeof spy.fakeResult === 'function';
10
10
  }
11
- exports.isSelectorSpyCall = isSelectorSpyCall;
12
11
  //# sourceMappingURL=typings.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"typings.js","sourceRoot":"","sources":["../../src/store/typings.ts"],"names":[],"mappings":";;;AA0CA;;;GAGG;AACH,SAAgB,iBAAiB,CAAI,GAAmB;IACtD,OAAO,OAAO,GAAG,CAAC,UAAU,KAAK,UAAU,CAAC;AAC9C,CAAC;AAFD,8CAEC","sourcesContent":["/* eslint-disable @typescript-eslint/ban-types */\nimport { Observable } from 'rxjs';\n\n/** Specifies a fake select call */\nexport type FakeSelectCall<R> = ($source: Observable<any>) => Observable<R>;\n\n/**\n * Type representing a state selector function\n */\nexport type SelectorFunction<S, R> = (state: S, props?: object) => R;\n\n/**\n * Base selector spy\n */\nexport interface BaseSelectorSpy<R, S extends object = object> {\n /** The selector to be spied on */\n selector: SelectorFunction<S, R>;\n}\n\n/**\n * Represents a spy for a given Memoized selector\n * that returns a fake value\n */\nexport interface SelectorSpyResult<R, S extends object = object> extends BaseSelectorSpy<R, S> {\n /** The fake result to be returned */\n fakeResult: R;\n}\n\n/**\n * Represents a spy for a given Memoized selector\n * that returns a fake call\n */\nexport interface SelectorSpyCall<R, S extends object = object> extends BaseSelectorSpy<R, S> {\n /** The fake result call to be used */\n fakeResult: FakeSelectCall<R>;\n}\n\n/**\n * Represents a spy for a given Memoized selector\n */\nexport type SelectorSpy<R, S extends object = object> = SelectorSpyResult<R, S> | SelectorSpyCall<R, S>;\n\n/**\n * Identifies if spy is a spyResult or spyCall\n * @param spy\n */\nexport function isSelectorSpyCall<R>(spy: SelectorSpy<R>): spy is SelectorSpyCall<R> {\n return typeof spy.fakeResult === 'function';\n}\n"]}
1
+ {"version":3,"file":"typings.js","sourceRoot":"","sources":["../../src/store/typings.ts"],"names":[],"mappings":";;AA8CA,8CAEC;AAND;;;GAGG;AACH,SAAgB,iBAAiB,CAAI,GAAmB;IACtD,OAAO,OAAO,GAAG,CAAC,UAAU,KAAK,UAAU,CAAC;AAC9C,CAAC","sourcesContent":["/* eslint-disable @typescript-eslint/ban-types */\nimport { Observable } from 'rxjs';\n\n/** Specifies a fake select call */\nexport type FakeSelectCall<R> = ($source: Observable<any>) => Observable<R>;\n\n/**\n * Type representing a state selector function\n */\nexport type SelectorFunction<S, R> = (state: S, props?: object) => R;\n\n/**\n * Base selector spy\n */\nexport interface BaseSelectorSpy<R, S extends object = object> {\n /** The selector to be spied on */\n selector: SelectorFunction<S, R>;\n}\n\n/**\n * Represents a spy for a given Memoized selector\n * that returns a fake value\n */\nexport interface SelectorSpyResult<R, S extends object = object> extends BaseSelectorSpy<R, S> {\n /** The fake result to be returned */\n fakeResult: R;\n}\n\n/**\n * Represents a spy for a given Memoized selector\n * that returns a fake call\n */\nexport interface SelectorSpyCall<R, S extends object = object> extends BaseSelectorSpy<R, S> {\n /** The fake result call to be used */\n fakeResult: FakeSelectCall<R>;\n}\n\n/**\n * Represents a spy for a given Memoized selector\n */\nexport type SelectorSpy<R, S extends object = object> = SelectorSpyResult<R, S> | SelectorSpyCall<R, S>;\n\n/**\n * Identifies if spy is a spyResult or spyCall\n * @param spy\n */\nexport function isSelectorSpyCall<R>(spy: SelectorSpy<R>): spy is SelectorSpyCall<R> {\n return typeof spy.fakeResult === 'function';\n}\n"]}
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.adjustPath = void 0;
3
+ exports.adjustPath = adjustPath;
4
4
  var tslib_1 = require("tslib");
5
5
  /* eslint-disable no-undef */
6
6
  var esbuild_1 = require("esbuild");
@@ -55,5 +55,4 @@ function adjustPath(frameworkName, customTransformOptions) {
55
55
  }
56
56
  };
57
57
  }
58
- exports.adjustPath = adjustPath;
59
58
  //# sourceMappingURL=path-replacement.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"path-replacement.js","sourceRoot":"","sources":["../../../src/tools/path-replacement/path-replacement.ts"],"names":[],"mappings":";;;;AAAA,6BAA6B;AAC7B,mCAA0D;AAC1D,4BAA8B;AAC9B,2CAAqC;AACrC,yDAAuD;AACvD,gCAAkC;AAClC;;;;;GAKG;AACH,SAAgB,UAAU,CAAC,aAA0C,EAAE,sBAA6C;IAA7C,uCAAA,EAAA,2BAA6C;IAClH,IAAM,YAAY,GAAwB,EAAE,CAAC;IAC7C,IAAM,eAAe,GAAG,oBAAM,CAAC,SAAS,CAAC,OAAO,CAAC;IACjD,IAAM,KAAK,GAAG,IAAI,MAAM,CAAC,+BAAwB,aAAa,UAAO,CAAC,CAAC;IACvE,oBAAM,CAAC,SAAS,CAAC,OAAO,GAAG,UAA+B,EAAU;QAClE,IAAM,KAAK,GAAG,EAAE,CAAC,OAAO,CAAC,KAAK,EAAE,4BAAqB,aAAa,OAAI,CAAC,CAAC;QAExE,IAAI,CAAC;YACH,OAAO,eAAe,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC;QAC9C,CAAC;QAAC,OAAO,KAAU,EAAE,CAAC;YACpB,IAAM,KAAK,GAAI,EAAe;iBAC3B,MAAM,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,UAAA,CAAC,IAAI,OAAA,CAAC,CAAC,OAAO,CAAC,oBAAoB,EAAE,EAAE,CAAC,EAAnC,CAAmC,CAAC,CAAC,CAAC;YAEhF,IAAM,QAAQ,GAAG,OAAO,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,KAAK,OAAA,EAAE,CAAC,CAAC;YACnD,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,EAAE,CAAC;gBAC5B,IAAM,WAAW,GAAG,EAAE,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC;gBAC9C,IAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,KAAK,CAAC,CAAC;gBAC/C,0CAA0C;gBAC1C,IAAM,KAAK,GAAG,IAAA,uBAAa,EAAC,WAAW,CAAC,QAAQ,EAAE,qBAChD,MAAM,EAAE,IAAI,EACZ,MAAM,EAAE,KAAK,EACb,MAAM,EAAE,QAAQ,EAChB,cAAc,EAAE,IAAI,EACpB,UAAU,EAAE,GAAG,IACZ,sBAAsB,EACzB,CAAC;gBAEH;;;;;;mBAMG;gBACH,IAAI,CAAC;oBACH,YAAY,CAAC,QAAQ,CAAC,GAAG,IAAA,sCAAiB,EAAC,KAAK,CAAC,IAAI,EAAE;wBACrD,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC;wBAC/B,gBAAgB,EAAE,IAAI;qBACvB,CAAC,CAAC;gBACL,CAAC;gBAAC,OAAO,EAAE,EAAE,CAAC;oBACZ,sCAAsC;oBACtC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;gBACpB,CAAC;YACH,CAAC;YAED,OAAO,YAAY,CAAC,QAAQ,CAAC,CAAC;QAChC,CAAC;IAEH,CAAmB,CAAC;AACtB,CAAC;AAjDD,gCAiDC","sourcesContent":["/* eslint-disable no-undef */\nimport { TransformOptions, transformSync } from 'esbuild';\nimport * as fs from 'node:fs';\nimport { Module } from 'node:module';\nimport { requireFromString } from 'module-from-string';\nimport * as path from 'node:path';\n/**\n * Switch to the needed implementation of core testing, when running e2e tests\n * transforms ESM into CJS when needed\n * @param frameworkName Name of the framework used for e2e testing (playwright|protractor)\n * @param customTransformOptions\n */\nexport function adjustPath(frameworkName: 'playwright' | 'protractor', customTransformOptions: TransformOptions = {}) {\n const modulesCache: Record<string, any> = {};\n const originalRequire = Module.prototype.require;\n const regex = new RegExp(`@o3r/testing/core(?!/${frameworkName})(.*)`);\n Module.prototype.require = function (this: NodeJS.Module, id: string) {\n const newId = id.replace(regex, `@o3r/testing/core/${frameworkName}$1`);\n\n try {\n return originalRequire.apply(this, [newId]);\n } catch (error: any) {\n const paths = ([] as string[])\n .concat(this.paths, this.paths.map(i => i.replace(/[\\\\/]node_modules$/, '')));\n\n const filePath = require.resolve(newId, { paths });\n if (!modulesCache[filePath]) {\n const fileContent = fs.readFileSync(filePath);\n const cwd = path.resolve(process.cwd(), 'src');\n // we use ESBUILD to transform it into CJS\n const trans = transformSync(fileContent.toString(), {\n loader: 'js',\n format: 'cjs',\n target: 'es2016',\n sourcesContent: true,\n sourceRoot: cwd,\n ...customTransformOptions\n });\n\n /**\n * requireFromString will execute the file apart from just returning a module\n * It can throw an exception which will prevent stop the execution\n *\n * That main blocker includes IVY-compatible libraries which have\n * no compiler facade in a global scope.\n */\n try {\n modulesCache[filePath] = requireFromString(trans.code, {\n dirname: path.dirname(filePath),\n useCurrentGlobal: true\n });\n } catch (ex) {\n // eslint-disable-next-line no-console\n console.error(ex);\n }\n }\n\n return modulesCache[filePath];\n }\n\n } as NodeJS.Require;\n}\n"]}
1
+ {"version":3,"file":"path-replacement.js","sourceRoot":"","sources":["../../../src/tools/path-replacement/path-replacement.ts"],"names":[],"mappings":";;AAYA,gCAiDC;;AA7DD,6BAA6B;AAC7B,mCAA0D;AAC1D,4BAA8B;AAC9B,2CAAqC;AACrC,yDAAuD;AACvD,gCAAkC;AAClC;;;;;GAKG;AACH,SAAgB,UAAU,CAAC,aAA0C,EAAE,sBAA6C;IAA7C,uCAAA,EAAA,2BAA6C;IAClH,IAAM,YAAY,GAAwB,EAAE,CAAC;IAC7C,IAAM,eAAe,GAAG,oBAAM,CAAC,SAAS,CAAC,OAAO,CAAC;IACjD,IAAM,KAAK,GAAG,IAAI,MAAM,CAAC,+BAAwB,aAAa,UAAO,CAAC,CAAC;IACvE,oBAAM,CAAC,SAAS,CAAC,OAAO,GAAG,UAA+B,EAAU;QAClE,IAAM,KAAK,GAAG,EAAE,CAAC,OAAO,CAAC,KAAK,EAAE,4BAAqB,aAAa,OAAI,CAAC,CAAC;QAExE,IAAI,CAAC;YACH,OAAO,eAAe,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC;QAC9C,CAAC;QAAC,OAAO,KAAU,EAAE,CAAC;YACpB,IAAM,KAAK,GAAI,EAAe;iBAC3B,MAAM,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,UAAA,CAAC,IAAI,OAAA,CAAC,CAAC,OAAO,CAAC,oBAAoB,EAAE,EAAE,CAAC,EAAnC,CAAmC,CAAC,CAAC,CAAC;YAEhF,IAAM,QAAQ,GAAG,OAAO,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,KAAK,OAAA,EAAE,CAAC,CAAC;YACnD,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,EAAE,CAAC;gBAC5B,IAAM,WAAW,GAAG,EAAE,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC;gBAC9C,IAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,KAAK,CAAC,CAAC;gBAC/C,0CAA0C;gBAC1C,IAAM,KAAK,GAAG,IAAA,uBAAa,EAAC,WAAW,CAAC,QAAQ,EAAE,qBAChD,MAAM,EAAE,IAAI,EACZ,MAAM,EAAE,KAAK,EACb,MAAM,EAAE,QAAQ,EAChB,cAAc,EAAE,IAAI,EACpB,UAAU,EAAE,GAAG,IACZ,sBAAsB,EACzB,CAAC;gBAEH;;;;;;mBAMG;gBACH,IAAI,CAAC;oBACH,YAAY,CAAC,QAAQ,CAAC,GAAG,IAAA,sCAAiB,EAAC,KAAK,CAAC,IAAI,EAAE;wBACrD,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC;wBAC/B,gBAAgB,EAAE,IAAI;qBACvB,CAAC,CAAC;gBACL,CAAC;gBAAC,OAAO,EAAE,EAAE,CAAC;oBACZ,sCAAsC;oBACtC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;gBACpB,CAAC;YACH,CAAC;YAED,OAAO,YAAY,CAAC,QAAQ,CAAC,CAAC;QAChC,CAAC;IAEH,CAAmB,CAAC;AACtB,CAAC","sourcesContent":["/* eslint-disable no-undef */\nimport { TransformOptions, transformSync } from 'esbuild';\nimport * as fs from 'node:fs';\nimport { Module } from 'node:module';\nimport { requireFromString } from 'module-from-string';\nimport * as path from 'node:path';\n/**\n * Switch to the needed implementation of core testing, when running e2e tests\n * transforms ESM into CJS when needed\n * @param frameworkName Name of the framework used for e2e testing (playwright|protractor)\n * @param customTransformOptions\n */\nexport function adjustPath(frameworkName: 'playwright' | 'protractor', customTransformOptions: TransformOptions = {}) {\n const modulesCache: Record<string, any> = {};\n const originalRequire = Module.prototype.require;\n const regex = new RegExp(`@o3r/testing/core(?!/${frameworkName})(.*)`);\n Module.prototype.require = function (this: NodeJS.Module, id: string) {\n const newId = id.replace(regex, `@o3r/testing/core/${frameworkName}$1`);\n\n try {\n return originalRequire.apply(this, [newId]);\n } catch (error: any) {\n const paths = ([] as string[])\n .concat(this.paths, this.paths.map(i => i.replace(/[\\\\/]node_modules$/, '')));\n\n const filePath = require.resolve(newId, { paths });\n if (!modulesCache[filePath]) {\n const fileContent = fs.readFileSync(filePath);\n const cwd = path.resolve(process.cwd(), 'src');\n // we use ESBUILD to transform it into CJS\n const trans = transformSync(fileContent.toString(), {\n loader: 'js',\n format: 'cjs',\n target: 'es2016',\n sourcesContent: true,\n sourceRoot: cwd,\n ...customTransformOptions\n });\n\n /**\n * requireFromString will execute the file apart from just returning a module\n * It can throw an exception which will prevent stop the execution\n *\n * That main blocker includes IVY-compatible libraries which have\n * no compiler facade in a global scope.\n */\n try {\n modulesCache[filePath] = requireFromString(trans.code, {\n dirname: path.dirname(filePath),\n useCurrentGlobal: true\n });\n } catch (ex) {\n // eslint-disable-next-line no-console\n console.error(ex);\n }\n }\n\n return modulesCache[filePath];\n }\n\n } as NodeJS.Require;\n}\n"]}
@@ -0,0 +1 @@
1
+ //# sourceMappingURL=_fetch-manager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"_fetch-manager.d.ts","sourceRoot":"","sources":["../../../../src/tools/protractor/fetch-manager/_fetch-manager.ts"],"names":[],"mappings":""}
@@ -0,0 +1,127 @@
1
+ "use strict";
2
+ /**
3
+ * Note: This file is not part of the running script, it is injected in the browser while running e2e tests.
4
+ */
5
+ (function () {
6
+ var MAX_WAITING_TIME_FOR_FETCH = 45 * 1000; // 45 seconds
7
+ var fetchManager = /** @class */ (function () {
8
+ function FetchManager() {
9
+ this.nbCurrentFetch = 0;
10
+ }
11
+ FetchManager.prototype.interceptor = function (ref, nativeFetch) {
12
+ var args = [];
13
+ for (var _i = 2; _i < arguments.length; _i++) {
14
+ args[_i - 2] = arguments[_i];
15
+ }
16
+ var promise = Promise.resolve(args);
17
+ promise = promise.then(function () {
18
+ ref.nbCurrentFetch++;
19
+ return [args[0], args[1]];
20
+ }, function (error) {
21
+ return Promise.reject(error);
22
+ });
23
+ promise = promise.then(function () { return nativeFetch.apply(void 0, args); });
24
+ promise = promise.then(function (response) {
25
+ ref.nbCurrentFetch--;
26
+ return response;
27
+ }, function (error) {
28
+ ref.nbCurrentFetch--;
29
+ return Promise.reject(error);
30
+ });
31
+ return promise;
32
+ };
33
+ /**
34
+ * Register the fetchs events to count the number of pending fetchs.
35
+ */
36
+ FetchManager.prototype.registerFetchInterceptor = function () {
37
+ var _this = this;
38
+ var nativeFetch = window.fetch;
39
+ // eslint-disable-next-line @typescript-eslint/no-this-alias
40
+ var that = this;
41
+ Object.assign(window, { fetch: function () {
42
+ var args = [];
43
+ for (var _i = 0; _i < arguments.length; _i++) {
44
+ args[_i] = arguments[_i];
45
+ }
46
+ return _this.interceptor.apply(_this, __spreadArray([that, nativeFetch], args, false));
47
+ } });
48
+ };
49
+ FetchManager.prototype.unregisterFetchInterceptor = function () {
50
+ Object.assign(window, { fetch: this.windowFetch });
51
+ };
52
+ /**
53
+ * Returns the single instance of FetchManager
54
+ */
55
+ FetchManager.getInstance = function () {
56
+ return this._instance || (this._instance = new this());
57
+ };
58
+ /**
59
+ * Initialize the fetch manager
60
+ */
61
+ FetchManager.prototype.init = function () {
62
+ this.nbCurrentFetch = 0;
63
+ this.registerFetchInterceptor();
64
+ };
65
+ /**
66
+ *
67
+ */
68
+ FetchManager.prototype.stop = function () {
69
+ this.nbCurrentFetch = 0;
70
+ this.unregisterFetchInterceptor();
71
+ };
72
+ /**
73
+ * Get the number of active fetchs on the page.
74
+ */
75
+ FetchManager.prototype.getPendingFetchs = function () {
76
+ return this.nbCurrentFetch;
77
+ };
78
+ /**
79
+ * This function waits for all fetchs calls to be resolved and the page to be stable to call the callback.
80
+ * It permits to easily run synchronous tests with protractor.
81
+ * This is very usefull in the case of Otter calls to backend because protractor synchronization manager do not care
82
+ * about fetchs calls. As a consequence, the `waitForAngular` method will not work.
83
+ * @param callback : Callback called when all the fetchs are finished and the page is stable.
84
+ * @param timeoutInterval : Interval in milliseconds between two checks of the number of pending fetchs
85
+ */
86
+ FetchManager.prototype.waitForFetchs = function (callback, timeoutInterval) {
87
+ var _this = this;
88
+ if (timeoutInterval === void 0) { timeoutInterval = 100; }
89
+ var interval;
90
+ var timeout;
91
+ if (!this.getPendingFetchs()) {
92
+ callback();
93
+ return;
94
+ }
95
+ var cancelPolling = function () {
96
+ if (interval) {
97
+ clearInterval(interval);
98
+ interval = undefined;
99
+ }
100
+ if (timeout) {
101
+ clearTimeout(timeout);
102
+ timeout = undefined;
103
+ }
104
+ // Handle polling result
105
+ if (_this.getPendingFetchs() > 0) {
106
+ // Error case will just log in console
107
+ // and allow to continue as o3r elements might be checking fetchManager
108
+ // concurrently
109
+ _this.nbCurrentFetch = 0;
110
+ callback();
111
+ throw new Error('Fetch timeout. Please check network requests.');
112
+ }
113
+ else {
114
+ callback();
115
+ }
116
+ };
117
+ var polling = function () { return _this.getPendingFetchs() > 0 || cancelPolling(); };
118
+ interval = setInterval(polling, timeoutInterval);
119
+ timeout = setTimeout(cancelPolling, MAX_WAITING_TIME_FOR_FETCH);
120
+ };
121
+ return FetchManager;
122
+ }());
123
+ if (!('fetchManager' in window)) {
124
+ Object.assign(window, { fetchManager: fetchManager });
125
+ }
126
+ })();
127
+ //# sourceMappingURL=_fetch-manager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"_fetch-manager.js","sourceRoot":"","sources":["../../../../src/tools/protractor/fetch-manager/_fetch-manager.ts"],"names":[],"mappings":";AAAA;;GAEG;AACH,CAAC;IAUC,IAAM,0BAA0B,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC,aAAa;IAE3D,IAAM,YAAY;QAMhB;YAHQ,mBAAc,GAAG,CAAC,CAAC;QAGJ,CAAC;QAEhB,kCAAW,GAAnB,UAAoB,GAAiB,EAAE,WAAgB;YAAE,cAAc;iBAAd,UAAc,EAAd,qBAAc,EAAd,IAAc;gBAAd,6BAAc;;YACrE,IAAI,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;YACpC,OAAO,GAAG,OAAO,CAAC,IAAI,CACpB;gBACE,GAAG,CAAC,cAAc,EAAE,CAAC;gBACrB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;YAC5B,CAAC,EACD,UAAC,KAAK;gBACJ,OAAO,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YAC/B,CAAC,CAAC,CAAC;YACL,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,cAAM,OAAA,WAAW,eAAI,IAAI,GAAnB,CAAoB,CAAC,CAAC;YACnD,OAAO,GAAG,OAAO,CAAC,IAAI,CACpB,UAAC,QAAQ;gBACP,GAAG,CAAC,cAAc,EAAE,CAAC;gBACrB,OAAO,QAAQ,CAAC;YAClB,CAAC,EACD,UAAC,KAAK;gBACJ,GAAG,CAAC,cAAc,EAAE,CAAC;gBACrB,OAAO,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YAC/B,CAAC,CAAC,CAAC;YACL,OAAO,OAAO,CAAC;QACjB,CAAC;QAED;;WAEG;QACK,+CAAwB,GAAhC;YAAA,iBAKC;YAJC,IAAM,WAAW,GAAG,MAAM,CAAC,KAAK,CAAC;YACjC,4DAA4D;YAC5D,IAAM,IAAI,GAAG,IAAI,CAAC;YAClB,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,EAAC,KAAK,EAAE;oBAAC,cAAc;yBAAd,UAAc,EAAd,qBAAc,EAAd,IAAc;wBAAd,yBAAc;;oBAAK,OAAA,KAAI,CAAC,WAAW,OAAhB,KAAI,iBAAa,IAAI,EAAE,WAAW,GAAK,IAAI;gBAA3C,CAA4C,EAAC,CAAC,CAAC;QACnG,CAAC;QAEO,iDAA0B,GAAlC;YACE,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,EAAC,KAAK,EAAE,IAAI,CAAC,WAAW,EAAC,CAAC,CAAC;QACnD,CAAC;QAED;;WAEG;QACW,wBAAW,GAAzB;YACE,OAAO,IAAI,CAAC,SAAS,IAAI,CAAC,IAAI,CAAC,SAAS,GAAG,IAAI,IAAI,EAAE,CAAC,CAAC;QACzD,CAAC;QAED;;WAEG;QACI,2BAAI,GAAX;YACE,IAAI,CAAC,cAAc,GAAG,CAAC,CAAC;YACxB,IAAI,CAAC,wBAAwB,EAAE,CAAC;QAClC,CAAC;QAED;;WAEG;QACI,2BAAI,GAAX;YACE,IAAI,CAAC,cAAc,GAAG,CAAC,CAAC;YACxB,IAAI,CAAC,0BAA0B,EAAE,CAAC;QACpC,CAAC;QAED;;WAEG;QACI,uCAAgB,GAAvB;YACE,OAAO,IAAI,CAAC,cAAc,CAAC;QAC7B,CAAC;QAED;;;;;;;WAOG;QACI,oCAAa,GAApB,UAAqB,QAAa,EAAE,eAAqB;YAAzD,iBAsCC;YAtCmC,gCAAA,EAAA,qBAAqB;YACvD,IAAI,QAA2B,CAAC;YAChC,IAAI,OAA0B,CAAC;YAE/B,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE,EAAE,CAAC;gBAC7B,QAAQ,EAAE,CAAC;gBACX,OAAO;YACT,CAAC;YAED,IAAM,aAAa,GAAG;gBACpB,IAAI,QAAQ,EAAE,CAAC;oBACb,aAAa,CAAC,QAAQ,CAAC,CAAC;oBACxB,QAAQ,GAAG,SAAS,CAAC;gBACvB,CAAC;gBAED,IAAI,OAAO,EAAE,CAAC;oBACZ,YAAY,CAAC,OAAO,CAAC,CAAC;oBACtB,OAAO,GAAG,SAAS,CAAC;gBACtB,CAAC;gBAED,wBAAwB;gBACxB,IAAI,KAAI,CAAC,gBAAgB,EAAE,GAAG,CAAC,EAAE,CAAC;oBAChC,sCAAsC;oBACtC,uEAAuE;oBACvE,eAAe;oBACf,KAAI,CAAC,cAAc,GAAG,CAAC,CAAC;oBACxB,QAAQ,EAAE,CAAC;oBAEX,MAAM,IAAI,KAAK,CAAC,+CAA+C,CAAC,CAAC;gBACnE,CAAC;qBAAM,CAAC;oBACN,QAAQ,EAAE,CAAC;gBACb,CAAC;YACH,CAAC,CAAC;YAEF,IAAM,OAAO,GAAG,cAAM,OAAA,KAAI,CAAC,gBAAgB,EAAE,GAAG,CAAC,IAAI,aAAa,EAAE,EAA9C,CAA8C,CAAC;YAErE,QAAQ,GAAG,WAAW,CAAC,OAAO,EAAE,eAAe,CAAC,CAAC;YACjD,OAAO,GAAG,UAAU,CAAC,aAAa,EAAE,0BAA0B,CAAC,CAAC;QAClE,CAAC;QACH,mBAAC;IAAD,CAAC,AA1HoB,GA0HpB,CAAC;IAEF,IAAI,CAAC,CAAC,cAAc,IAAI,MAAM,CAAC,EAAE,CAAC;QAChC,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,EAAE,YAAY,cAAA,EAAE,CAAC,CAAC;IAC1C,CAAC;AACH,CAAC,CAAC,EAAE,CAAC"}
@@ -1,6 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.stopFetchManager = exports.initFetchManager = exports.waitForOtterStable = void 0;
3
+ exports.waitForOtterStable = waitForOtterStable;
4
+ exports.initFetchManager = initFetchManager;
5
+ exports.stopFetchManager = stopFetchManager;
4
6
  var tslib_1 = require("tslib");
5
7
  var fs = require("node:fs");
6
8
  var path = require("node:path");
@@ -36,7 +38,6 @@ function waitForOtterStable() {
36
38
  });
37
39
  });
38
40
  }
39
- exports.waitForOtterStable = waitForOtterStable;
40
41
  /**
41
42
  * This function initiliaze the FetchManager. Set `window.fetch` variable with a custom behaviour in order to count the
42
43
  * fetch calls.
@@ -59,7 +60,6 @@ function initFetchManager() {
59
60
  });
60
61
  });
61
62
  }
62
- exports.initFetchManager = initFetchManager;
63
63
  /**
64
64
  * This function stops the FetchManager. Reset `window.fetch` variable with its native behaviour.
65
65
  */
@@ -75,5 +75,4 @@ function stopFetchManager() {
75
75
  });
76
76
  });
77
77
  }
78
- exports.stopFetchManager = stopFetchManager;
79
78
  //# sourceMappingURL=utils.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../../src/tools/protractor/fetch-manager/utils.ts"],"names":[],"mappings":";;;;AAAA,4BAA8B;AAC9B,gCAAkC;AAClC,yCAAqC;AAErC;;;;;;;;;;GAUG;AACH,SAAsB,kBAAkB;;;;wBACtC,qBAAM,oBAAO,CAAC,cAAc,EAAE,EAAA;;oBAA9B,SAA8B,CAAC;yBAC3B,CAAC,oBAAO,CAAC,qBAAqB,EAA9B,wBAA8B;oBAChC,qBAAM,oBAAO,CAAC,kBAAkB,CAC9B,mFAAmF,CAAC,EAAA;;oBADtF,SACsF,CAAC;oBACvF,qBAAM,oBAAO,CAAC,cAAc,EAAE,EAAA;;oBAA9B,SAA8B,CAAC;;;;;;CAElC;AAPD,gDAOC;AAED;;;GAGG;AACH,SAAsB,gBAAgB;;;;;;oBAC9B,YAAY,GAAG,EAAE,CAAC,YAAY,CAClC,IAAI,CAAC,OAAO,CACV,OAAO,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,YAAY,EAAE,eAAe,EACxF,mBAAmB,CAAC,EACtB,EAAC,QAAQ,EAAE,OAAO,EAAC,CAAC,CAAC;oBACvB,qBAAM,oBAAO,CAAC,aAAa,CAAC,YAAY,CAAC,EAAA;;oBAAzC,SAAyC,CAAC;oBAC1C,qBAAM,oBAAO,CAAC,aAAa,CAAC,2CAA2C,CAAC,EAAA;;oBAAxE,SAAwE,CAAC;;;;;CAC1E;AARD,4CAQC;AAED;;GAEG;AACH,SAAsB,gBAAgB;;;;wBACpC,qBAAM,oBAAO,CAAC,aAAa,CAAC,2CAA2C,CAAC,EAAA;;oBAAxE,SAAwE,CAAC;;;;;CAC1E;AAFD,4CAEC","sourcesContent":["import * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport { browser } from 'protractor';\n\n/**\n * This function waits for all fetchs calls to be resolved and the page to be stable to resolve the promise.\n * It permits to easily run synchronous e2e tests on a flow that uses fetchs calls with protractor.\n * This is very useful in the case of Otter calls to backend because protractor synchronization manager do not care\n * about fetchs calls.\n *\n * This function needs the FetchManager to have been initialized and injected in the browser at the beginning of the\n * flow with `initFetchManager()`\n *\n * You can ignore the waiting of fetchs by setting `browser.ignoreSynchronization` to `true`\n */\nexport async function waitForOtterStable() {\n await browser.waitForAngular();\n if (!browser.ignoreSynchronization) {\n await browser.executeAsyncScript(\n 'window.fetchManager.getInstance().waitForFetchs(arguments[arguments.length - 1]);');\n await browser.waitForAngular();\n }\n}\n\n/**\n * This function initiliaze the FetchManager. Set `window.fetch` variable with a custom behaviour in order to count the\n * fetch calls.\n */\nexport async function initFetchManager() {\n const fetchManager = fs.readFileSync(\n path.resolve(\n process.cwd(), 'node_modules', '@o3r', 'testing', 'tools', 'protractor', 'fetch-manager',\n '_fetch-manager.js'),\n {encoding: 'utf-8'});\n await browser.executeScript(fetchManager);\n await browser.executeScript('window.fetchManager.getInstance().init();');\n}\n\n/**\n * This function stops the FetchManager. Reset `window.fetch` variable with its native behaviour.\n */\nexport async function stopFetchManager() {\n await browser.executeScript('window.fetchManager.getInstance().stop();');\n}\n"]}
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../../src/tools/protractor/fetch-manager/utils.ts"],"names":[],"mappings":";;AAeA,gDAOC;AAMD,4CAQC;AAKD,4CAEC;;AA3CD,4BAA8B;AAC9B,gCAAkC;AAClC,yCAAqC;AAErC;;;;;;;;;;GAUG;AACH,SAAsB,kBAAkB;;;;wBACtC,qBAAM,oBAAO,CAAC,cAAc,EAAE,EAAA;;oBAA9B,SAA8B,CAAC;yBAC3B,CAAC,oBAAO,CAAC,qBAAqB,EAA9B,wBAA8B;oBAChC,qBAAM,oBAAO,CAAC,kBAAkB,CAC9B,mFAAmF,CAAC,EAAA;;oBADtF,SACsF,CAAC;oBACvF,qBAAM,oBAAO,CAAC,cAAc,EAAE,EAAA;;oBAA9B,SAA8B,CAAC;;;;;;CAElC;AAED;;;GAGG;AACH,SAAsB,gBAAgB;;;;;;oBAC9B,YAAY,GAAG,EAAE,CAAC,YAAY,CAClC,IAAI,CAAC,OAAO,CACV,OAAO,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,YAAY,EAAE,eAAe,EACxF,mBAAmB,CAAC,EACtB,EAAC,QAAQ,EAAE,OAAO,EAAC,CAAC,CAAC;oBACvB,qBAAM,oBAAO,CAAC,aAAa,CAAC,YAAY,CAAC,EAAA;;oBAAzC,SAAyC,CAAC;oBAC1C,qBAAM,oBAAO,CAAC,aAAa,CAAC,2CAA2C,CAAC,EAAA;;oBAAxE,SAAwE,CAAC;;;;;CAC1E;AAED;;GAEG;AACH,SAAsB,gBAAgB;;;;wBACpC,qBAAM,oBAAO,CAAC,aAAa,CAAC,2CAA2C,CAAC,EAAA;;oBAAxE,SAAwE,CAAC;;;;;CAC1E","sourcesContent":["import * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport { browser } from 'protractor';\n\n/**\n * This function waits for all fetchs calls to be resolved and the page to be stable to resolve the promise.\n * It permits to easily run synchronous e2e tests on a flow that uses fetchs calls with protractor.\n * This is very useful in the case of Otter calls to backend because protractor synchronization manager do not care\n * about fetchs calls.\n *\n * This function needs the FetchManager to have been initialized and injected in the browser at the beginning of the\n * flow with `initFetchManager()`\n *\n * You can ignore the waiting of fetchs by setting `browser.ignoreSynchronization` to `true`\n */\nexport async function waitForOtterStable() {\n await browser.waitForAngular();\n if (!browser.ignoreSynchronization) {\n await browser.executeAsyncScript(\n 'window.fetchManager.getInstance().waitForFetchs(arguments[arguments.length - 1]);');\n await browser.waitForAngular();\n }\n}\n\n/**\n * This function initiliaze the FetchManager. Set `window.fetch` variable with a custom behaviour in order to count the\n * fetch calls.\n */\nexport async function initFetchManager() {\n const fetchManager = fs.readFileSync(\n path.resolve(\n process.cwd(), 'node_modules', '@o3r', 'testing', 'tools', 'protractor', 'fetch-manager',\n '_fetch-manager.js'),\n {encoding: 'utf-8'});\n await browser.executeScript(fetchManager);\n await browser.executeScript('window.fetchManager.getInstance().init();');\n}\n\n/**\n * This function stops the FetchManager. Reset `window.fetch` variable with its native behaviour.\n */\nexport async function stopFetchManager() {\n await browser.executeScript('window.fetchManager.getInstance().stop();');\n}\n"]}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Note: This file is not part of the running script, it is injected in the browser while running e2e tests.
3
+ */
4
+ export {};
5
+ //# sourceMappingURL=_post-message-interceptor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"_post-message-interceptor.d.ts","sourceRoot":"","sources":["../../../../src/tools/protractor/post-message-interceptor/_post-message-interceptor.ts"],"names":[],"mappings":"AAAA;;GAEG"}
@@ -0,0 +1,157 @@
1
+ "use strict";
2
+ /**
3
+ * Note: This file is not part of the running script, it is injected in the browser while running e2e tests.
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ // TODO: Move to PollyJS when the winter comes
7
+ (function () {
8
+ /**
9
+ * PostMessageInterceptor permits to intercept calls to postMessage.
10
+ */
11
+ var postMessageInterceptor = /** @class */ (function () {
12
+ function PostMessageInterceptor() {
13
+ this.lastCalls = [];
14
+ this.listening = false;
15
+ }
16
+ /**
17
+ * Logs a message in the console
18
+ * @param message
19
+ * @param {...any} args
20
+ */
21
+ PostMessageInterceptor.prototype.log = function (message) {
22
+ var args = [];
23
+ for (var _i = 1; _i < arguments.length; _i++) {
24
+ args[_i - 1] = arguments[_i];
25
+ }
26
+ // eslint-disable-next-line no-console
27
+ console.log.apply(console, __spreadArray(["#postMessageInterceptor: ".concat(message)], args, false));
28
+ };
29
+ /**
30
+ * Intercepts the native postMessage call
31
+ * @param ref Singleton instance of the interceptor
32
+ * @param nativeMethod native postMessage method
33
+ * @param args all the args passed to the postMessage
34
+ */
35
+ PostMessageInterceptor.prototype.interceptor = function (ref, nativeMethod) {
36
+ var args = [];
37
+ for (var _i = 2; _i < arguments.length; _i++) {
38
+ args[_i - 2] = arguments[_i];
39
+ }
40
+ this.log('Intercepted', args);
41
+ var postCall = {
42
+ data: args[0],
43
+ targetOrigin: args[1],
44
+ timestamp: new Date()
45
+ };
46
+ if (ref.listening) {
47
+ if (ref.conditionFn && !ref.conditionFn(postCall)) {
48
+ this.log('Intercepted message does not pass the condition');
49
+ return;
50
+ }
51
+ ref.lastCalls.push(postCall);
52
+ this.log('Last call count', ref.lastCalls.length);
53
+ }
54
+ else {
55
+ this.log('Not listening');
56
+ }
57
+ nativeMethod.apply(void 0, args);
58
+ };
59
+ /**
60
+ * Register the interceptor in the window object
61
+ */
62
+ PostMessageInterceptor.prototype.registerFetchInterceptor = function () {
63
+ var _this = this;
64
+ var nativeMethod = window.postMessage;
65
+ this.nativeMethod = nativeMethod;
66
+ Object.assign(window, { postMessage: function () {
67
+ var args = [];
68
+ for (var _i = 0; _i < arguments.length; _i++) {
69
+ args[_i] = arguments[_i];
70
+ }
71
+ return _this.interceptor.apply(_this, __spreadArray([_this, nativeMethod], args, false));
72
+ } });
73
+ };
74
+ /**
75
+ * Unregister the interceptor from the window object
76
+ */
77
+ PostMessageInterceptor.prototype.unregisterFetchInterceptor = function () {
78
+ Object.assign(window, { postMessage: this.nativeMethod });
79
+ };
80
+ /**
81
+ * Returns the singleton instance of the interceptor
82
+ */
83
+ PostMessageInterceptor.getInstance = function () {
84
+ return this._instance || (this._instance = new this());
85
+ };
86
+ /**
87
+ * Initialize the interceptor
88
+ */
89
+ PostMessageInterceptor.prototype.init = function () {
90
+ this.reset();
91
+ this.log('Init');
92
+ this.registerFetchInterceptor();
93
+ };
94
+ /**
95
+ * Stops the interceptor
96
+ */
97
+ PostMessageInterceptor.prototype.stop = function () {
98
+ this.reset();
99
+ this.log('Stop');
100
+ this.unregisterFetchInterceptor();
101
+ };
102
+ /**
103
+ * Resets the stack of lastCalls
104
+ */
105
+ PostMessageInterceptor.prototype.reset = function () {
106
+ this.lastCalls = [];
107
+ };
108
+ /**
109
+ * Starts listening and saving postMessages
110
+ * @param conditionFnString The function string to be used as condition checker
111
+ */
112
+ PostMessageInterceptor.prototype.listen = function (conditionFnString) {
113
+ this.listening = false;
114
+ this.reset();
115
+ if (conditionFnString) {
116
+ // eslint-disable-next-line no-eval
117
+ this.conditionFn = eval(conditionFnString);
118
+ }
119
+ this.listening = true;
120
+ };
121
+ /**
122
+ * Stops listening
123
+ * NOTE: It resets the interceptor and clears the conditionFn (if any)
124
+ */
125
+ PostMessageInterceptor.prototype.stopListening = function () {
126
+ this.listening = false;
127
+ this.reset();
128
+ this.conditionFn = undefined;
129
+ this.listening = true;
130
+ };
131
+ /**
132
+ * Get the messages stack
133
+ * @param timeoutInterval the interval, in ms, between each check
134
+ * @param retries number of tentatives if fail
135
+ * @param callback
136
+ */
137
+ PostMessageInterceptor.prototype.getMessages = function (timeoutInterval, retries, callback) {
138
+ var _this = this;
139
+ var activeMessageWatch = function (remainingRetries) {
140
+ if (remainingRetries === 0 || _this.lastCalls.length > 0) {
141
+ var copyCalls = _this.lastCalls.slice();
142
+ _this.reset();
143
+ callback(copyCalls);
144
+ return;
145
+ }
146
+ else if (remainingRetries > 0) {
147
+ remainingRetries--;
148
+ }
149
+ setTimeout(function () { return activeMessageWatch(remainingRetries); }, timeoutInterval);
150
+ };
151
+ activeMessageWatch(retries);
152
+ };
153
+ return PostMessageInterceptor;
154
+ }());
155
+ Object.assign(window, { postMessageInterceptor: postMessageInterceptor });
156
+ })();
157
+ //# sourceMappingURL=_post-message-interceptor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"_post-message-interceptor.js","sourceRoot":"","sources":["../../../../src/tools/protractor/post-message-interceptor/_post-message-interceptor.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.toggleVisualTestingRender = exports.isVisualTestingEnabled = exports.prepareVisualTesting = void 0;
3
+ exports.prepareVisualTesting = prepareVisualTesting;
4
+ exports.isVisualTestingEnabled = isVisualTestingEnabled;
5
+ exports.toggleVisualTestingRender = toggleVisualTestingRender;
4
6
  /**
5
7
  * Prepare css rule to hide specific blocks
6
8
  *
@@ -15,7 +17,6 @@ function prepareVisualTesting(ignoreClass) {
15
17
  visualTestingCss.textContent = "\n .".concat(visualTestingClass, " .").concat(ignoreClass, " {position: relative;}\n\n .").concat(visualTestingClass, " .").concat(ignoreClass, ":before {\n z-index: 999;\n content: '';\n width: 100%;\n height: 100%;\n background: grey;\n position: absolute;\n left: 0;\n top: 0;\n }");
16
18
  document.head.appendChild(visualTestingCss);
17
19
  }
18
- exports.prepareVisualTesting = prepareVisualTesting;
19
20
  /**
20
21
  * Determine if the visual testing is enabled
21
22
  */
@@ -23,7 +24,6 @@ function isVisualTestingEnabled() {
23
24
  var visualTestingClass = 'visual-testing-render';
24
25
  return document.body.classList.contains(visualTestingClass);
25
26
  }
26
- exports.isVisualTestingEnabled = isVisualTestingEnabled;
27
27
  /**
28
28
  * Toggle the visual testing view : if it is active, will hide tagged components as grey blocks.
29
29
  * @note: this function is evaluated in the context of the page and cannot use external code
@@ -38,5 +38,4 @@ function toggleVisualTestingRender(enabled) {
38
38
  document.body.classList.remove(visualTestingClass);
39
39
  }
40
40
  }
41
- exports.toggleVisualTestingRender = toggleVisualTestingRender;
42
41
  //# sourceMappingURL=utils.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/visual-test/utils.ts"],"names":[],"mappings":";;;AAAA;;;;;;GAMG;AACH,SAAgB,oBAAoB,CAAC,WAA0B;IAA1B,4BAAA,EAAA,0BAA0B;IAC7D,IAAM,gBAAgB,GAAG,QAAQ,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;IACzD,IAAM,kBAAkB,GAAG,uBAAuB,CAAC;IACnD,gBAAgB,CAAC,WAAW,GAAG,iBAC1B,kBAAkB,eAAK,WAAW,4CAElC,kBAAkB,eAAK,WAAW,wLASrC,CAAC;IAEH,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,gBAAgB,CAAC,CAAC;AAC9C,CAAC;AAlBD,oDAkBC;AAED;;GAEG;AACH,SAAgB,sBAAsB;IACpC,IAAM,kBAAkB,GAAG,uBAAuB,CAAC;IACnD,OAAO,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,kBAAkB,CAAC,CAAC;AAC9D,CAAC;AAHD,wDAGC;AAED;;;;GAIG;AACH,SAAgB,yBAAyB,CAAC,OAAgB;IACxD,IAAM,kBAAkB,GAAG,uBAAuB,CAAC;IACnD,IAAI,OAAO,EAAE,CAAC;QACZ,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC;IAClD,CAAC;SAAM,CAAC;QACN,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,kBAAkB,CAAC,CAAC;IACrD,CAAC;AACH,CAAC;AAPD,8DAOC","sourcesContent":["/**\n * Prepare css rule to hide specific blocks\n *\n * Should be called only once during the visual test.\n * @note: this function is evaluated in the context of the page and should not use external variables\n * @param ignoreClass\n */\nexport function prepareVisualTesting(ignoreClass = 'e2e-ignore') {\n const visualTestingCss = document.createElement('style');\n const visualTestingClass = 'visual-testing-render';\n visualTestingCss.textContent = `\n .${visualTestingClass} .${ignoreClass} {position: relative;}\n\n .${visualTestingClass} .${ignoreClass}:before {\n z-index: 999;\n content: '';\n width: 100%;\n height: 100%;\n background: grey;\n position: absolute;\n left: 0;\n top: 0;\n }`;\n\n document.head.appendChild(visualTestingCss);\n}\n\n/**\n * Determine if the visual testing is enabled\n */\nexport function isVisualTestingEnabled() {\n const visualTestingClass = 'visual-testing-render';\n return document.body.classList.contains(visualTestingClass);\n}\n\n/**\n * Toggle the visual testing view : if it is active, will hide tagged components as grey blocks.\n * @note: this function is evaluated in the context of the page and cannot use external code\n * @param enabled\n */\nexport function toggleVisualTestingRender(enabled: boolean) {\n const visualTestingClass = 'visual-testing-render';\n if (enabled) {\n document.body.classList.add(visualTestingClass);\n } else {\n document.body.classList.remove(visualTestingClass);\n }\n}\n"]}
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/visual-test/utils.ts"],"names":[],"mappings":";;AAOA,oDAkBC;AAKD,wDAGC;AAOD,8DAOC;AA/CD;;;;;;GAMG;AACH,SAAgB,oBAAoB,CAAC,WAA0B;IAA1B,4BAAA,EAAA,0BAA0B;IAC7D,IAAM,gBAAgB,GAAG,QAAQ,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;IACzD,IAAM,kBAAkB,GAAG,uBAAuB,CAAC;IACnD,gBAAgB,CAAC,WAAW,GAAG,iBAC1B,kBAAkB,eAAK,WAAW,4CAElC,kBAAkB,eAAK,WAAW,wLASrC,CAAC;IAEH,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,gBAAgB,CAAC,CAAC;AAC9C,CAAC;AAED;;GAEG;AACH,SAAgB,sBAAsB;IACpC,IAAM,kBAAkB,GAAG,uBAAuB,CAAC;IACnD,OAAO,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,kBAAkB,CAAC,CAAC;AAC9D,CAAC;AAED;;;;GAIG;AACH,SAAgB,yBAAyB,CAAC,OAAgB;IACxD,IAAM,kBAAkB,GAAG,uBAAuB,CAAC;IACnD,IAAI,OAAO,EAAE,CAAC;QACZ,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC;IAClD,CAAC;SAAM,CAAC;QACN,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,kBAAkB,CAAC,CAAC;IACrD,CAAC;AACH,CAAC","sourcesContent":["/**\n * Prepare css rule to hide specific blocks\n *\n * Should be called only once during the visual test.\n * @note: this function is evaluated in the context of the page and should not use external variables\n * @param ignoreClass\n */\nexport function prepareVisualTesting(ignoreClass = 'e2e-ignore') {\n const visualTestingCss = document.createElement('style');\n const visualTestingClass = 'visual-testing-render';\n visualTestingCss.textContent = `\n .${visualTestingClass} .${ignoreClass} {position: relative;}\n\n .${visualTestingClass} .${ignoreClass}:before {\n z-index: 999;\n content: '';\n width: 100%;\n height: 100%;\n background: grey;\n position: absolute;\n left: 0;\n top: 0;\n }`;\n\n document.head.appendChild(visualTestingCss);\n}\n\n/**\n * Determine if the visual testing is enabled\n */\nexport function isVisualTestingEnabled() {\n const visualTestingClass = 'visual-testing-render';\n return document.body.classList.contains(visualTestingClass);\n}\n\n/**\n * Toggle the visual testing view : if it is active, will hide tagged components as grey blocks.\n * @note: this function is evaluated in the context of the page and cannot use external code\n * @param enabled\n */\nexport function toggleVisualTestingRender(enabled: boolean) {\n const visualTestingClass = 'visual-testing-render';\n if (enabled) {\n document.body.classList.add(visualTestingClass);\n } else {\n document.body.classList.remove(visualTestingClass);\n }\n}\n"]}
@@ -1,6 +1,11 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.o3rVisualTest = exports.compareScreenshot = exports.writeScreenshotsDiff = exports.saveScreenshot = exports.toBeVisuallySimilar = exports.visualTestMessages = exports.toggleVisualTestingRender = exports.prepareVisualTesting = void 0;
3
+ exports.visualTestMessages = exports.toggleVisualTestingRender = exports.prepareVisualTesting = void 0;
4
+ exports.toBeVisuallySimilar = toBeVisuallySimilar;
5
+ exports.saveScreenshot = saveScreenshot;
6
+ exports.writeScreenshotsDiff = writeScreenshotsDiff;
7
+ exports.compareScreenshot = compareScreenshot;
8
+ exports.o3rVisualTest = o3rVisualTest;
4
9
  var fs = require("node:fs");
5
10
  var path = require("node:path");
6
11
  var pngjs_1 = require("pngjs");
@@ -54,7 +59,6 @@ function toBeVisuallySimilar() {
54
59
  }
55
60
  };
56
61
  }
57
- exports.toBeVisuallySimilar = toBeVisuallySimilar;
58
62
  /**
59
63
  * It will create a file for the passed screenshot object.
60
64
  * The path of the new file will be calculated using the parameters
@@ -77,7 +81,6 @@ function saveScreenshot(screenshot, scenarioName, device, filenameWithoutExtensi
77
81
  stream.write(Buffer.from(screenshot, 'base64'));
78
82
  stream.end();
79
83
  }
80
- exports.saveScreenshot = saveScreenshot;
81
84
  /**
82
85
  * Write the 3 images (base/new/diff) on the reports folder
83
86
  * The path inside the reports forlder will be calculated using the parameters
@@ -99,7 +102,6 @@ function writeScreenshotsDiff(pathToScenarioReport, screenshotsDirName, diff, ba
99
102
  fs.writeFileSync(oldPath, pngjs_1.PNG.sync.write(baseImage));
100
103
  fs.writeFileSync(newPath, pngjs_1.PNG.sync.write(currentImg));
101
104
  }
102
- exports.writeScreenshotsDiff = writeScreenshotsDiff;
103
105
  /**
104
106
  * Compare images helper function. If the comparison fails the 3 images (base/new/diff) will be written inside the reports folder of the actual scenario
105
107
  * @param screenshot Actual captured screenshot object
@@ -138,7 +140,6 @@ function compareScreenshot(screenshot, baseImagePath, threshold, pathToScenarioR
138
140
  return { diff: { actualDiff: pr, threshold: threshold, screenshotName: diffDirName } };
139
141
  }
140
142
  }
141
- exports.compareScreenshot = compareScreenshot;
142
143
  /**
143
144
  * Helper function to perform a visual test operation
144
145
  * @param screenshotObj Ex: for protractor browser.takeScreenshot()
@@ -166,5 +167,4 @@ function o3rVisualTest(screenshotObj, filenameWithoutExtension, device, scenario
166
167
  return visualTestResult;
167
168
  }
168
169
  }
169
- exports.o3rVisualTest = o3rVisualTest;
170
170
  //# sourceMappingURL=visual-test.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"visual-test.js","sourceRoot":"","sources":["../../src/visual-test/visual-test.ts"],"names":[],"mappings":";;;AAAA,4BAA8B;AAC9B,gCAAkC;AAClC,+BAA0B;AAC1B,uCAAyC;AAEzC,iCAGiB;AAFf,6GAAA,oBAAoB,OAAA;AACpB,kHAAA,yBAAyB,OAAA;AAiB3B,uDAAuD;AAC1C,QAAA,kBAAkB,GAAsB;IACnD,UAAU,EAAE,+BAA+B;IAC3C,WAAW,EAAE,oDAAoD;IACjE,eAAe,EAAE,iCAAiC;IAClD,OAAO,EAAE,wBAAwB;IACjC,YAAY,EAAE,iCAAiC;CAChD,CAAC;AAgBF;;;GAGG;AACH,SAAgB,mBAAmB;IACjC,OAAO;QACL,OAAO,EAAE,UAAC,MAAwB,EAAE,SAA2B;YAC7D,IAAI,MAAM,CAAC,YAAY,EAAE,CAAC;gBACxB,OAAO;oBACL,IAAI,EAAE,IAAI;oBACV,OAAO,EAAE,0BAAkB,CAAC,YAAY;iBACzC,CAAC;YACJ,CAAC;YACD,IAAI,MAAM,CAAC,sBAAsB,EAAE,CAAC;gBAClC,OAAO;oBACL,IAAI,EAAE,KAAK;oBACX,OAAO,EAAE,UAAG,0BAAkB,CAAC,eAAe,cAAI,MAAM,CAAC,sBAAsB,CAAC,kBAAkB,CAAE;iBAAC,CAAC;YAC1G,CAAC;YACD,IAAI,MAAM,CAAC,UAAU,EAAE,CAAC;gBACtB,OAAO;oBACL,IAAI,EAAE,KAAK;oBACX,OAAO,EAAE,UAAG,0BAAkB,CAAC,UAAU,cAAI,MAAM,CAAC,UAAU,CAAC,cAAc,CAAE;iBAChF,CAAC;YACJ,CAAC;YACD,IAAI,MAAM,CAAC,IAAI,IAAI,MAAM,CAAC,IAAI,CAAC,UAAU,GAAG,MAAM,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC;gBAClE,OAAO;oBACL,IAAI,EAAE,KAAK;oBACX,OAAO,EAAE,UAAG,MAAM,CAAC,IAAI,CAAC,UAAU,gBAAM,MAAM,CAAC,IAAI,CAAC,SAAS,gBAAM,0BAAkB,CAAC,WAAW,cAAI,MAAM,CAAC,IAAI,CAAC,cAAc,CAAE;iBAClI,CAAC;YACJ,CAAC;YACD,OAAO;gBACL,IAAI,EAAE,IAAI;gBACV,OAAO,EAAE,0BAAkB,CAAC,OAAO;aACpC,CAAC;QACJ,CAAC;KACF,CAAC;AACJ,CAAC;AAhCD,kDAgCC;AAED;;;;;;;;;;GAUG;AACH,SAAgB,cAAc,CAAC,UAAkB,EAAE,YAAoB,EAAE,MAAc,EAAE,wBAAgC,EAAE,kBAAuC;IAAvC,mCAAA,EAAA,uCAAuC;IAChK,IAAM,cAAc,GAAG,IAAI,CAAC,OAAO,CAAC,kBAAkB,EAAE,YAAY,EAAE,UAAG,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAE,CAAC,CAAC;IACvG,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,cAAc,CAAC,EAAE,CAAC;QACnC,EAAE,CAAC,SAAS,CAAC,cAAc,EAAE,EAAC,SAAS,EAAE,IAAI,EAAC,CAAC,CAAC;IAClD,CAAC;IACD,IAAM,YAAY,GAAG,UAAG,wBAAwB,SAAM,CAAC;IACvD,IAAM,MAAM,GAAG,EAAE,CAAC,iBAAiB,CAAC,IAAI,CAAC,OAAO,CAAC,cAAc,EAAE,YAAY,CAAC,CAAC,CAAC;IAChF,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC,CAAC;IAChD,MAAM,CAAC,GAAG,EAAE,CAAC;AACf,CAAC;AATD,wCASC;AAED;;;;;;;;GAQG;AACH,SAAgB,oBAAoB,CAAC,oBAA4B,EAAE,kBAA0B,EAAE,IAAS,EAAE,SAAc,EAAE,UAAe;IACvI,IAAM,sBAAsB,GAAG,IAAI,CAAC,IAAI,CAAC,oBAAoB,EAAE,kBAAkB,EAAE,kBAAkB,CAAC,CAAC;IACvG,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,sBAAsB,CAAC,EAAE,CAAC;QAC3C,EAAE,CAAC,SAAS,CAAC,sBAAsB,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC5D,CAAC;IAED,IAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,sBAAsB,EAAE,UAAU,CAAC,CAAC;IAClE,IAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,sBAAsB,EAAE,SAAS,CAAC,CAAC;IAChE,IAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,sBAAsB,EAAE,SAAS,CAAC,CAAC;IAChE,EAAE,CAAC,aAAa,CAAC,QAAQ,EAAE,WAAG,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC;IACjD,EAAE,CAAC,aAAa,CAAC,OAAO,EAAE,WAAG,CAAC,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC;IACrD,EAAE,CAAC,aAAa,CAAC,OAAO,EAAE,WAAG,CAAC,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC;AACxD,CAAC;AAZD,oDAYC;AAED;;;;;;;GAOG;AACH,SAAgB,iBAAiB,CAAC,UAAkB,EAAE,aAAqB,EAAE,SAAiB,EAAE,oBAA4B;IAC1H,IAAM,eAAe,GAAG,EAAE,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC;IACrD,IAAI,CAAC,eAAe,EAAE,CAAC;QACrB,OAAO,EAAC,sBAAsB,EAAE,EAAC,kBAAkB,EAAE,aAAa,EAAC,EAAC,CAAC;IACvE,CAAC;SACI,CAAC;QACJ,IAAM,SAAS,GAAG,WAAG,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,YAAY,CAAC,aAAa,CAAC,CAAC,CAAC;QACzD,IAAA,KAAK,GAAY,SAAS,MAArB,EAAE,MAAM,GAAI,SAAS,OAAb,CAAc;QAClC,IAAM,IAAI,GAAG,IAAI,WAAG,CAAC,EAAC,KAAK,OAAA,EAAE,MAAM,QAAA,EAAC,CAAC,CAAC;QAEtC,IAAM,gBAAgB,GAAG,MAAM,CAAC,IAAI,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;QAC3D,IAAM,UAAU,GAAG,WAAG,CAAC,IAAI,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;QACnD,IAAM,WAAW,GAAG,IAAI,CAAC,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC;QACzD,IAAI,MAAM,SAAA,CAAC;QACX,IAAI,CAAC;YACH,MAAM,GAAG,UAAU,CAAC,SAAS,CAAC,IAAI,EAAE,UAAU,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,EAAC,SAAS,EAAE,GAAG,EAAC,CAAC,CAAC;QACnG,CAAC;QAAC,OAAO,GAAQ,EAAE,CAAC;YAClB,IAAI,GAAG,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,2BAA2B,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC;gBAC/D,MAAM,GAAG,CAAC;YACZ,CAAC;YACD,oBAAoB,CAAC,oBAAoB,EAAE,WAAW,EAAE,IAAI,EAAE,SAAS,EAAE,UAAU,CAAC,CAAC;YACrF,OAAO,EAAC,UAAU,EAAE,EAAC,cAAc,EAAE,WAAW,EAAC,EAAC,CAAC;QACrD,CAAC;QACD,IAAM,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,GAAG,GAAG,GAAG,MAAM,GAAG,CAAC,KAAK,GAAG,MAAM,CAAC,CAAC,GAAG,GAAG,CAAC;QACnE,IAAI,EAAE,GAAG,SAAS,EAAE,CAAC;YACnB,oBAAoB,CAAC,oBAAoB,EAAE,WAAW,EAAE,IAAI,EAAE,SAAS,EAAE,UAAU,CAAC,CAAC;QACvF,CAAC;QACD,OAAO,EAAC,IAAI,EAAE,EAAC,UAAU,EAAE,EAAE,EAAE,SAAS,WAAA,EAAE,cAAc,EAAE,WAAW,EAAC,EAAC,CAAC;IAC1E,CAAC;AACH,CAAC;AA7BD,8CA6BC;AAED;;;;;;;;;;;GAWG;AACH,SAAgB,aAAa,CAC3B,aAAqB,EACrB,wBAAgC,EAChC,MAAc,EACd,YAAoB,EACpB,oBAAgC,EAChC,SAAa,EACb,YAAoB,EACpB,sBAAgD;IAHhD,qCAAA,EAAA,gCAAgC;IAChC,0BAAA,EAAA,aAAa;IACb,6BAAA,EAAA,oBAAoB;IACpB,uCAAA,EAAA,gDAAgD;IAEhD,IAAI,YAAY,EAAE,CAAC;QACjB,cAAc,CAAC,aAAa,EAAE,YAAY,EAAE,MAAM,EAAE,wBAAwB,CAAC,CAAC;QAC9E,OAAO,EAAC,YAAY,EAAE,IAAI,EAAC,CAAC;IAC9B,CAAC;SAAM,CAAC;QACN,IAAM,aAAa,GAAG,IAAI,CAAC,OAAO,CAAC,sBAAsB,EAAE,YAAY,EAAE,MAAM,EAAE,UAAG,wBAAwB,SAAM,CAAC,CAAC;QACpH,IAAM,gBAAgB,GAAG,iBAAiB,CAAC,aAAa,EAAE,aAAa,EAAE,SAAS,EAAE,oBAAoB,CAAC,CAAC;QAC1G,OAAO,gBAAgB,CAAC;IAC1B,CAAC;AACH,CAAC;AAlBD,sCAkBC","sourcesContent":["import * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport {PNG} from 'pngjs';\nimport * as pixelmatch from 'pixelmatch';\n\nexport {\n prepareVisualTesting,\n toggleVisualTestingRender\n} from './utils';\n\n/** Error types returned by visual testing comparison */\nexport interface VisualTestMessage {\n /** Error message when base image and actual image have different sizes */\n imagesSize: string;\n /** Error message when base screensot not found */\n baseImgNotFound: string;\n /** Error message when the threshold is passed */\n diffMessage: string;\n /** The message in case of success */\n success: string;\n /** The message in case of generate mode run */\n generateMode: string;\n}\n\n/** Error messages in case of visual testing failure */\nexport const visualTestMessages: VisualTestMessage = {\n imagesSize: 'Image sizes do not match for:',\n diffMessage: 'Diff between images is greater than threshold for:',\n baseImgNotFound: 'Base screenshot file not found:',\n success: 'Visual test successful',\n generateMode: 'Run in generate screenshot mode'\n};\n\n/**\n * Object returned by a visual test operation\n */\nexport interface VisualTestResult {\n /** Error object when base image and actual image have different sizes; Contains the screenshot ffile name */\n imagesSize?: {screenshotName: string};\n /** Error object when base screensot not found. Contains the not found path as a string */\n baseScreenshotNotFound?: {baseScreenshotPath: string};\n /** Object containing the actual diff between images as percentage, the threshold and screenshot file name */\n diff?: {actualDiff: number; threshold: number; screenshotName: string};\n /** Run only generation of screenshots */\n generateMode?: boolean;\n}\n\n/**\n * Visual test matcher\n * Based on the VisualTestResult object return by compareScreenshots function, this matcher will compute the error messages\n */\nexport function toBeVisuallySimilar() {\n return {\n compare: (actual: VisualTestResult, _expected: VisualTestResult) => {\n if (actual.generateMode) {\n return {\n pass: true,\n message: visualTestMessages.generateMode\n };\n }\n if (actual.baseScreenshotNotFound) {\n return {\n pass: false,\n message: `${visualTestMessages.baseImgNotFound} ${actual.baseScreenshotNotFound.baseScreenshotPath}`};\n }\n if (actual.imagesSize) {\n return {\n pass: false,\n message: `${visualTestMessages.imagesSize} ${actual.imagesSize.screenshotName}`\n };\n }\n if (actual.diff && actual.diff.actualDiff > actual.diff.threshold) {\n return {\n pass: false,\n message: `${actual.diff.actualDiff} > ${actual.diff.threshold} : ${visualTestMessages.diffMessage} ${actual.diff.screenshotName}`\n };\n }\n return {\n pass: true,\n message: visualTestMessages.success\n };\n }\n };\n}\n\n/**\n * It will create a file for the passed screenshot object.\n * The path of the new file will be calculated using the parameters\n * Ex: ./dist-screenshots\\OWBooking\\windows_chrome_91\\fare-page-after-click-on-continue-0.png\n * distScreenshotsDir/scenarionName/device/filenameWithoutExtension.png\n * @param screenshot The screenshot object captured. Ex: for protractor - browser.takeScreenshot()\n * @param scenarioName E2e Scenario class name\n * @param device Details of the platform on which the test is run. If there are spaces the helper will do the concatenation. Ex: `Windows 10 chrome 89`\n * @param filenameWithoutExtension file name to save the screenshot - .png will be added at the end\n * @param distScreenshotsDir Name of the directory to save the screenshots\n */\nexport function saveScreenshot(screenshot: string, scenarioName: string, device: string, filenameWithoutExtension: string, distScreenshotsDir = 'dist-screenshots') {\n const screenshotsDir = path.resolve(distScreenshotsDir, scenarioName, `${device.replace(/ +/g, '_')}`);\n if (!fs.existsSync(screenshotsDir)) {\n fs.mkdirSync(screenshotsDir, {recursive: true});\n }\n const fullFileName = `${filenameWithoutExtension}.png`;\n const stream = fs.createWriteStream(path.resolve(screenshotsDir, fullFileName));\n stream.write(Buffer.from(screenshot, 'base64'));\n stream.end();\n}\n\n/**\n * Write the 3 images (base/new/diff) on the reports folder\n * The path inside the reports forlder will be calculated using the parameters\n * @param pathToScenarioReport Path where the scenario report is saved inside reports folder\n * @param screenshotsDirName Name of the directory which will contain the 3 images\n * @param diff diff image\n * @param baseImage the base image\n * @param currentImg the actual taken screenshot image\n */\nexport function writeScreenshotsDiff(pathToScenarioReport: string, screenshotsDirName: string, diff: PNG, baseImage: PNG, currentImg: PNG) {\n const destScreenshotsDiffDir = path.join(pathToScenarioReport, 'screenshots-diff', screenshotsDirName);\n if (!fs.existsSync(destScreenshotsDiffDir)) {\n fs.mkdirSync(destScreenshotsDiffDir, { recursive: true });\n }\n\n const diffPath = path.resolve(destScreenshotsDiffDir, 'diff.png');\n const oldPath = path.resolve(destScreenshotsDiffDir, 'old.png');\n const newPath = path.resolve(destScreenshotsDiffDir, 'new.png');\n fs.writeFileSync(diffPath, PNG.sync.write(diff));\n fs.writeFileSync(oldPath, PNG.sync.write(baseImage));\n fs.writeFileSync(newPath, PNG.sync.write(currentImg));\n}\n\n/**\n * Compare images helper function. If the comparison fails the 3 images (base/new/diff) will be written inside the reports folder of the actual scenario\n * @param screenshot Actual captured screenshot object\n * @param baseImagePath The path to the base screenshot\n * @param threshold The diff between base screenshot and the current one should not be bigger than this value.\n * @param pathToScenarioReport Path where the scenario report is saved inside reports folder. Used to compute the path to write diff images in case there is a diff at comparison\n * @returns An object of visual test result type\n */\nexport function compareScreenshot(screenshot: string, baseImagePath: string, threshold: number, pathToScenarioReport: string): VisualTestResult {\n const baseImageExists = fs.existsSync(baseImagePath);\n if (!baseImageExists) {\n return {baseScreenshotNotFound: {baseScreenshotPath: baseImagePath}};\n }\n else {\n const baseImage = PNG.sync.read(fs.readFileSync(baseImagePath));\n const {width, height} = baseImage;\n const diff = new PNG({width, height});\n\n const screenshotBuffer = Buffer.from(screenshot, 'base64');\n const currentImg = PNG.sync.read(screenshotBuffer);\n const diffDirName = path.basename(baseImagePath, '.png');\n let result;\n try {\n result = pixelmatch(baseImage.data, currentImg.data, diff.data, width, height, {threshold: 0.1});\n } catch (err: any) {\n if (err.toString().indexOf('Image sizes do not match.') === -1) {\n throw err;\n }\n writeScreenshotsDiff(pathToScenarioReport, diffDirName, diff, baseImage, currentImg);\n return {imagesSize: {screenshotName: diffDirName}};\n }\n const pr = Math.round(100 * 100 * result / (width * height)) / 100;\n if (pr > threshold) {\n writeScreenshotsDiff(pathToScenarioReport, diffDirName, diff, baseImage, currentImg);\n }\n return {diff: {actualDiff: pr, threshold, screenshotName: diffDirName}};\n }\n}\n\n/**\n * Helper function to perform a visual test operation\n * @param screenshotObj Ex: for protractor browser.takeScreenshot()\n * @param filenameWithoutExtension file name to save the screenshot - .png will be added at the end\n * @param device os followed by browser version - ex: `Windows 10 chrome 89`\n * @param scenarioName E2e Scenario class name\n * @param pathToScenarioReport Path used in compare mode for saving the base,new,diff images in reports in case there is a diff\n * @param threshold The diff between base screenshot and the current one should not be bigger than this value.\n * If the diff is bigger, 3 png files will be created: base screenshot, new screenshot and diff image\n * @param generateMode If true it will generate the screenshot file without screenshots comparison\n * @param baseScreenshotsDirPath The folder path to search base screenshots; used only in compare mode\n */\nexport function o3rVisualTest(\n screenshotObj: string,\n filenameWithoutExtension: string,\n device: string,\n scenarioName: string,\n pathToScenarioReport = 'reports',\n threshold = 0,\n generateMode = false,\n baseScreenshotsDirPath = 'dist-screenshots-base'\n) {\n if (generateMode) {\n saveScreenshot(screenshotObj, scenarioName, device, filenameWithoutExtension);\n return {generateMode: true};\n } else {\n const baseImagePath = path.resolve(baseScreenshotsDirPath, scenarioName, device, `${filenameWithoutExtension}.png`);\n const visualTestResult = compareScreenshot(screenshotObj, baseImagePath, threshold, pathToScenarioReport);\n return visualTestResult;\n }\n}\n"]}
1
+ {"version":3,"file":"visual-test.js","sourceRoot":"","sources":["../../src/visual-test/visual-test.ts"],"names":[],"mappings":"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","sourcesContent":["import * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport {PNG} from 'pngjs';\nimport * as pixelmatch from 'pixelmatch';\n\nexport {\n prepareVisualTesting,\n toggleVisualTestingRender\n} from './utils';\n\n/** Error types returned by visual testing comparison */\nexport interface VisualTestMessage {\n /** Error message when base image and actual image have different sizes */\n imagesSize: string;\n /** Error message when base screensot not found */\n baseImgNotFound: string;\n /** Error message when the threshold is passed */\n diffMessage: string;\n /** The message in case of success */\n success: string;\n /** The message in case of generate mode run */\n generateMode: string;\n}\n\n/** Error messages in case of visual testing failure */\nexport const visualTestMessages: VisualTestMessage = {\n imagesSize: 'Image sizes do not match for:',\n diffMessage: 'Diff between images is greater than threshold for:',\n baseImgNotFound: 'Base screenshot file not found:',\n success: 'Visual test successful',\n generateMode: 'Run in generate screenshot mode'\n};\n\n/**\n * Object returned by a visual test operation\n */\nexport interface VisualTestResult {\n /** Error object when base image and actual image have different sizes; Contains the screenshot ffile name */\n imagesSize?: {screenshotName: string};\n /** Error object when base screensot not found. Contains the not found path as a string */\n baseScreenshotNotFound?: {baseScreenshotPath: string};\n /** Object containing the actual diff between images as percentage, the threshold and screenshot file name */\n diff?: {actualDiff: number; threshold: number; screenshotName: string};\n /** Run only generation of screenshots */\n generateMode?: boolean;\n}\n\n/**\n * Visual test matcher\n * Based on the VisualTestResult object return by compareScreenshots function, this matcher will compute the error messages\n */\nexport function toBeVisuallySimilar() {\n return {\n compare: (actual: VisualTestResult, _expected: VisualTestResult) => {\n if (actual.generateMode) {\n return {\n pass: true,\n message: visualTestMessages.generateMode\n };\n }\n if (actual.baseScreenshotNotFound) {\n return {\n pass: false,\n message: `${visualTestMessages.baseImgNotFound} ${actual.baseScreenshotNotFound.baseScreenshotPath}`};\n }\n if (actual.imagesSize) {\n return {\n pass: false,\n message: `${visualTestMessages.imagesSize} ${actual.imagesSize.screenshotName}`\n };\n }\n if (actual.diff && actual.diff.actualDiff > actual.diff.threshold) {\n return {\n pass: false,\n message: `${actual.diff.actualDiff} > ${actual.diff.threshold} : ${visualTestMessages.diffMessage} ${actual.diff.screenshotName}`\n };\n }\n return {\n pass: true,\n message: visualTestMessages.success\n };\n }\n };\n}\n\n/**\n * It will create a file for the passed screenshot object.\n * The path of the new file will be calculated using the parameters\n * Ex: ./dist-screenshots\\OWBooking\\windows_chrome_91\\fare-page-after-click-on-continue-0.png\n * distScreenshotsDir/scenarionName/device/filenameWithoutExtension.png\n * @param screenshot The screenshot object captured. Ex: for protractor - browser.takeScreenshot()\n * @param scenarioName E2e Scenario class name\n * @param device Details of the platform on which the test is run. If there are spaces the helper will do the concatenation. Ex: `Windows 10 chrome 89`\n * @param filenameWithoutExtension file name to save the screenshot - .png will be added at the end\n * @param distScreenshotsDir Name of the directory to save the screenshots\n */\nexport function saveScreenshot(screenshot: string, scenarioName: string, device: string, filenameWithoutExtension: string, distScreenshotsDir = 'dist-screenshots') {\n const screenshotsDir = path.resolve(distScreenshotsDir, scenarioName, `${device.replace(/ +/g, '_')}`);\n if (!fs.existsSync(screenshotsDir)) {\n fs.mkdirSync(screenshotsDir, {recursive: true});\n }\n const fullFileName = `${filenameWithoutExtension}.png`;\n const stream = fs.createWriteStream(path.resolve(screenshotsDir, fullFileName));\n stream.write(Buffer.from(screenshot, 'base64'));\n stream.end();\n}\n\n/**\n * Write the 3 images (base/new/diff) on the reports folder\n * The path inside the reports forlder will be calculated using the parameters\n * @param pathToScenarioReport Path where the scenario report is saved inside reports folder\n * @param screenshotsDirName Name of the directory which will contain the 3 images\n * @param diff diff image\n * @param baseImage the base image\n * @param currentImg the actual taken screenshot image\n */\nexport function writeScreenshotsDiff(pathToScenarioReport: string, screenshotsDirName: string, diff: PNG, baseImage: PNG, currentImg: PNG) {\n const destScreenshotsDiffDir = path.join(pathToScenarioReport, 'screenshots-diff', screenshotsDirName);\n if (!fs.existsSync(destScreenshotsDiffDir)) {\n fs.mkdirSync(destScreenshotsDiffDir, { recursive: true });\n }\n\n const diffPath = path.resolve(destScreenshotsDiffDir, 'diff.png');\n const oldPath = path.resolve(destScreenshotsDiffDir, 'old.png');\n const newPath = path.resolve(destScreenshotsDiffDir, 'new.png');\n fs.writeFileSync(diffPath, PNG.sync.write(diff));\n fs.writeFileSync(oldPath, PNG.sync.write(baseImage));\n fs.writeFileSync(newPath, PNG.sync.write(currentImg));\n}\n\n/**\n * Compare images helper function. If the comparison fails the 3 images (base/new/diff) will be written inside the reports folder of the actual scenario\n * @param screenshot Actual captured screenshot object\n * @param baseImagePath The path to the base screenshot\n * @param threshold The diff between base screenshot and the current one should not be bigger than this value.\n * @param pathToScenarioReport Path where the scenario report is saved inside reports folder. Used to compute the path to write diff images in case there is a diff at comparison\n * @returns An object of visual test result type\n */\nexport function compareScreenshot(screenshot: string, baseImagePath: string, threshold: number, pathToScenarioReport: string): VisualTestResult {\n const baseImageExists = fs.existsSync(baseImagePath);\n if (!baseImageExists) {\n return {baseScreenshotNotFound: {baseScreenshotPath: baseImagePath}};\n }\n else {\n const baseImage = PNG.sync.read(fs.readFileSync(baseImagePath));\n const {width, height} = baseImage;\n const diff = new PNG({width, height});\n\n const screenshotBuffer = Buffer.from(screenshot, 'base64');\n const currentImg = PNG.sync.read(screenshotBuffer);\n const diffDirName = path.basename(baseImagePath, '.png');\n let result;\n try {\n result = pixelmatch(baseImage.data, currentImg.data, diff.data, width, height, {threshold: 0.1});\n } catch (err: any) {\n if (err.toString().indexOf('Image sizes do not match.') === -1) {\n throw err;\n }\n writeScreenshotsDiff(pathToScenarioReport, diffDirName, diff, baseImage, currentImg);\n return {imagesSize: {screenshotName: diffDirName}};\n }\n const pr = Math.round(100 * 100 * result / (width * height)) / 100;\n if (pr > threshold) {\n writeScreenshotsDiff(pathToScenarioReport, diffDirName, diff, baseImage, currentImg);\n }\n return {diff: {actualDiff: pr, threshold, screenshotName: diffDirName}};\n }\n}\n\n/**\n * Helper function to perform a visual test operation\n * @param screenshotObj Ex: for protractor browser.takeScreenshot()\n * @param filenameWithoutExtension file name to save the screenshot - .png will be added at the end\n * @param device os followed by browser version - ex: `Windows 10 chrome 89`\n * @param scenarioName E2e Scenario class name\n * @param pathToScenarioReport Path used in compare mode for saving the base,new,diff images in reports in case there is a diff\n * @param threshold The diff between base screenshot and the current one should not be bigger than this value.\n * If the diff is bigger, 3 png files will be created: base screenshot, new screenshot and diff image\n * @param generateMode If true it will generate the screenshot file without screenshots comparison\n * @param baseScreenshotsDirPath The folder path to search base screenshots; used only in compare mode\n */\nexport function o3rVisualTest(\n screenshotObj: string,\n filenameWithoutExtension: string,\n device: string,\n scenarioName: string,\n pathToScenarioReport = 'reports',\n threshold = 0,\n generateMode = false,\n baseScreenshotsDirPath = 'dist-screenshots-base'\n) {\n if (generateMode) {\n saveScreenshot(screenshotObj, scenarioName, device, filenameWithoutExtension);\n return {generateMode: true};\n } else {\n const baseImagePath = path.resolve(baseScreenshotsDirPath, scenarioName, device, `${filenameWithoutExtension}.png`);\n const visualTestResult = compareScreenshot(screenshotObj, baseImagePath, threshold, pathToScenarioReport);\n return visualTestResult;\n }\n}\n"]}