@jskit-ai/shell-web 0.1.162 → 0.1.164
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/fixtures/adaptive-shell/src/ScreenPage.vue +1 -1
- package/package.json +8 -253
- package/patterns/application-shell/PATTERN.md +66 -0
- package/{templates → patterns/application-shell/example}/expected-existing/src/pages/home/index.vue +8 -8
- package/{templates → patterns/application-shell/example}/src/pages/home/index.vue +8 -8
- package/{templates → patterns/application-shell/example}/src/pages/home/settings/general/index.vue +1 -1
- package/{templates → patterns/application-shell/example}/src/pages/home/settings.vue +8 -8
- package/patterns/page-and-placement/PATTERN.md +76 -0
- package/patterns/page-and-placement/example/packages/main/src/client/providers/MainClientProvider.js +14 -0
- package/patterns/page-and-placement/example/src/components/SyncStatusElement.vue +16 -0
- package/patterns/page-and-placement/example/src/pages/home/reports/activity.vue +8 -0
- package/patterns/page-and-placement/example/src/pages/home/reports/index.vue +7 -0
- package/patterns/page-and-placement/example/src/pages/home/reports/overview.vue +8 -0
- package/patterns/page-and-placement/example/src/pages/home/reports.vue +33 -0
- package/patterns/page-and-placement/example/src/placement.js +52 -0
- package/patterns/page-and-placement/example/src/placementTopology.js +29 -0
- package/src/client/bootstrap/bootstrapPayloadHandlerRegistry.js +30 -42
- package/src/client/bootstrap/index.js +2 -3
- package/src/client/index.js +2 -11
- package/src/client/placement/runtime.js +9 -12
- package/src/client/providers/ShellWebClientProvider.js +95 -129
- package/src/client/requestRecovery/runtime.js +9 -29
- package/src/client/runtime/bootstrapRuntime.js +18 -29
- package/src/test/adaptiveShellSmoke.js +3 -9
- package/test/bootstrapRuntime.test.js +10 -61
- package/test/pageAndPlacementPattern.test.js +38 -0
- package/test/placementRuntime.test.js +36 -50
- package/test/playwrightContract.test.js +2 -12
- package/test/provider.test.js +126 -737
- package/test/settingsPlacementContract.test.js +75 -126
- package/src/server/support/localLinkItemScaffolds.js +0 -80
- package/test/bootstrapClaimContract.test.js +0 -76
- package/test/linkItemScaffoldContract.test.js +0 -248
- /package/{templates → patterns/application-shell/example}/expected-existing/src/App.vue +0 -0
- /package/{templates → patterns/application-shell/example}/expected-existing/src/pages/home.vue +0 -0
- /package/{templates → patterns/application-shell/example}/src/App.vue +0 -0
- /package/{templates → patterns/application-shell/example}/src/components/ShellLayout.vue +0 -0
- /package/{templates → patterns/application-shell/example}/src/components/menus/MenuLinkItem.vue +0 -0
- /package/{templates → patterns/application-shell/example}/src/components/menus/SurfaceAwareMenuLinkItem.vue +0 -0
- /package/{templates → patterns/application-shell/example}/src/components/menus/TabLinkItem.vue +0 -0
- /package/{templates → patterns/application-shell/example}/src/error.js +0 -0
- /package/{templates → patterns/application-shell/example}/src/pages/home/settings/index.vue +0 -0
- /package/{templates → patterns/application-shell/example}/src/pages/home.vue +0 -0
- /package/{templates → patterns/application-shell/example}/src/placement.js +0 -0
- /package/{templates → patterns/application-shell/example}/src/placementTopology.js +0 -0
- /package/{templates → patterns/application-shell/example}/tests/e2e/adaptive-shell.spec.ts +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import assert from "node:assert/strict";
|
|
2
2
|
import test from "node:test";
|
|
3
|
-
import {
|
|
3
|
+
import { createBootstrapPayloadHandlerRegistry } from "../src/client/bootstrap/bootstrapPayloadHandlerRegistry.js";
|
|
4
4
|
import { createShellBootstrapRuntime } from "../src/client/runtime/bootstrapRuntime.js";
|
|
5
5
|
|
|
6
6
|
function createPlacementRuntime(initialContext = {}) {
|
|
@@ -32,52 +32,6 @@ function createPlacementRuntime(initialContext = {}) {
|
|
|
32
32
|
};
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
-
function createAppDouble({ placementRuntime, realtimeSocket = null } = {}) {
|
|
36
|
-
const singletons = new Map();
|
|
37
|
-
const singletonInstances = new Map();
|
|
38
|
-
return {
|
|
39
|
-
singleton(token, factory) {
|
|
40
|
-
singletons.set(token, factory);
|
|
41
|
-
},
|
|
42
|
-
tag(token, tagName) {
|
|
43
|
-
const current = this._tags.get(tagName) || [];
|
|
44
|
-
current.push(token);
|
|
45
|
-
this._tags.set(tagName, current);
|
|
46
|
-
},
|
|
47
|
-
resolveTag(tagName) {
|
|
48
|
-
return (this._tags.get(tagName) || []).map((token) => this.make(token));
|
|
49
|
-
},
|
|
50
|
-
_tags: new Map(),
|
|
51
|
-
has(token) {
|
|
52
|
-
if (token === "runtime.web-placement.client") {
|
|
53
|
-
return true;
|
|
54
|
-
}
|
|
55
|
-
if (token === "runtime.realtime.client.socket") {
|
|
56
|
-
return Boolean(realtimeSocket);
|
|
57
|
-
}
|
|
58
|
-
return singletons.has(token) || singletonInstances.has(token);
|
|
59
|
-
},
|
|
60
|
-
make(token) {
|
|
61
|
-
if (token === "runtime.web-placement.client") {
|
|
62
|
-
return placementRuntime;
|
|
63
|
-
}
|
|
64
|
-
if (token === "runtime.realtime.client.socket") {
|
|
65
|
-
return realtimeSocket;
|
|
66
|
-
}
|
|
67
|
-
if (singletonInstances.has(token)) {
|
|
68
|
-
return singletonInstances.get(token);
|
|
69
|
-
}
|
|
70
|
-
const factory = singletons.get(token);
|
|
71
|
-
if (!factory) {
|
|
72
|
-
throw new Error(`Unknown token ${String(token)}`);
|
|
73
|
-
}
|
|
74
|
-
const instance = factory(this);
|
|
75
|
-
singletonInstances.set(token, instance);
|
|
76
|
-
return instance;
|
|
77
|
-
}
|
|
78
|
-
};
|
|
79
|
-
}
|
|
80
|
-
|
|
81
35
|
test("shell bootstrap runtime refreshes /api/bootstrap on init and applies registered handlers", async () => {
|
|
82
36
|
const placementRuntime = createPlacementRuntime({
|
|
83
37
|
auth: {}
|
|
@@ -97,9 +51,8 @@ test("shell bootstrap runtime refreshes /api/bootstrap on init and applies regis
|
|
|
97
51
|
const calls = [];
|
|
98
52
|
const observedRequests = [];
|
|
99
53
|
const observedResolveMeta = [];
|
|
100
|
-
const
|
|
101
|
-
|
|
102
|
-
Object.freeze({
|
|
54
|
+
const handlers = createBootstrapPayloadHandlerRegistry();
|
|
55
|
+
handlers.register(Object.freeze({
|
|
103
56
|
handlerId: "test.bootstrap.request",
|
|
104
57
|
order: -10,
|
|
105
58
|
resolveBootstrapRequest() {
|
|
@@ -115,10 +68,8 @@ test("shell bootstrap runtime refreshes /api/bootstrap on init and applies regis
|
|
|
115
68
|
applyBootstrapPayload({ request }) {
|
|
116
69
|
observedRequests.push(request);
|
|
117
70
|
}
|
|
118
|
-
})
|
|
119
|
-
|
|
120
|
-
registerBootstrapPayloadHandler(app, "test.bootstrap.request-meta", () =>
|
|
121
|
-
Object.freeze({
|
|
71
|
+
}));
|
|
72
|
+
handlers.register(Object.freeze({
|
|
122
73
|
handlerId: "test.bootstrap.request-meta",
|
|
123
74
|
order: -5,
|
|
124
75
|
resolveBootstrapRequest({ request }) {
|
|
@@ -126,10 +77,8 @@ test("shell bootstrap runtime refreshes /api/bootstrap on init and applies regis
|
|
|
126
77
|
return {};
|
|
127
78
|
},
|
|
128
79
|
applyBootstrapPayload() {}
|
|
129
|
-
})
|
|
130
|
-
|
|
131
|
-
registerBootstrapPayloadHandler(app, "test.bootstrap.surfaceAccess", () =>
|
|
132
|
-
Object.freeze({
|
|
80
|
+
}));
|
|
81
|
+
handlers.register(Object.freeze({
|
|
133
82
|
handlerId: "test.bootstrap.surfaceAccess",
|
|
134
83
|
order: 0,
|
|
135
84
|
applyBootstrapPayload({ payload, placementRuntime: targetRuntime }) {
|
|
@@ -137,11 +86,11 @@ test("shell bootstrap runtime refreshes /api/bootstrap on init and applies regis
|
|
|
137
86
|
surfaceAccess: payload.surfaceAccess || {}
|
|
138
87
|
});
|
|
139
88
|
}
|
|
140
|
-
})
|
|
141
|
-
);
|
|
89
|
+
}));
|
|
142
90
|
|
|
143
91
|
const runtime = createShellBootstrapRuntime({
|
|
144
|
-
|
|
92
|
+
handlers,
|
|
93
|
+
placementRuntime,
|
|
145
94
|
fetchImplementation: async (url) => {
|
|
146
95
|
calls.push(String(url || ""));
|
|
147
96
|
const payload = payloads.shift() || {};
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import assert from "node:assert/strict";
|
|
2
|
+
import { readFile } from "node:fs/promises";
|
|
3
|
+
import test from "node:test";
|
|
4
|
+
import { parse as parseSfc } from "@vue/compiler-sfc";
|
|
5
|
+
|
|
6
|
+
const patternRoot = new URL("../patterns/page-and-placement/example/", import.meta.url);
|
|
7
|
+
const vueFiles = [
|
|
8
|
+
"src/pages/home/reports.vue",
|
|
9
|
+
"src/pages/home/reports/index.vue",
|
|
10
|
+
"src/pages/home/reports/overview.vue",
|
|
11
|
+
"src/pages/home/reports/activity.vue",
|
|
12
|
+
"src/components/SyncStatusElement.vue"
|
|
13
|
+
];
|
|
14
|
+
const jsFiles = [
|
|
15
|
+
"src/placement.js",
|
|
16
|
+
"src/placementTopology.js",
|
|
17
|
+
"packages/main/src/client/providers/MainClientProvider.js"
|
|
18
|
+
];
|
|
19
|
+
|
|
20
|
+
test("page and placement pattern is executable, semantic application source", async () => {
|
|
21
|
+
const sources = [];
|
|
22
|
+
for (const relativePath of vueFiles) {
|
|
23
|
+
const source = await readFile(new URL(relativePath, patternRoot), "utf8");
|
|
24
|
+
sources.push(source);
|
|
25
|
+
const parsed = parseSfc(source, { filename: relativePath });
|
|
26
|
+
assert.equal(parsed.errors.length, 0, `${relativePath}: ${parsed.errors.join("\n")}`);
|
|
27
|
+
}
|
|
28
|
+
for (const relativePath of jsFiles) {
|
|
29
|
+
const source = await readFile(new URL(relativePath, patternRoot), "utf8");
|
|
30
|
+
sources.push(source);
|
|
31
|
+
assert.match(source, /(?:export|addPlacement|registerMainClientComponent)/u, relativePath);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const combined = sources.join("\n");
|
|
35
|
+
assert.match(combined, /createPlacementRegistry|addPlacementTopology|ShellOutlet/u);
|
|
36
|
+
assert.doesNotMatch(combined, /ui-generator|generated-ui|scaffold|receipt|provenance/u);
|
|
37
|
+
assert.doesNotMatch(combined, /replace this|ready for your/u);
|
|
38
|
+
});
|
|
@@ -3,22 +3,16 @@ import test from "node:test";
|
|
|
3
3
|
import { definePlacement } from "../src/client/placement/validators.js";
|
|
4
4
|
import { createWebPlacementRuntime } from "../src/client/placement/runtime.js";
|
|
5
5
|
|
|
6
|
-
function
|
|
6
|
+
function createComponentsStub({ tokens = {} } = {}) {
|
|
7
7
|
return {
|
|
8
8
|
has(token) {
|
|
9
9
|
return Object.prototype.hasOwnProperty.call(tokens, token);
|
|
10
10
|
},
|
|
11
|
-
|
|
11
|
+
get(token) {
|
|
12
12
|
if (!this.has(token)) {
|
|
13
13
|
throw new Error(`Unknown token: ${String(token)}`);
|
|
14
14
|
}
|
|
15
15
|
return tokens[token];
|
|
16
|
-
},
|
|
17
|
-
resolveTag(tagName) {
|
|
18
|
-
if (tagName === "web-placement.context.client") {
|
|
19
|
-
return contextContributors;
|
|
20
|
-
}
|
|
21
|
-
return [];
|
|
22
16
|
}
|
|
23
17
|
};
|
|
24
18
|
}
|
|
@@ -60,14 +54,14 @@ function semanticTopologyEntry({
|
|
|
60
54
|
}
|
|
61
55
|
|
|
62
56
|
test("web placement runtime resolves semantic targets through topology variants", () => {
|
|
63
|
-
const
|
|
57
|
+
const components = createComponentsStub({
|
|
64
58
|
tokens: {
|
|
65
59
|
"component.bottom": () => null,
|
|
66
60
|
"component.menu": () => null
|
|
67
61
|
}
|
|
68
62
|
});
|
|
69
63
|
|
|
70
|
-
const runtime = createWebPlacementRuntime({
|
|
64
|
+
const runtime = createWebPlacementRuntime({ components });
|
|
71
65
|
runtime.replacePlacementTopology([
|
|
72
66
|
semanticTopologyEntry({
|
|
73
67
|
id: "shell.primary-nav",
|
|
@@ -109,13 +103,13 @@ test("web placement runtime resolves semantic targets through topology variants"
|
|
|
109
103
|
});
|
|
110
104
|
|
|
111
105
|
test("web placement runtime accepts append-only topology objects", () => {
|
|
112
|
-
const
|
|
106
|
+
const components = createComponentsStub({
|
|
113
107
|
tokens: {
|
|
114
108
|
"component.menu": () => null
|
|
115
109
|
}
|
|
116
110
|
});
|
|
117
111
|
|
|
118
|
-
const runtime = createWebPlacementRuntime({
|
|
112
|
+
const runtime = createWebPlacementRuntime({ components });
|
|
119
113
|
runtime.replacePlacementTopology({
|
|
120
114
|
placements: [
|
|
121
115
|
semanticTopologyEntry({
|
|
@@ -146,7 +140,7 @@ test("web placement runtime accepts append-only topology objects", () => {
|
|
|
146
140
|
});
|
|
147
141
|
|
|
148
142
|
test("web placement runtime filters by surface/host/position, resolves component tokens, and sorts by order", () => {
|
|
149
|
-
const
|
|
143
|
+
const components = createComponentsStub({
|
|
150
144
|
tokens: {
|
|
151
145
|
"component.alerts": () => null,
|
|
152
146
|
"component.profile": () => null,
|
|
@@ -154,7 +148,7 @@ test("web placement runtime filters by surface/host/position, resolves component
|
|
|
154
148
|
}
|
|
155
149
|
});
|
|
156
150
|
|
|
157
|
-
const runtime = createWebPlacementRuntime({
|
|
151
|
+
const runtime = createWebPlacementRuntime({ components });
|
|
158
152
|
runtime.replacePlacements([
|
|
159
153
|
definePlacement({
|
|
160
154
|
id: "test.menu",
|
|
@@ -195,14 +189,14 @@ test("web placement runtime filters by surface/host/position, resolves component
|
|
|
195
189
|
});
|
|
196
190
|
|
|
197
191
|
test("web placement runtime preserves source order when placements share the same order", () => {
|
|
198
|
-
const
|
|
192
|
+
const components = createComponentsStub({
|
|
199
193
|
tokens: {
|
|
200
194
|
"component.beta": () => null,
|
|
201
195
|
"component.alpha": () => null
|
|
202
196
|
}
|
|
203
197
|
});
|
|
204
198
|
|
|
205
|
-
const runtime = createWebPlacementRuntime({
|
|
199
|
+
const runtime = createWebPlacementRuntime({ components });
|
|
206
200
|
runtime.replacePlacements([
|
|
207
201
|
definePlacement({
|
|
208
202
|
id: "test.beta",
|
|
@@ -228,19 +222,19 @@ test("web placement runtime preserves source order when placements share the sam
|
|
|
228
222
|
});
|
|
229
223
|
|
|
230
224
|
test("web placement runtime applies context contributors and placement when() predicates", () => {
|
|
231
|
-
const
|
|
225
|
+
const components = createComponentsStub({
|
|
232
226
|
tokens: {
|
|
233
227
|
"component.guest": () => null,
|
|
234
228
|
"component.authenticated": () => null
|
|
235
|
-
}
|
|
229
|
+
}
|
|
230
|
+
});
|
|
231
|
+
|
|
232
|
+
const runtime = createWebPlacementRuntime({
|
|
233
|
+
components,
|
|
236
234
|
contextContributors: [
|
|
237
|
-
() => ({
|
|
238
|
-
auth: { authenticated: true }
|
|
239
|
-
})
|
|
235
|
+
() => ({ auth: { authenticated: true } })
|
|
240
236
|
]
|
|
241
237
|
});
|
|
242
|
-
|
|
243
|
-
const runtime = createWebPlacementRuntime({ app });
|
|
244
238
|
runtime.replacePlacements([
|
|
245
239
|
definePlacement({
|
|
246
240
|
id: "guest.item",
|
|
@@ -265,20 +259,18 @@ test("web placement runtime applies context contributors and placement when() pr
|
|
|
265
259
|
});
|
|
266
260
|
|
|
267
261
|
test("web placement runtime uses runtime context and local context overrides contributor values", () => {
|
|
268
|
-
const
|
|
262
|
+
const components = createComponentsStub({
|
|
269
263
|
tokens: {
|
|
270
264
|
"component.allowed": () => null
|
|
271
|
-
}
|
|
265
|
+
}
|
|
266
|
+
});
|
|
267
|
+
|
|
268
|
+
const runtime = createWebPlacementRuntime({
|
|
269
|
+
components,
|
|
272
270
|
contextContributors: [
|
|
273
|
-
() => ({
|
|
274
|
-
auth: {
|
|
275
|
-
authenticated: false
|
|
276
|
-
}
|
|
277
|
-
})
|
|
271
|
+
() => ({ auth: { authenticated: false } })
|
|
278
272
|
]
|
|
279
273
|
});
|
|
280
|
-
|
|
281
|
-
const runtime = createWebPlacementRuntime({ app });
|
|
282
274
|
runtime.replacePlacements([
|
|
283
275
|
definePlacement({
|
|
284
276
|
id: "allowed",
|
|
@@ -311,8 +303,8 @@ test("web placement runtime uses runtime context and local context overrides con
|
|
|
311
303
|
});
|
|
312
304
|
|
|
313
305
|
test("web placement runtime notifies subscribers on placement and context updates", () => {
|
|
314
|
-
const
|
|
315
|
-
const runtime = createWebPlacementRuntime({
|
|
306
|
+
const components = createComponentsStub();
|
|
307
|
+
const runtime = createWebPlacementRuntime({ components });
|
|
316
308
|
const events = [];
|
|
317
309
|
const unsubscribe = runtime.subscribe((event) => {
|
|
318
310
|
events.push(event.type);
|
|
@@ -336,8 +328,8 @@ test("web placement runtime notifies subscribers on placement and context update
|
|
|
336
328
|
});
|
|
337
329
|
|
|
338
330
|
test("web placement runtime rejects duplicate placement ids", () => {
|
|
339
|
-
const
|
|
340
|
-
const runtime = createWebPlacementRuntime({
|
|
331
|
+
const components = createComponentsStub();
|
|
332
|
+
const runtime = createWebPlacementRuntime({ components });
|
|
341
333
|
|
|
342
334
|
assert.throws(() => {
|
|
343
335
|
runtime.replacePlacements([
|
|
@@ -360,11 +352,11 @@ test("web placement runtime rejects duplicate placement ids", () => {
|
|
|
360
352
|
});
|
|
361
353
|
|
|
362
354
|
test("web placement runtime skips throwing component tokens and logs resolution errors once", () => {
|
|
363
|
-
const
|
|
355
|
+
const components = {
|
|
364
356
|
has(token) {
|
|
365
357
|
return token === "component.bad" || token === "component.good";
|
|
366
358
|
},
|
|
367
|
-
|
|
359
|
+
get(token) {
|
|
368
360
|
if (token === "component.bad") {
|
|
369
361
|
throw new Error("bad component token");
|
|
370
362
|
}
|
|
@@ -372,15 +364,12 @@ test("web placement runtime skips throwing component tokens and logs resolution
|
|
|
372
364
|
return () => null;
|
|
373
365
|
}
|
|
374
366
|
throw new Error(`Unknown token: ${String(token)}`);
|
|
375
|
-
},
|
|
376
|
-
resolveTag() {
|
|
377
|
-
return [];
|
|
378
367
|
}
|
|
379
368
|
};
|
|
380
369
|
|
|
381
370
|
const errors = [];
|
|
382
371
|
const runtime = createWebPlacementRuntime({
|
|
383
|
-
|
|
372
|
+
components,
|
|
384
373
|
logger: {
|
|
385
374
|
warn() {},
|
|
386
375
|
error(payload, message) {
|
|
@@ -417,11 +406,11 @@ test("web placement runtime skips throwing component tokens and logs resolution
|
|
|
417
406
|
|
|
418
407
|
test("web placement runtime clears failed token cache when placements are replaced", () => {
|
|
419
408
|
let shouldThrow = true;
|
|
420
|
-
const
|
|
409
|
+
const components = {
|
|
421
410
|
has(token) {
|
|
422
411
|
return token === "component.toggle";
|
|
423
412
|
},
|
|
424
|
-
|
|
413
|
+
get(token) {
|
|
425
414
|
if (token !== "component.toggle") {
|
|
426
415
|
throw new Error(`Unknown token: ${String(token)}`);
|
|
427
416
|
}
|
|
@@ -429,14 +418,11 @@ test("web placement runtime clears failed token cache when placements are replac
|
|
|
429
418
|
throw new Error("toggle failure");
|
|
430
419
|
}
|
|
431
420
|
return () => null;
|
|
432
|
-
},
|
|
433
|
-
resolveTag() {
|
|
434
|
-
return [];
|
|
435
421
|
}
|
|
436
422
|
};
|
|
437
423
|
|
|
438
424
|
const runtime = createWebPlacementRuntime({
|
|
439
|
-
|
|
425
|
+
components,
|
|
440
426
|
logger: {
|
|
441
427
|
warn() {},
|
|
442
428
|
error() {}
|
|
@@ -475,14 +461,14 @@ test("web placement runtime clears failed token cache when placements are replac
|
|
|
475
461
|
});
|
|
476
462
|
|
|
477
463
|
test("web placement runtime follows explicit surface targeting without role indirection", () => {
|
|
478
|
-
const
|
|
464
|
+
const components = createComponentsStub({
|
|
479
465
|
tokens: {
|
|
480
466
|
"component.global": () => null,
|
|
481
467
|
"component.app": () => null,
|
|
482
468
|
"component.admin": () => null
|
|
483
469
|
}
|
|
484
470
|
});
|
|
485
|
-
const runtime = createWebPlacementRuntime({
|
|
471
|
+
const runtime = createWebPlacementRuntime({ components });
|
|
486
472
|
runtime.replacePlacements([
|
|
487
473
|
definePlacement({
|
|
488
474
|
id: "global.banner",
|
|
@@ -9,17 +9,6 @@ import {
|
|
|
9
9
|
|
|
10
10
|
const PACKAGE_ROOT = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
|
|
11
11
|
|
|
12
|
-
test("shell-web owns the exact Playwright dependency used by its generated smoke", async () => {
|
|
13
|
-
const packageJson = JSON.parse(await readFile(path.join(PACKAGE_ROOT, "package.json"), "utf8"));
|
|
14
|
-
const rootPackage = JSON.parse(await readFile(path.resolve(PACKAGE_ROOT, "../../package.json"), "utf8"));
|
|
15
|
-
|
|
16
|
-
assert.equal(packageJson.jskit.mutations.dependencies.dev["@playwright/test"], "1.61.1");
|
|
17
|
-
assert.equal(
|
|
18
|
-
packageJson.jskit.mutations.dependencies.dev["@playwright/test"],
|
|
19
|
-
rootPackage.devDependencies["@playwright/test"]
|
|
20
|
-
);
|
|
21
|
-
});
|
|
22
|
-
|
|
23
12
|
test("adaptive shell smoke navigates through Playwright baseURL", async () => {
|
|
24
13
|
const source = await readFile(path.join(PACKAGE_ROOT, "src/test/adaptiveShellSmoke.js"), "utf8");
|
|
25
14
|
|
|
@@ -69,7 +58,8 @@ test("adaptive shell smoke follows rendered layout state and waits for drawer tr
|
|
|
69
58
|
assert.match(source, /data-rail-width/u);
|
|
70
59
|
assert.match(source, /expect\.poll/u);
|
|
71
60
|
assert.match(source, /toBeFocused/u);
|
|
72
|
-
assert.match(source, /
|
|
61
|
+
assert.match(source, /getByRole\("button", \{ name: "Close navigation menu" \}\)/u);
|
|
62
|
+
assert.doesNotMatch(source, /v-navigation-drawer__scrim/u);
|
|
73
63
|
assert.match(source, /page\.keyboard\.press\("Escape"\)[\s\S]*data-presentation", "drawer"/u);
|
|
74
64
|
assert.match(source, /centers\.push\(box\.x \+ box\.width \/ 2\)/u);
|
|
75
65
|
assert.match(source, /fit\.endGap - configuredSpacing/u);
|