jsgui3-server 0.0.152 → 0.0.155
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/docs/agi/skills/README.md +23 -0
- package/docs/agi/skills/agent-output-control/SKILL.md +56 -0
- package/docs/agi/skills/ai-deep-research/SKILL.md +52 -0
- package/docs/agi/skills/autonomous-ui-inspection/SKILL.md +102 -0
- package/docs/agi/skills/deep-research/SKILL.md +156 -0
- package/docs/agi/skills/endurance/SKILL.md +53 -0
- package/docs/agi/skills/exploring-other-codebases/SKILL.md +56 -0
- package/docs/agi/skills/instruction-adherence/SKILL.md +73 -0
- package/docs/agi/skills/jsgui3-activation-debug/SKILL.md +94 -0
- package/docs/agi/skills/jsgui3-context-menu-patterns/SKILL.md +94 -0
- package/docs/agi/skills/puppeteer-efficient-ui-verification/SKILL.md +65 -0
- package/docs/agi/skills/runaway-process-guard/SKILL.md +49 -0
- package/docs/agi/skills/session-discipline/SKILL.md +40 -0
- package/docs/agi/skills/skill-writing/SKILL.md +211 -0
- package/docs/agi/skills/static-analysis/SKILL.md +58 -0
- package/docs/agi/skills/targeted-testing/SKILL.md +63 -0
- package/docs/agi/skills/understanding-jsgui3/SKILL.md +85 -0
- package/docs/books/jsgui3-bundling-research-book/06-unused-module-elimination-strategy.md +1 -0
- package/docs/books/jsgui3-bundling-research-book/07-jsgui3-html-control-and-mixin-pruning.md +33 -0
- package/docs/bundling-system-deep-dive.md +112 -3
- package/docs/configuration-reference.md +30 -0
- package/package.json +5 -2
- package/resources/processors/bundlers/js/esbuild/Advanced_JS_Bundler_Using_ESBuild.js +90 -22
- package/resources/processors/bundlers/js/esbuild/Core_JS_Non_Minifying_Bundler_Using_ESBuild.js +50 -14
- package/resources/processors/bundlers/js/esbuild/Core_JS_Single_File_Minifying_Bundler_Using_ESBuild.js +48 -14
- package/resources/processors/bundlers/js/esbuild/JSGUI3_HTML_Control_Optimizer.js +396 -44
- package/serve-factory.js +3 -54
- package/server.js +168 -68
- package/tests/README.md +63 -1
- package/tests/bundling-default-control-elimination.puppeteer.test.js +32 -1
- package/tests/control-elimination-root-feature-pruning.test.js +440 -0
- package/tests/control-elimination-static-bracket-access.test.js +245 -0
- package/tests/control-scan-manifest-regression.test.js +2 -0
- package/tests/end-to-end.test.js +22 -21
- package/tests/fixtures/control_scan_manifest_expectations.json +4 -2
- package/tests/helpers/puppeteer-e2e-harness.js +62 -1
- package/tests/project-local-controls-bundling.puppeteer.test.js +462 -0
- package/tests/test-runner.js +3 -0
|
@@ -0,0 +1,462 @@
|
|
|
1
|
+
const assert = require('assert');
|
|
2
|
+
const fs = require('fs').promises;
|
|
3
|
+
const path = require('path');
|
|
4
|
+
const { describe, it, before, after } = require('mocha');
|
|
5
|
+
|
|
6
|
+
const Server = require('../server');
|
|
7
|
+
const { get_free_port } = require('../port-utils');
|
|
8
|
+
const {
|
|
9
|
+
ensure_puppeteer_module,
|
|
10
|
+
launch_puppeteer_browser,
|
|
11
|
+
open_page,
|
|
12
|
+
stop_server_instance,
|
|
13
|
+
assert_clean_page_probe,
|
|
14
|
+
extract_esbuild_warning_headers_from_bundle,
|
|
15
|
+
assert_no_unexpected_esbuild_warning_headers
|
|
16
|
+
} = require('./helpers/puppeteer-e2e-harness');
|
|
17
|
+
|
|
18
|
+
const window_markers = [
|
|
19
|
+
'Minimize window',
|
|
20
|
+
'window_manager',
|
|
21
|
+
'__type_name = "window"',
|
|
22
|
+
"__type_name = 'window'",
|
|
23
|
+
"__type_name='window'",
|
|
24
|
+
'add_class("window")',
|
|
25
|
+
"add_class('window')"
|
|
26
|
+
];
|
|
27
|
+
|
|
28
|
+
const count_window_markers = (bundle_text = '') => {
|
|
29
|
+
return window_markers.reduce((total, marker) => {
|
|
30
|
+
return total + (bundle_text.includes(marker) ? 1 : 0);
|
|
31
|
+
}, 0);
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
const allowed_esbuild_warning_patterns = [
|
|
35
|
+
/\[different-path-case\]/
|
|
36
|
+
];
|
|
37
|
+
|
|
38
|
+
const get_server_esbuild_warning_headers = (server_instance) => {
|
|
39
|
+
const latest_wp_bundle = server_instance && server_instance.latest_wp_bundle;
|
|
40
|
+
assert(latest_wp_bundle, 'Expected server_instance.latest_wp_bundle to inspect esbuild warnings');
|
|
41
|
+
return extract_esbuild_warning_headers_from_bundle(latest_wp_bundle);
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
const assert_no_unexpected_server_esbuild_warnings = (server_instance, {
|
|
45
|
+
allowed_warning_patterns = [],
|
|
46
|
+
required_warning_patterns = []
|
|
47
|
+
} = {}) => {
|
|
48
|
+
const warning_headers = get_server_esbuild_warning_headers(server_instance);
|
|
49
|
+
assert_no_unexpected_esbuild_warning_headers(warning_headers, {
|
|
50
|
+
allowed_warning_patterns,
|
|
51
|
+
required_warning_patterns
|
|
52
|
+
});
|
|
53
|
+
return warning_headers;
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
const temp_fixture_specs = [
|
|
57
|
+
{
|
|
58
|
+
file_name: 'temp_project_local_value_formatter.js',
|
|
59
|
+
source_text: `
|
|
60
|
+
const format_click_count = (next_count) => {
|
|
61
|
+
const normalized_count = Number.isFinite(next_count) ? next_count : 0;
|
|
62
|
+
return 'Clicks: ' + String(normalized_count);
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
module.exports = { format_click_count };
|
|
66
|
+
`.trimStart()
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
file_name: 'temp_project_local_status_chip.js',
|
|
70
|
+
source_text: `
|
|
71
|
+
const jsgui = require('jsgui3-html');
|
|
72
|
+
const { Control } = jsgui;
|
|
73
|
+
|
|
74
|
+
class Project_Local_Status_Chip extends Control {
|
|
75
|
+
constructor(spec = {}) {
|
|
76
|
+
super(spec);
|
|
77
|
+
if (!spec.el) {
|
|
78
|
+
const chip_label = spec.label || 'ready';
|
|
79
|
+
this.add_class('project-local-status-chip');
|
|
80
|
+
this.add('Status: ' + String(chip_label));
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
Project_Local_Status_Chip.css = \`
|
|
86
|
+
.project-local-status-chip {
|
|
87
|
+
display: inline-block;
|
|
88
|
+
padding: 4px 10px;
|
|
89
|
+
border: 1px solid #8e44ad;
|
|
90
|
+
border-radius: 999px;
|
|
91
|
+
background: #f7ecff;
|
|
92
|
+
color: #5c2c73;
|
|
93
|
+
font-size: 12px;
|
|
94
|
+
}
|
|
95
|
+
\`;
|
|
96
|
+
|
|
97
|
+
module.exports = { Project_Local_Status_Chip };
|
|
98
|
+
`.trimStart()
|
|
99
|
+
},
|
|
100
|
+
{
|
|
101
|
+
file_name: 'temp_project_local_counter_panel.js',
|
|
102
|
+
source_text: `
|
|
103
|
+
const jsgui = require('jsgui3-html');
|
|
104
|
+
const controls_registry = jsgui['controls'];
|
|
105
|
+
const { Control } = jsgui;
|
|
106
|
+
const { format_click_count } = require('./temp_project_local_value_formatter');
|
|
107
|
+
const { Project_Local_Status_Chip } = require('./temp_project_local_status_chip');
|
|
108
|
+
|
|
109
|
+
class Project_Local_Counter_Panel extends Control {
|
|
110
|
+
constructor(spec = {}) {
|
|
111
|
+
super(spec);
|
|
112
|
+
this._click_count = 0;
|
|
113
|
+
if (!spec.el) {
|
|
114
|
+
const context = this.context;
|
|
115
|
+
this.add_class('project-local-counter-panel');
|
|
116
|
+
|
|
117
|
+
const heading = new controls_registry.h3({ context });
|
|
118
|
+
heading.dom.attributes['data-test'] = 'project-local-title';
|
|
119
|
+
heading.add('Project Local Counter');
|
|
120
|
+
this.add(heading);
|
|
121
|
+
|
|
122
|
+
const count_readout = new controls_registry.div({ context });
|
|
123
|
+
count_readout.dom.attributes['data-test'] = 'project-local-count';
|
|
124
|
+
count_readout.add(format_click_count(this._click_count));
|
|
125
|
+
this.add(count_readout);
|
|
126
|
+
|
|
127
|
+
const increment_button = new controls_registry.button({ context });
|
|
128
|
+
increment_button.dom.attributes.type = 'button';
|
|
129
|
+
increment_button.dom.attributes['data-test'] = 'project-local-increment';
|
|
130
|
+
increment_button.add('Increment');
|
|
131
|
+
this.add(increment_button);
|
|
132
|
+
|
|
133
|
+
const status_chip = new Project_Local_Status_Chip({
|
|
134
|
+
context,
|
|
135
|
+
label: 'loaded'
|
|
136
|
+
});
|
|
137
|
+
status_chip.dom.attributes['data-test'] = 'project-local-chip';
|
|
138
|
+
this.add(status_chip);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
Project_Local_Counter_Panel.css = \`
|
|
144
|
+
.project-local-counter-panel {
|
|
145
|
+
margin: 16px;
|
|
146
|
+
padding: 14px;
|
|
147
|
+
border: 2px dashed #1f6feb;
|
|
148
|
+
border-radius: 8px;
|
|
149
|
+
background: #f8fbff;
|
|
150
|
+
}
|
|
151
|
+
\`;
|
|
152
|
+
|
|
153
|
+
module.exports = { Project_Local_Counter_Panel };
|
|
154
|
+
`.trimStart()
|
|
155
|
+
},
|
|
156
|
+
{
|
|
157
|
+
file_name: 'temp_project_local_controls_client.js',
|
|
158
|
+
source_text: `
|
|
159
|
+
const jsgui = require('jsgui3-html');
|
|
160
|
+
const controls_registry = jsgui['controls'];
|
|
161
|
+
const { Project_Local_Counter_Panel } = require('./temp_project_local_counter_panel');
|
|
162
|
+
|
|
163
|
+
if (typeof window !== 'undefined') {
|
|
164
|
+
window.__project_local_controls_client_loaded = true;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
class Project_Local_Bundling_App extends controls_registry['Active_HTML_Document'] {
|
|
168
|
+
constructor(spec = {}) {
|
|
169
|
+
spec.__type_name = spec.__type_name || 'project_local_bundling_app';
|
|
170
|
+
super(spec);
|
|
171
|
+
|
|
172
|
+
if (!spec.el) {
|
|
173
|
+
const context = this.context;
|
|
174
|
+
const root = new controls_registry.div({ context });
|
|
175
|
+
root.dom.attributes['data-test'] = 'project-local-root';
|
|
176
|
+
root.add_class('project-local-root');
|
|
177
|
+
root.add('Project-local controls loaded');
|
|
178
|
+
|
|
179
|
+
const local_counter_panel = new Project_Local_Counter_Panel({ context });
|
|
180
|
+
local_counter_panel.dom.attributes['data-test'] = 'project-local-counter-panel';
|
|
181
|
+
root.add(local_counter_panel);
|
|
182
|
+
|
|
183
|
+
this.body.add(root);
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
controls_registry.Project_Local_Counter_Panel = Project_Local_Counter_Panel;
|
|
189
|
+
controls_registry.Project_Local_Bundling_App = Project_Local_Bundling_App;
|
|
190
|
+
|
|
191
|
+
module.exports = jsgui;
|
|
192
|
+
`.trimStart()
|
|
193
|
+
}
|
|
194
|
+
];
|
|
195
|
+
|
|
196
|
+
const write_temp_fixture_files = async () => {
|
|
197
|
+
const fixture_dir_path = await fs.mkdtemp(path.join(__dirname, 'temp_project_local_controls_'));
|
|
198
|
+
|
|
199
|
+
for (const fixture_spec of temp_fixture_specs) {
|
|
200
|
+
const fixture_path = path.join(fixture_dir_path, fixture_spec.file_name);
|
|
201
|
+
await fs.writeFile(fixture_path, fixture_spec.source_text, 'utf8');
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
return {
|
|
205
|
+
fixture_dir_path,
|
|
206
|
+
client_file_path: path.join(fixture_dir_path, 'temp_project_local_controls_client.js')
|
|
207
|
+
};
|
|
208
|
+
};
|
|
209
|
+
|
|
210
|
+
const remove_fixture_dir_if_exists = async (fixture_dir_path) => {
|
|
211
|
+
try {
|
|
212
|
+
await fs.rm(fixture_dir_path, { recursive: true, force: true });
|
|
213
|
+
} catch (err) {
|
|
214
|
+
if (err && err.code !== 'ENOENT') {
|
|
215
|
+
throw err;
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
};
|
|
219
|
+
|
|
220
|
+
const clear_require_cache_for_fixture_dir = (fixture_dir_path) => {
|
|
221
|
+
if (!fixture_dir_path) {
|
|
222
|
+
return;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
const fixture_dir_prefix = fixture_dir_path.endsWith(path.sep)
|
|
226
|
+
? fixture_dir_path
|
|
227
|
+
: `${fixture_dir_path}${path.sep}`;
|
|
228
|
+
|
|
229
|
+
for (const cache_key of Object.keys(require.cache)) {
|
|
230
|
+
if (cache_key.startsWith(fixture_dir_prefix)) {
|
|
231
|
+
delete require.cache[cache_key];
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
};
|
|
235
|
+
|
|
236
|
+
const read_bundle_from_page = async (page, route_path) => {
|
|
237
|
+
return page.evaluate(async (next_route_path) => {
|
|
238
|
+
const response = await fetch(next_route_path, { cache: 'no-store' });
|
|
239
|
+
const body_text = await response.text();
|
|
240
|
+
return {
|
|
241
|
+
status_code: response.status,
|
|
242
|
+
body_text
|
|
243
|
+
};
|
|
244
|
+
}, route_path);
|
|
245
|
+
};
|
|
246
|
+
|
|
247
|
+
const load_fixture_control = (client_file_path, control_name, fixture_dir_path) => {
|
|
248
|
+
clear_require_cache_for_fixture_dir(fixture_dir_path);
|
|
249
|
+
const resolved_client_file_path = require.resolve(client_file_path);
|
|
250
|
+
delete require.cache[resolved_client_file_path];
|
|
251
|
+
|
|
252
|
+
const client_module = require(resolved_client_file_path);
|
|
253
|
+
const control_constructor = client_module.controls && client_module.controls[control_name];
|
|
254
|
+
assert(control_constructor, `Missing exported control jsgui.controls.${control_name} in ${client_file_path}`);
|
|
255
|
+
return control_constructor;
|
|
256
|
+
};
|
|
257
|
+
|
|
258
|
+
const start_fixture_server = async ({ client_file_path, control_name, fixture_dir_path, bundler }) => {
|
|
259
|
+
const control_constructor = load_fixture_control(client_file_path, control_name, fixture_dir_path);
|
|
260
|
+
|
|
261
|
+
const server_instance = new Server({
|
|
262
|
+
Ctrl: control_constructor,
|
|
263
|
+
src_path_client_js: client_file_path,
|
|
264
|
+
name: `tests/project-local/${control_name}`,
|
|
265
|
+
bundler
|
|
266
|
+
});
|
|
267
|
+
|
|
268
|
+
server_instance.allowed_addresses = ['127.0.0.1'];
|
|
269
|
+
|
|
270
|
+
await new Promise((resolve, reject) => {
|
|
271
|
+
const timeout_handle = setTimeout(() => reject(new Error('Publisher ready timeout')), 60000);
|
|
272
|
+
server_instance.on('ready', () => {
|
|
273
|
+
clearTimeout(timeout_handle);
|
|
274
|
+
resolve();
|
|
275
|
+
});
|
|
276
|
+
});
|
|
277
|
+
|
|
278
|
+
const port = await get_free_port();
|
|
279
|
+
await new Promise((resolve, reject) => {
|
|
280
|
+
server_instance.start(port, (error) => {
|
|
281
|
+
if (error) reject(error);
|
|
282
|
+
else resolve();
|
|
283
|
+
});
|
|
284
|
+
});
|
|
285
|
+
|
|
286
|
+
return {
|
|
287
|
+
server_instance,
|
|
288
|
+
port
|
|
289
|
+
};
|
|
290
|
+
};
|
|
291
|
+
|
|
292
|
+
const close_page_with_probe = async (page, page_probe) => {
|
|
293
|
+
if (page_probe && typeof page_probe.detach === 'function') {
|
|
294
|
+
page_probe.detach();
|
|
295
|
+
}
|
|
296
|
+
if (page) {
|
|
297
|
+
await page.close();
|
|
298
|
+
}
|
|
299
|
+
};
|
|
300
|
+
|
|
301
|
+
const stop_server_instance_with_timeout = async (server_instance, timeout_ms = 12000) => {
|
|
302
|
+
if (!server_instance) {
|
|
303
|
+
return;
|
|
304
|
+
}
|
|
305
|
+
await Promise.race([
|
|
306
|
+
stop_server_instance(server_instance),
|
|
307
|
+
new Promise((resolve) => setTimeout(resolve, timeout_ms))
|
|
308
|
+
]);
|
|
309
|
+
};
|
|
310
|
+
|
|
311
|
+
const run_project_local_controls_scenario = async ({
|
|
312
|
+
browser_instance,
|
|
313
|
+
client_file_path,
|
|
314
|
+
fixture_dir_path,
|
|
315
|
+
bundler,
|
|
316
|
+
allowed_warning_patterns = []
|
|
317
|
+
}) => {
|
|
318
|
+
let server_instance = null;
|
|
319
|
+
let page = null;
|
|
320
|
+
let page_probe = null;
|
|
321
|
+
|
|
322
|
+
try {
|
|
323
|
+
const started_server = await start_fixture_server({
|
|
324
|
+
client_file_path,
|
|
325
|
+
control_name: 'Project_Local_Bundling_App',
|
|
326
|
+
fixture_dir_path,
|
|
327
|
+
bundler
|
|
328
|
+
});
|
|
329
|
+
server_instance = started_server.server_instance;
|
|
330
|
+
|
|
331
|
+
const open_result = await open_page(
|
|
332
|
+
browser_instance,
|
|
333
|
+
`http://127.0.0.1:${started_server.port}/`,
|
|
334
|
+
{ wait_until: 'domcontentloaded' }
|
|
335
|
+
);
|
|
336
|
+
page = open_result.page;
|
|
337
|
+
page_probe = open_result.page_probe;
|
|
338
|
+
|
|
339
|
+
await page.waitForSelector('[data-test="project-local-root"]');
|
|
340
|
+
await page.waitForSelector('[data-test="project-local-counter-panel"]');
|
|
341
|
+
await page.waitForSelector('[data-test="project-local-chip"]');
|
|
342
|
+
await page.waitForSelector('[data-test="project-local-increment"]');
|
|
343
|
+
await page.waitForFunction(() => window.__project_local_controls_client_loaded === true, { timeout: 12000 });
|
|
344
|
+
|
|
345
|
+
const initial_count_text = await page.$eval('[data-test="project-local-count"]', (element) => {
|
|
346
|
+
return String(element.textContent || '').trim();
|
|
347
|
+
});
|
|
348
|
+
assert.strictEqual(initial_count_text, 'Clicks: 0');
|
|
349
|
+
|
|
350
|
+
const js_bundle_response = await read_bundle_from_page(page, '/js/js.js');
|
|
351
|
+
assert.strictEqual(js_bundle_response.status_code, 200, 'Expected /js/js.js to load');
|
|
352
|
+
assert(js_bundle_response.body_text.includes('project-local-increment'), 'Expected project-local increment marker in JS bundle');
|
|
353
|
+
assert(js_bundle_response.body_text.includes('Project Local Counter'), 'Expected project-local heading marker in JS bundle');
|
|
354
|
+
|
|
355
|
+
const css_bundle_response = await read_bundle_from_page(page, '/css/css.css');
|
|
356
|
+
assert.strictEqual(css_bundle_response.status_code, 200, 'Expected /css/css.css to load');
|
|
357
|
+
assert(css_bundle_response.body_text.includes('.project-local-counter-panel'), 'Expected project-local panel CSS in CSS bundle');
|
|
358
|
+
assert(css_bundle_response.body_text.includes('.project-local-status-chip'), 'Expected project-local status-chip CSS in CSS bundle');
|
|
359
|
+
|
|
360
|
+
assert_no_unexpected_server_esbuild_warnings(server_instance, { allowed_warning_patterns });
|
|
361
|
+
|
|
362
|
+
assert_clean_page_probe(page_probe);
|
|
363
|
+
|
|
364
|
+
return {
|
|
365
|
+
js_bytes: Buffer.byteLength(js_bundle_response.body_text, 'utf8'),
|
|
366
|
+
css_bytes: Buffer.byteLength(css_bundle_response.body_text, 'utf8'),
|
|
367
|
+
window_marker_count: count_window_markers(js_bundle_response.body_text)
|
|
368
|
+
};
|
|
369
|
+
} finally {
|
|
370
|
+
await close_page_with_probe(page, page_probe);
|
|
371
|
+
await stop_server_instance_with_timeout(server_instance);
|
|
372
|
+
}
|
|
373
|
+
};
|
|
374
|
+
|
|
375
|
+
describe('Project-Local Controls Bundling Puppeteer E2E Tests', function () {
|
|
376
|
+
this.timeout(420000);
|
|
377
|
+
|
|
378
|
+
let puppeteer_module = null;
|
|
379
|
+
let browser_instance = null;
|
|
380
|
+
let fixture_dir_path = null;
|
|
381
|
+
let fixture_client_file_path = null;
|
|
382
|
+
|
|
383
|
+
before(async function () {
|
|
384
|
+
this.timeout(90000);
|
|
385
|
+
const fixture_write_result = await write_temp_fixture_files();
|
|
386
|
+
fixture_dir_path = fixture_write_result.fixture_dir_path;
|
|
387
|
+
fixture_client_file_path = fixture_write_result.client_file_path;
|
|
388
|
+
|
|
389
|
+
puppeteer_module = ensure_puppeteer_module();
|
|
390
|
+
if (!puppeteer_module) {
|
|
391
|
+
this.skip();
|
|
392
|
+
return;
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
try {
|
|
396
|
+
browser_instance = await launch_puppeteer_browser(puppeteer_module);
|
|
397
|
+
} catch {
|
|
398
|
+
this.skip();
|
|
399
|
+
}
|
|
400
|
+
});
|
|
401
|
+
|
|
402
|
+
after(async function () {
|
|
403
|
+
if (browser_instance) {
|
|
404
|
+
await browser_instance.close();
|
|
405
|
+
browser_instance = null;
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
clear_require_cache_for_fixture_dir(fixture_dir_path);
|
|
409
|
+
await remove_fixture_dir_if_exists(fixture_dir_path);
|
|
410
|
+
fixture_dir_path = null;
|
|
411
|
+
fixture_client_file_path = null;
|
|
412
|
+
});
|
|
413
|
+
|
|
414
|
+
it('bundles and runs project-local controls with default elimination', async function () {
|
|
415
|
+
const metrics = await run_project_local_controls_scenario({
|
|
416
|
+
browser_instance,
|
|
417
|
+
client_file_path: fixture_client_file_path,
|
|
418
|
+
fixture_dir_path
|
|
419
|
+
});
|
|
420
|
+
|
|
421
|
+
assert(metrics.js_bytes > 1000, 'Expected non-trivial JS bundle size for project-local controls');
|
|
422
|
+
assert(metrics.css_bytes > 100, 'Expected non-trivial CSS bundle size for project-local controls');
|
|
423
|
+
assert.strictEqual(
|
|
424
|
+
metrics.window_marker_count,
|
|
425
|
+
0,
|
|
426
|
+
'Expected default elimination to remove unused Window control code for project-local app'
|
|
427
|
+
);
|
|
428
|
+
});
|
|
429
|
+
|
|
430
|
+
it('keeps project-local controls working when elimination is disabled and default bundle stays smaller', async function () {
|
|
431
|
+
const default_metrics = await run_project_local_controls_scenario({
|
|
432
|
+
browser_instance,
|
|
433
|
+
client_file_path: fixture_client_file_path,
|
|
434
|
+
fixture_dir_path
|
|
435
|
+
});
|
|
436
|
+
const elimination_disabled_metrics = await run_project_local_controls_scenario({
|
|
437
|
+
browser_instance,
|
|
438
|
+
client_file_path: fixture_client_file_path,
|
|
439
|
+
fixture_dir_path,
|
|
440
|
+
allowed_warning_patterns: allowed_esbuild_warning_patterns,
|
|
441
|
+
bundler: {
|
|
442
|
+
elimination: {
|
|
443
|
+
enabled: false,
|
|
444
|
+
jsgui3_html_controls: {
|
|
445
|
+
enabled: false
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
});
|
|
450
|
+
|
|
451
|
+
assert(elimination_disabled_metrics.js_bytes > 1000, 'Expected non-trivial JS bundle size with elimination disabled');
|
|
452
|
+
assert(elimination_disabled_metrics.css_bytes > 100, 'Expected non-trivial CSS bundle size with elimination disabled');
|
|
453
|
+
assert(
|
|
454
|
+
elimination_disabled_metrics.window_marker_count > 0,
|
|
455
|
+
'Expected elimination-disabled bundle to retain Window control markers'
|
|
456
|
+
);
|
|
457
|
+
assert(
|
|
458
|
+
default_metrics.js_bytes < elimination_disabled_metrics.js_bytes,
|
|
459
|
+
'Expected default elimination JS bundle to stay smaller than elimination-disabled bundle'
|
|
460
|
+
);
|
|
461
|
+
});
|
|
462
|
+
});
|
package/tests/test-runner.js
CHANGED
|
@@ -38,6 +38,8 @@ class TestRunner {
|
|
|
38
38
|
'end-to-end.test.js',
|
|
39
39
|
'content-analysis.test.js',
|
|
40
40
|
'small-controls-bundle-size.test.js',
|
|
41
|
+
'control-elimination-static-bracket-access.test.js',
|
|
42
|
+
'control-elimination-root-feature-pruning.test.js',
|
|
41
43
|
'control-optimizer-cache-behavior.test.js',
|
|
42
44
|
'control-scan-manifest-regression.test.js',
|
|
43
45
|
'performance.test.js',
|
|
@@ -47,6 +49,7 @@ class TestRunner {
|
|
|
47
49
|
'playwright-smoke.test.js',
|
|
48
50
|
'jsgui3-html-examples.puppeteer.test.js',
|
|
49
51
|
'bundling-default-control-elimination.puppeteer.test.js',
|
|
52
|
+
'project-local-controls-bundling.puppeteer.test.js',
|
|
50
53
|
'window-examples.puppeteer.test.js',
|
|
51
54
|
'window-resource-integration.puppeteer.test.js'
|
|
52
55
|
];
|