testuiwright
v0.1.12
Published
A CLI tool that runs plain-English UI tests in Chrome using Playwright
Maintainers
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 firstExample 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 repeatSeparate 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=s3cr3tReference 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:4bHTML 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 --headlessExit 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