Gathering detailed insights and metrics for wdio-testgen-from-gherkin-js
Gathering detailed insights and metrics for wdio-testgen-from-gherkin-js
Gathering detailed insights and metrics for wdio-testgen-from-gherkin-js
Gathering detailed insights and metrics for wdio-testgen-from-gherkin-js
Automatically generate WebdriverIO Page Object classes, AI/NLP-Driven Selector Name Inference and Mocha test specs from Gherkin `.feature` files.
npm install wdio-testgen-from-gherkin-js
Typescript
Module System
Node Version
NPM Version
JavaScript (94.35%)
Gherkin (5.65%)
Total Downloads
0
Last Day
0
Last Week
0
Last Month
0
Last Year
0
MIT License
1 Stars
24 Commits
1 Watchers
1 Branches
1 Contributors
Updated on Jun 30, 2025
Latest Version
1.0.10
Package Id
wdio-testgen-from-gherkin-js@1.0.10
Unpacked Size
39.94 kB
Size
11.89 kB
File Count
11
NPM Version
10.2.3
Node Version
20.10.0
Published on
Jun 30, 2025
Cumulative downloads
Total Downloads
Last Day
0%
NaN
Compared to previous day
Last Week
0%
NaN
Compared to previous week
Last Month
0%
NaN
Compared to previous month
Last Year
0%
NaN
Compared to previous year
7
wdio-testgen-from-gherkin-js
(WebdriverIO Test Generator from Gherkin JavaScript)CLI and Node.js tool to auto-generate WebdriverIO Page Object classes and Mocha test specs from Gherkin
.feature
files using NLP for selector and method inference.
Step Map Generation
Parses .feature
files into structured .stepMap.json
with fields like action
, selectorName
, selector
, fallbackSelector
, and note
.
Test Code Generation
Uses step maps to generate:
1 2git clone https://github.com/amiya-pattnaik/wdio-testgen-from-gherkin-js.git 3cd wdio-testgen-from-gherkin-js 4npm install
npm install wdio-testgen-from-gherkin-js
project-root/
├── features/ # Gherkin .feature files (user input / source file)
├── stepMaps/ # Auto-generated .stepMap.json files
├── test/
│ ├── pageobjects/ # Auto-generated WebdriverIO tests Page Object Model classes
│ └── specs/ # Auto-generated Mocha test specs
├── src/
│ ├── cli.js # Main CLI logic
│ ├── generateStepsMap.js # Feature-to-stepMap generator
│ ├── generateTestsFromMap.js # stepMap-to-page/spec generator
│ ├── utils.js # Helper methods
│ └── config.js # Paths, fallback selectors, aliases
│ └── __tests__/ # Unit tests (Vitest)
├── testgen.js # CLI entry point
│── wdio.config.js # WebdriverIO configuration
├── package.json # Scripts and dependencies
├── selector-aliases.json # Optional user-defined selector overrides the primary selector
1npm install -g 2npm install -g tsx # Required for CLI to run with node shebang 3chmod +x testgen.js # Make CLI executable (Mac/Linux) 4npm link # If fails, try: sudo npm link 5 6⚠️ Now run from anywhere 7 8# Step 1: Generate stepMap.json from the .feature files 9testgen steps --all 10testgen steps --file login.feature 11 12# Step 2: Generate test code (Page Objects and Mocha Specs) from stepMap.json 13testgen tests --all 14testgen tests --file login.stepMap.json 15testgen tests --file login.stepMap.json --dry-run 16 17# Step 3: Execute tests and generate Allure report 18testgen run --report # ⬅️ Runs tests and generate allure report 19testgen run --report-only # ⬅️ Generate report without rerunning testsbash
1# Step 1: Generate stepMap.json from the .feature files 2npm run dev:testgen:steps -- --all 3npm run dev:testgen:steps -- --file login.feature 4 5# Step 2: Generate Page Objects and Mocha Specs from stepMap.json 6npm run dev:testgen:tests -- --all 7npm run dev:testgen:tests -- --file login.stepMap.json 8npm run dev:testgen:tests -- --file login.stepMap.json --dry-run 9 10# Step 3: Execute tests and generate Allure reoprt 11npm run dev:testgen:run 12npm run dev:testgen:run -- --report # Run tests + generate report 13npm run dev:testgen:run -- --report-only # Just show last test run report
You can use wdio-testgen-from-gherkin-js
package both as a CLI tool and as a Node.js module in custom scripts.
In your project workking directory like any other NPM modules install this package as npm install wdio-testgen-from-gherkin-js
Example: generate-tests.js
1const { generateStepMaps, generateTestSpecs } = require('wdio-testgen-from-gherkin-js');
2
3// Generate stepMap JSON files from .feature files
4generateStepMaps({
5 featuresPath: './features', // path to your .feature files. Make sure features folder exist and has .feature files
6 outputPath: './stepMaps', // where to write stepMap JSONs
7 watch: false,
8 force: true
9});
10
11// Generate Page Object classes and Mocha test specs
12generateTestSpecs({
13 stepMapDir: './stepMaps', // location of generated stepMaps
14 outputDir: './test', // base directory to create pageobjects/ and specs/
15 dryRun: false,
16 watch: false
17});
18
19NOTE: If you don't mention the stepMapDir path then stepMaps and test folder will be created under your project root directory.
test/
├── pageobjects/
│ └── login.page.js
└── specs/
└── login.spec.js
testgen steps
Flag | Description |
---|---|
--all | Parse all feature files |
--file | Parse specific feature file(s) |
--watch | Watch for changes |
--verbose | Print detailed logs |
--dry-run | Show files that would be created |
--force | Overwrite existing stepMap files |
testgen tests
Flag | Description |
---|---|
--all | Generate tests for all step maps |
--file | Generate tests for specific step maps |
--watch | Watch and regenerate on change |
--verbose | Print detailed logs |
--dry-run | Show files that would be created |
--force | Overwrite existing test files |
testgen run
Flag | Description |
---|---|
--report | Generate Allure report after test run |
--report-only | Generate only Allure report (skip running tests) |
features/login.feature
1Feature: Login 2 Scenario: Successful login 3 Given I open the login page 4 When I enter "admin" into the username field 5 And I enter "adminpass" into the password field 6 And I click the login button 7 Then I should see the dashboard
stepMaps/login.stepMap.json
1{ 2 "Successful login": [ 3 { 4 "action": "setValue", 5 "selectorName": "userNameField", 6 "selector": "[data-testid=\"userNameField\"]", 7 "fallbackSelector": "#username, input[name=\"username\"]", 8 "note": "admin" 9 }, 10 { 11 "action": "setValue", 12 "selectorName": "passwordField", 13 "selector": "[data-testid=\"passwordField\"]", 14 "fallbackSelector": "#password, input[type=\"password\"]", 15 "note": "adminpass" 16 }, 17 { 18 "action": "click", 19 "selectorName": "loginButton", 20 "selector": "[data-testid=\"loginButton\"]", 21 "fallbackSelector": "#login, button[type=\"submit\"]", 22 "note": "" 23 }, 24 { 25 "action": "assertVisible", 26 "selectorName": "dashboard", 27 "selector": "[data-testid=\"dashboard\"]", 28 "fallbackSelector": "", 29 "note": "" 30 } 31 ] 32}
Note: Additionally, ensure that you update the relevant selector for the DOM element of your application under test after generating your JSON file. This will serve as your foundation, and your page objects and test spec files will be constructed based on this data.
test/pageobjects/page.js
1const { browser, $ } = require('@wdio/globals'); 2 3class Page { 4 open(path) { 5 return browser.url(`https://the-internet.herokuapp.com/${path}`); 6 } 7 8 async trySelector(primary, fallbacks) { 9 try { 10 const el = await $(primary); 11 if (await el.isExisting() && await el.isDisplayed()) { 12 console.log(`✅ Using primary selector: ${primary}`); 13 return el; 14 } 15 } catch (e) { 16 console.warn(`⚠️ Failed to find element with primary selector: ${primary}`); 17 } 18 for (const sel of fallbacks) { 19 try { 20 const fallback = await $(sel); 21 if (await fallback.isExisting() && await fallback.isDisplayed()) { 22 console.log(`↪️ Using fallback selector: ${sel}`); 23 return fallback; 24 } 25 } catch {} 26 } 27 throw new Error(`❌ All selectors failed:\nPrimary: ${primary}\nFallbacks: ${fallbacks.join(', ')}`); 28 } 29} 30 31module.exports = Page;
test/pageobjects/login.page.js
1const Page = require('./page'); 2class LoginPage extends Page { 3 get loginbutton() { 4 return this.trySelector('button.login-btn', ['#login', 'button[type="submit"]']); 5 } 6 get usernamefield() { 7 return this.trySelector('#login-username-amiya', ['#username', 'input[name="username"]']); 8 } 9 get passwordfield() { 10 return this.trySelector('#login-password-Patt', ['#password', 'input[type="password"]']); 11 } 12 get welcomebanner() { 13 return this.trySelector('[data-testid="welcomeBanner"]', ['#welcome-message', '.welcome']); 14 } 15 async mySuccessfulLogin() { 16 await (await this.usernamefield).setValue(''); 17 await (await this.passwordfield).setValue(''); 18 await (await this.loginbutton).click(); 19 await expect(await this.welcomebanner).toBeDisplayed(); 20 } 21 open(pathSegment = 'login') { 22 return super.open(pathSegment); 23 } 24} 25module.exports = new LoginPage();
test/specs/login.spec.js
1const { expect } = require('@wdio/globals'); 2const LoginPage = require('../pageobjects/login.page'); 3describe('login feature tests', () => { 4 it('mySuccessfulLogin', async () => { 5 await LoginPage.open(); 6 await (await LoginPage.usernamefield).setValue(''); 7 await (await LoginPage.passwordfield).setValue(''); 8 await (await LoginPage.loginbutton).click(); 9 await expect(await LoginPage.welcomebanner).toBeDisplayed(); 10 // Or simply use: 11 // await LoginPage.mySuccessfulLogin(); 12 }); 13});
Note: It is recommended to examine the generated code and implement any required adjustments to meet your needs, such as invoking methods from test spec files to the page class, incorporating reusable methods, renaming selector name, method name (if any) and managing your test data etc.
.feature
files and generate scenario-wise stepMap.json
.stepMap.json
to auto-generate:
compromise
NLP library to generate meaningful selector, method names based on verbs/nouns in step text."When user clicks login"
→ selectorName: "clicklogin"
Applies regex-based matching to map common UI elements to logical names:
username
→ userNameField
login
→ loginButton
Logical names are mapped to selector and fallbackSelector:
1{ 2 "selector": "[data-testid=\"loginButton\"]", 3 "fallbackSelector": "#login, button[type=\"submit\"]", 4}
The
fallbackSelector
is a palce holder for containing more than one alternative selector. At the run time if the primary selector (i.e. "selector": "[data-testid="loginButton"]") fails to locate the element, it will log⚠️ Failed to find element with primary selector
, and then it will pick one of the alternative selctor mentioned in thefallbackSelector
. If it finds the right selector it will log↪️ Using fallback selector
. If none of the alternative selector found, then it will trrow error❌ All selectors failed
.
selector-aliases.json
. When implemented it overrides the default primary selector ("selector": "#login-username",) of the generated .stepMap.json. If you don't need the selector-aliases.json then either you rename it or delete it from the root.1{ 2 "userNameField": "#login-username", 3 "loginButton": "#login-btn" 4}
Priority Order:
selector
generated by tool.Automatically extracts values from steps:
1When user enters "admin" in the username field
→ action: "setValue", note: "admin"
Gherkin Step Example | Action | Notes |
---|---|---|
When user enters "admin" | setValue | "admin" |
When user clicks login | Click | |
Then user should see the welcome message | assertVisible | |
Then title should be "Dashboard" | assertTitle | "Dashboard" |
Then url should contain "success" | assertUrlContains |
Supports a wide range of actions: setValue
, click
, selectDropdown
, uploadFile
, hover
, clearText
, scrollTo
, assertVisible
, assertText
, assertEnabled
, assertDisabled
, assertTitle
, assertUrlContains
, etc.
Action | Description |
---|---|
setValue | Sets input value |
click | Clicks on the element |
hover | Hovers over an element |
doubleClick | Performs a double-click |
selectDropdown | Selects dropdown option by visible text |
uploadFile | Uploads a file |
scrollTo | Scrolls element into view |
assertVisible | Validates visibility of element |
assertText | Checks element text |
clearText | Clears input field |
assertEnabled | Validates element is enabled |
assertDisabled | Validates element is disabled |
assertTitle | Validates page title |
assertUrlContains | Checks partial match on URL |
waitForVisible | Waits until element is visible |
Please be advised that any unrecognized actions have been commented out in the generated code for your review. Should you wish to include any additional actions, kindly refer to the source code (src\) and incorporate the necessary actions, which is quite straightforward. You may utilize any WebdriverIO commands as needed.
Error: command not found: testgen
✅ Run npm link
again inside the project root.
Error: env: tsx: No such file or directory
✅ Install tsx
globally: npm install -g tsx
Error: ENOENT: no such file or directory, open 'package.json'
✅ You’re running npm run
outside the project — run from root.
wdio-testgen-from-gherkin-ts
Check out the Releases tab for version history and improvements.
Want to discuss features or share feedback? Use GitHub Discussions or open an issue.
Amiya Pattanaik
For issues, enhancements or feature requests, open an issue.
No vulnerabilities found.
No security vulnerabilities found.