@bleedingdev/modern-js-boundary-debugger 3.9.0-ultramodern.6 → 3.9.0-ultramodern.7
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/package.json
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
"directory": "packages/runtime/boundary-debugger"
|
|
12
12
|
},
|
|
13
13
|
"license": "MIT",
|
|
14
|
-
"version": "3.9.0-ultramodern.
|
|
14
|
+
"version": "3.9.0-ultramodern.7",
|
|
15
15
|
"engines": {
|
|
16
16
|
"node": ">=26.7.0"
|
|
17
17
|
},
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
}
|
|
37
37
|
},
|
|
38
38
|
"dependencies": {
|
|
39
|
-
"@modern-js/plugin": "npm:@bleedingdev/modern-js-plugin@3.9.0-ultramodern.
|
|
39
|
+
"@modern-js/plugin": "npm:@bleedingdev/modern-js-plugin@3.9.0-ultramodern.7"
|
|
40
40
|
},
|
|
41
41
|
"devDependencies": {
|
|
42
42
|
"@rslib/core": "1.0.0",
|
|
@@ -272,11 +272,6 @@ describe('ultramodern boundary debugger browser overlay', () => {
|
|
|
272
272
|
).not.toBeNull();
|
|
273
273
|
});
|
|
274
274
|
|
|
275
|
-
const overlay = document.querySelector(
|
|
276
|
-
'[data-modern-boundary-overlay-label="Checkout"]',
|
|
277
|
-
) as HTMLElement;
|
|
278
|
-
expect(overlay.style.width).toBe('160px');
|
|
279
|
-
|
|
280
275
|
rects.set('late-checkout', new DOMRect(24, 48, 220, 56));
|
|
281
276
|
const boundaryObserver = resizeObservers.find(observer =>
|
|
282
277
|
observer.elements.has(boundary),
|
|
@@ -294,4 +289,41 @@ describe('ultramodern boundary debugger browser overlay', () => {
|
|
|
294
289
|
expect(resizedOverlay?.style.height).toBe('56px');
|
|
295
290
|
});
|
|
296
291
|
});
|
|
292
|
+
test('renders non-intrusive overlays naming the boundary owner and exposed module', async () => {
|
|
293
|
+
let WrappedApp: React.ComponentType | undefined;
|
|
294
|
+
ultramodernBoundaryDebuggerPlugin({
|
|
295
|
+
enabledByDefault: true,
|
|
296
|
+
metadata: {
|
|
297
|
+
appId: 'shell',
|
|
298
|
+
boundaries: [
|
|
299
|
+
{ appId: 'checkout', label: 'Checkout', mfName: 'verticalCheckout' },
|
|
300
|
+
],
|
|
301
|
+
schemaVersion: 1,
|
|
302
|
+
},
|
|
303
|
+
}).setup?.({
|
|
304
|
+
wrapRoot(factory: (App: React.ComponentType) => React.ComponentType) {
|
|
305
|
+
WrappedApp = factory(() => (
|
|
306
|
+
<main>
|
|
307
|
+
<section
|
|
308
|
+
data-modern-boundary-id="verticalCheckout"
|
|
309
|
+
data-modern-mf-expose="./Controls"
|
|
310
|
+
data-testid="checkout-control"
|
|
311
|
+
/>
|
|
312
|
+
</main>
|
|
313
|
+
));
|
|
314
|
+
},
|
|
315
|
+
} as any);
|
|
316
|
+
const App = WrappedApp!;
|
|
317
|
+
render(<App />);
|
|
318
|
+
|
|
319
|
+
await waitFor(() => {
|
|
320
|
+
const overlay = document.querySelector(
|
|
321
|
+
'[data-modern-boundary-overlay-label="Checkout"]',
|
|
322
|
+
) as HTMLElement | null;
|
|
323
|
+
expect(overlay?.style.position).toBe('fixed');
|
|
324
|
+
expect(overlay?.style.pointerEvents).toBe('none');
|
|
325
|
+
expect(overlay?.textContent).toContain('Checkout');
|
|
326
|
+
expect(overlay?.textContent).toContain('./Controls');
|
|
327
|
+
});
|
|
328
|
+
});
|
|
297
329
|
});
|
|
@@ -1,252 +0,0 @@
|
|
|
1
|
-
import { mkdtempSync, readFileSync, rmSync, writeFileSync } from 'node:fs';
|
|
2
|
-
import { createRequire } from 'node:module';
|
|
3
|
-
import { tmpdir } from 'node:os';
|
|
4
|
-
import path from 'node:path';
|
|
5
|
-
import { pathToFileURL } from 'node:url';
|
|
6
|
-
import { build } from 'esbuild';
|
|
7
|
-
|
|
8
|
-
type BrowserType = {
|
|
9
|
-
launch: (options?: Record<string, unknown>) => Promise<{
|
|
10
|
-
close: () => Promise<void>;
|
|
11
|
-
newPage: () => Promise<{
|
|
12
|
-
click: (selector: string) => Promise<void>;
|
|
13
|
-
evaluate: <T>(callback: () => T | Promise<T>) => Promise<T>;
|
|
14
|
-
goto: (url: string) => Promise<unknown>;
|
|
15
|
-
waitForFunction: (
|
|
16
|
-
callback: () => boolean,
|
|
17
|
-
arg?: unknown,
|
|
18
|
-
options?: Record<string, unknown>,
|
|
19
|
-
) => Promise<unknown>;
|
|
20
|
-
on: (event: string, handler: (value: any) => void) => void;
|
|
21
|
-
}>;
|
|
22
|
-
}>;
|
|
23
|
-
};
|
|
24
|
-
|
|
25
|
-
const requireFromRstestBrowserFixture = createRequire(
|
|
26
|
-
path.resolve(
|
|
27
|
-
__dirname,
|
|
28
|
-
'../../../../../tests/integration/rstest/basic-app-rstest-browser/package.json',
|
|
29
|
-
),
|
|
30
|
-
);
|
|
31
|
-
const { chromium }: { chromium: BrowserType } =
|
|
32
|
-
requireFromRstestBrowserFixture('playwright');
|
|
33
|
-
|
|
34
|
-
describe('ultramodern boundary debugger chromium overlay', () => {
|
|
35
|
-
test('keeps overlays out of layout and renders Checkout ownership inside Decide', async () => {
|
|
36
|
-
const tempDir = mkdtempSync(
|
|
37
|
-
path.join(tmpdir(), 'modern-boundary-debugger-'),
|
|
38
|
-
);
|
|
39
|
-
const entryPath = path.join(tempDir, 'entry.tsx');
|
|
40
|
-
const bundlePath = path.join(tempDir, 'bundle.js');
|
|
41
|
-
const htmlPath = path.join(tempDir, 'index.html');
|
|
42
|
-
|
|
43
|
-
try {
|
|
44
|
-
writeFileSync(
|
|
45
|
-
entryPath,
|
|
46
|
-
`import { runtime } from '@modern-js/plugin/runtime';
|
|
47
|
-
import React from 'react';
|
|
48
|
-
import { createRoot } from 'react-dom/client';
|
|
49
|
-
import ultramodernBoundaryDebuggerPlugin from ${JSON.stringify(
|
|
50
|
-
path.resolve(__dirname, '../../src/boundary-debugger/index.tsx'),
|
|
51
|
-
)};
|
|
52
|
-
|
|
53
|
-
globalThis.React = React;
|
|
54
|
-
|
|
55
|
-
function App() {
|
|
56
|
-
return (
|
|
57
|
-
<main style={{ minHeight: 1600, padding: 48 }}>
|
|
58
|
-
<button
|
|
59
|
-
data-testid="primary-control"
|
|
60
|
-
style={{ height: 44, width: 180 }}
|
|
61
|
-
type="button"
|
|
62
|
-
>
|
|
63
|
-
Decide
|
|
64
|
-
</button>
|
|
65
|
-
<section
|
|
66
|
-
data-modern-boundary-id="shellSuperApp"
|
|
67
|
-
data-modern-mf-expose="./Decide"
|
|
68
|
-
data-testid="decide-surface"
|
|
69
|
-
style={{
|
|
70
|
-
border: '1px solid #d1d5db',
|
|
71
|
-
height: 260,
|
|
72
|
-
marginTop: 48,
|
|
73
|
-
padding: 36,
|
|
74
|
-
width: 720,
|
|
75
|
-
}}
|
|
76
|
-
>
|
|
77
|
-
<button
|
|
78
|
-
data-modern-boundary-id="verticalCheckout"
|
|
79
|
-
data-modern-mf-expose="./Controls"
|
|
80
|
-
data-testid="checkout-control"
|
|
81
|
-
style={{ height: 48, width: 220 }}
|
|
82
|
-
type="button"
|
|
83
|
-
>
|
|
84
|
-
Pay now
|
|
85
|
-
</button>
|
|
86
|
-
</section>
|
|
87
|
-
</main>
|
|
88
|
-
);
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
const { runtimeContext } = runtime.run({
|
|
92
|
-
config: {},
|
|
93
|
-
plugins: [ultramodernBoundaryDebuggerPlugin({
|
|
94
|
-
metadata: {
|
|
95
|
-
appId: 'shell',
|
|
96
|
-
boundaries: [
|
|
97
|
-
{
|
|
98
|
-
appId: 'shell',
|
|
99
|
-
label: 'Decide',
|
|
100
|
-
mfName: 'shellSuperApp',
|
|
101
|
-
role: 'host',
|
|
102
|
-
},
|
|
103
|
-
{
|
|
104
|
-
appId: 'checkout',
|
|
105
|
-
label: 'Checkout',
|
|
106
|
-
mfName: 'verticalCheckout',
|
|
107
|
-
ownerTeam: 'checkout-platform',
|
|
108
|
-
role: 'vertical',
|
|
109
|
-
},
|
|
110
|
-
],
|
|
111
|
-
schemaVersion: 1,
|
|
112
|
-
},
|
|
113
|
-
})],
|
|
114
|
-
});
|
|
115
|
-
const WrappedApp = runtimeContext.hooks.wrapRoot.call(App);
|
|
116
|
-
|
|
117
|
-
createRoot(document.getElementById('root')).render(
|
|
118
|
-
React.createElement(WrappedApp),
|
|
119
|
-
);
|
|
120
|
-
`,
|
|
121
|
-
'utf8',
|
|
122
|
-
);
|
|
123
|
-
await build({
|
|
124
|
-
absWorkingDir: path.resolve(__dirname, '../..'),
|
|
125
|
-
bundle: true,
|
|
126
|
-
define: {
|
|
127
|
-
'process.env.NODE_ENV': '"test"',
|
|
128
|
-
},
|
|
129
|
-
entryPoints: [entryPath],
|
|
130
|
-
format: 'esm',
|
|
131
|
-
jsx: 'transform',
|
|
132
|
-
jsxFactory: 'React.createElement',
|
|
133
|
-
jsxFragment: 'React.Fragment',
|
|
134
|
-
nodePaths: [
|
|
135
|
-
path.resolve(__dirname, '../../node_modules'),
|
|
136
|
-
path.resolve(__dirname, '../../../../../node_modules'),
|
|
137
|
-
],
|
|
138
|
-
outfile: bundlePath,
|
|
139
|
-
platform: 'browser',
|
|
140
|
-
});
|
|
141
|
-
writeFileSync(
|
|
142
|
-
htmlPath,
|
|
143
|
-
`<!doctype html><html><body><div id="root"></div><script type="module">${readFileSync(
|
|
144
|
-
bundlePath,
|
|
145
|
-
'utf8',
|
|
146
|
-
)}</script></body></html>`,
|
|
147
|
-
'utf8',
|
|
148
|
-
);
|
|
149
|
-
|
|
150
|
-
const browser = await chromium.launch({ headless: true });
|
|
151
|
-
try {
|
|
152
|
-
const page = await browser.newPage();
|
|
153
|
-
const browserErrors: string[] = [];
|
|
154
|
-
page.on('console', message => {
|
|
155
|
-
if (message.type?.() === 'error') {
|
|
156
|
-
browserErrors.push(message.text?.() ?? String(message));
|
|
157
|
-
}
|
|
158
|
-
});
|
|
159
|
-
page.on('pageerror', error => {
|
|
160
|
-
browserErrors.push(
|
|
161
|
-
error instanceof Error ? error.message : String(error),
|
|
162
|
-
);
|
|
163
|
-
});
|
|
164
|
-
await page.goto(pathToFileURL(htmlPath).href);
|
|
165
|
-
try {
|
|
166
|
-
await page.waitForFunction(
|
|
167
|
-
() =>
|
|
168
|
-
Boolean(
|
|
169
|
-
document.querySelector('[data-testid="primary-control"]'),
|
|
170
|
-
),
|
|
171
|
-
undefined,
|
|
172
|
-
{ timeout: 5000 },
|
|
173
|
-
);
|
|
174
|
-
} catch (error) {
|
|
175
|
-
const bodyHtml = await page.evaluate(() => document.body.innerHTML);
|
|
176
|
-
throw new Error(
|
|
177
|
-
`${error instanceof Error ? error.message : String(error)}\n` +
|
|
178
|
-
`browserErrors=${JSON.stringify(browserErrors)}\n` +
|
|
179
|
-
`body=${bodyHtml.slice(0, 500)}`,
|
|
180
|
-
);
|
|
181
|
-
}
|
|
182
|
-
expect(browserErrors).toEqual([]);
|
|
183
|
-
|
|
184
|
-
const before = await page.evaluate(() => {
|
|
185
|
-
const control = document.querySelector(
|
|
186
|
-
'[data-testid="primary-control"]',
|
|
187
|
-
) as HTMLElement;
|
|
188
|
-
const rect = control.getBoundingClientRect();
|
|
189
|
-
return {
|
|
190
|
-
rect: {
|
|
191
|
-
height: rect.height,
|
|
192
|
-
left: rect.left,
|
|
193
|
-
top: rect.top,
|
|
194
|
-
width: rect.width,
|
|
195
|
-
},
|
|
196
|
-
scrollHeight: document.documentElement.scrollHeight,
|
|
197
|
-
};
|
|
198
|
-
});
|
|
199
|
-
|
|
200
|
-
await page.click('text=show team boundaries');
|
|
201
|
-
await page.waitForFunction(
|
|
202
|
-
() =>
|
|
203
|
-
document.querySelectorAll('[data-modern-boundary-overlay]')
|
|
204
|
-
.length === 2,
|
|
205
|
-
undefined,
|
|
206
|
-
{ timeout: 5000 },
|
|
207
|
-
);
|
|
208
|
-
|
|
209
|
-
const after = await page.evaluate(() => {
|
|
210
|
-
const control = document.querySelector(
|
|
211
|
-
'[data-testid="primary-control"]',
|
|
212
|
-
) as HTMLElement;
|
|
213
|
-
const rect = control.getBoundingClientRect();
|
|
214
|
-
const checkoutOverlay = document.querySelector(
|
|
215
|
-
'[data-modern-boundary-overlay-label="Checkout"]',
|
|
216
|
-
) as HTMLElement | null;
|
|
217
|
-
return {
|
|
218
|
-
checkoutOverlayStyle: checkoutOverlay
|
|
219
|
-
? {
|
|
220
|
-
boxSizing: checkoutOverlay.style.boxSizing,
|
|
221
|
-
pointerEvents: checkoutOverlay.style.pointerEvents,
|
|
222
|
-
position: checkoutOverlay.style.position,
|
|
223
|
-
}
|
|
224
|
-
: null,
|
|
225
|
-
checkoutOverlayText: checkoutOverlay?.textContent ?? '',
|
|
226
|
-
rect: {
|
|
227
|
-
height: rect.height,
|
|
228
|
-
left: rect.left,
|
|
229
|
-
top: rect.top,
|
|
230
|
-
width: rect.width,
|
|
231
|
-
},
|
|
232
|
-
scrollHeight: document.documentElement.scrollHeight,
|
|
233
|
-
};
|
|
234
|
-
});
|
|
235
|
-
|
|
236
|
-
expect(after.scrollHeight).toBe(before.scrollHeight);
|
|
237
|
-
expect(after.rect).toEqual(before.rect);
|
|
238
|
-
expect(after.checkoutOverlayStyle).toEqual({
|
|
239
|
-
boxSizing: 'border-box',
|
|
240
|
-
pointerEvents: 'none',
|
|
241
|
-
position: 'fixed',
|
|
242
|
-
});
|
|
243
|
-
expect(after.checkoutOverlayText).toContain('Checkout');
|
|
244
|
-
expect(after.checkoutOverlayText).toContain('./Controls');
|
|
245
|
-
} finally {
|
|
246
|
-
await browser.close();
|
|
247
|
-
}
|
|
248
|
-
} finally {
|
|
249
|
-
rmSync(tempDir, { force: true, recursive: true });
|
|
250
|
-
}
|
|
251
|
-
});
|
|
252
|
-
});
|