openqa
Health Warn
- No license — Repository has no license file
- Description — Repository has a description
- Active repo — Last push 0 days ago
- Low visibility — Only 5 GitHub stars
Code Warn
- process.env — Environment variable access in examples/cucumberjs/features/step_definitions/steps.js
Permissions Pass
- Permissions — No dangerous permissions requested
No AI report is available for this listing yet.
AI Driven Test Automation
OpenQA
AI Powered Natural Language Browser Test Automation
No selectors. No flake. Just plain English.
Features
- 🗣️ Write Tests in Plain English — Describe what you want, not how to find it. "Add laptop to cart" just works.
- 📝 BDD & YAML Support — Works with Playwright-BDD, Cucumber.js, or simple YAML files.
- ⚡ 2-Minute Setup —
npx openqa initscaffolds a fully configured.openqa/in your existing project. - 🔒 No API Keys Required Locally — Uses your existing
claude loginsession (Claude Code) oropencode auth login(OpenCode). API keys only needed for CI.
Powered by: Claude Code SDK • OpenCode SDK • Playwright MCP • Playwright-BDD • Cucumber.js • Varlock
Quick Start
Run this from your existing project root:
npx openqa init
The interactive wizard will ask you:
- Agent — Claude Code (
@anthropic-ai/claude-agent-sdk) or OpenCode (@opencode-ai/sdk) - Model —
claude-haiku-4-5(default),claude-sonnet-4-6,claude-opus-4-7, or custom (OpenCode supportsanthropic/...,openai/...,google/...) - Framework — Playwright-BDD or Cucumber.js
- Feature files path — Where feature files live, relative to
.openqa/(default:features)
This scaffolds a .openqa/ directory in your project containing:
playwright.config.tsorcucumber.js— pre-configured and pointing at your feature filessteps/steps.ts(or.js) — a single AI step definition that handles all Gherkin stepssteps/fixtures.ts— the Playwright-BDD fixture extension (Playwright-BDD only)features/— two example feature files to get started (todomvc.feature,getting-started.feature).env.example— copy this to.envand fill in your values.env.schema— committed schema: documents every variable, types, and defaults; secrets are redacted from logs automatically
Then:
cd .openqa
cp .env.example .env
# Local: run `claude login` or `opencode auth login` — no API key needed
# CI: add the relevant API key to .env
npm run test:headed
How It Works
- Your BDD step definitions call
runAgent(claudeCode('model'), 'natural language step', page). - OpenQA creates a Playwright MCP server in-process and exposes it over HTTP/SSE on a random localhost port.
- The chosen AI provider SDK connects to that MCP URL and receives your natural language instruction.
- The agent drives the real browser using Playwright MCP tools (
browser_navigate,browser_click, etc.). - The step passes or fails based on what the agent reports back.
- True browser sharing — the agent drives the exact same page object your test holds.
- Parallel-safe — each test worker gets its own HTTP port. No shared config files.
- Session resumption — within a scenario, the agent resumes its conversation across steps.
- Multi-provider — swap
claudeCodeforopenCodeto use any model from OpenAI, Google, Anthropic, etc.
Environment Variables
The .openqa/ directory uses varlock for environment variable management. Variables are defined in .env.schema (committed to git) and values go in .env (gitignored). Secrets are automatically redacted from logs.
| Variable | Default | Description |
|---|---|---|
BASE_URL |
— | App URL — sets Playwright baseURL and is injected into every agent prompt |
APP_USERNAME |
— | Username — injected into agent prompt for login steps |
APP_PASSWORD |
— | Password — injected into agent prompt; always redacted from logs |
OPENQA_VERBOSE |
true |
Set false to suppress step-by-step agent logs |
HEADLESS |
true |
Set false to watch the browser |
ANTHROPIC_API_KEY |
— | Anthropic API key — only needed for CI (use claude login locally) |
OPENAI_API_KEY |
— | OpenAI API key — only needed for CI via OpenCode |
GOOGLE_API_KEY |
— | Google API key — only needed for CI via OpenCode |
Adding your own variables — edit .openqa/.env.schema to declare them, then add values to .env:
# .openqa/.env.schema (add to the bottom)
# @sensitive=false
ENVIRONMENT = staging
# Your test account credentials for the staging environment
STAGING_USER =
# @sensitive
STAGING_PASSWORD =
Then use them in your steps or anywhere in the test process via process.env.ENVIRONMENT, etc.
Authentication
No API key needed for local development — just log in with the CLI once:
# Claude Code
claude login
# OpenCode (supports GitLab Duo, GitHub Copilot, Anthropic, OpenAI, Google, …)
opencode auth login
For CI (or if you prefer an API key), set the relevant key in .openqa/.env:
# Claude Code
ANTHROPIC_API_KEY=your_key
# OpenCode — use whichever provider you're connecting to
ANTHROPIC_API_KEY=your_key
# OPENAI_API_KEY=your_key
# GOOGLE_API_KEY=your_key
Customizing Your Setup
openqa init creates a working starting point — everything in .openqa/ is yours to edit. Common customizations:
Playwright config — .openqa/playwright.config.ts is a standard Playwright config. Add projects, change timeouts, add reporters, enable retries for CI:
// .openqa/playwright.config.ts
export default defineConfig({
timeout: 120000,
retries: process.env.CI ? 2 : 0,
use: {
baseURL: process.env.BASE_URL,
locale: 'en-US',
timezoneId: 'America/New_York',
},
});
Step definitions — .openqa/steps/steps.ts is a regular Playwright-BDD or Cucumber.js step file. Add custom (non-AI) steps alongside the AI step, or add Before/After hooks:
// .openqa/steps/steps.ts — add a manual step alongside the AI one
import { createBdd } from 'playwright-bdd';
const { Given } = createBdd();
Given('I am on the home page', async ({ page }) => {
await page.goto(process.env.BASE_URL!);
});
Writing Feature Files
openqa init places two example feature files in .openqa/features/ — todomvc.feature (2 scenarios) and getting-started.feature (1 scenario). Edit or replace them with your own.
Feature files use standard Gherkin syntax. We recommend using * (asterisk) for steps instead of Given/When/Then — it reads more naturally for AI-driven tests:
Feature: TodoMVC
Scenario: Add a todo item
* I navigate to "https://demo.playwright.dev/todomvc/"
* I add a new todo item "Buy groceries"
* I should see "Buy groceries" in the todo list
Scenario: Filter completed todos
* I navigate to "https://demo.playwright.dev/todomvc/"
* I add three todo items: "Task 1", "Task 2", and "Task 3"
* I mark the first todo as completed
* I click the Active filter
* I should see 2 active todos
You can still use Given/When/Then — both work identically.
Moving feature files elsewhere — if your feature files live outside .openqa/ (e.g. features/ in the project root), update the path in your config:
For Playwright-BDD, edit .openqa/playwright.config.ts:
const testDir = defineBddConfig({
featuresRoot: '../features',
features: '../features/**/*.feature',
steps: 'steps/*.ts',
});
For Cucumber.js, edit .openqa/cucumber.js:
paths: ['../features/**/*.feature'],
Changing Model or Provider
After running openqa init, your model is set in one line inside .openqa/steps/steps.ts (or steps.js for Cucumber.js). Open that file and edit the provider call:
Change the Claude Code model:
// .openqa/steps/steps.ts
import { runAgent, claudeCode } from 'openqa';
// Before
await runAgent(claudeCode('claude-haiku-4-5'), action, page);
// After — switch to a more capable model
await runAgent(claudeCode('claude-sonnet-4-6'), action, page);
Switch from Claude Code to OpenCode (GitLab Duo, GitHub Copilot, etc.):
// .openqa/steps/steps.ts
import { runAgent, openCode } from 'openqa'; // swap the import
// GitLab Duo
await runAgent(openCode('gitlab/duo-chat-haiku-4-5'), action, page);
// GitHub Copilot
await runAgent(openCode('github-copilot/gpt-5.4'), action, page);
// Anthropic via OpenCode
await runAgent(openCode('anthropic/claude-sonnet-4-6'), action, page);
// OpenAI
await runAgent(openCode('openai/gpt-4o'), action, page);
// Google
await runAgent(openCode('google/gemini-2.0-flash'), action, page);
That's the only change needed — one import swap and one string update.
Using runAgent Directly
For custom Playwright tests (without BDD):
import { test } from "@playwright/test";
import { runAgent, claudeCode } from "openqa";
test("AI agent fills form", async ({ page }) => {
await page.goto("https://example.com/form");
await runAgent(claudeCode('claude-haiku-4-5'), "Fill in the form with test data", page, { verbose: true });
await expect(page.locator('input[name="email"]')).toHaveValue("[email protected]");
});
API Reference
runAgent(provider, prompt, pageOrContext, options?)
Runs the AI agent with a natural language instruction.
| Parameter | Type | Description |
|---|---|---|
provider |
object |
Agent provider, e.g. claudeCode('claude-haiku-4-5') |
prompt |
string |
Natural language instruction |
pageOrContext |
Page | BrowserContext |
Playwright page or browser context |
options.verbose |
boolean |
Enable logging (default: true) |
options.returnUsage |
boolean |
Return token usage stats (default: false) |
Returns: Promise<string> — the agent's final response.
claudeCode(model?)
import { claudeCode } from 'openqa';
const provider = claudeCode('claude-haiku-4-5'); // default
| Model | Description |
|---|---|
claude-haiku-4-5 |
Fast, cost-efficient (default) |
claude-sonnet-4-6 |
Balanced performance |
claude-opus-4-7 |
Most capable |
Requires @anthropic-ai/claude-agent-sdk to be installed.
openCode(model?)
import { openCode } from 'openqa';
const provider = openCode('gitlab/duo-chat-haiku-4-5'); // GitLab Duo (default in init)
// or: openCode('github-copilot/gpt-5.4')
// or: openCode('anthropic/claude-haiku-4-5'), openCode('openai/gpt-4o'), openCode('google/gemini-2.0-flash')
Model format: provider/model. Supports any provider configured in your OpenCode installation.
| Model | Provider |
|---|---|
gitlab/duo-chat-haiku-4-5 |
GitLab Duo (default) |
github-copilot/gpt-5.4 |
GitHub Copilot |
anthropic/claude-haiku-4-5 |
Anthropic |
openai/gpt-4o |
OpenAI |
google/gemini-2.0-flash |
Requires @opencode-ai/sdk to be installed.
runAgent.resetSession(browserContext)
Resets the Claude Code conversation session for a specific browser context. Useful when you want to start a fresh conversation mid-test.
Examples
examples/playwright-bdd/— Playwright-BDD with natural language stepsexamples/playwright-yaml/— YAML-based testsexamples/cucumberjs/— Cucumber.js integration
Requirements
- openqa library: Node.js 18+
- Scaffolded
.openqa/project: Node.js 22+ (required by varlock) @playwright/test^1.57.0- One of:
@anthropic-ai/claude-agent-sdk(forclaudeCode) or@opencode-ai/sdk(foropenCode)
Links
- Website: https://openqa.io/
- NPM: https://www.npmjs.com/package/openqa
- GitHub: https://github.com/openqa-labs/openqa
License
MIT
Reviews (0)
Sign in to leave a review.
Leave a reviewNo results found