Testing and devtools

Test your app the way a user meets it, by role and label through every shadow root, and watch its store and routes while you build it.

Tests

@lit-material/testing renders with fixture(), which waits until every nested element has rendered, and finds controls by role, label or text through shadow roots: getByLabel("Email") is the <input> inside the text field, the one the user types into.

import { cleanup, fixture, getByLabel, getByRole, user } from "@lit-material/testing";

afterEach(() => cleanup());

it("signs up", async () => {
  await fixture(html`<signup-form></signup-form>`);
  await user.type(getByLabel("Email"), "ada@example.com");
  await user.click(getByRole("button", { name: "Sign up" }));
  expect(getByRole("status").textContent).to.contain("Check your inbox");
});

It works in any browser test runner. When a query finds nothing, the error lists the roles and names it did find.

Devtools

@lit-material/devtools records a store's actions and states, and the router's navigations. With the Redux DevTools browser extension installed, stores show up there, time travel included; without it, the <lit-material-devtools> panel shows the same on the page.

if (import.meta.env.DEV) {
  const { connectStore, connectRouter } = await import("@lit-material/devtools");
  await import("@lit-material/devtools/panel.js");
  connectStore(store, { name: "app" });
  connectRouter();
  document.body.append(document.createElement("lit-material-devtools"));
}

Loaded behind a development check like this, it adds nothing to a production build.