kempo-testing-framework 1.2.4 → 1.3.3

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.
Files changed (54) hide show
  1. package/.github/copilot-instructions.md +105 -105
  2. package/.github/workflows/publish-npm.yml +29 -0
  3. package/CONTRIBUTING.md +107 -107
  4. package/gui/components/Collapsible.js +54 -54
  5. package/gui/components/Icon.js +151 -151
  6. package/gui/components/Logs.js +73 -73
  7. package/gui/components/SettingCheckbox.js +42 -42
  8. package/gui/components/SettingNumber.js +77 -77
  9. package/gui/components/SettingSelect.js +67 -67
  10. package/gui/components/TestFramework.js +378 -378
  11. package/gui/components/TestSuite.js +181 -181
  12. package/gui/components/TestSummary.js +189 -189
  13. package/gui/components/Theme.js +40 -40
  14. package/gui/components/settingsStore.js +46 -46
  15. package/gui/icons/fail.svg +1 -1
  16. package/gui/icons/pass.svg +1 -1
  17. package/gui/icons/running.svg +1 -1
  18. package/gui/icons/settings.svg +1 -1
  19. package/package.json +6 -1
  20. package/src/browserTestServer.js +115 -115
  21. package/src/cli.js +198 -198
  22. package/src/gui.js +15 -2
  23. package/src/runBrowserTests.js +87 -87
  24. package/src/runTestFiles.js +94 -94
  25. package/src/runTests.js +83 -83
  26. package/src/utils/logLevels.js +7 -7
  27. package/test.html +30 -30
  28. package/tests/Counter.js +33 -33
  29. package/tests/cli-flags.node-test.js +54 -54
  30. package/tests/cli-help.node-test.js +61 -61
  31. package/tests/cli-loglevel.node-test.js +40 -40
  32. package/tests/collapsible.browser-test.js +49 -49
  33. package/tests/counter.browser-test.js +140 -140
  34. package/tests/example.node-test.js +103 -103
  35. package/tests/fibonacci.js +92 -92
  36. package/tests/fibonacci.test.js +285 -285
  37. package/tests/icon.browser-test.js +54 -54
  38. package/tests/logs.browser-test.js +47 -47
  39. package/tests/setting-checkbox.browser-test.js +48 -48
  40. package/tests/setting-number.browser-test.js +54 -54
  41. package/tests/setting-select.browser-test.js +47 -47
  42. package/tests/settings-store.browser-test.js +26 -26
  43. package/tests/src-browserTestServer.node-test.js +47 -47
  44. package/tests/src-cli.node-test.js +32 -32
  45. package/tests/src-findTests.node-test.js +41 -41
  46. package/tests/src-logLevels.node-test.js +29 -29
  47. package/tests/src-runBrowserTests.node-test.js +41 -41
  48. package/tests/src-runTestFiles.node-test.js +42 -42
  49. package/tests/src-runTests.node-test.js +56 -56
  50. package/tests/test-framework.browser-test.js +65 -65
  51. package/tests/test-summary.browser-test.js +78 -78
  52. package/tests/test.browser-test.js +56 -56
  53. package/tests/testfile.browser-test.js +60 -60
  54. package/tests/theme.browser-test.js +38 -38
@@ -1,77 +1,77 @@
1
- import { LitElement, html } from '../lit-all.min.js';
2
- import { getSettings, setSettings, subscribe } from './settingsStore.js';
3
-
4
- window.customElements.define('ktf-setting-number', class extends LitElement {
5
- static properties = {
6
- name: { type: String },
7
- label: { type: String },
8
- min: { type: Number },
9
- max: { type: Number },
10
- step: { type: Number },
11
- value: { state: true },
12
- suffix: { type: String },
13
- };
14
-
15
- constructor(){
16
- super();
17
- this.min = 0;
18
- this.step = 100;
19
- this.max = 600000; // 10 minutes
20
- this.suffix = '';
21
- }
22
-
23
- createRenderRoot() { return this; }
24
-
25
- connectedCallback() {
26
- super.connectedCallback();
27
- this.apply(getSettings());
28
- this.unsub = subscribe((s) => this.apply(s));
29
- }
30
- disconnectedCallback() {
31
- super.disconnectedCallback();
32
- if (this.unsub) this.unsub();
33
- }
34
-
35
- apply(s) {
36
- const v = this.name ? s?.[this.name] : undefined;
37
- this.value = (typeof v === 'number' && !Number.isNaN(v)) ? v : 0;
38
- }
39
-
40
- onChange(e) {
41
- let v = e.target.value;
42
- let n = parseInt(v, 10);
43
- if (Number.isNaN(n)) n = 0;
44
- if (this.min !== undefined && n < this.min) n = this.min;
45
- if (this.max !== undefined && n > this.max) n = this.max;
46
- if (this.name) setSettings({ [this.name]: n });
47
- }
48
-
49
- updated(changed) {
50
- if (changed.has('value')) {
51
- const id = `setting-${this.name || 'number'}`;
52
- const el = this.querySelector(`#${id}`);
53
- if (el && String(el.value) !== String(this.value ?? '')) el.value = String(this.value ?? '');
54
- }
55
- }
56
-
57
- render() {
58
- const id = `setting-${this.name || 'number'}`;
59
- return html`
60
- ${this.label ? html`<label for="${id}">${this.label}</label>` : ''}
61
- <div class="mb">
62
- <input
63
- id="${id}"
64
- type="number"
65
- min="${this.min}"
66
- max="${this.max}"
67
- step="${this.step}"
68
- .value=${String(this.value ?? '')}
69
- @change=${(e) => this.onChange(e)}
70
- style="width: 10rem;"
71
- class="d-ib"
72
- />
73
- ${this.suffix ? html`<span class="ml-xs">${this.suffix}</span>` : ''}
74
- </div>
75
- `;
76
- }
77
- });
1
+ import { LitElement, html } from '../lit-all.min.js';
2
+ import { getSettings, setSettings, subscribe } from './settingsStore.js';
3
+
4
+ window.customElements.define('ktf-setting-number', class extends LitElement {
5
+ static properties = {
6
+ name: { type: String },
7
+ label: { type: String },
8
+ min: { type: Number },
9
+ max: { type: Number },
10
+ step: { type: Number },
11
+ value: { state: true },
12
+ suffix: { type: String },
13
+ };
14
+
15
+ constructor(){
16
+ super();
17
+ this.min = 0;
18
+ this.step = 100;
19
+ this.max = 600000; // 10 minutes
20
+ this.suffix = '';
21
+ }
22
+
23
+ createRenderRoot() { return this; }
24
+
25
+ connectedCallback() {
26
+ super.connectedCallback();
27
+ this.apply(getSettings());
28
+ this.unsub = subscribe((s) => this.apply(s));
29
+ }
30
+ disconnectedCallback() {
31
+ super.disconnectedCallback();
32
+ if (this.unsub) this.unsub();
33
+ }
34
+
35
+ apply(s) {
36
+ const v = this.name ? s?.[this.name] : undefined;
37
+ this.value = (typeof v === 'number' && !Number.isNaN(v)) ? v : 0;
38
+ }
39
+
40
+ onChange(e) {
41
+ let v = e.target.value;
42
+ let n = parseInt(v, 10);
43
+ if (Number.isNaN(n)) n = 0;
44
+ if (this.min !== undefined && n < this.min) n = this.min;
45
+ if (this.max !== undefined && n > this.max) n = this.max;
46
+ if (this.name) setSettings({ [this.name]: n });
47
+ }
48
+
49
+ updated(changed) {
50
+ if (changed.has('value')) {
51
+ const id = `setting-${this.name || 'number'}`;
52
+ const el = this.querySelector(`#${id}`);
53
+ if (el && String(el.value) !== String(this.value ?? '')) el.value = String(this.value ?? '');
54
+ }
55
+ }
56
+
57
+ render() {
58
+ const id = `setting-${this.name || 'number'}`;
59
+ return html`
60
+ ${this.label ? html`<label for="${id}">${this.label}</label>` : ''}
61
+ <div class="mb">
62
+ <input
63
+ id="${id}"
64
+ type="number"
65
+ min="${this.min}"
66
+ max="${this.max}"
67
+ step="${this.step}"
68
+ .value=${String(this.value ?? '')}
69
+ @change=${(e) => this.onChange(e)}
70
+ style="width: 10rem;"
71
+ class="d-ib"
72
+ />
73
+ ${this.suffix ? html`<span class="ml-xs">${this.suffix}</span>` : ''}
74
+ </div>
75
+ `;
76
+ }
77
+ });
@@ -1,67 +1,67 @@
1
- import { LitElement, html } from '../lit-all.min.js';
2
- import { getSettings, setSettings, subscribe } from './settingsStore.js';
3
-
4
- const PRESETS = {
5
- logLevel: [
6
- { value: '0', label: 'Silent: Summary only' },
7
- { value: '1', label: 'Minimal: Summary and test statuses' },
8
- { value: '2', label: 'Normal: Summary, statuses, and logs for failures' },
9
- { value: '3', label: 'Verbose: All test logs' },
10
- { value: '4', label: 'Debug: All test logs and framework internal logs' },
11
- ],
12
- theme: [
13
- { value: 'auto', label: 'Auto (system)' },
14
- { value: 'light', label: 'Light' },
15
- { value: 'dark', label: 'Dark' },
16
- ],
17
- };
18
-
19
- window.customElements.define('ktf-setting-select', class extends LitElement {
20
- static properties = {
21
- name: { type: String },
22
- label: { type: String },
23
- value: { state: true },
24
- };
25
-
26
- createRenderRoot() { return this; }
27
-
28
- connectedCallback() {
29
- super.connectedCallback();
30
- this.apply(getSettings());
31
- this.unsub = subscribe((s) => this.apply(s));
32
- }
33
- disconnectedCallback() {
34
- super.disconnectedCallback();
35
- if (this.unsub) this.unsub();
36
- }
37
-
38
- apply(s) {
39
- const v = this.name ? s?.[this.name] : undefined;
40
- this.value = v !== undefined && v !== null ? String(v) : '';
41
- }
42
-
43
- onChange(e) {
44
- let v = e.target.value;
45
- if (/^-?\d+$/.test(v)) v = parseInt(v, 10);
46
- if (this.name) setSettings({ [this.name]: v });
47
- }
48
-
49
- updated(changed) {
50
- if (changed.has('value')) {
51
- const id = `setting-${this.name || 'select'}`;
52
- const el = this.querySelector(`#${id}`);
53
- if (el && el.value !== String(this.value ?? '')) el.value = String(this.value ?? '');
54
- }
55
- }
56
-
57
- render() {
58
- const options = PRESETS[this.name] || [];
59
- const id = `setting-${this.name || 'select'}`;
60
- return html`
61
- ${this.label ? html`<label for="${id}">${this.label}</label>` : ''}
62
- <select id="${id}" class="mb" .value=${this.value ?? ''} @change=${(e) => this.onChange(e)}>
63
- ${options.map(o => html`<option value="${o.value}">${o.label}</option>`)}
64
- </select>
65
- `;
66
- }
67
- });
1
+ import { LitElement, html } from '../lit-all.min.js';
2
+ import { getSettings, setSettings, subscribe } from './settingsStore.js';
3
+
4
+ const PRESETS = {
5
+ logLevel: [
6
+ { value: '0', label: 'Silent: Summary only' },
7
+ { value: '1', label: 'Minimal: Summary and test statuses' },
8
+ { value: '2', label: 'Normal: Summary, statuses, and logs for failures' },
9
+ { value: '3', label: 'Verbose: All test logs' },
10
+ { value: '4', label: 'Debug: All test logs and framework internal logs' },
11
+ ],
12
+ theme: [
13
+ { value: 'auto', label: 'Auto (system)' },
14
+ { value: 'light', label: 'Light' },
15
+ { value: 'dark', label: 'Dark' },
16
+ ],
17
+ };
18
+
19
+ window.customElements.define('ktf-setting-select', class extends LitElement {
20
+ static properties = {
21
+ name: { type: String },
22
+ label: { type: String },
23
+ value: { state: true },
24
+ };
25
+
26
+ createRenderRoot() { return this; }
27
+
28
+ connectedCallback() {
29
+ super.connectedCallback();
30
+ this.apply(getSettings());
31
+ this.unsub = subscribe((s) => this.apply(s));
32
+ }
33
+ disconnectedCallback() {
34
+ super.disconnectedCallback();
35
+ if (this.unsub) this.unsub();
36
+ }
37
+
38
+ apply(s) {
39
+ const v = this.name ? s?.[this.name] : undefined;
40
+ this.value = v !== undefined && v !== null ? String(v) : '';
41
+ }
42
+
43
+ onChange(e) {
44
+ let v = e.target.value;
45
+ if (/^-?\d+$/.test(v)) v = parseInt(v, 10);
46
+ if (this.name) setSettings({ [this.name]: v });
47
+ }
48
+
49
+ updated(changed) {
50
+ if (changed.has('value')) {
51
+ const id = `setting-${this.name || 'select'}`;
52
+ const el = this.querySelector(`#${id}`);
53
+ if (el && el.value !== String(this.value ?? '')) el.value = String(this.value ?? '');
54
+ }
55
+ }
56
+
57
+ render() {
58
+ const options = PRESETS[this.name] || [];
59
+ const id = `setting-${this.name || 'select'}`;
60
+ return html`
61
+ ${this.label ? html`<label for="${id}">${this.label}</label>` : ''}
62
+ <select id="${id}" class="mb" .value=${this.value ?? ''} @change=${(e) => this.onChange(e)}>
63
+ ${options.map(o => html`<option value="${o.value}">${o.label}</option>`)}
64
+ </select>
65
+ `;
66
+ }
67
+ });