@stencil/vitest 1.2.0 → 1.4.0

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/README.md CHANGED
@@ -270,6 +270,44 @@ const formatted = prettifyHtml('<div><span>Hello</span></div>');
270
270
  // </div>
271
271
  ```
272
272
 
273
+ ### `waitForStable(elementOrSelector, timeout?)`
274
+
275
+ Waits for an element to be rendered and visible in the DOM. Only works in real browser environments (not jsdom/happy-dom).
276
+
277
+ Accepts either an `Element` or a CSS selector string. When a selector is provided, it polls until the element appears in the DOM.
278
+
279
+ ```tsx
280
+ import { render, waitForStable, h } from '@stencil/vitest';
281
+
282
+ // Wait for a rendered element to be stable / visible
283
+ const { root } = await render(<my-component />);
284
+ await waitForStable(root);
285
+
286
+ // Wait for an element using a selector (useful when element isn't in DOM yet)
287
+ await waitForStable('my-component .inner-element');
288
+
289
+ // Custom timeout (default: 5000ms)
290
+ await waitForStable('my-component', 10000);
291
+ ```
292
+
293
+ > **Note:** In non-browser environments, `waitForStable` logs a warning and returns immediately.
294
+
295
+ ### `waitForExist(selector, timeout?)`
296
+
297
+ Waits for an element matching the selector to exist in the DOM. Unlike `waitForStable`, this works in both real browsers and mock DOM environments (jsdom/happy-dom).
298
+
299
+ Returns the element if found, or `null` if timeout is reached.
300
+
301
+ ```tsx
302
+ import { waitForExist } from '@stencil/vitest';
303
+
304
+ // Wait for an element to appear in the DOM
305
+ const element = await waitForExist('my-component .lazy-loaded');
306
+
307
+ // Custom timeout (default: 5000ms)
308
+ const element = await waitForExist('#dynamic-content', 10000);
309
+ ```
310
+
273
311
  ## CLI
274
312
 
275
313
  The `stencil-test` CLI wraps both Stencil builds with Vitest testing.
package/dist/core.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import './testing/matchers.js';
2
2
  import './testing/snapshot-serializer.js';
3
3
  export { h } from '@stencil/core';
4
- export { render } from './testing/render.js';
4
+ export { render, waitForStable, waitForExist } from './testing/render.js';
5
5
  export { serializeHtml, prettifyHtml, SerializeOptions } from './testing/html-serializer.js';
6
6
  export type { RenderOptions, RenderResult } from './types.js';
7
7
  //# sourceMappingURL=core.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"core.d.ts","sourceRoot":"","sources":["../src/core.ts"],"names":[],"mappings":"AACA,OAAO,uBAAuB,CAAC;AAC/B,OAAO,kCAAkC,CAAC;AAE1C,OAAO,EAAE,CAAC,EAAE,MAAM,eAAe,CAAC;AAClC,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAC7F,YAAY,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"core.d.ts","sourceRoot":"","sources":["../src/core.ts"],"names":[],"mappings":"AACA,OAAO,uBAAuB,CAAC;AAC/B,OAAO,kCAAkC,CAAC;AAE1C,OAAO,EAAE,CAAC,EAAE,MAAM,eAAe,CAAC;AAClC,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAC1E,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAC7F,YAAY,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC"}
package/dist/core.js CHANGED
@@ -2,5 +2,5 @@
2
2
  import './testing/matchers.js';
3
3
  import './testing/snapshot-serializer.js';
4
4
  export { h } from '@stencil/core';
5
- export { render } from './testing/render.js';
5
+ export { render, waitForStable, waitForExist } from './testing/render.js';
6
6
  export { serializeHtml, prettifyHtml } from './testing/html-serializer.js';
@@ -15,6 +15,18 @@ interface RenderOptions {
15
15
  */
16
16
  waitForReady?: boolean;
17
17
  }
18
+ /**
19
+ * Poll until element has dimensions (is rendered/visible in real browser).
20
+ * Accepts either an Element or a CSS selector string.
21
+ * If a selector is provided, waits for the element to appear in the DOM first.
22
+ */
23
+ export declare function waitForStable(elementOrSelector: Element | string, timeout?: number): Promise<void>;
24
+ /**
25
+ * Poll until element exists in the DOM.
26
+ * Accepts a CSS selector string and waits for a matching element to appear.
27
+ * Works in both real browsers and mock DOM environments.
28
+ */
29
+ export declare function waitForExist(selector: string, timeout?: number): Promise<Element | null>;
18
30
  /**
19
31
  * Render using Stencil's render
20
32
  */
@@ -1 +1 @@
1
- {"version":3,"file":"render.d.ts","sourceRoot":"","sources":["../../src/testing/render.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAY,MAAM,aAAa,CAAC;AAE1D,UAAU,aAAa;IACrB;;OAEG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;OAEG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACpC;;;;OAIG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAwCD;;GAEG;AACH,wBAAsB,MAAM,CAAC,CAAC,SAAS,WAAW,GAAG,WAAW,EAAE,CAAC,GAAG,GAAG,EACvE,KAAK,EAAE,GAAG,EACV,OAAO,GAAE,aAGR,GACA,OAAO,CAAC,YAAY,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CA6I7B"}
1
+ {"version":3,"file":"render.d.ts","sourceRoot":"","sources":["../../src/testing/render.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAY,MAAM,aAAa,CAAC;AAE1D,UAAU,aAAa;IACrB;;OAEG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;OAEG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACpC;;;;OAIG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAyBD;;;;GAIG;AACH,wBAAsB,aAAa,CAAC,iBAAiB,EAAE,OAAO,GAAG,MAAM,EAAE,OAAO,SAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAiCtG;AAED;;;;GAIG;AACH,wBAAsB,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,SAAO,GAAG,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,CAY5F;AAED;;GAEG;AACH,wBAAsB,MAAM,CAAC,CAAC,SAAS,WAAW,GAAG,WAAW,EAAE,CAAC,GAAG,GAAG,EACvE,KAAK,EAAE,GAAG,EACV,OAAO,GAAE,aAGR,GACA,OAAO,CAAC,YAAY,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CA6I7B"}
@@ -22,18 +22,53 @@ function isRealBrowser() {
22
22
  return true;
23
23
  }
24
24
  /**
25
- * Poll until element has dimensions (is rendered/visible in real browser)
25
+ * Poll until element has dimensions (is rendered/visible in real browser).
26
+ * Accepts either an Element or a CSS selector string.
27
+ * If a selector is provided, waits for the element to appear in the DOM first.
26
28
  */
27
- async function waitForRendered(element, timeout = 5000) {
29
+ export async function waitForStable(elementOrSelector, timeout = 5000) {
30
+ if (!isRealBrowser()) {
31
+ console.warn('[waitForStable] Only works in real browser environments');
32
+ return;
33
+ }
28
34
  const start = Date.now();
35
+ // Resolve element from selector if needed
36
+ let element = typeof elementOrSelector === 'string' ? null : elementOrSelector;
37
+ // If an Element was passed, verify it's in the DOM
38
+ if (element && !document.contains(element)) {
39
+ console.warn('[waitForStable] Element is not attached to the DOM');
40
+ }
29
41
  while (Date.now() - start < timeout) {
30
- const rect = element.getBoundingClientRect();
31
- if (rect.width > 0 && rect.height > 0) {
32
- return;
42
+ // If we have a selector, try to find the element
43
+ if (typeof elementOrSelector === 'string' && !element) {
44
+ element = document.querySelector(elementOrSelector);
45
+ }
46
+ // If we have an element, check if it has dimensions
47
+ if (element) {
48
+ const rect = element.getBoundingClientRect();
49
+ if (rect.width > 0 && rect.height > 0) {
50
+ return;
51
+ }
33
52
  }
34
53
  await new Promise((r) => requestAnimationFrame(r));
35
54
  }
36
- // Don't throw on timeout - element might be intentionally zero-sized
55
+ // Don't throw on timeout - element might be intentionally zero-sized or not found
56
+ }
57
+ /**
58
+ * Poll until element exists in the DOM.
59
+ * Accepts a CSS selector string and waits for a matching element to appear.
60
+ * Works in both real browsers and mock DOM environments.
61
+ */
62
+ export async function waitForExist(selector, timeout = 5000) {
63
+ const start = Date.now();
64
+ while (Date.now() - start < timeout) {
65
+ const element = document.querySelector(selector);
66
+ if (element) {
67
+ return element;
68
+ }
69
+ await new Promise((r) => setTimeout(r, 16));
70
+ }
71
+ return null;
37
72
  }
38
73
  /**
39
74
  * Render using Stencil's render
@@ -99,7 +134,7 @@ export async function render(vnode, options = {
99
134
  if (options.waitForReady !== false) {
100
135
  if (isRealBrowser()) {
101
136
  // In real browser, poll until element has dimensions
102
- await waitForRendered(element);
137
+ await waitForStable(element);
103
138
  }
104
139
  // Always wait for Stencil's update cycle to complete
105
140
  await waitForChanges();
package/package.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "type": "git",
5
5
  "url": "https://github.com/stenciljs/vitest"
6
6
  },
7
- "version": "1.2.0",
7
+ "version": "1.4.0",
8
8
  "description": "First-class testing utilities for Stencil design systems with Vitest",
9
9
  "license": "MIT",
10
10
  "type": "module",
@@ -97,7 +97,7 @@
97
97
  "dependencies": {
98
98
  "jiti": "^2.6.1",
99
99
  "local-pkg": "^1.1.2",
100
- "vitest-environment-stencil": "1.2.0"
100
+ "vitest-environment-stencil": "1.4.0"
101
101
  },
102
102
  "devDependencies": {
103
103
  "@eslint/js": "^9.39.2",