p-elements-core 1.2.30 → 1.2.32-rc-10

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 (82) hide show
  1. package/.editorconfig +17 -17
  2. package/.gitlab-ci.yml +18 -18
  3. package/CHANGELOG.md +201 -0
  4. package/demo/sample.js +1 -1
  5. package/demo/screen.css +16 -16
  6. package/demo/theme.css +1 -0
  7. package/dist/p-elements-core-modern.js +1 -1
  8. package/dist/p-elements-core.js +1 -1
  9. package/docs/package-lock.json +6897 -6897
  10. package/docs/package.json +27 -27
  11. package/docs/src/404.md +8 -8
  12. package/docs/src/_data/demos/hello-world/hello-world.tsx +35 -35
  13. package/docs/src/_data/demos/hello-world/index.html +10 -10
  14. package/docs/src/_data/demos/hello-world/project.json +7 -7
  15. package/docs/src/_data/demos/timer/demo-timer.tsx +120 -120
  16. package/docs/src/_data/demos/timer/icons.tsx +62 -62
  17. package/docs/src/_data/demos/timer/index.html +12 -12
  18. package/docs/src/_data/demos/timer/project.json +8 -8
  19. package/docs/src/_data/global.js +13 -13
  20. package/docs/src/_data/helpers.js +19 -19
  21. package/docs/src/_includes/layouts/base.njk +30 -30
  22. package/docs/src/_includes/layouts/playground.njk +40 -40
  23. package/docs/src/_includes/partials/app-header.njk +8 -8
  24. package/docs/src/_includes/partials/head.njk +14 -14
  25. package/docs/src/_includes/partials/nav.njk +19 -19
  26. package/docs/src/_includes/partials/top-nav.njk +51 -51
  27. package/docs/src/documentation/custom-element.md +221 -221
  28. package/docs/src/documentation/decorators/bind.md +71 -71
  29. package/docs/src/documentation/decorators/custom-element-config.md +63 -63
  30. package/docs/src/documentation/decorators/property.md +83 -83
  31. package/docs/src/documentation/decorators/query.md +66 -66
  32. package/docs/src/documentation/decorators/render-property-on-set.md +60 -60
  33. package/docs/src/documentation/decorators.md +9 -9
  34. package/docs/src/documentation/reactive-properties.md +53 -53
  35. package/docs/src/index.d.ts +25 -25
  36. package/docs/src/index.md +3 -3
  37. package/docs/src/scripts/components/app-mode-switch/app-mode-switch.css +78 -78
  38. package/docs/src/scripts/components/app-mode-switch/app-mode-switch.tsx +166 -166
  39. package/docs/src/scripts/components/app-playground/app-playground.tsx +189 -189
  40. package/docs/tsconfig.json +22 -22
  41. package/index.html +15 -2
  42. package/p-elements-core.d.ts +12 -3
  43. package/package.json +11 -4
  44. package/readme.md +206 -206
  45. package/src/custom-element-controller.test.ts +226 -0
  46. package/src/custom-element-controller.ts +31 -31
  47. package/src/custom-element.test.ts +906 -0
  48. package/src/custom-element.ts +471 -188
  49. package/src/custom-style-element.ts +4 -1
  50. package/src/decorators/bind.test.ts +163 -0
  51. package/src/decorators/bind.ts +46 -46
  52. package/src/decorators/custom-element-config.ts +17 -17
  53. package/src/decorators/property.test.ts +279 -0
  54. package/src/decorators/property.ts +822 -150
  55. package/src/decorators/query.test.ts +146 -0
  56. package/src/decorators/query.ts +12 -12
  57. package/src/decorators/render-property-on-set.ts +3 -3
  58. package/src/helpers/css.test.ts +150 -0
  59. package/src/helpers/css.ts +71 -71
  60. package/src/maquette/cache.test.ts +150 -0
  61. package/src/maquette/cache.ts +35 -35
  62. package/src/maquette/dom.test.ts +263 -0
  63. package/src/maquette/dom.ts +115 -115
  64. package/src/maquette/h.test.ts +165 -0
  65. package/src/maquette/h.ts +100 -100
  66. package/src/maquette/index.ts +12 -12
  67. package/src/maquette/interfaces.ts +536 -536
  68. package/src/maquette/jsx.ts +61 -61
  69. package/src/maquette/mapping.test.ts +294 -0
  70. package/src/maquette/mapping.ts +56 -56
  71. package/src/maquette/maquette.test.ts +493 -0
  72. package/src/maquette/projection.test.ts +366 -0
  73. package/src/maquette/projection.ts +666 -666
  74. package/src/maquette/projector.test.ts +351 -0
  75. package/src/maquette/projector.ts +200 -200
  76. package/src/sample/mixin/highlight.tsx +33 -32
  77. package/src/sample/sample.tsx +167 -7
  78. package/src/test-setup.ts +85 -0
  79. package/src/test-utils.ts +223 -0
  80. package/tsconfig.json +1 -0
  81. package/vitest.config.ts +41 -0
  82. package/webpack.config.js +1 -1
@@ -1,20 +1,80 @@
1
1
  import { Highlightable } from "./mixin/highlight";
2
2
  import anime from "animejs";
3
3
 
4
- import {customElementConfig as CustomElementConfig} from "../decorators/custom-element-config";
4
+ import {customElementConfig, customElementConfig as CustomElementConfig} from "../decorators/custom-element-config";
5
5
  import {property as Property, AttributeConverter} from "../decorators/property";
6
6
  import {propertyRenderOnSet as PropertyRenderOnSet} from "../decorators/render-property-on-set";
7
7
  import {query as Query} from "../decorators/query";
8
8
  import {CustomElement} from "../custom-element";
9
9
  import {CustomElementController} from "../custom-element-controller";
10
10
 
11
+
12
+ @customElementConfig({tagName: "render-on-set"})
13
+ export class RenderOnSet extends CustomElement {
14
+
15
+ @PropertyRenderOnSet
16
+ public name: string = "foo";
17
+
18
+ render() {
19
+ return <div>Render on set: {this.name}</div>;
20
+ }
21
+
22
+ #initDone = false;
23
+
24
+ connectedCallback(): void {
25
+
26
+ if (this.#initDone) {
27
+ return
28
+ }
29
+ this.#initDone = true;
30
+ let template = this.templateFromString(`<style>div{color: lime}</style><div />`);
31
+ this.shadowRoot.appendChild(template);
32
+ this.createProjector(this.shadowRoot.querySelector("div"), this.render);
33
+ }
34
+
35
+ }
36
+
37
+
38
+ @CustomElementConfig({
39
+ tagName: "p-bugs-03",
40
+ })
41
+ export class PBugs03 extends CustomElement {
42
+ static style = `/* */`;
43
+
44
+ @PropertyRenderOnSet
45
+ private _zero: number = 0;
46
+
47
+ private _renderCount: number = 0;
48
+
49
+ private alwaysZero() {
50
+ return 0;
51
+ }
52
+
53
+ private get zero(): number {
54
+ this._zero = this.alwaysZero();
55
+ return this._zero;
56
+ }
57
+
58
+ // Bug: Updating a @RenderOnSet property with same value triggers useless re-render
59
+
60
+ render() {
61
+ this._renderCount++;
62
+
63
+ return (
64
+ <div>
65
+ Value of Zero: {this.zero} - Renders: {this._renderCount}
66
+ </div>
67
+ );
68
+ };
69
+ }
70
+
11
71
  @CustomElementConfig({
12
72
  tagName: "my-button",
13
73
  })
14
74
  export class MyButton extends CustomElement {
15
75
  static style = `.foo{background-color: red; color: white; border: 0px;}`;
16
76
  static delegatesFocus = true;
17
- render = () => {
77
+ render(){
18
78
  return <button class="foo"><slot></slot></button>;
19
79
  }
20
80
  }
@@ -22,7 +82,7 @@ export class MyButton extends CustomElement {
22
82
  @CustomElementConfig({
23
83
  tagName: "my-greetings",
24
84
  })
25
- export class MyGreetings extends Highlightable(class extends CustomElement { }) {
85
+ export class MyGreetings extends Highlightable(class extends CustomElement { render() { return <div></div> } }) {
26
86
 
27
87
  static isFormAssociated = true;
28
88
 
@@ -94,7 +154,7 @@ export class MyGreetings extends Highlightable(class extends CustomElement { })
94
154
  console.log({ e, p: this });
95
155
  };
96
156
 
97
- private render = () => {
157
+ render(){
98
158
  return (
99
159
  <div>
100
160
  <input type="checkbox" checked={this.name === "Peter"} />
@@ -139,8 +199,8 @@ export class MyGreetings extends Highlightable(class extends CustomElement { })
139
199
  afterCreate={this.peterCreate}
140
200
  class="is-peter"
141
201
  eventListeners={[["click", this.onPeterClick]]}
142
- enterAnimation={this.enterAnimation}
143
- exitAnimation={this.exitAnimation}
202
+ enterAnimation={(element, properties) => this.enterAnimation(element, properties)}
203
+ exitAnimation={(element, removeDomNodeFunction, properties) => this.exitAnimation(element, removeDomNodeFunction, properties)}
144
204
  >
145
205
  <p>Hello Peter</p>
146
206
  <img
@@ -165,6 +225,7 @@ export class MyGreetings extends Highlightable(class extends CustomElement { })
165
225
  }
166
226
 
167
227
  connectedCallback() {
228
+ super.connectedCallback();
168
229
  let template = this.templateFromString(`
169
230
  <style>
170
231
 
@@ -308,7 +369,7 @@ class PFoo extends CustomElement {
308
369
  @Property({ attribute: "items", type: "object", reflect: true, converter: stringArrayConverter })
309
370
  items: string[] = ["foo", "bar"];
310
371
 
311
- @Property({ type: "string", attribute: "nick-name", readonly: true })
372
+ @Property({ type: "string", attribute: "nick-name"})
312
373
  nickName: string = "de prutser";
313
374
 
314
375
  shouldUpdate(property, oldValue, newValue) {
@@ -359,9 +420,108 @@ class SuperAnchorElement extends HTMLAnchorElement {
359
420
  }
360
421
  }
361
422
  public connectedCallback() {
423
+
362
424
  this.classList.add("super");
363
425
  this.style.color = "red";
364
426
  }
365
427
  }
366
428
 
367
429
  window.customElements.define("super-a", SuperAnchorElement, { extends: "a" });
430
+
431
+
432
+ // Bring your own projector in non shadow root element
433
+ @CustomElementConfig({
434
+ tagName: "bring-your-own-projector",
435
+ })
436
+ export class BringYourOwnProjector extends CustomElement {
437
+
438
+ constructor() {
439
+ super();
440
+ this.initProjector();
441
+ }
442
+
443
+ init() {
444
+ console.log("This is a lifecycle for BringYourOwnProjector");
445
+ }
446
+
447
+ initProjector() {
448
+ this.rootElement = document.createElement("div");
449
+ this.rootElement.classList.add("root");
450
+ this.createProjector(this.rootElement, this.render);
451
+ console.log("init");
452
+ }
453
+
454
+ @PropertyRenderOnSet
455
+ name: string = "foo";
456
+
457
+ #_doneSOmething = false;
458
+
459
+ get doneSomething() {
460
+ return this.#_doneSOmething;
461
+ }
462
+
463
+ doItNow(value) {
464
+ this.#_doneSOmething = value;
465
+ this.renderNow();
466
+ }
467
+
468
+ rootElement: HTMLDivElement;
469
+
470
+ render() {
471
+ return <div>Hello {this.name} {this.doneSomething && <p>We did it!!</p>}</div>;
472
+ }
473
+
474
+ connectedCallback() {
475
+ this.appendChild(this.rootElement);
476
+ }
477
+
478
+ }
479
+
480
+ // Bring your own projector in non shadow root element
481
+ @CustomElementConfig({
482
+ tagName: "bring-your-own-projector-in-shadow-root",
483
+ })
484
+ export class BringYourOwnProjectorInShadowRoot extends CustomElement {
485
+
486
+ constructor() {
487
+ super();
488
+ this.initProjector();
489
+ }
490
+
491
+ init() {
492
+ console.log("This is a lifecycle for BringYourOwnProjector");
493
+ }
494
+
495
+ initProjector() {
496
+ this.attachShadow({ mode: "open" });
497
+ this.rootElement = document.createElement("div");
498
+ this.rootElement.classList.add("root");
499
+ this.createProjector(this.rootElement, this.render);
500
+ console.log("init");
501
+ }
502
+
503
+ @PropertyRenderOnSet
504
+ name: string = "foo";
505
+
506
+ #_doneSOmething = false;
507
+
508
+ get doneSomething() {
509
+ return this.#_doneSOmething;
510
+ }
511
+
512
+ doItNow(value) {
513
+ this.#_doneSOmething = value;
514
+ this.renderNow();
515
+ }
516
+
517
+ rootElement: HTMLDivElement;
518
+
519
+ render() {
520
+ return <div>Hello {this.name} {this.doneSomething && <p>We did it!!</p>}</div>;
521
+ }
522
+
523
+ connectedCallback() {
524
+ this.shadowRoot.appendChild(this.rootElement);
525
+ }
526
+
527
+ }
@@ -0,0 +1,85 @@
1
+ /**
2
+ * Test setup file - Vitest configuration
3
+ * Configures polyfills and global test utilities
4
+ */
5
+
6
+ import { expect, afterEach, vi } from 'vitest';
7
+
8
+ // Import Maquette at the top level for type definitions
9
+ import * as Maquette from './maquette/index.js';
10
+
11
+ // Declare global Maquette if in browser environment
12
+ declare global {
13
+ interface Window {
14
+ Maquette: typeof Maquette;
15
+ }
16
+ }
17
+
18
+ // Only run setup code if we're in a browser environment
19
+ if (typeof window !== 'undefined') {
20
+ // Set up Maquette global
21
+ (window as any).Maquette = Maquette;
22
+
23
+ // Import and register CustomStyleElement for CSS @apply polyfill
24
+ if (typeof HTMLLinkElement !== 'undefined') {
25
+ import('./custom-style-element.js').catch(() => {
26
+ // Ignore if import fails in test environment
27
+ });
28
+ }
29
+ }
30
+
31
+ // Extend Chai matchers for better custom element testing
32
+ declare global {
33
+ namespace Chai {
34
+ interface Assertion {
35
+ shadowRoot: ShadowRoot;
36
+ }
37
+ }
38
+ }
39
+
40
+ // Store for tracking registered custom element names to prevent conflicts
41
+ const registeredElements = new Set<string>();
42
+ const elementsCreated: HTMLElement[] = [];
43
+
44
+ /**
45
+ * Generate a unique custom element tag name for testing
46
+ * Ensures no conflicts between test cases
47
+ */
48
+ export function generateUniqueTagName(prefix: string = 'test-element'): string {
49
+ const timestamp = Date.now();
50
+ const random = Math.random().toString(36).substr(2, 9);
51
+ const tagName = `${prefix}-${timestamp}-${random}`.toLowerCase();
52
+
53
+ registeredElements.add(tagName);
54
+ return tagName;
55
+ }
56
+
57
+ /**
58
+ * Clean up helper - unregister all test elements after tests
59
+ * Note: CustomElementRegistry doesn't support unregistration,
60
+ * so we track what was registered for uniqueness
61
+ */
62
+ export function resetRegisteredElements(): void {
63
+ registeredElements.clear();
64
+ }
65
+
66
+ /**
67
+ * Track created elements for cleanup
68
+ */
69
+ export function trackElement(el: HTMLElement): void {
70
+ elementsCreated.push(el);
71
+ }
72
+
73
+ /**
74
+ * Clean up all created elements after each test
75
+ */
76
+ afterEach(() => {
77
+ elementsCreated.forEach(el => {
78
+ if (el.parentElement) {
79
+ el.parentElement.removeChild(el);
80
+ }
81
+ });
82
+ elementsCreated.length = 0;
83
+ });
84
+ // Global test timeout for async operations
85
+ export const DEFAULT_TEST_TIMEOUT = 5000;
@@ -0,0 +1,223 @@
1
+ /**
2
+ * Test utilities for p-elements-core testing with Vitest
3
+ * Provides helpers for creating and testing custom elements
4
+ */
5
+
6
+ import { CustomElement } from './custom-element.js';
7
+ import { customElementConfig } from './decorators/custom-element-config.js';
8
+ import { generateUniqueTagName, trackElement } from './test-setup.js';
9
+ import type { VNode } from './maquette/interfaces.js';
10
+
11
+ /**
12
+ * Wait for an element to complete its update cycle
13
+ */
14
+ export async function waitForRender(element: CustomElement): Promise<void> {
15
+ // Wait for shadowRoot to be created (async in requestAnimationFrame)
16
+ let attempts = 0;
17
+ const maxAttempts = 100;
18
+ while (!element.shadowRoot && attempts < maxAttempts) {
19
+ await new Promise(resolve => setTimeout(resolve, 10));
20
+ attempts++;
21
+ }
22
+
23
+ if (!element.shadowRoot && attempts >= maxAttempts) {
24
+ console.warn('waitForRender: shadowRoot was not created after max attempts');
25
+ }
26
+
27
+ // Wait for projector to render (also async in requestAnimationFrame)
28
+ await new Promise(resolve => requestAnimationFrame(() => requestAnimationFrame(() => resolve(undefined))));
29
+
30
+ // Then wait for update to complete
31
+ await element.updateComplete;
32
+ }
33
+
34
+ /**
35
+ * Create and register a test custom element
36
+ * Returns the tag name for the registered element
37
+ */
38
+ export function defineTestElement(
39
+ render: () => VNode,
40
+ options: {
41
+ tagName?: string;
42
+ isFormAssociated?: boolean;
43
+ delegatesFocus?: boolean;
44
+ style?: string;
45
+ extends?: string;
46
+ } = {}
47
+ ): string {
48
+ const tagName = options.tagName || generateUniqueTagName();
49
+
50
+ @customElementConfig({
51
+ tagName,
52
+ options: options.extends ? { extends: options.extends } : undefined,
53
+ })
54
+ class TestElement extends CustomElement {
55
+ static style = options.style || '';
56
+ static isFormAssociated = options.isFormAssociated || false;
57
+ static delegatesFocus = options.delegatesFocus || false;
58
+
59
+ render() {
60
+ return render();
61
+ }
62
+ }
63
+
64
+ return tagName;
65
+ }
66
+
67
+ /**
68
+ * Create a simple test element directly in the DOM
69
+ */
70
+ export async function createTestElement<T extends HTMLElement = HTMLElement>(
71
+ tagName: string,
72
+ attributes: Record<string, any> = {}
73
+ ): Promise<T> {
74
+ const el = document.createElement(tagName) as T;
75
+
76
+ // Set attributes
77
+ Object.entries(attributes).forEach(([key, value]) => {
78
+ if (typeof value === 'boolean') {
79
+ if (value) {
80
+ el.setAttribute(key, '');
81
+ }
82
+ } else if (value !== null && value !== undefined) {
83
+ el.setAttribute(key, String(value));
84
+ }
85
+ });
86
+
87
+ // Add to body for connection
88
+ document.body.appendChild(el);
89
+ trackElement(el);
90
+
91
+ // Wait for render if it's a CustomElement
92
+ if (el instanceof CustomElement) {
93
+ await waitForRender(el as CustomElement);
94
+ }
95
+
96
+ return el;
97
+ }
98
+
99
+ /**
100
+ * Get property descriptor from an element (helps test decorator-generated properties)
101
+ */
102
+ export function getPropertyDescriptor(
103
+ element: any,
104
+ propertyName: string
105
+ ): PropertyDescriptor | undefined {
106
+ let proto = Object.getPrototypeOf(element);
107
+
108
+ while (proto) {
109
+ const descriptor = Object.getOwnPropertyDescriptor(proto, propertyName);
110
+ if (descriptor) {
111
+ return descriptor;
112
+ }
113
+ proto = Object.getPrototypeOf(proto);
114
+ }
115
+
116
+ return undefined;
117
+ }
118
+
119
+ /**
120
+ * Wait for a condition to be true
121
+ */
122
+ export async function waitFor(
123
+ condition: () => boolean,
124
+ timeout: number = 1000,
125
+ interval: number = 10
126
+ ): Promise<void> {
127
+ const startTime = Date.now();
128
+
129
+ while (!condition()) {
130
+ if (Date.now() - startTime > timeout) {
131
+ throw new Error('Timeout waiting for condition');
132
+ }
133
+ await new Promise(resolve => setTimeout(resolve, interval));
134
+ }
135
+ }
136
+
137
+ /**
138
+ * Simulate an attribute change on an element
139
+ */
140
+ export function setAttributeAndNotify(
141
+ element: HTMLElement & { attributeChangedCallback?: Function },
142
+ name: string,
143
+ value: string | null
144
+ ): void {
145
+ const oldValue = element.getAttribute(name);
146
+
147
+ if (value === null) {
148
+ element.removeAttribute(name);
149
+ } else {
150
+ element.setAttribute(name, value);
151
+ }
152
+
153
+ // Manually trigger attributeChangedCallback if it exists
154
+ if (element.attributeChangedCallback) {
155
+ element.attributeChangedCallback(name, oldValue, value);
156
+ }
157
+ }
158
+
159
+ /**
160
+ * Assert that a VNode has specific properties
161
+ */
162
+ export function assertVNode(
163
+ vnode: VNode,
164
+ expected: Partial<{
165
+ vnodeSelector: string;
166
+ text?: string;
167
+ children?: VNode[];
168
+ }>
169
+ ): void {
170
+ if (expected.vnodeSelector) {
171
+ if (vnode.vnodeSelector !== expected.vnodeSelector) {
172
+ throw new Error(
173
+ `Expected vnodeSelector "${expected.vnodeSelector}" but got "${vnode.vnodeSelector}"`
174
+ );
175
+ }
176
+ }
177
+
178
+ if (expected.text !== undefined) {
179
+ if (vnode.text !== expected.text) {
180
+ throw new Error(`Expected text "${expected.text}" but got "${vnode.text}"`);
181
+ }
182
+ }
183
+
184
+ if (expected.children) {
185
+ if (!vnode.children || vnode.children.length !== expected.children.length) {
186
+ throw new Error(
187
+ `Expected ${expected.children.length} children but got ${vnode.children?.length || 0}`
188
+ );
189
+ }
190
+ }
191
+ }
192
+
193
+ /**
194
+ * Get the shadow root of an element, throwing if not found
195
+ */
196
+ export function getShadowRoot(element: HTMLElement): ShadowRoot {
197
+ if (!element.shadowRoot) {
198
+ throw new Error('Element does not have a shadow root');
199
+ }
200
+ return element.shadowRoot;
201
+ }
202
+
203
+ /**
204
+ * Query a selector within an element's shadow DOM
205
+ */
206
+ export function shadowQuery<T extends Element = Element>(
207
+ element: HTMLElement,
208
+ selector: string
209
+ ): T | null {
210
+ return getShadowRoot(element).querySelector<T>(selector);
211
+ }
212
+
213
+ /**
214
+ * Query all selectors within an element's shadow DOM
215
+ */
216
+ export function shadowQueryAll<T extends Element = Element>(
217
+ element: HTMLElement,
218
+ selector: string
219
+ ): NodeListOf<T> {
220
+ return getShadowRoot(element).querySelectorAll<T>(selector);
221
+ }
222
+
223
+
package/tsconfig.json CHANGED
@@ -60,5 +60,6 @@
60
60
  },
61
61
  "exclude": [
62
62
  "docs",
63
+ "vitest.config.ts"
63
64
  ],
64
65
  }
@@ -0,0 +1,41 @@
1
+ import { defineConfig } from 'vitest/config';
2
+ import { playwright } from '@vitest/browser-playwright';
3
+
4
+ export default defineConfig({
5
+ test: {
6
+ browser: {
7
+ enabled: true,
8
+ provider: playwright(),
9
+ headless: process.env.HEADED !== 'true',
10
+ instances: [
11
+ {
12
+ browser: 'chromium',
13
+ },
14
+ ],
15
+ },
16
+ globals: true,
17
+ setupFiles: ['./src/test-setup.ts'],
18
+ include: ['src/**/*.test.{ts,tsx}'],
19
+ exclude: ['node_modules', 'dist', '.idea', '.git', '.cache'],
20
+ coverage: {
21
+ provider: 'v8',
22
+ reporter: ['text', 'json', 'html', 'lcov'],
23
+ reportsDirectory: 'coverage',
24
+ exclude: [
25
+ 'node_modules/',
26
+ 'src/test-setup.ts',
27
+ 'src/test-utils.ts',
28
+ 'src/**/*.test.ts',
29
+ ],
30
+ thresholds: {
31
+ lines: 70,
32
+ functions: 70,
33
+ branches: 60,
34
+ statements: 70,
35
+ },
36
+ },
37
+ testTimeout: 5000,
38
+ hookTimeout: 5000,
39
+ },
40
+ });
41
+
package/webpack.config.js CHANGED
@@ -41,7 +41,7 @@ module.exports = {
41
41
  {
42
42
  test: /\.tsx?$/,
43
43
  use: ["babel-loader", "ts-loader"],
44
- exclude: /node_modules/,
44
+ exclude: [/node_modules/, /\.test\.ts$/],
45
45
  },
46
46
  ],
47
47
  },