@magnit-ce/code-tests 0.0.20 → 0.1.1

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.
@@ -12,7 +12,7 @@ export declare class CodeTestElement extends HTMLElement {
12
12
  connectedCallback(): void;
13
13
  enable(): void;
14
14
  disable(): void;
15
- runTest(contextManager: ContextManager, testContext: TestContext): Promise<void>;
15
+ runTest(contextManager: CodeTestsContext, testContext: TestContext): Promise<void>;
16
16
  reset(): void;
17
17
  getMessageElement(): HTMLElement;
18
18
  static observedAttributes: string[];
@@ -29,8 +29,27 @@ export declare const CodeTestEvent: {
29
29
  Cancel: string;
30
30
  Context: string;
31
31
  Reset: string;
32
+ TestEnd: string;
33
+ Init: string;
34
+ Enabled: string;
32
35
  };
33
36
 
37
+ declare class CodeTestsContext {
38
+ #private;
39
+ codeTestsElement: CodeTestsElement;
40
+ constructor(parent: CodeTestsElement);
41
+ loadTests(path?: string): Promise<void>;
42
+ shouldContinueRunningTests: boolean;
43
+ runTests(tests: CodeTestElement[]): Promise<void>;
44
+ runTest(test: CodeTestElement | undefined, inLoop: boolean, testContext?: TestContext): Promise<void>;
45
+ runHook(testStateName: keyof Pick<CodeTestsState, 'requiredBeforeAnyState' | 'requiredAfterAnyState' | 'beforeEachState' | 'afterEachState' | 'beforeAllState' | 'afterAllState'>, test: CodeTestElement | undefined, testContext: TestContext): Promise<string | void | HTMLElement | TestResult | typeof NOTESTDEFINED>;
46
+ parseTestResult(result: TestResultType | typeof NOTESTDEFINED, finishedTest: boolean, error?: Error): {
47
+ result: string | HTMLElement;
48
+ resultCategory: TestResultCategory;
49
+ };
50
+ createTestContext(testElement?: CodeTestElement): Promise<TestContext>;
51
+ }
52
+
34
53
  export declare class CodeTestsElement extends HTMLElement {
35
54
  #private;
36
55
  state: CodeTestsState;
@@ -74,22 +93,6 @@ export declare type CodeTestState = {
74
93
  afterEachState?: TestResultState;
75
94
  };
76
95
 
77
- declare class ContextManager {
78
- #private;
79
- codeTestsElement: CodeTestsElement;
80
- constructor(parent: CodeTestsElement);
81
- loadTests(path?: string): Promise<void>;
82
- shouldContinueRunningTests: boolean;
83
- runTests(tests: CodeTestElement[]): Promise<void>;
84
- runTest(test: CodeTestElement | undefined, inLoop: boolean, testContext?: TestContext): Promise<void>;
85
- runHook(testStateName: keyof Pick<CodeTestsState, 'requiredBeforeAnyState' | 'requiredAfterAnyState' | 'beforeEachState' | 'afterEachState' | 'beforeAllState' | 'afterAllState'>, test: CodeTestElement | undefined, testContext: TestContext): Promise<string | void | HTMLElement | TestResult | typeof NOTESTDEFINED>;
86
- parseTestResult(result: TestResultType | typeof NOTESTDEFINED, finishedTest: boolean, error?: Error): {
87
- result: string | HTMLElement;
88
- resultCategory: TestResultCategory;
89
- };
90
- createTestContext(testElement?: CodeTestElement): Promise<TestContext>;
91
- }
92
-
93
96
  export declare function createElementFromTemplate(target: string | HTMLTemplateElement, parent?: HTMLElement): HTMLElement;
94
97
 
95
98
  export declare function expect<T>(value: T): TestPromise<T>;
@@ -18,15 +18,7 @@ const style = `:host
18
18
  --border-process: solid 1px var(--primary-process);
19
19
 
20
20
 
21
-
22
- --surface-test-summary: var(--uchu-gray);
23
- --surface-hook-summary: var(--uchu-light-purple);
24
- --surface-hook-any-summary: var(--uchu-light-blue);
25
-
26
- --border-test: solid 1px var(--uchu-dark-gray);
27
- --border-hook: solid 1px var(--uchu-dark-purple);
28
- --border-hook-any: solid 1px var(--uchu-dark-blue);
29
- --border-button: solid 1px var(--uchu-blue);
21
+ --surface-footer: rgb(0 0 0 / .04);
30
22
 
31
23
  --success-icon: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="%232e943a" d="M20.285 2l-11.285 11.567-5.286-5.011-3.714 3.716 9 8.728 15-15.285z"/></svg>');
32
24
  --info-icon: url('data:image/svg+xml,%3Csvg%20viewBox%3D%220%200%2022.812714%2022.814663%22%20version%3D%221.1%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20xmlns%3Asvg%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%3Cpath%20style%3D%22fill%3Atransparent%3Bstroke%3Atransparent%3Bstroke-width%3A0.999999%3Bstroke-linejoin%3Around%3Bstroke-miterlimit%3A6.3%3Bstroke-dasharray%3Anone%3Bstroke-dashoffset%3A29.2913%3Bstroke-opacity%3A1%22%20d%3D%22M%2022.295505%2C11.407332%20A%2010.889144%2C10.889144%200%200%201%2011.406424%2C22.296479%2010.889144%2C10.889144%200%200%201%200.51720881%2C11.407332%2010.889144%2C10.889144%200%200%201%2011.406424%2C0.51818382%2010.889144%2C10.889144%200%200%201%2022.295505%2C11.407332%20Z%22%3E%3C%2Fpath%3E%3Cpath%20d%3D%22m%2013.945668%2C4.3053761%20c%200.150778%2C-0.96462%20-0.30687%2C-1.43709%20-1.36997%2C-1.43709%20-1.063%2C0%20-1.668452%2C0.47247%20-1.81923%2C1.43709%20-0.150779%2C0.96462%200.306971%2C1.43708%201.369971%2C1.43708%201.004%2C0%201.66845%2C-0.47246%201.819229%2C-1.43708%20z%20M%2011.693889%2C17.829726%2013.373994%2C7.0811161%20h%20-2.9333%20L%208.7605887%2C17.829726%20Z%22%20style%3D%22font-size%3A19.6861px%3Bfont-family%3APassageway%3B-inkscape-font-specification%3APassageway%3Bfill%3A%23a30d30%3Bstroke-width%3A2.5%3Bstroke-linejoin%3Around%3Bstroke-miterlimit%3A6.3%3Bstroke-dashoffset%3A29.2913%22%20aria-label%3D%22i%22%3E%3C%2Fpath%3E%3C%2Fsvg%3E');
@@ -38,6 +30,13 @@ const style = `:host
38
30
  font-family: sans-serif;
39
31
  font-size: 12px;
40
32
  }
33
+ @media (prefers-color-scheme: dark)
34
+ {
35
+ :host
36
+ {
37
+ --surface-footer: rgb(255 255 255 / .1);
38
+ }
39
+ }
41
40
 
42
41
  #header
43
42
  {
@@ -45,18 +44,20 @@ const style = `:host
45
44
  display: flex;
46
45
  align-items: center;
47
46
  gap: var(--gap);
48
- padding: var(--gap-small) var(--gap);
49
47
  }
50
48
  #title
51
49
  {
52
50
  flex: 1;
51
+ white-space: nowrap;
52
+ overflow: hidden;
53
+ text-overflow: ellipsis;
53
54
  }
54
55
 
55
56
  #tests
56
57
  ,#component-content
57
58
  {
58
59
  display: grid;
59
- gap: var(--gap);
60
+ gap: var(--gap-small);
60
61
  grid-auto-rows: max-content;
61
62
  }
62
63
 
@@ -100,11 +101,13 @@ summary > .run-test-button
100
101
 
101
102
  summary:not(#component-summary)
102
103
  {
103
- padding: var(--gap-small) var(--gap);
104
+ padding: var(--gap-small);
104
105
  }
105
106
  #component-summary
106
107
  {
107
- padding-block: var(--gap-small);
108
+ padding: var(--gap) var(--gap-small);
109
+ border-bottom: solid 1px;
110
+ margin-bottom: var(--gap-small);
108
111
  }
109
112
 
110
113
 
@@ -128,6 +131,15 @@ details[open] > summary > .arrow-icon
128
131
  transform: rotate(0);
129
132
  }
130
133
 
134
+ #enabled
135
+ {
136
+ display: none;
137
+ }
138
+ :host([optional]) #enabled
139
+ {
140
+ display: block;
141
+ }
142
+
131
143
  /* Result Icon */
132
144
  .result-icon
133
145
  {
@@ -297,6 +309,10 @@ code-test
297
309
  code-test > details > summary > .description
298
310
  {
299
311
  flex: 1;
312
+ white-space: nowrap;
313
+ overflow: hidden;
314
+ text-overflow: ellipsis;
315
+ width: 0; /* hack to make overflow work right; "contain: inline-size" is correct fix, but it's too new to implement on jan 25, 2026; */
300
316
  }
301
317
  :host(:not([ordered="false"])) code-test > details > summary > .description::before
302
318
  {
@@ -308,7 +324,6 @@ code-test > details > summary > .description
308
324
  {
309
325
  border-radius: 3px;
310
326
  border: solid 1px;
311
- /* background: rgb(0 0 0 / .2); */
312
327
  font-family: monospace;
313
328
  text-transform: uppercase;
314
329
  font-size: 11px;
@@ -319,6 +334,10 @@ code-test > details > summary > .description
319
334
  {
320
335
  display: flex;
321
336
  justify-content: flex-end;
337
+ border-top: solid 1px;
338
+ border-bottom: solid 1px;
339
+ background: var(--surface-footer);
340
+ margin-top: var(--gap-small);
322
341
  }
323
342
  #group-results
324
343
  {
@@ -327,6 +346,19 @@ code-test > details > summary > .description
327
346
  padding: var(--gap);
328
347
  }
329
348
 
349
+ #results-progress-value
350
+ {
351
+ min-width: 40px;
352
+ width: auto;
353
+ }
354
+
355
+ #duration
356
+ ,#passed-total-pair
357
+ ,#passed-total-percent
358
+ {
359
+ white-space: nowrap;
360
+ }
361
+
330
362
  #passed-total-percent::before
331
363
  {
332
364
  content: '(';
@@ -341,7 +373,7 @@ code-test > details > summary > .description
341
373
  from { transform: rotate(0deg); }
342
374
  to { transform: rotate(360deg); }
343
375
  }`;
344
- const html = '<details id="component-details" class="details">\n <summary id="component-summary" class="summary">\n <svg class="icon arrow-icon"><use href="#icon-definition_arrow"></use></svg>\n <slot name="header">\n <header id="header">\n <span id="component-result-icon" class="result-icon"></span>\n <span id="title"><slot name="title"><span id="title-text">Tests</span></slot></span>\n <slot name="reload-button">\n <button type="button" id="reload-button" title="Reload">\n <slot name="reload-button-content">\n <slot name="reload-button-icon"><svg class="icon reset-icon reload-button-icon"><use href="#icon-definition_reset"></use></svg></slot>\n <slot name="reload-button-label"><span class="reload-button-label button-label label icon">Reload</span></slot>\n </slot>\n </button>\n </slot>\n <slot name="run-all-button">\n <button type="button" id="run-all-button" title="Run All Tests">\n <slot name="run-all-button-content">\n <slot name="run-all-button-icon"><svg class="icon arrow-icon run-button-icon run-all-button-icon"><use href="#icon-definition_arrow"></use></svg></slot>\n <slot name="run-all-button-label"><span class="run-all-button-label run-button-label button-label label icon">Run Tests</span></slot>\n </slot>\n </button>\n </slot>\n <slot name="header-details"></slot>\n </header>\n </slot>\n </summary>\n <div id="component-content" class="content">\n <details id="required-before-any-details" class="hook">\n <summary id="required-before-any-summary">\n <svg class="icon arrow-icon"><use href="#icon-definition_arrow"></use></svg>\n <span id="required-before-any-result-icon" class="result-icon"></span>\n <span id="required-before-any-description" class="description hook-name">Required Before Any Hook</span>\n </summary>\n <div class="results">\n <div id="required-before-any-results" class="result message"></div>\n </div>\n </details>\n <details id="before-all-details" class="hook">\n <summary id="before-all-summary">\n <svg class="icon arrow-icon"><use href="#icon-definition_arrow"></use></svg>\n <span id="before-all-result-icon" class="result-icon"></span>\n <span id="before-all-description" class="description hook-name">Before All Hook</span>\n </summary>\n <div class="results">\n <div id="before-all-results" class="result message"></div>\n </div>\n </details>\n <div id="tests"></div>\n <details id="after-all-details" class="hook">\n <summary id="after-all-summary">\n <svg class="icon arrow-icon"><use href="#icon-definition_arrow"></use></svg>\n <span id="after-all-result-icon" class="result-icon"></span>\n <span id="after-all-description" class="description hook-name">After All Hook</span>\n </summary>\n <div class="results">\n <div id="after-all-results" class="result message"></div>\n </div>\n </details>\n <details id="required-after-any-details" class="hook">\n <summary id="required-after-any-summary">\n <svg class="icon arrow-icon"><use href="#icon-definition_arrow"></use></svg>\n <span id="required-after-any-result-icon" class="result-icon"></span>\n <span id="required-after-any-description" class="description hook-name">Required After Any Hook</span>\n </summary>\n <div class="results">\n <div id="required-after-any-results" class="result message"></div>\n </div>\n </details>\n </div>\n \n <slot name="footer">\n <foooter id="footer">\n <span id="group-results">\n <span id="duration">\n <span id="duration-label">Duration</span>\n <span id="duration-value"></span>\n <span id="duration-unit">ms</span>\n </span>\n <span id="results-progress">\n <progress id="results-progress-value"></progress>\n </span>\n <span id="passed-total-pair">\n <span id="total-tests-passed-value"></span>\n <span id="passed-total-delimiter">of</span>\n <span id="total-tests-count-value"></span>\n <span id="total-tests-passed-label">Passed</span>\n </span>\n <span id="passed-total-percent">\n <span id="passed-total-percent-value"></span>\n <span id="passed-total-percent-label">%</span>\n </span>\n </span>\n </foooter>\n </slot>\n</details>\n<template id="prompt-template">\n <div class="prompt">\n <div class="prompt-display">\n <span class="icon prompt-icon"></span>\n <span class="label prompt-label"></span>\n </div>\n <div class="prompt-actions">\n <button class="prompt-button accept" type="button">Accept</button>\n <button class="prompt-button reject" type="button">Reject</button>\n </div>\n </div>\n</template>\n<div id="icon-definitions" style="display: none;">\n <svg id="icon-definition_arrow" viewBox="0 0 8 8" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg">\n <path d="m3.26,6.81l-2.93,-4.69c-0.37,-0.58 0.05,-1.34 0.74,-1.34l5.87,0c0.69,0 1.11,0.76 0.74,1.34l-2.93,4.69c-0.35,0.55 -1.14,0.55 -1.49,0z" fill="var(--fill-color, currentcolor)" />\n </svg>\n <svg id="icon-definition_reset" class="icon reset" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg">\n <path\n style="fill:var(--fill-color, currentcolor);stroke-linecap:round;stroke-linejoin:round;-inkscape-stroke:none;paint-order:markers stroke fill"\n d="M 5.484375 0.43359375 A 1.5224222 1.5224222 0 0 0 4.2558594 1.2011719 L 0.99804688 6.9453125 A 1.5224222 1.5224222 0 0 0 2.5488281 9.2011719 L 9.34375 8.171875 A 1.5224222 1.5224222 0 0 0 10.332031 5.7539062 L 9.4746094 4.6113281 C 11.949333 3.8016718 14.718209 4.258351 16.822266 5.9570312 C 19.510764 8.1275534 20.456787 11.785479 19.160156 14.988281 C 17.863527 18.191083 14.6405 20.15873 11.199219 19.847656 C 7.7579362 19.536584 4.9376009 17.022073 4.2363281 13.638672 A 1.5 1.5 0 0 0 2.4628906 12.474609 A 1.5 1.5 0 0 0 1.2988281 14.248047 C 2.2656928 18.912838 6.1831413 22.407052 10.927734 22.835938 C 15.672328 23.264824 20.153706 20.531029 21.941406 16.115234 C 23.729107 11.699441 22.413741 6.6156073 18.707031 3.6230469 C 16.853677 2.1267667 14.61485 1.3255701 12.347656 1.2324219 C 10.738216 1.1662975 9.1150542 1.4598646 7.6035156 2.1132812 L 6.7988281 1.0390625 A 1.5224222 1.5224222 0 0 0 5.484375 0.43359375 z " />\n </svg>\n <svg id="icon-definition_cancel" class="icon cancel" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg">\n <path\n style="fill:var(--fill-color, currentcolor);stroke-linecap:round;stroke-linejoin:round;-inkscape-stroke:none;paint-order:markers stroke fill"\n d="M -7.063234 9.5244002 C -5.8135728 7.6769245 -5.0820528 5.453265 -5.0820528 3.0633809 C -5.0820529 -3.3096433 -10.278145 -8.5098163 -16.65117 -8.5098163 C -23.024193 -8.5098163 -28.22385 -3.3110105 -28.22385 3.0620137 C -28.22385 9.4350379 -23.025043 14.634694 -16.65202 14.634694 C -12.668879 14.634694 -9.1460028 12.603526 -7.063234 9.5244002 z M -9.5406311 7.8637601 C -11.076991 10.143147 -13.683157 11.63463 -16.652974 11.63463 C -19.960499 11.63463 -22.814085 9.782061 -24.244824 7.0543029 L -24.236684 7.0527515 L -8.1332524 3.983715 L -8.1305391 3.9831979 C -8.2815631 5.4121635 -8.7798709 6.7350751 -9.5406311 7.8637601 z M -9.0610781 -0.92890828 L -9.069218 -0.92735695 L -25.17265 2.1416796 L -25.175363 2.1421967 C -24.719122 -2.1725739 -21.093311 -5.5092358 -16.652928 -5.5092358 C -13.345403 -5.5092358 -10.491243 -3.6566663 -9.0610781 -0.92890828 z "\n transform="rotate(-124.20981)" />\n </svg>\n</div>';
376
+ const html = '<details id="component-details" class="details">\n <summary id="component-summary" class="summary">\n <svg class="icon arrow-icon"><use href="#icon-definition_arrow"></use></svg>\n <slot name="header">\n <header id="header">\n <span id="component-result-icon" class="result-icon"></span>\n <slot name="enabled-toggle">\n <input type="checkbox" name="enabled" id="enabled" title="Enabled?" checked />\n </slot>\n <span id="title"><slot name="title"><span id="title-text">Tests</span></slot></span>\n <slot name="reload-button">\n <button type="button" id="reload-button" title="Reload">\n <slot name="reload-button-content">\n <slot name="reload-button-icon"><svg class="icon reset-icon reload-button-icon"><use href="#icon-definition_reset"></use></svg></slot>\n <slot name="reload-button-label"><span class="reload-button-label button-label label icon">Reload</span></slot>\n </slot>\n </button>\n </slot>\n <slot name="run-all-button">\n <button type="button" id="run-all-button" title="Run All Tests">\n <slot name="run-all-button-content">\n <slot name="run-all-button-icon"><svg class="icon arrow-icon run-button-icon run-all-button-icon"><use href="#icon-definition_arrow"></use></svg></slot>\n <slot name="run-all-button-label"><span class="run-all-button-label run-button-label button-label label icon">Run Tests</span></slot>\n </slot>\n </button>\n </slot>\n <slot name="header-details"></slot>\n </header>\n </slot>\n </summary>\n <div id="component-content" class="content">\n <details id="required-before-any-details" class="hook">\n <summary id="required-before-any-summary">\n <svg class="icon arrow-icon"><use href="#icon-definition_arrow"></use></svg>\n <span id="required-before-any-result-icon" class="result-icon"></span>\n <span id="required-before-any-description" class="description hook-name">Required Before Any Hook</span>\n </summary>\n <div class="results">\n <div id="required-before-any-results" class="result message"></div>\n </div>\n </details>\n <details id="before-all-details" class="hook">\n <summary id="before-all-summary">\n <svg class="icon arrow-icon"><use href="#icon-definition_arrow"></use></svg>\n <span id="before-all-result-icon" class="result-icon"></span>\n <span id="before-all-description" class="description hook-name">Before All Hook</span>\n </summary>\n <div class="results">\n <div id="before-all-results" class="result message"></div>\n </div>\n </details>\n <div id="tests"></div>\n <details id="after-all-details" class="hook">\n <summary id="after-all-summary">\n <svg class="icon arrow-icon"><use href="#icon-definition_arrow"></use></svg>\n <span id="after-all-result-icon" class="result-icon"></span>\n <span id="after-all-description" class="description hook-name">After All Hook</span>\n </summary>\n <div class="results">\n <div id="after-all-results" class="result message"></div>\n </div>\n </details>\n <details id="required-after-any-details" class="hook">\n <summary id="required-after-any-summary">\n <svg class="icon arrow-icon"><use href="#icon-definition_arrow"></use></svg>\n <span id="required-after-any-result-icon" class="result-icon"></span>\n <span id="required-after-any-description" class="description hook-name">Required After Any Hook</span>\n </summary>\n <div class="results">\n <div id="required-after-any-results" class="result message"></div>\n </div>\n </details>\n </div>\n \n <slot name="footer">\n <foooter id="footer">\n <span id="group-results">\n <span id="duration">\n <span id="duration-label">Duration</span>\n <span id="duration-value">0</span>\n <span id="duration-unit">ms</span>\n </span>\n <span id="results-progress">\n <progress id="results-progress-value"></progress>\n </span>\n <span id="passed-total-pair">\n <span id="total-tests-passed-value"></span>\n <span id="passed-total-delimiter">of</span>\n <span id="total-tests-count-value"></span>\n <span id="total-tests-passed-label">Passed</span>\n </span>\n <span id="passed-total-percent">\n <span id="passed-total-percent-value">0</span>\n <span id="passed-total-percent-label">%</span>\n </span>\n </span>\n </foooter>\n </slot>\n</details>\n<template id="prompt-template">\n <div class="prompt">\n <div class="prompt-display">\n <span class="icon prompt-icon"></span>\n <span class="label prompt-label"></span>\n </div>\n <div class="prompt-actions">\n <button class="prompt-button accept" type="button">Accept</button>\n <button class="prompt-button reject" type="button">Reject</button>\n </div>\n </div>\n</template>\n<div id="icon-definitions" style="display: none;">\n <svg id="icon-definition_arrow" viewBox="0 0 8 8" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg">\n <path d="m3.26,6.81l-2.93,-4.69c-0.37,-0.58 0.05,-1.34 0.74,-1.34l5.87,0c0.69,0 1.11,0.76 0.74,1.34l-2.93,4.69c-0.35,0.55 -1.14,0.55 -1.49,0z" fill="var(--fill-color, currentcolor)" />\n </svg>\n <svg id="icon-definition_reset" class="icon reset" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg">\n <path\n style="fill:var(--fill-color, currentcolor);stroke-linecap:round;stroke-linejoin:round;-inkscape-stroke:none;paint-order:markers stroke fill"\n d="M 5.484375 0.43359375 A 1.5224222 1.5224222 0 0 0 4.2558594 1.2011719 L 0.99804688 6.9453125 A 1.5224222 1.5224222 0 0 0 2.5488281 9.2011719 L 9.34375 8.171875 A 1.5224222 1.5224222 0 0 0 10.332031 5.7539062 L 9.4746094 4.6113281 C 11.949333 3.8016718 14.718209 4.258351 16.822266 5.9570312 C 19.510764 8.1275534 20.456787 11.785479 19.160156 14.988281 C 17.863527 18.191083 14.6405 20.15873 11.199219 19.847656 C 7.7579362 19.536584 4.9376009 17.022073 4.2363281 13.638672 A 1.5 1.5 0 0 0 2.4628906 12.474609 A 1.5 1.5 0 0 0 1.2988281 14.248047 C 2.2656928 18.912838 6.1831413 22.407052 10.927734 22.835938 C 15.672328 23.264824 20.153706 20.531029 21.941406 16.115234 C 23.729107 11.699441 22.413741 6.6156073 18.707031 3.6230469 C 16.853677 2.1267667 14.61485 1.3255701 12.347656 1.2324219 C 10.738216 1.1662975 9.1150542 1.4598646 7.6035156 2.1132812 L 6.7988281 1.0390625 A 1.5224222 1.5224222 0 0 0 5.484375 0.43359375 z " />\n </svg>\n <svg id="icon-definition_cancel" class="icon cancel" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg">\n <path\n style="fill:var(--fill-color, currentcolor);stroke-linecap:round;stroke-linejoin:round;-inkscape-stroke:none;paint-order:markers stroke fill"\n d="M -7.063234 9.5244002 C -5.8135728 7.6769245 -5.0820528 5.453265 -5.0820528 3.0633809 C -5.0820529 -3.3096433 -10.278145 -8.5098163 -16.65117 -8.5098163 C -23.024193 -8.5098163 -28.22385 -3.3110105 -28.22385 3.0620137 C -28.22385 9.4350379 -23.025043 14.634694 -16.65202 14.634694 C -12.668879 14.634694 -9.1460028 12.603526 -7.063234 9.5244002 z M -9.5406311 7.8637601 C -11.076991 10.143147 -13.683157 11.63463 -16.652974 11.63463 C -19.960499 11.63463 -22.814085 9.782061 -24.244824 7.0543029 L -24.236684 7.0527515 L -8.1332524 3.983715 L -8.1305391 3.9831979 C -8.2815631 5.4121635 -8.7798709 6.7350751 -9.5406311 7.8637601 z M -9.0610781 -0.92890828 L -9.069218 -0.92735695 L -25.17265 2.1416796 L -25.175363 2.1421967 C -24.719122 -2.1725739 -21.093311 -5.5092358 -16.652928 -5.5092358 C -13.345403 -5.5092358 -10.491243 -3.6566663 -9.0610781 -0.92890828 z "\n transform="rotate(-124.20981)" />\n </svg>\n</div>';
345
377
  const CodeTestEvent = {
346
378
  BeforeAll: "beforeall",
347
379
  AfterAll: "afterall",
@@ -351,7 +383,10 @@ const CodeTestEvent = {
351
383
  AfterHook: "afterhook",
352
384
  Cancel: "cancel",
353
385
  Context: "context",
354
- Reset: "reset"
386
+ Reset: "reset",
387
+ TestEnd: "testend",
388
+ Init: "init",
389
+ Enabled: "enabled"
355
390
  };
356
391
  const COMPONENT_TAG_NAME$1 = "code-test";
357
392
  class CodeTestElement extends HTMLElement {
@@ -441,7 +476,7 @@ class CodeTestElement extends HTMLElement {
441
476
  <summary class="test-summary" part="test-summary">
442
477
  <svg class="icon arrow-icon"><use href="#icon-definition_arrow"></use></svg>
443
478
  <div class="result-icon test-result-icon${this.state.testState?.resultCategory != "none" ? ` ${this.state.testState?.resultCategory}` : ""}" part="result-icon"></div>
444
- <span class="test-description description">${this.state.description}</span>
479
+ <span class="test-description description" title="${this.state.description}">${this.state.description}</span>
445
480
  ${this.state.testState?.duration != null && this.state.testState.duration > 0 ? `<span class="test-duration duration">
446
481
  <span class="test-duration-value">${this.state.testState.duration > 10 ? this.state.testState.duration.toFixed(0) : this.state.testState.duration.toFixed(2)}</span>
447
482
  <span class="test-duration-unit">ms</span>
@@ -594,7 +629,7 @@ if (customElements.get(COMPONENT_TAG_NAME$1) == null) {
594
629
  customElements.define(COMPONENT_TAG_NAME$1, CodeTestElement);
595
630
  }
596
631
  const NOTESTDEFINED = /* @__PURE__ */ Symbol("No Test Defined");
597
- class ContextManager {
632
+ class CodeTestsContext {
598
633
  codeTestsElement;
599
634
  // testContext?: TestContext;
600
635
  constructor(parent) {
@@ -818,6 +853,7 @@ class ContextManager {
818
853
  for (let i = 0; i < tests.length; i++) {
819
854
  tests[i].enable();
820
855
  }
856
+ this.codeTestsElement.dispatchEvent(new CustomEvent(CodeTestEvent.TestEnd, { bubbles: true, composed: true, cancelable: true, detail: { target: this } }));
821
857
  }
822
858
  async runHook(testStateName, test, testContext) {
823
859
  const testState = this.codeTestsElement.state[testStateName];
@@ -1107,12 +1143,12 @@ class CodeTestsElement extends HTMLElement {
1107
1143
  return "none";
1108
1144
  } else if (testCategory == "fail" || statesCategory == "fail") {
1109
1145
  return "fail";
1110
- } else if (testCategory == "success" && statesCategory == "success") {
1146
+ } else if (testCategory == "success" || statesCategory == "success") {
1111
1147
  return "success";
1112
1148
  }
1113
1149
  return "none";
1114
1150
  }
1115
- #contextManager;
1151
+ #context;
1116
1152
  constructor() {
1117
1153
  super();
1118
1154
  this.attachShadow({ mode: "open" });
@@ -1134,11 +1170,12 @@ class CodeTestsElement extends HTMLElement {
1134
1170
  this.#isInitializing = true;
1135
1171
  assignClassAndIdToPart(this.shadowRoot);
1136
1172
  this.addEventListener("click", this.#boundClickHandler);
1173
+ this.findElement("#enabled").addEventListener("change", this.#boundEnabledHandler);
1137
1174
  await new Promise((resolve) => requestAnimationFrame(() => {
1138
- this.#contextManager = new ContextManager(this);
1175
+ this.#context = new CodeTestsContext(this);
1139
1176
  this.#isInitialized = true;
1140
1177
  this.#isInitializing = false;
1141
- const allowAutoLoad = this.dispatchEvent(new CustomEvent("init", { bubbles: true, composed: true, cancelable: true, detail: { target: this } }));
1178
+ const allowAutoLoad = this.dispatchEvent(new CustomEvent(CodeTestEvent.Init, { bubbles: true, composed: true, cancelable: true, detail: { target: this } }));
1142
1179
  if (allowAutoLoad == false) {
1143
1180
  resolve();
1144
1181
  return;
@@ -1154,6 +1191,7 @@ class CodeTestsElement extends HTMLElement {
1154
1191
  }
1155
1192
  #destroy() {
1156
1193
  this.removeEventListener("click", this.#boundClickHandler);
1194
+ this.findElement("#enabled").removeEventListener("change", this.#boundEnabledHandler);
1157
1195
  this.#isInitialized = false;
1158
1196
  this.#isInitializing = false;
1159
1197
  }
@@ -1179,7 +1217,17 @@ class CodeTestsElement extends HTMLElement {
1179
1217
  return;
1180
1218
  }
1181
1219
  const test = runButton.closest("code-test") ?? void 0;
1182
- this.#contextManager.runTest(test, false);
1220
+ this.#context.runTest(test, false);
1221
+ }
1222
+ #boundEnabledHandler = this.#enabled_onChange.bind(this);
1223
+ #enabled_onChange(event) {
1224
+ const input = event.target;
1225
+ const allowToggle = this.dispatchEvent(new CustomEvent(CodeTestEvent.Enabled, { bubbles: true, composed: true, cancelable: true, detail: { target: this } }));
1226
+ if (allowToggle == false) {
1227
+ event.preventDefault();
1228
+ event.stopPropagation();
1229
+ input.checked = !input.checked;
1230
+ }
1183
1231
  }
1184
1232
  #getCurrentTestsPath() {
1185
1233
  return this.getAttribute("src") ?? this.getAttribute("test") ?? this.getAttribute("tests") ?? this.getAttribute("run") ?? this.getAttribute("path") ?? void 0;
@@ -1222,12 +1270,12 @@ class CodeTestsElement extends HTMLElement {
1222
1270
  this.part.toggle("has-required-after-hook", hasRequiredAfterAnyState);
1223
1271
  const runAllButtonLabel = this.findElement(".run-all-button-label");
1224
1272
  if (runAllButtonLabel != null) {
1225
- runAllButtonLabel.textContent = isRunning == true ? "Cancel" : resultCategory == "fail" ? "Reset" : "Run Tests";
1226
- runAllButtonLabel.title = isRunning == true ? "Cancel the testing" : resultCategory == "fail" ? "Reset the tests so they can be run again" : "Run the tests";
1273
+ runAllButtonLabel.textContent = isRunning == true ? "Cancel" : resultCategory == "fail" || resultCategory == "success" ? "Reset" : "Run Tests";
1274
+ runAllButtonLabel.title = isRunning == true ? "Cancel the testing" : resultCategory == "fail" || resultCategory == "success" ? "Reset the tests so they can be run again" : "Run the tests";
1227
1275
  }
1228
1276
  const runAllIcon = this.findElement(".run-all-button-icon");
1229
1277
  if (runAllIcon != null) {
1230
- runAllIcon.innerHTML = isRunning == true ? '<use href="#icon-definition_cancel"></use>' : resultCategory == "fail" ? '<use href="#icon-definition_reset"></use>' : '<use href="#icon-definition_arrow"></use>';
1278
+ runAllIcon.innerHTML = isRunning == true ? '<use href="#icon-definition_cancel"></use>' : resultCategory == "fail" || resultCategory == "success" ? '<use href="#icon-definition_reset"></use>' : '<use href="#icon-definition_arrow"></use>';
1231
1279
  }
1232
1280
  this.#renderHook(this.state.beforeAllState, "#before-all-results");
1233
1281
  this.#renderHook(this.state.afterAllState, "#after-all-results");
@@ -1298,13 +1346,13 @@ class CodeTestsElement extends HTMLElement {
1298
1346
  }
1299
1347
  async runTests() {
1300
1348
  const tests = this.findElements("code-test");
1301
- return this.#contextManager.runTests(tests);
1349
+ return this.#context.runTests(tests);
1302
1350
  }
1303
1351
  async reloadTests() {
1304
1352
  this.findElement("#tests").innerHTML = "";
1305
1353
  await this.reset();
1306
1354
  const testsPath = this.#getCurrentTestsPath();
1307
- this.#contextManager.loadTests(testsPath);
1355
+ this.#context.loadTests(testsPath);
1308
1356
  }
1309
1357
  async reset() {
1310
1358
  const tests = this.findElements("code-test");
@@ -1347,15 +1395,15 @@ class CodeTestsElement extends HTMLElement {
1347
1395
  requiredAfterAnyState,
1348
1396
  requiredBeforeAnyState
1349
1397
  });
1350
- this.#contextManager.shouldContinueRunningTests = true;
1398
+ this.#context.shouldContinueRunningTests = true;
1351
1399
  if (this.state.resetHook != null) {
1352
- await this.state.resetHook(await this.#contextManager.createTestContext());
1400
+ await this.state.resetHook(await this.#context.createTestContext());
1353
1401
  }
1354
1402
  this.dispatchEvent(new CustomEvent(CodeTestEvent.Reset, { bubbles: true, composed: true }));
1355
1403
  }
1356
1404
  cancel() {
1357
1405
  this.state.isCanceled = true;
1358
- this.#contextManager.shouldContinueRunningTests = false;
1406
+ this.#context.shouldContinueRunningTests = false;
1359
1407
  this.classList.add("canceled");
1360
1408
  this.part.add("canceled");
1361
1409
  this.dispatchEvent(new CustomEvent(CodeTestEvent.Cancel, { bubbles: true, composed: true }));