Strongly Typed Gherkin-to-Playwright Pipelines
ai-test-generator-4playwright-ts is the TypeScript sibling of my JavaScript generator. The npm package still ships as playwright-testgen-from-gherkin-ts, but the code now lives in amiya-pattnaik/ai-test-generator-4playwright-ts.
The goal stays the same: honor the scenarios product owners capture in Gherkin and produce high quality Playwright suites automatically. The TypeScript flavor adds end-to-end typing so editors surface locator names, method signatures, and data contracts.
What Sets The TS Edition Apart
- Type-safe Page Objects: Generated classes include typed locators and return values, giving you auto-complete and compile time checks.
- Typed pipeline utilities: Both
processStepsandprocessTestsexport TypeScript definitions, so custom build scripts can rely on intellisense. - Scriptable watch modes:
npm run watch:stepsandnpm run watch:testskeep the output in sync with live edits. - Shared AI selector engine: The same NLP logic powers selector naming, keeping parity with the JavaScript build.
Getting Started
git clone git@github.com:amiya-pattnaik/ai-test-generator-4playwright-ts.git
cd ai-test-generator-4playwright-ts
npm install
npm install -g tsx
npm link
Run the generator:
testgen steps --all
testgen tests --all
testgen run --report
Or stay local without a global link:
npm run steps
npm run tests
npm run run:all # steps → tests → playwright report
Embed In Tooling
import { processSteps, processTests } from 'playwright-testgen-from-gherkin-ts';
await processSteps({
featuresPath: './features',
outputPath: './stepMaps',
watch: false,
force: true
});
await processTests({
stepMapDir: './stepMaps',
outputDir: './tests',
dryRun: false,
all: true
});
That snippet shows the current npm package name. The import path will change after the package is republished under the ai-test-generator naming.
End-To-End Example
Feature Input
Feature: Login
Scenario: User signs in
Given I am on the "login" page
When I fill "userName" with "testuser"
And I fill "password" with "password123"
And I click on "login"
Then I should see "welcomeBack"
Generated Step Map (excerpt)
{
"scenario": "User signs in",
"steps": [
{ "action": "open", "selectorName": "open", "note": "login" },
{ "action": "setValue", "selectorName": "userNameField", "note": "testuser" },
{ "action": "setValue", "selectorName": "passwordField", "note": "password123" },
{ "action": "click", "selectorName": "loginButton" },
{ "action": "assertVisible", "selectorName": "welcomeBack" }
]
}
Generated Spec Snippet
import { test, expect } from '@playwright/test';
import LoginPage from '../pageobjects/login.page';
test.describe('login feature tests', () => {
test('user signs in', async ({ page }) => {
const pageObj = new LoginPage(page);
await pageObj.open('login');
await pageObj.userNameField.fill('testuser');
await pageObj.passwordField.fill('password123');
await pageObj.loginButton.click();
await expect(pageObj.welcomeBack).toBeVisible();
});
});
Roadmap And Feedback
I am collecting requests for improved type helpers, scenario metadata, and generated Playwright fixtures. If you depend on the TypeScript output, please share the gaps you still fill by hand. The more concrete examples I see, the faster we can bake them into the generator.