npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@mercury-fx/testing

v3.0.0

Published

Tests on Mercury Hyperscript: render with container-scoped queries, exact native events, act that drains the renderer and awaits what it is given, renderHook and a loop guard, on DOM Testing Library.

Readme

@mercury-fx/testing

Tests on Mercury Hyperscript, the runtime your users ship (mercury.testing.1). It uses one renderer (hyperscript's own render and act), DOM Testing Library's queries, and no React, React Testing Library or bare-Preact adapter.

import { act, cleanup, fireEvent, render, screen, typeInto, waitFor } from "@mercury-fx/testing";

afterEach(cleanup);

const view = render(<Search />);                       // queries are bound to this container
typeInto(view.getByRole("searchbox"), "alpha");        // input, then change
await waitFor(() => expect(view.getByText("Alpha")).toBeTruthy());

| Export | What it does | |---|---| | render(ui, { container?, baseElement? }) | Mounts inside act and returns the queries bound to the container (or to baseElement, for a portal's host), plus rerender, unmount (idempotent) and debug. screen is document-wide and explicit. | | cleanup() | Unmounts every tree render mounted, then removes only the containers render created. DOM the test owns itself stays. | | act(callback) | Hyperscript's act: it runs the callback, awaits the promise the callback returns, and drains queued renders and effects. It spends no extra microtask turns. Work that wasn't returned (a promise chain an effect started, a timer) isn't done when act resolves; wait for its outcome with waitFor. Every failure is the returned promise's rejection. | | fireEvent | DOM Testing Library's, each call inside act. It dispatches exactly the native event named: change is the DOM's commit event, and focus doesn't bubble (a container uses focusIn). Nothing is remapped. | | typeInto(element, value) | Sets the value, then fires input and then change, as a user's typing and commit do. | | renderHook(hook, { initialProps?, wrapper? }) | Gives result.current, rerender(props?) and unmount. rerender() with no argument re-renders with the last props given (initialProps until a rerender(props)); rerender(undefined) passes undefined. | | guardRenders({ budget, label }) | Throws RenderBudgetExceeded from inside the render once a guarded stretch exceeds budget diffs, which fails an update loop while it runs. It chains options.diffed, and release() restores it. It's test-only. | | screen, within, waitFor, waitForElementToBeRemoved, prettyDOM | Re-exported from @testing-library/dom. |

Peers: @mercury-fx/hyperscript (the same Mercury version) and @testing-library/dom 10. Provide a DOM environment such as Vitest's jsdom.

Commands

Run these from mercury/packages/mhs-testing.

| Command | Covers | |---|---| | pnpm run test:contract | MHT1 to MHT3: vitest run --config vitest.config.ts, on src/*.spec.ts(x) only, which the root config's *.test.* globs don't collect | | pnpm run test:loop-watchdog | MHT3's negative control: the unstable fixture with the guard disabled (MHT3_NO_GUARD=1), in a child process ended by an outside 30 s watchdog. That's a failed run, never a pass. --guarded runs the same with the guard on, expecting it to end by itself | | pnpm run check:closure | MHT6 and MHT7: the packed testing and hyperscript tarballs installed in a fresh consumer outside the workspace. It checks the dist imports, the install closure, a runtime render, click and guard in Node with jsdom, the packed manifest, and the adopters (no built dist imports this package). Needs pnpm run build here and in packages/hyperscript | | pnpm run test:browser | MHT5 (T2): native interaction in a real headless Chromium through Playwright's driver (userEvent from vitest/browser), on src/browser/*.spec.tsx with vitest.browser.config.ts. It covers typing character by character before any blur, a checkbox's and a select's committed change, focus-within through focusin, double-click, and a portal dialog's keyboard close with focus back on its opener. Chromium comes from PLAYWRIGHT_BROWSERS_PATH; this lane is Chromium only | | pnpm run typecheck | tsc --noEmit |

Negative controls, each of which must make its row fail:

  • node scripts/check-closure.mjs --mutant foreign-renderer: the packed bundle imports npm preact. Fails MHT7's manifest row and MHT6's install row.
  • node scripts/check-closure.mjs --mutant drop-export: dist/testing.js is missing from the tarball. Fails MHT6's runtime row.
  • node scripts/loop-watchdog.mjs: the guard disabled. Ended by the watchdog.
  • In src/browser, by hand:
    • the text input's onInput changed to onChange fails "typing updates visible state … before any blur";
    • the container's onFocusIn changed to onFocus fails the focus-within row.
  • In src, by hand:
    • queries bound to document.body fail MHT1's two-root, portal and cleanup cases;
    • an act with ten extra microtask turns fails "act spends no extra turns";
    • an act that swallows errors fails the two rejection cases.

Owned scope and disposal (MHT4) is in the Effector adopter, packages/mercury-effector/src/testing-adoption.test.tsx. It measures the engine's own seam: a scoped watch is a node in the scope's additionalLinks.