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

testuiwright

v0.1.12

Published

A CLI tool that runs plain-English UI tests in Chrome using Playwright

Readme

Plainwright

A CLI tool that runs plain-English UI tests in Chrome using Playwright. Write tests in simple .txt files — no code, no API key required. Secrets come from .env and are never exposed in logs or reports.

Quickstart

npm install -g testuiwright

cd my-project
plainwright init       # auto-detects framework, creates tests/ and .env.example
cp .env.example .env   # fill in your BASE_URL and credentials

plainwright run tests/smoke.txt          # opens browser, runs tests
plainwright run tests/smoke.txt --serve  # auto-starts your dev server first

Example test file

title: Login works
tags: smoke, login
timeout: 30s

steps:
open ${BASE_URL}

if see "Cookie consent"
  click "Accept"
end if

type "${USERNAME}" into "Email"
type "${PASSWORD}" into "Password"
click "Log in"
should see "Dashboard"
url should contain "/dashboard"

---

title: Multi-user test
tags: smoke
timeout: 60s

steps:
open ${BASE_URL}/login

repeat for each "[email protected], [email protected]"
  type "${LOOP_VALUE}" into "Email"
  type "${PASSWORD}" into "Password"
  click "Sign in"
  should see "Dashboard"
  click "Sign out"
  wait 1s
end repeat

Separate test cases with ---. Each case gets a fresh browser tab.

Commands

| Command | Description | |---|---| | plainwright init | Scaffold a test project (auto-detects Vite / Next / Nuxt / Angular / etc.) | | plainwright run <file> | Run one or more .txt test files | | plainwright record <output.txt> | Open browser, record interactions, save as test file | | plainwright models | List all available AI providers and models |

Run options

| Flag | Description | |---|---| | --headless | Run without showing the browser window (for CI) | | --slow <ms> | Delay between steps in milliseconds | | --serve | Auto-start the project dev server before running tests | | --tag <tag> | Only run test cases with a matching tag | | --retries <n> | Retry each failed test up to N times | | --bail | Stop after the first test failure | | --parallel <n> | Run up to N tests simultaneously | | --watch | Re-run tests whenever a test file changes | | --reporter junit | Also generate test-results/results.xml | | --provider <name> | AI provider: gemini | openai | anthropic | ollama | | --model <name> | Specific AI model (e.g. gpt-4o-mini, gemma3:4b) |

Step syntax

Navigation

| Step | What it does | |---|---| | open <url> | Navigate to a URL |

Interactions

| Step | What it does | |---|---| | click "<label>" | Click a button, link, or element | | click "<label>" at <N> | Click the Nth matching element (1-based) | | click "<label>" near "<context>" | Click a button inside the same card as the context text | | type "<value>" into "<field>" | Clear and fill a text input | | select "<option>" from "<field>" | Choose a dropdown option | | hover over "<label>" | Hover over an element | | press "<key>" | Press a keyboard key (Enter, Tab, Escape, …) | | upload "<file>" to "<field>" | Upload a file to a file input | | drag "<source>" to "<target>" | Drag and drop an element | | scroll to bottom / scroll to top | Scroll the page | | scroll to "<text>" | Scroll to an element | | execute "<js>" | Run arbitrary JavaScript |

Waits

| Step | What it does | |---|---| | wait <N>ms / wait <N>s | Pause for a fixed duration | | wait until "<text>" is visible | Wait up to 15s for text to appear | | wait for "<selector>" | Wait up to 15s for a CSS selector | | <any step> wait <N>s | Pause before the step fires |

Assertions

| Step | What it does | |---|---| | should see "<text>" | Assert text is visible | | should not see "<text>" | Assert text is NOT visible | | should see <N> "<text>" | Assert exactly N instances are visible | | url should contain "<text>" | Assert URL contains string | | url should equal "<url>" | Assert exact URL match | | "<label>" should have "<attr>" as "<value>" | Assert element attribute value | | "<field>" field should contain "<value>" | Assert input field value |

Tabs

| Step | What it does | |---|---| | switch to new tab | Switch context to a newly opened tab | | close tab | Close current tab and return to previous |

iFrames

| Step | What it does | |---|---| | switch to frame "<name>" | Switch context into an iframe | | switch to main frame | Return to the main page |

Store values

| Step | What it does | |---|---| | store url as "<VAR>" | Save current URL — use as ${VAR} later | | store text of "<sel>" as "<VAR>" | Save element text — use as ${VAR} later |

Control flow

| Step | What it does | |---|---| | if see "<text>" / if not see "<text>" | Conditional block — close with end if | | repeat <N> times | Repeat block N times — close with end repeat | | repeat for each "<v1, v2, v3>" | Iterate over values — use ${LOOP_VALUE} — close with end repeat |

Screenshots

| Step | What it does | |---|---| | take screenshot | Save full-page screenshot | | take screenshot as "<name>" | Save screenshot with custom filename |

Step screenshots are also saved automatically to test-results/steps/ after every interaction, showing the highlighted element.

Test case metadata

title: My test name
tags: smoke, login       # comma-separated; filter with --tag
timeout: 30s             # per-step timeout (default: 30s)

Env vars and secrets

Create a .env file in your project root:

BASE_URL=http://localhost:3000
USERNAME=testuser
PASSWORD=s3cr3t

Reference them in tests with ${VAR_NAME}. Values are never printed in logs or reports.

AI smart-fill (optional)

AI is only used for plainwright generate and plainwright record. The run command needs no API key.

| Provider | Key in .env | Local? | Cost | |---|---|---|---| | Ollama | none | Yes | Free | | Google Gemini | GEMINI_API_KEY | No | Free tier available | | OpenAI | OPENAI_API_KEY | No | Paid | | Anthropic Claude | ANTHROPIC_API_KEY | No | Paid |

plainwright run tests/smoke.txt --provider gemini
plainwright run tests/smoke.txt --provider ollama --model gemma3:4b

HTML report

After every run an HTML report is saved to test-results/report.html and opened automatically. It includes:

  • Pass/fail stats and duration
  • Per-test step log
  • Error messages (secrets masked)
  • Tag filter buttons

Framework support

plainwright init auto-detects your framework and sets the correct port:

| Framework | Default port | |---|---| | Vite | 5173 | | Next.js | 3000 | | Nuxt | 3000 | | Angular | 4200 | | SvelteKit | 5173 | | Remix | 3000 | | Astro | 4321 | | CRA | 3000 |

CI usage

plainwright run tests/smoke.txt --serve --headless

Exit code is 0 if all tests pass, 1 if any fail.

Install from source

git clone https://github.com/helloamit3107/plainwright.git
cd plainwright
npm install
npx playwright install chromium
npm link