@luigi-project/testing-utilities 1.24.1-dev.20220992341 → 1.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.
package/index.d.ts CHANGED
@@ -1 +1,2 @@
1
- export { LuigiMockUtil } from './luigi-mock-util';
1
+ export { LuigiMockUtil } from './luigi-mock-util.js';
2
+ export { LuigiMockEngine } from './luigi-mock-engine.js';
package/index.js CHANGED
@@ -1,6 +1,2 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.LuigiMockUtil = void 0;
4
- var luigi_mock_util_1 = require("./luigi-mock-util");
5
- Object.defineProperty(exports, "LuigiMockUtil", { enumerable: true, get: function () { return luigi_mock_util_1.LuigiMockUtil; } });
6
- //# sourceMappingURL=index.js.map
1
+ export { LuigiMockUtil } from './luigi-mock-util.js';
2
+ export { LuigiMockEngine } from './luigi-mock-engine.js';
@@ -0,0 +1,4 @@
1
+ export declare class LuigiMockEngine {
2
+ static initPostMessageHook(): () => Promise<void>;
3
+ static visualize(data: string): void;
4
+ }
@@ -0,0 +1,152 @@
1
+ /*
2
+ * This class mocks Luigi Core related functionality.
3
+ *
4
+ * Micro Frontends that use Luigi Client would usually communicate with Luigi Core
5
+ * back and forth. When testing Luigi Client based components, Luigi Core might
6
+ * not be present which leads into limitations on integration/e2e testing for standalone
7
+ * microfrontends.
8
+ *
9
+ * This module adds a hook to the window postMessage API by adding an event listener to the
10
+ * global message event of the window object and mocking the callback.
11
+ * In the normal workflow this message would picked up by Luigi Core which then sends the response back.
12
+ */
13
+ export class LuigiMockEngine {
14
+ // Add a hook to the post message api to mock the LuigiCore response to the Client
15
+ static initPostMessageHook() {
16
+ return async () => {
17
+ // Check if Luigi Client is running standalone
18
+ if (window.parent === window) {
19
+ console.debug('Detected standalone mode');
20
+ // Check and skip if Luigi environment is already mocked
21
+ if (window.luigiMockEnvironment) {
22
+ return;
23
+ }
24
+ // mock target origin
25
+ if (window.LuigiClient) {
26
+ window.LuigiClient.setTargetOrigin('*');
27
+ }
28
+ window.luigiMockEnvironment = {
29
+ msgListener: function (e) {
30
+ if (e.data.msg && (e.data.msg.startsWith('luigi.') || e.data.msg === 'storage')) {
31
+ console.debug('Luigi msg', e.data);
32
+ if (e.data.msg === 'luigi.get-context') {
33
+ window.postMessage({
34
+ msg: 'luigi.init',
35
+ emulated: true,
36
+ internal: {
37
+ viewStackSize: 1
38
+ },
39
+ context: e.data.context
40
+ }, '*');
41
+ }
42
+ // vizualise retrieved event data
43
+ LuigiMockEngine.visualize(JSON.stringify(e.data));
44
+ // Check and run mocked callback if it exists
45
+ const mockListener = window.luigiMockEnvironment.mockListeners[e.data.msg];
46
+ if (mockListener) {
47
+ mockListener(e);
48
+ }
49
+ }
50
+ },
51
+ mockListeners: {
52
+ 'luigi.navigation.pathExists': (event) => {
53
+ const mockData = window.sessionStorage.getItem('luigiMockData');
54
+ let mockDataParsed = mockData ? JSON.parse(mockData) : undefined;
55
+ const inputPath = event.data.data.link;
56
+ const pathExists = mockDataParsed && mockDataParsed.pathExists && mockDataParsed.pathExists[inputPath];
57
+ const response = {
58
+ msg: 'luigi.navigation.pathExists.answer',
59
+ data: {
60
+ correlationId: event.data.data.id,
61
+ pathExists: pathExists ? pathExists : false
62
+ },
63
+ emulated: true
64
+ };
65
+ window.postMessage(response, '*');
66
+ },
67
+ //ux
68
+ 'luigi.ux.confirmationModal.show': (event) => {
69
+ const response = {
70
+ msg: 'luigi.ux.confirmationModal.hide',
71
+ data: event.data,
72
+ emulated: true
73
+ };
74
+ window.postMessage(response, '*');
75
+ },
76
+ 'luigi.ux.alert.show': (event) => {
77
+ const response = {
78
+ msg: 'luigi.ux.alert.hide',
79
+ data: event.data,
80
+ emulated: true
81
+ };
82
+ window.postMessage(response, '*');
83
+ },
84
+ 'luigi.ux.set-current-locale': (event) => {
85
+ const response = {
86
+ msg: 'luigi.current-locale-changed',
87
+ currentLocale: event.data.data.currentLocale,
88
+ emulated: true
89
+ };
90
+ window.postMessage(response, '*');
91
+ },
92
+ // linkManager
93
+ 'luigi.navigation.open': (event) => {
94
+ const response = {
95
+ msg: 'luigi.navigate.ok',
96
+ data: event.data,
97
+ emulated: true
98
+ };
99
+ window.postMessage(response, '*');
100
+ },
101
+ 'luigi.navigation.splitview.close': (event) => {
102
+ const response = {
103
+ msg: 'luigi.navigate.ok',
104
+ data: event.data,
105
+ emulated: true
106
+ };
107
+ window.postMessage(response, '*');
108
+ },
109
+ 'luigi.navigation.splitview.collapse': (event) => {
110
+ const response = {
111
+ msg: 'luigi.navigate.ok',
112
+ data: event.data,
113
+ emulated: true
114
+ };
115
+ window.postMessage(response, '*');
116
+ },
117
+ 'luigi.navigation.splitview.expand': (event) => {
118
+ const response = {
119
+ msg: 'luigi.navigate.ok',
120
+ data: event.data,
121
+ emulated: true
122
+ };
123
+ window.postMessage(response, '*');
124
+ },
125
+ // storage
126
+ storage: () => { }
127
+ }
128
+ };
129
+ // Listen to the global 'message' event of the window object
130
+ window.addEventListener('message', window.luigiMockEnvironment.msgListener);
131
+ }
132
+ };
133
+ }
134
+ /*
135
+ * This method takes a data object of type 'any' and vizualizes a simple container
136
+ * which holds data that is useful for e2e testing.
137
+ */
138
+ static visualize(data) {
139
+ let luigiVisualizationContainer = document.querySelector('#luigi-debug-vis-cnt');
140
+ // Construct element structure if not already constructed
141
+ if (!luigiVisualizationContainer) {
142
+ luigiVisualizationContainer = document.createElement('div');
143
+ luigiVisualizationContainer.setAttribute('id', 'luigi-debug-vis-cnt');
144
+ // Hide the added DOM element to avoid interferring/overlapping with other elements during testing.
145
+ luigiVisualizationContainer.setAttribute('style', 'display:none');
146
+ document.body.appendChild(luigiVisualizationContainer);
147
+ }
148
+ const line = document.createElement('div');
149
+ line.textContent = data;
150
+ luigiVisualizationContainer.appendChild(line);
151
+ }
152
+ }
@@ -1,16 +1,4 @@
1
- "use strict";
2
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
- return new (P || (P = Promise))(function (resolve, reject) {
5
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
- step((generator = generator.apply(thisArg, _arguments || [])).next());
9
- });
10
- };
11
- Object.defineProperty(exports, "__esModule", { value: true });
12
- exports.LuigiMockUtil = void 0;
13
- class LuigiMockUtil {
1
+ export class LuigiMockUtil {
14
2
  constructor(browser) {
15
3
  /**
16
4
  * Mocks the context by sending luigi context messegaes with the desired mocked context as parameter.
@@ -54,25 +42,23 @@ class LuigiMockUtil {
54
42
  /**
55
43
  * Parses the elements added by LuigiMockModule into the DOM and assigns them to the local this.messages variable
56
44
  */
57
- parseLuigiMockedMessages() {
58
- return __awaiter(this, void 0, void 0, function* () {
59
- try {
60
- const textElements = yield this.browser.executeScript(() => Array.from(document.getElementById('luigi-debug-vis-cnt').childNodes).map(item => item.textContent));
61
- this.messages = textElements
62
- .map((item) => {
63
- try {
64
- return JSON.parse(item);
65
- }
66
- catch (error) {
67
- return undefined;
68
- }
69
- })
70
- .filter(item => item !== undefined);
71
- }
72
- catch (e) {
73
- console.debug('Failed to parse luigi mocked messages: ', e);
74
- }
75
- });
45
+ async parseLuigiMockedMessages() {
46
+ try {
47
+ const textElements = await this.browser.executeScript(() => Array.from(document.getElementById('luigi-debug-vis-cnt').childNodes).map(item => item.textContent));
48
+ this.messages = textElements
49
+ .map((item) => {
50
+ try {
51
+ return JSON.parse(item);
52
+ }
53
+ catch (error) {
54
+ return undefined;
55
+ }
56
+ })
57
+ .filter(item => item !== undefined);
58
+ }
59
+ catch (e) {
60
+ console.debug('Failed to parse luigi mocked messages: ', e);
61
+ }
76
62
  }
77
63
  /**
78
64
  * Checks on the printed DOM Luigi message responses for a modal with given title
@@ -100,29 +86,27 @@ class LuigiMockUtil {
100
86
  * }
101
87
  *
102
88
  */
103
- modalOpenedWithTitle(title) {
104
- return __awaiter(this, void 0, void 0, function* () {
105
- // parse messages into a readable array
106
- yield this.parseLuigiMockedMessages();
107
- // traverse the array and find the modal message response
108
- // check if its modal option has the title
109
- const indexFoundModalMessageWTitle = this.messages.findIndex(message => {
110
- const msgExists = message.msg &&
111
- message.msg === 'luigi.navigation.open' &&
112
- message.params &&
113
- message.params.modal &&
114
- message.params.modal.title;
115
- if (msgExists) {
116
- return message.params.modal.title === title;
117
- }
118
- return false;
119
- });
120
- if (indexFoundModalMessageWTitle >= 0) {
121
- return true;
89
+ async modalOpenedWithTitle(title) {
90
+ // parse messages into a readable array
91
+ await this.parseLuigiMockedMessages();
92
+ // traverse the array and find the modal message response
93
+ // check if its modal option has the title
94
+ const indexFoundModalMessageWTitle = this.messages.findIndex(message => {
95
+ const msgExists = message.msg &&
96
+ message.msg === 'luigi.navigation.open' &&
97
+ message.params &&
98
+ message.params.modal &&
99
+ message.params.modal.title;
100
+ if (msgExists) {
101
+ return message.params.modal.title === title;
122
102
  }
123
- console.debug('Could not find modal with title: ', title);
124
103
  return false;
125
104
  });
105
+ if (indexFoundModalMessageWTitle >= 0) {
106
+ return true;
107
+ }
108
+ console.debug('Could not find modal with title: ', title);
109
+ return false;
126
110
  }
127
111
  /**
128
112
  * Return list of messages, representing message elements added in the DOM for testing.
@@ -131,5 +115,3 @@ class LuigiMockUtil {
131
115
  return this.messages;
132
116
  }
133
117
  }
134
- exports.LuigiMockUtil = LuigiMockUtil;
135
- //# sourceMappingURL=luigi-mock-util.js.map
package/package.json CHANGED
@@ -31,5 +31,5 @@
31
31
  "microfrontends",
32
32
  "testing"
33
33
  ],
34
- "version": "1.24.1-dev.20220992341"
35
- }
34
+ "version": "1.25.0"
35
+ }
package/index.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAAA,qDAAkD;AAAzC,gHAAA,aAAa,OAAA"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"luigi-mock-util.js","sourceRoot":"","sources":["../src/luigi-mock-util.ts"],"names":[],"mappings":"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"}