jsgui3-server 0.0.144 → 0.0.145
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/jsgui3-html-improvement-ideas.md +162 -0
- package/docs/jsgui3-html-improvement-ideas.svg +151 -0
- package/examples/controls/14d) window, canvas globe/EarthGlobeRenderer.js +19 -14
- package/examples/controls/14d) window, canvas globe/pipeline/TransformStage.js +5 -5
- package/examples/jsgui3-html/01) mvvm-counter/client.js +648 -0
- package/examples/jsgui3-html/01) mvvm-counter/server.js +21 -0
- package/examples/jsgui3-html/02) date-transform/client.js +764 -0
- package/examples/jsgui3-html/02) date-transform/server.js +21 -0
- package/examples/jsgui3-html/03) form-validation/client.js +1045 -0
- package/examples/jsgui3-html/03) form-validation/server.js +21 -0
- package/examples/jsgui3-html/04) data-grid/client.js +738 -0
- package/examples/jsgui3-html/04) data-grid/server.js +21 -0
- package/examples/jsgui3-html/05) master-detail/client.js +649 -0
- package/examples/jsgui3-html/05) master-detail/server.js +21 -0
- package/examples/jsgui3-html/06) theming/client.js +514 -0
- package/examples/jsgui3-html/06) theming/server.js +21 -0
- package/examples/jsgui3-html/07) mixins/client.js +465 -0
- package/examples/jsgui3-html/07) mixins/server.js +21 -0
- package/examples/jsgui3-html/08) router/client.js +372 -0
- package/examples/jsgui3-html/08) router/server.js +21 -0
- package/examples/jsgui3-html/09) resource-transform/client.js +692 -0
- package/examples/jsgui3-html/09) resource-transform/server.js +21 -0
- package/examples/jsgui3-html/10) binding-debugger/client.js +810 -0
- package/examples/jsgui3-html/10) binding-debugger/server.js +21 -0
- package/examples/jsgui3-html/README.md +48 -0
- package/http/responders/static/Static_Route_HTTP_Responder.js +25 -20
- package/package.json +3 -3
- package/publishers/http-webpageorsite-publisher.js +3 -1
- package/serve-factory.js +12 -5
- package/server.js +103 -85
- package/tests/README.md +7 -0
- package/tests/end-to-end.test.js +336 -365
- package/tests/examples-controls.e2e.test.js +13 -1
- package/tests/fixtures/end-to-end-client.js +54 -0
- package/tests/fixtures/jsgui3-html/binding_debugger_expectations.json +15 -0
- package/tests/fixtures/jsgui3-html/counter_expectations.json +31 -0
- package/tests/fixtures/jsgui3-html/data_grid_expectations.json +26 -0
- package/tests/fixtures/jsgui3-html/date_transform_expectations.json +26 -0
- package/tests/fixtures/jsgui3-html/form_validation_expectations.json +27 -0
- package/tests/fixtures/jsgui3-html/master_detail_expectations.json +15 -0
- package/tests/fixtures/jsgui3-html/mixins_expectations.json +10 -0
- package/tests/fixtures/jsgui3-html/resource_transform_expectations.json +11 -0
- package/tests/fixtures/jsgui3-html/router_expectations.json +10 -0
- package/tests/fixtures/jsgui3-html/theming_expectations.json +10 -0
- package/tests/jsgui3-html-examples.puppeteer.test.js +537 -0
- package/tests/test-runner.js +1 -0
- package/tests/window-examples.puppeteer.test.js +217 -1
|
@@ -0,0 +1,537 @@
|
|
|
1
|
+
const assert = require('assert');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
const fs = require('fs').promises;
|
|
4
|
+
const { describe, it, before, after } = require('mocha');
|
|
5
|
+
|
|
6
|
+
const Server = require('../server');
|
|
7
|
+
const { get_free_port } = require('../port-utils');
|
|
8
|
+
|
|
9
|
+
const repo_root_path = path.join(__dirname, '..');
|
|
10
|
+
const examples_root_path = path.join(repo_root_path, 'examples', 'jsgui3-html');
|
|
11
|
+
const fixtures_root_path = path.join(__dirname, 'fixtures', 'jsgui3-html');
|
|
12
|
+
|
|
13
|
+
let puppeteer;
|
|
14
|
+
let browser_instance;
|
|
15
|
+
|
|
16
|
+
const launch_browser = async () => {
|
|
17
|
+
const launch_options = {
|
|
18
|
+
headless: true,
|
|
19
|
+
args: ['--no-sandbox', '--disable-setuid-sandbox']
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
if (process.env.PUPPETEER_EXECUTABLE_PATH) {
|
|
23
|
+
launch_options.executablePath = process.env.PUPPETEER_EXECUTABLE_PATH;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
return puppeteer.launch(launch_options);
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
const load_fixture = async (fixture_name) => {
|
|
30
|
+
const fixture_path = path.join(fixtures_root_path, fixture_name);
|
|
31
|
+
const raw_fixture = await fs.readFile(fixture_path, 'utf8');
|
|
32
|
+
return JSON.parse(raw_fixture);
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
const start_example_server = async ({ dir_name, ctrl_name }) => {
|
|
36
|
+
const example_dir_path = path.join(examples_root_path, dir_name);
|
|
37
|
+
const example_client_path = path.join(example_dir_path, 'client.js');
|
|
38
|
+
|
|
39
|
+
const jsgui = require(example_client_path);
|
|
40
|
+
const ctrl = jsgui.controls && jsgui.controls[ctrl_name];
|
|
41
|
+
assert(ctrl, `Missing exported control jsgui.controls.${ctrl_name} in ${example_client_path}`);
|
|
42
|
+
|
|
43
|
+
const server_instance = new Server({
|
|
44
|
+
Ctrl: ctrl,
|
|
45
|
+
src_path_client_js: example_client_path,
|
|
46
|
+
name: `examples/jsgui3-html/${dir_name}`
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
server_instance.allowed_addresses = ['127.0.0.1'];
|
|
50
|
+
|
|
51
|
+
await new Promise((resolve, reject) => {
|
|
52
|
+
const timeout = setTimeout(() => reject(new Error('Publisher ready timeout')), 60000);
|
|
53
|
+
server_instance.on('ready', () => {
|
|
54
|
+
clearTimeout(timeout);
|
|
55
|
+
resolve();
|
|
56
|
+
});
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
const port = await get_free_port();
|
|
60
|
+
await new Promise((resolve, reject) => {
|
|
61
|
+
server_instance.start(port, (err) => (err ? reject(err) : resolve()));
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
return { server_instance, port };
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
const stop_example_server = async (server_instance) => {
|
|
68
|
+
await new Promise((resolve) => server_instance.close(resolve));
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
const open_example_page = async (port) => {
|
|
72
|
+
const page = await browser_instance.newPage();
|
|
73
|
+
await page.setViewport({ width: 1280, height: 720 });
|
|
74
|
+
await page.goto(`http://127.0.0.1:${port}/`, { waitUntil: 'load' });
|
|
75
|
+
return page;
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
const wait_for_text = async (page, selector, expected_text) => {
|
|
79
|
+
await page.waitForFunction(
|
|
80
|
+
(selector_arg, expected_arg) => {
|
|
81
|
+
const element = document.querySelector(selector_arg);
|
|
82
|
+
if (!element) return false;
|
|
83
|
+
return element.textContent.trim() === expected_arg;
|
|
84
|
+
},
|
|
85
|
+
{},
|
|
86
|
+
selector,
|
|
87
|
+
expected_text
|
|
88
|
+
);
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
const wait_for_input_value = async (page, selector, expected_value) => {
|
|
92
|
+
await page.waitForFunction(
|
|
93
|
+
(selector_arg, expected_arg) => {
|
|
94
|
+
const element = document.querySelector(selector_arg);
|
|
95
|
+
if (!element) return false;
|
|
96
|
+
return element.value === expected_arg;
|
|
97
|
+
},
|
|
98
|
+
{},
|
|
99
|
+
selector,
|
|
100
|
+
expected_value
|
|
101
|
+
);
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
const wait_for_class = async (page, selector, class_name, expected_state) => {
|
|
105
|
+
await page.waitForFunction(
|
|
106
|
+
(selector_arg, class_arg, expected_arg) => {
|
|
107
|
+
const element = document.querySelector(selector_arg);
|
|
108
|
+
if (!element) return false;
|
|
109
|
+
return element.classList.contains(class_arg) === expected_arg;
|
|
110
|
+
},
|
|
111
|
+
{},
|
|
112
|
+
selector,
|
|
113
|
+
class_name,
|
|
114
|
+
expected_state
|
|
115
|
+
);
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
const ensure_classes = async (page, selector, expected_classes) => {
|
|
119
|
+
const class_list = await page.$eval(selector, (el) => Array.from(el.classList));
|
|
120
|
+
expected_classes.forEach((class_name) => {
|
|
121
|
+
assert(
|
|
122
|
+
class_list.includes(class_name),
|
|
123
|
+
`Expected ${selector} to include class '${class_name}', got ${class_list.join(', ')}`
|
|
124
|
+
);
|
|
125
|
+
});
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
const set_input_value = async (page, selector, next_value) => {
|
|
129
|
+
await page.$eval(
|
|
130
|
+
selector,
|
|
131
|
+
(el, value) => {
|
|
132
|
+
el.value = value;
|
|
133
|
+
el.dispatchEvent(new Event('input', { bubbles: true }));
|
|
134
|
+
el.dispatchEvent(new Event('change', { bubbles: true }));
|
|
135
|
+
},
|
|
136
|
+
next_value
|
|
137
|
+
);
|
|
138
|
+
};
|
|
139
|
+
|
|
140
|
+
const get_grid_names = async (page) => {
|
|
141
|
+
return page.$$eval('[data-test="grid-body"] tr', (rows) => {
|
|
142
|
+
return rows.map((row) => {
|
|
143
|
+
const cell = row.querySelector('[data-col="name"]');
|
|
144
|
+
return cell ? cell.textContent.trim() : '';
|
|
145
|
+
});
|
|
146
|
+
});
|
|
147
|
+
};
|
|
148
|
+
|
|
149
|
+
const wait_for_first_grid_name = async (page, expected_name) => {
|
|
150
|
+
await page.waitForFunction(
|
|
151
|
+
(expected_name_arg) => {
|
|
152
|
+
const first_row = document.querySelector('[data-test="grid-body"] tr');
|
|
153
|
+
if (!first_row) return false;
|
|
154
|
+
const cell = first_row.querySelector('[data-col="name"]');
|
|
155
|
+
if (!cell) return false;
|
|
156
|
+
return cell.textContent.trim() === expected_name_arg;
|
|
157
|
+
},
|
|
158
|
+
{},
|
|
159
|
+
expected_name
|
|
160
|
+
);
|
|
161
|
+
};
|
|
162
|
+
|
|
163
|
+
describe('JSGUI3-HTML Example Puppeteer Tests', function () {
|
|
164
|
+
this.timeout(180000);
|
|
165
|
+
|
|
166
|
+
before(async function () {
|
|
167
|
+
this.timeout(60000);
|
|
168
|
+
try {
|
|
169
|
+
puppeteer = require('puppeteer');
|
|
170
|
+
} catch (error) {
|
|
171
|
+
this.skip();
|
|
172
|
+
return;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
try {
|
|
176
|
+
browser_instance = await launch_browser();
|
|
177
|
+
} catch (error) {
|
|
178
|
+
this.skip();
|
|
179
|
+
}
|
|
180
|
+
});
|
|
181
|
+
|
|
182
|
+
after(async function () {
|
|
183
|
+
if (browser_instance) {
|
|
184
|
+
await browser_instance.close();
|
|
185
|
+
browser_instance = null;
|
|
186
|
+
}
|
|
187
|
+
});
|
|
188
|
+
|
|
189
|
+
it('supports MVVM bindings and validation in mvvm-counter example', async function () {
|
|
190
|
+
const expectations = await load_fixture('counter_expectations.json');
|
|
191
|
+
const { server_instance, port } = await start_example_server({
|
|
192
|
+
dir_name: '01) mvvm-counter',
|
|
193
|
+
ctrl_name: 'Demo_UI'
|
|
194
|
+
});
|
|
195
|
+
|
|
196
|
+
let page;
|
|
197
|
+
try {
|
|
198
|
+
page = await open_example_page(port);
|
|
199
|
+
await page.waitForSelector('[data-test="counter-display"]');
|
|
200
|
+
|
|
201
|
+
await wait_for_text(page, '[data-test="counter-display"]', expectations.initial.display_text);
|
|
202
|
+
await wait_for_text(page, '[data-test="counter-status"]', expectations.initial.status_text);
|
|
203
|
+
await ensure_classes(page, '[data-test="counter-display"]', expectations.initial.display_classes);
|
|
204
|
+
|
|
205
|
+
await page.click('[data-test="increment-button"]');
|
|
206
|
+
await wait_for_text(page, '[data-test="counter-display"]', expectations.after_increment.display_text);
|
|
207
|
+
await wait_for_text(page, '[data-test="counter-status"]', expectations.after_increment.status_text);
|
|
208
|
+
await ensure_classes(page, '[data-test="counter-display"]', expectations.after_increment.display_classes);
|
|
209
|
+
|
|
210
|
+
await page.click('[data-test="increment-button"]');
|
|
211
|
+
await wait_for_text(page, '[data-test="counter-display"]', expectations.after_second_increment.display_text);
|
|
212
|
+
await wait_for_text(page, '[data-test="counter-status"]', expectations.after_second_increment.status_text);
|
|
213
|
+
await ensure_classes(page, '[data-test="counter-display"]', expectations.after_second_increment.display_classes);
|
|
214
|
+
|
|
215
|
+
await set_input_value(page, '[data-test="step-input"]', '3');
|
|
216
|
+
await page.click('[data-test="increment-button"]');
|
|
217
|
+
await wait_for_text(page, '[data-test="counter-display"]', expectations.after_step_increment.display_text);
|
|
218
|
+
await wait_for_text(page, '[data-test="counter-status"]', expectations.after_step_increment.status_text);
|
|
219
|
+
await ensure_classes(page, '[data-test="counter-display"]', expectations.after_step_increment.display_classes);
|
|
220
|
+
|
|
221
|
+
await page.click('[data-test="reset-button"]');
|
|
222
|
+
await wait_for_text(page, '[data-test="counter-display"]', expectations.after_reset.display_text);
|
|
223
|
+
await wait_for_text(page, '[data-test="counter-status"]', expectations.after_reset.status_text);
|
|
224
|
+
await ensure_classes(page, '[data-test="counter-display"]', expectations.after_reset.display_classes);
|
|
225
|
+
|
|
226
|
+
await set_input_value(page, '[data-test="step-input"]', '0');
|
|
227
|
+
await wait_for_text(page, '[data-test="step-error"]', expectations.invalid_step.step_error);
|
|
228
|
+
await wait_for_class(page, '[data-test="increment-button"]', expectations.invalid_step.disabled_class, true);
|
|
229
|
+
await wait_for_class(page, '[data-test="decrement-button"]', expectations.invalid_step.disabled_class, true);
|
|
230
|
+
} finally {
|
|
231
|
+
if (page) {
|
|
232
|
+
await page.close();
|
|
233
|
+
}
|
|
234
|
+
await stop_example_server(server_instance);
|
|
235
|
+
}
|
|
236
|
+
});
|
|
237
|
+
|
|
238
|
+
it('transforms locale dates and validates ranges in date-transform example', async function () {
|
|
239
|
+
const expectations = await load_fixture('date_transform_expectations.json');
|
|
240
|
+
const { server_instance, port } = await start_example_server({
|
|
241
|
+
dir_name: '02) date-transform',
|
|
242
|
+
ctrl_name: 'Demo_UI'
|
|
243
|
+
});
|
|
244
|
+
|
|
245
|
+
let page;
|
|
246
|
+
try {
|
|
247
|
+
page = await open_example_page(port);
|
|
248
|
+
await page.waitForSelector('[data-test="iso-input"]');
|
|
249
|
+
|
|
250
|
+
await wait_for_input_value(page, '[data-test="iso-input"]', expectations.default.iso_value);
|
|
251
|
+
await wait_for_text(page, '[data-test="local-display"]', expectations.default.local_display);
|
|
252
|
+
await wait_for_text(page, '[data-test="format-text"]', expectations.default.format_text);
|
|
253
|
+
await wait_for_text(page, '[data-test="range-message"]', expectations.default.range_message);
|
|
254
|
+
|
|
255
|
+
await page.select('[data-test="locale-select"]', expectations.locale_gb.locale);
|
|
256
|
+
await wait_for_text(page, '[data-test="format-text"]', expectations.locale_gb.format_text);
|
|
257
|
+
await wait_for_text(page, '[data-test="local-display"]', expectations.locale_gb.local_display);
|
|
258
|
+
|
|
259
|
+
await set_input_value(page, '[data-test="locale-input"]', expectations.locale_gb.valid_input);
|
|
260
|
+
await wait_for_input_value(page, '[data-test="iso-input"]', expectations.locale_gb.iso_value);
|
|
261
|
+
|
|
262
|
+
await page.select('[data-test="locale-select"]', expectations.locale_us.locale);
|
|
263
|
+
await wait_for_text(page, '[data-test="format-text"]', expectations.locale_us.format_text);
|
|
264
|
+
await wait_for_text(page, '[data-test="local-display"]', expectations.locale_us.local_display);
|
|
265
|
+
|
|
266
|
+
await set_input_value(page, '[data-test="iso-input"]', expectations.out_of_range.iso_value);
|
|
267
|
+
await wait_for_text(page, '[data-test="range-message"]', expectations.out_of_range.range_message);
|
|
268
|
+
|
|
269
|
+
await page.select('[data-test="locale-select"]', expectations.locale_gb.locale);
|
|
270
|
+
await set_input_value(page, '[data-test="locale-input"]', expectations.locale_gb.invalid_input);
|
|
271
|
+
await wait_for_text(page, '[data-test="locale-error"]', expectations.locale_gb.error);
|
|
272
|
+
} finally {
|
|
273
|
+
if (page) {
|
|
274
|
+
await page.close();
|
|
275
|
+
}
|
|
276
|
+
await stop_example_server(server_instance);
|
|
277
|
+
}
|
|
278
|
+
});
|
|
279
|
+
|
|
280
|
+
it('validates registration fields in form-validation example', async function () {
|
|
281
|
+
const expectations = await load_fixture('form_validation_expectations.json');
|
|
282
|
+
const { server_instance, port } = await start_example_server({
|
|
283
|
+
dir_name: '03) form-validation',
|
|
284
|
+
ctrl_name: 'Demo_UI'
|
|
285
|
+
});
|
|
286
|
+
|
|
287
|
+
let page;
|
|
288
|
+
try {
|
|
289
|
+
page = await open_example_page(port);
|
|
290
|
+
await page.waitForSelector('[data-test="full-name-input"]');
|
|
291
|
+
|
|
292
|
+
await wait_for_text(page, '[data-test="full-name-error"]', expectations.initial.full_name_error);
|
|
293
|
+
await wait_for_text(page, '[data-test="email-error"]', expectations.initial.email_error);
|
|
294
|
+
await wait_for_text(page, '[data-test="password-error"]', expectations.initial.password_error);
|
|
295
|
+
await wait_for_text(page, '[data-test="confirm-password-error"]', expectations.initial.confirm_password_error);
|
|
296
|
+
await wait_for_text(page, '[data-test="status-text"]', expectations.initial.status_text);
|
|
297
|
+
|
|
298
|
+
await set_input_value(page, '[data-test="email-input"]', expectations.invalid_email.email);
|
|
299
|
+
await wait_for_text(page, '[data-test="email-error"]', expectations.invalid_email.error);
|
|
300
|
+
|
|
301
|
+
await set_input_value(page, '[data-test="full-name-input"]', expectations.valid.full_name);
|
|
302
|
+
await set_input_value(page, '[data-test="email-input"]', expectations.valid.email);
|
|
303
|
+
await set_input_value(page, '[data-test="website-input"]', expectations.valid.website);
|
|
304
|
+
await set_input_value(page, '[data-test="password-input"]', expectations.valid.password);
|
|
305
|
+
await set_input_value(page, '[data-test="confirm-password-input"]', expectations.valid.confirm_password);
|
|
306
|
+
|
|
307
|
+
await wait_for_text(page, '[data-test="summary-text"]', expectations.valid.summary_text);
|
|
308
|
+
await wait_for_text(page, '[data-test="status-text"]', expectations.valid.status_text);
|
|
309
|
+
await wait_for_class(page, '[data-test="submit-button"]', 'is-disabled', false);
|
|
310
|
+
|
|
311
|
+
await page.click('[data-test="submit-button"]');
|
|
312
|
+
await wait_for_text(page, '[data-test="feedback-text"]', expectations.submit.feedback);
|
|
313
|
+
} finally {
|
|
314
|
+
if (page) {
|
|
315
|
+
await page.close();
|
|
316
|
+
}
|
|
317
|
+
await stop_example_server(server_instance);
|
|
318
|
+
}
|
|
319
|
+
});
|
|
320
|
+
|
|
321
|
+
it('filters, sorts, and paginates in data-grid example', async function () {
|
|
322
|
+
const expectations = await load_fixture('data_grid_expectations.json');
|
|
323
|
+
const { server_instance, port } = await start_example_server({
|
|
324
|
+
dir_name: '04) data-grid',
|
|
325
|
+
ctrl_name: 'Demo_UI'
|
|
326
|
+
});
|
|
327
|
+
|
|
328
|
+
let page;
|
|
329
|
+
try {
|
|
330
|
+
page = await open_example_page(port);
|
|
331
|
+
await page.waitForSelector('[data-test="grid-body"]');
|
|
332
|
+
|
|
333
|
+
await wait_for_text(page, '[data-test="range-text"]', expectations.initial.range_text);
|
|
334
|
+
await wait_for_text(page, '[data-test="page-text"]', expectations.initial.page_text);
|
|
335
|
+
await wait_for_first_grid_name(page, expectations.initial.first_name);
|
|
336
|
+
|
|
337
|
+
const initial_names = await get_grid_names(page);
|
|
338
|
+
assert.strictEqual(initial_names.length, expectations.initial.row_count);
|
|
339
|
+
|
|
340
|
+
await set_input_value(page, '[data-test="search-input"]', expectations.search.query);
|
|
341
|
+
await wait_for_text(page, '[data-test="range-text"]', expectations.search.range_text);
|
|
342
|
+
await wait_for_text(page, '[data-test="page-text"]', expectations.search.page_text);
|
|
343
|
+
await wait_for_first_grid_name(page, expectations.search.first_name);
|
|
344
|
+
|
|
345
|
+
const search_names = await get_grid_names(page);
|
|
346
|
+
assert.strictEqual(search_names.length, expectations.search.row_count);
|
|
347
|
+
|
|
348
|
+
await set_input_value(page, '[data-test="search-input"]', '');
|
|
349
|
+
await wait_for_text(page, '[data-test="range-text"]', expectations.reset.range_text);
|
|
350
|
+
await wait_for_text(page, '[data-test="page-text"]', expectations.reset.page_text);
|
|
351
|
+
|
|
352
|
+
await page.click('[data-test="sort-score"]');
|
|
353
|
+
await wait_for_first_grid_name(page, expectations.sort_score.first_name);
|
|
354
|
+
|
|
355
|
+
await page.click('[data-test="next-page"]');
|
|
356
|
+
await wait_for_text(page, '[data-test="page-text"]', expectations.page_2.page_text);
|
|
357
|
+
await wait_for_first_grid_name(page, expectations.page_2.first_name);
|
|
358
|
+
} finally {
|
|
359
|
+
if (page) {
|
|
360
|
+
await page.close();
|
|
361
|
+
}
|
|
362
|
+
await stop_example_server(server_instance);
|
|
363
|
+
}
|
|
364
|
+
});
|
|
365
|
+
|
|
366
|
+
it('syncs selection in master-detail example', async function () {
|
|
367
|
+
const expectations = await load_fixture('master_detail_expectations.json');
|
|
368
|
+
const { server_instance, port } = await start_example_server({
|
|
369
|
+
dir_name: '05) master-detail',
|
|
370
|
+
ctrl_name: 'Demo_UI'
|
|
371
|
+
});
|
|
372
|
+
|
|
373
|
+
let page;
|
|
374
|
+
try {
|
|
375
|
+
page = await open_example_page(port);
|
|
376
|
+
await page.waitForSelector('[data-test="detail-title"]');
|
|
377
|
+
|
|
378
|
+
await wait_for_text(page, '[data-test="detail-title"]', expectations.initial.detail_title);
|
|
379
|
+
await wait_for_text(page, '[data-test="detail-role"]', expectations.initial.detail_role);
|
|
380
|
+
await wait_for_text(page, '[data-test="nav-text"]', expectations.initial.nav_text);
|
|
381
|
+
|
|
382
|
+
await page.click('[data-test="next-button"]');
|
|
383
|
+
await wait_for_text(page, '[data-test="detail-title"]', expectations.after_next.detail_title);
|
|
384
|
+
await wait_for_text(page, '[data-test="nav-text"]', expectations.after_next.nav_text);
|
|
385
|
+
|
|
386
|
+
await page.click('[data-test="master-item-3"]');
|
|
387
|
+
await wait_for_text(page, '[data-test="detail-title"]', expectations.last_item.detail_title);
|
|
388
|
+
await wait_for_text(page, '[data-test="nav-text"]', expectations.last_item.nav_text);
|
|
389
|
+
await wait_for_class(page, '[data-test="master-item-3"]', 'is-active', true);
|
|
390
|
+
await wait_for_class(page, '[data-test="next-button"]', 'is-disabled', true);
|
|
391
|
+
} finally {
|
|
392
|
+
if (page) {
|
|
393
|
+
await page.close();
|
|
394
|
+
}
|
|
395
|
+
await stop_example_server(server_instance);
|
|
396
|
+
}
|
|
397
|
+
});
|
|
398
|
+
|
|
399
|
+
it('switches token themes in theming example', async function () {
|
|
400
|
+
const expectations = await load_fixture('theming_expectations.json');
|
|
401
|
+
const { server_instance, port } = await start_example_server({
|
|
402
|
+
dir_name: '06) theming',
|
|
403
|
+
ctrl_name: 'Demo_UI'
|
|
404
|
+
});
|
|
405
|
+
|
|
406
|
+
let page;
|
|
407
|
+
try {
|
|
408
|
+
page = await open_example_page(port);
|
|
409
|
+
await page.waitForSelector('[data-test="theme-name"]');
|
|
410
|
+
|
|
411
|
+
await wait_for_text(page, '[data-test="theme-name"]', expectations.initial.theme_label);
|
|
412
|
+
await wait_for_text(page, '[data-test="token-accent"]', expectations.initial.accent_value);
|
|
413
|
+
|
|
414
|
+
await page.click('[data-test="theme-tide"]');
|
|
415
|
+
await wait_for_text(page, '[data-test="theme-name"]', expectations.tide.theme_label);
|
|
416
|
+
await wait_for_text(page, '[data-test="token-accent"]', expectations.tide.accent_value);
|
|
417
|
+
await wait_for_class(page, '[data-test="theme-tide"]', 'is-active', true);
|
|
418
|
+
} finally {
|
|
419
|
+
if (page) {
|
|
420
|
+
await page.close();
|
|
421
|
+
}
|
|
422
|
+
await stop_example_server(server_instance);
|
|
423
|
+
}
|
|
424
|
+
});
|
|
425
|
+
|
|
426
|
+
it('highlights mixin selections in mixins example', async function () {
|
|
427
|
+
const expectations = await load_fixture('mixins_expectations.json');
|
|
428
|
+
const { server_instance, port } = await start_example_server({
|
|
429
|
+
dir_name: '07) mixins',
|
|
430
|
+
ctrl_name: 'Demo_UI'
|
|
431
|
+
});
|
|
432
|
+
|
|
433
|
+
let page;
|
|
434
|
+
try {
|
|
435
|
+
page = await open_example_page(port);
|
|
436
|
+
await page.waitForSelector('[data-test="selected-title"]');
|
|
437
|
+
|
|
438
|
+
await wait_for_text(page, '[data-test="selected-title"]', expectations.initial.selected_title);
|
|
439
|
+
await wait_for_text(page, '[data-test="selected-mixins"]', expectations.initial.selected_mixins_text);
|
|
440
|
+
|
|
441
|
+
await page.click('[data-test="mixins-card-resize"]');
|
|
442
|
+
await wait_for_text(page, '[data-test="selected-title"]', expectations.resizable.selected_title);
|
|
443
|
+
await wait_for_text(page, '[data-test="selected-mixins"]', expectations.resizable.selected_mixins_text);
|
|
444
|
+
await wait_for_class(page, '[data-test="mixins-card-resize"]', 'selected', true);
|
|
445
|
+
} finally {
|
|
446
|
+
if (page) {
|
|
447
|
+
await page.close();
|
|
448
|
+
}
|
|
449
|
+
await stop_example_server(server_instance);
|
|
450
|
+
}
|
|
451
|
+
});
|
|
452
|
+
|
|
453
|
+
it('switches hash routes in router example', async function () {
|
|
454
|
+
const expectations = await load_fixture('router_expectations.json');
|
|
455
|
+
const { server_instance, port } = await start_example_server({
|
|
456
|
+
dir_name: '08) router',
|
|
457
|
+
ctrl_name: 'Demo_UI'
|
|
458
|
+
});
|
|
459
|
+
|
|
460
|
+
let page;
|
|
461
|
+
try {
|
|
462
|
+
page = await open_example_page(port);
|
|
463
|
+
await page.waitForSelector('[data-test="route-title"]');
|
|
464
|
+
|
|
465
|
+
await wait_for_text(page, '[data-test="route-title"]', expectations.initial.route_title);
|
|
466
|
+
await wait_for_text(page, '[data-test="route-hint"]', expectations.initial.route_hint);
|
|
467
|
+
|
|
468
|
+
await page.click('[data-test="nav-metrics"]');
|
|
469
|
+
await wait_for_text(page, '[data-test="route-title"]', expectations.metrics.route_title);
|
|
470
|
+
await wait_for_text(page, '[data-test="route-hint"]', expectations.metrics.route_hint);
|
|
471
|
+
await wait_for_class(page, '[data-test="nav-metrics"]', 'is-active', true);
|
|
472
|
+
} finally {
|
|
473
|
+
if (page) {
|
|
474
|
+
await page.close();
|
|
475
|
+
}
|
|
476
|
+
await stop_example_server(server_instance);
|
|
477
|
+
}
|
|
478
|
+
});
|
|
479
|
+
|
|
480
|
+
it('runs the resource transform pipeline in resource-transform example', async function () {
|
|
481
|
+
const expectations = await load_fixture('resource_transform_expectations.json');
|
|
482
|
+
const { server_instance, port } = await start_example_server({
|
|
483
|
+
dir_name: '09) resource-transform',
|
|
484
|
+
ctrl_name: 'Demo_UI'
|
|
485
|
+
});
|
|
486
|
+
|
|
487
|
+
let page;
|
|
488
|
+
try {
|
|
489
|
+
page = await open_example_page(port);
|
|
490
|
+
await page.waitForSelector('[data-test="transform-status"]');
|
|
491
|
+
|
|
492
|
+
await wait_for_text(page, '[data-test="transform-status"]', expectations.initial.status_text);
|
|
493
|
+
await wait_for_text(page, '[data-test="summary-text"]', expectations.initial.summary_text);
|
|
494
|
+
|
|
495
|
+
await page.click('[data-test="run-transform"]');
|
|
496
|
+
await wait_for_text(page, '[data-test="transform-status"]', expectations.after_run.status_text);
|
|
497
|
+
await wait_for_text(page, '[data-test="summary-text"]', expectations.after_run.summary_text);
|
|
498
|
+
await wait_for_text(page, '[data-test="output-line-0"]', expectations.after_run.first_line);
|
|
499
|
+
} finally {
|
|
500
|
+
if (page) {
|
|
501
|
+
await page.close();
|
|
502
|
+
}
|
|
503
|
+
await stop_example_server(server_instance);
|
|
504
|
+
}
|
|
505
|
+
});
|
|
506
|
+
|
|
507
|
+
it('surfaces binding debugger summaries and logs in binding-debugger example', async function () {
|
|
508
|
+
const expectations = await load_fixture('binding_debugger_expectations.json');
|
|
509
|
+
const { server_instance, port } = await start_example_server({
|
|
510
|
+
dir_name: '10) binding-debugger',
|
|
511
|
+
ctrl_name: 'Demo_UI'
|
|
512
|
+
});
|
|
513
|
+
|
|
514
|
+
let page;
|
|
515
|
+
try {
|
|
516
|
+
page = await open_example_page(port);
|
|
517
|
+
await page.waitForSelector('[data-test="count-display"]');
|
|
518
|
+
|
|
519
|
+
await wait_for_text(page, '[data-test="count-display"]', expectations.initial.display_text);
|
|
520
|
+
await wait_for_text(page, '[data-test="status-text"]', expectations.initial.status_text);
|
|
521
|
+
await wait_for_text(page, '[data-test="summary-line"]', expectations.initial.summary_line);
|
|
522
|
+
|
|
523
|
+
await page.click('[data-test="increment-button"]');
|
|
524
|
+
await wait_for_text(page, '[data-test="count-display"]', expectations.after_increment.display_text);
|
|
525
|
+
await wait_for_text(page, '[data-test="log-entry-0"]', expectations.after_increment.log_entry);
|
|
526
|
+
|
|
527
|
+
await page.click('[data-test="enable-debug"]');
|
|
528
|
+
await wait_for_text(page, '[data-test="debug-status"]', expectations.after_enable.debug_status);
|
|
529
|
+
await wait_for_text(page, '[data-test="log-entry-0"]', expectations.after_enable.log_entry);
|
|
530
|
+
} finally {
|
|
531
|
+
if (page) {
|
|
532
|
+
await page.close();
|
|
533
|
+
}
|
|
534
|
+
await stop_example_server(server_instance);
|
|
535
|
+
}
|
|
536
|
+
});
|
|
537
|
+
});
|