@webjsdev/cli 0.10.7 → 0.10.8

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/lib/create.js CHANGED
@@ -311,6 +311,10 @@ export async function scaffoldApp(name, cwd, opts = {}) {
311
311
  '@web/test-runner': '^0.20.0',
312
312
  '@web/test-runner-playwright': '^0.11.0',
313
313
  'playwright': '^1.59.0',
314
+ // The standard accessibility engine, used opt-in by the
315
+ // assertNoA11yViolations() test helper from @webjsdev/core/testing.
316
+ // Test-only: dynamically imported, never shipped to the app runtime.
317
+ 'axe-core': '^4.10.0',
314
318
  // tsserver plugin for editor intelligence inside html`` templates.
315
319
  // @webjsdev/ts-plugin bundles ts-lit-plugin internally, so just one
316
320
  // plugin entry is needed in tsconfig (see below).
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@webjsdev/cli",
3
- "version": "0.10.7",
3
+ "version": "0.10.8",
4
4
  "type": "module",
5
5
  "description": "webjs CLI - dev, start, create, db",
6
6
  "bin": {
@@ -469,7 +469,7 @@ import '@webjsdev/core/client-router'; // enable SPA nav
469
469
  import { unsafeHTML, live } from '@webjsdev/core/directives';
470
470
  import { createContext } from '@webjsdev/core/context';
471
471
  import { Task } from '@webjsdev/core/task';
472
- import { fixture, waitForUpdate } from '@webjsdev/core/testing';
472
+ import { fixture, ssrFixture, waitForUpdate, assertNoA11yViolations } from '@webjsdev/core/testing';
473
473
 
474
474
  import { rateLimit, cors, cache, createAuth, Credentials, Session } from '@webjsdev/server';
475
475
  ```
@@ -442,6 +442,16 @@ test/
442
442
  | node (unit + integration) | `test/<feature>/*.test.ts` | Fast, no spawned process. Import server actions/queries/utilities and call them directly. Use `renderToString` for SSR HTML assertions. |
443
443
  | browser | `test/<feature>/browser/*.test.js` | Real Chromium via web-test-runner + Playwright. Shadow DOM, events, `adoptedStyleSheets`, `IntersectionObserver`. |
444
444
  | e2e | `test/<feature>/e2e/*.test.ts` | Boots the app and drives it through HTTP / a real browser. Gated behind `WEBJS_E2E=1` so it doesn't run on every `webjs test`. |
445
+
446
+ For a browser component test, `ssrFixture(html\`<my-el></my-el>\`)` from
447
+ `@webjsdev/core/testing` server-renders THEN hydrates the component, awaiting
448
+ its native `updateComplete`, so the post-hydration DOM is observable and an
449
+ SSR-vs-hydrate mismatch shows up (contrast `fixture()`, which only waits two
450
+ macrotasks). `assertNoA11yViolations(el)` is the OPT-IN axe-core accessibility
451
+ assertion: axe-core is a test-only devDependency, dynamically imported, never
452
+ shipped to the app runtime, and the assertion is never an automatic gate.
453
+ Install it once with `npm install -D axe-core` (the scaffold already lists it).
454
+ The scaffold's `test/hello/browser/hello.test.js` demonstrates both.
445
455
  | smoke | `test/<feature>/smoke/*.test.ts` | Fast deploy-time sanity check (single critical path; "does this surface still return 200"). |
446
456
 
447
457
  ### Running
@@ -8,6 +8,9 @@
8
8
  * adoptedStyleSheets, IntersectionObserver, events, etc.
9
9
  */
10
10
 
11
+ import { html } from '@webjsdev/core';
12
+ import { ssrFixture, assertNoA11yViolations } from '@webjsdev/core/testing';
13
+
11
14
  const assert = {
12
15
  ok: (v, msg) => { if (!v) throw new Error(msg || `Expected truthy`); },
13
16
  equal: (a, b, msg) => { if (a !== b) throw new Error(msg || `Expected ${b}, got ${a}`); },
@@ -29,12 +32,30 @@ suite('Example browser tests', () => {
29
32
  assert.ok(!host.querySelector('p'), 'Shadow content not in light DOM');
30
33
  });
31
34
 
35
+ // ssrFixture() server-renders a template THEN hydrates it in this real
36
+ // browser, awaiting the component's native updateComplete (the real
37
+ // render-cycle promise), so the post-hydration DOM is observable. Use it
38
+ // for any component test where the SSR-then-hydrate round-trip matters.
39
+ test('ssrFixture hydrates a server-rendered button', async () => {
40
+ const el = await ssrFixture(html`<button type="button">Save</button>`);
41
+ assert.equal(el.tagName, 'BUTTON', 'button hydrated');
42
+ assert.ok(el.textContent.includes('Save'), 'rendered label survives hydration');
43
+ });
44
+
45
+ // assertNoA11yViolations() is the OPT-IN accessibility assertion. It runs
46
+ // the standard axe-core engine against the element subtree (axe-core is a
47
+ // test-only devDependency, dynamically imported, never shipped to the app
48
+ // runtime). Resolves on a clean element, throws a named violation otherwise.
49
+ test('a button with an accessible name has no a11y violations', async () => {
50
+ const el = await ssrFixture(html`<button type="button">Submit form</button>`);
51
+ await assertNoA11yViolations(el);
52
+ });
53
+
32
54
  // Replace with your component tests:
33
- // test('my-widget renders correctly', () => {
34
- // import('../../components/my-widget.ts');
35
- // const el = document.createElement('my-widget');
36
- // document.body.appendChild(el);
37
- // assert.ok(el.shadowRoot);
38
- // el.remove();
55
+ // test('my-widget renders correctly', async () => {
56
+ // await import('../../components/my-widget.ts');
57
+ // const el = await ssrFixture(html`<my-widget></my-widget>`);
58
+ // assert.ok(el.shadowRoot ?? el.firstElementChild);
59
+ // await assertNoA11yViolations(el); // opt-in a11y check
39
60
  // });
40
61
  });