typescript-utility-types
Use when typeScript utility types, mapped types, and advanced type manipulation. Use when creating flexible, type-safe TypeScript code.
playwright-bdd-configuration
Use when configuring Playwright BDD projects, setting up defineBddConfig(), configuring feature and step file paths, and integrating with Playwright config.
Full skill instructions
Expert knowledge of Playwright BDD configuration, project setup, and integration with Playwright's testing framework for behavior-driven development.
Playwright BDD enables running Gherkin-syntax BDD tests with Playwright Test. Configuration is done through the playwright.config.ts file using the defineBddConfig() function, which generates Playwright test files from your .feature files.
# Install playwright-bdd
npm install -D playwright-bdd
# Or with specific Playwright version
npm install -D playwright-bdd @playwright/test
// playwright.config.ts
import { defineConfig } from '@playwright/test';
import { defineBddConfig } from 'playwright-bdd';
const testDir = defineBddConfig({
features: 'features/**/*.feature',
steps: 'steps/**/*.ts',
});
export default defineConfig({
testDir,
});
The defineBddConfig() function returns a path to the generated test directory. By default, this is .features-gen in your project root:
const testDir = defineBddConfig({
features: 'features/**/*.feature',
steps: 'steps/**/*.ts',
});
// testDir = '.features-gen/features'
const testDir = defineBddConfig({
features: 'features/**/*.feature',
steps: 'steps/**/*.ts',
outputDir: '.generated-tests', // Custom output directory
});
Configure where to find feature files:
defineBddConfig({
// Single pattern
features: 'features/**/*.feature',
// Multiple patterns
features: [
'features/**/*.feature',
'specs/**/*.feature',
],
// Exclude patterns
features: {
include: 'features/**/*.feature',
exclude: 'features/**/skip-*.feature',
},
});
Configure step definition locations:
defineBddConfig({
// Single pattern
steps: 'steps/**/*.ts',
// Multiple patterns
steps: [
'steps/**/*.ts',
'features/**/*.steps.ts',
],
// Mixed JavaScript and TypeScript
steps: [
'steps/**/*.ts',
'steps/**/*.js',
],
});
When using custom fixtures, import the test instance:
defineBddConfig({
features: 'features/**/*.feature',
steps: 'steps/**/*.ts',
importTestFrom: 'steps/fixtures.ts', // Path to your custom test instance
});
The fixtures file should export the test instance:
// steps/fixtures.ts
import { test as base, createBdd } from 'playwright-bdd';
export const test = base.extend<{
todoPage: TodoPage;
}>({
todoPage: async ({ page }, use) => {
const todoPage = new TodoPage(page);
await use(todoPage);
},
});
export const { Given, When, Then } = createBdd(test);
Configure different feature sets for different test projects:
import { defineConfig } from '@playwright/test';
import { defineBddConfig } from 'playwright-bdd';
const coreTestDir = defineBddConfig({
features: 'features/core/**/*.feature',
steps: 'steps/core/**/*.ts',
outputDir: '.features-gen/core',
});
const adminTestDir = defineBddConfig({
features: 'features/admin/**/*.feature',
steps: 'steps/admin/**/*.ts',
outputDir: '.features-gen/admin',
});
export default defineConfig({
projects: [
{
name: 'core',
testDir: coreTestDir,
},
{
name: 'admin',
testDir: adminTestDir,
},
],
});
Configure the Gherkin language:
defineBddConfig({
features: 'features/**/*.feature',
steps: 'steps/**/*.ts',
language: 'de', // German keywords (Gegeben, Wenn, Dann)
});
Supported languages follow the Gherkin specification:
en (English - default)de (German)fr (French)es (Spanish)ru (Russian)Configure quote style in generated test files:
defineBddConfig({
features: 'features/**/*.feature',
steps: 'steps/**/*.ts',
quotes: 'single', // 'single' | 'double' | 'backtick'
});
Enable verbose output during generation:
defineBddConfig({
features: 'features/**/*.feature',
steps: 'steps/**/*.ts',
verbose: true,
});
// playwright.config.ts
import { defineConfig, devices } from '@playwright/test';
import { defineBddConfig } from 'playwright-bdd';
const testDir = defineBddConfig({
features: 'features/**/*.feature',
steps: 'steps/**/*.ts',
importTestFrom: 'steps/fixtures.ts',
});
export default defineConfig({
testDir,
fullyParallel: true,
forbidOnly: !!process.env.CI,
retries: process.env.CI ? 2 : 0,
workers: process.env.CI ? 1 : undefined,
reporter: [
['html'],
['json', { outputFile: 'test-results/results.json' }],
],
use: {
baseURL: 'http://localhost:3000',
trace: 'on-first-retry',
screenshot: 'only-on-failure',
},
projects: [
{
name: 'chromium',
use: { ...devices['Desktop Chrome'] },
},
{
name: 'firefox',
use: { ...devices['Desktop Firefox'] },
},
{
name: 'webkit',
use: { ...devices['Desktop Safari'] },
},
],
webServer: {
command: 'npm run start',
url: 'http://localhost:3000',
reuseExistingServer: !process.env.CI,
},
});
import { defineConfig } from '@playwright/test';
import { defineBddConfig } from 'playwright-bdd';
const isCI = !!process.env.CI;
const testDir = defineBddConfig({
features: 'features/**/*.feature',
steps: 'steps/**/*.ts',
verbose: !isCI,
});
export default defineConfig({
testDir,
timeout: isCI ? 60000 : 30000,
retries: isCI ? 2 : 0,
workers: isCI ? 4 : undefined,
});
# Generate test files from features
npx bddgen
# Run Playwright tests
npx playwright test
# Or combine both
npx bddgen && npx playwright test
For development, regenerate on file changes:
# Watch feature and step files
npx bddgen --watch
# In another terminal, run tests
npx playwright test --watch
Export all step definitions for documentation:
npx bddgen export
Recommended project structure:
project/
├── playwright.config.ts
├── features/
│ ├── auth/
│ │ ├── login.feature
│ │ └── logout.feature
│ └── products/
│ └── catalog.feature
├── steps/
│ ├── auth/
│ │ ├── login.steps.ts
│ │ └── logout.steps.ts
│ ├── products/
│ │ └── catalog.steps.ts
│ └── fixtures.ts
└── .features-gen/ # Generated (gitignore this)
└── features/
├── auth/
│ ├── login.feature.spec.js
│ └── logout.feature.spec.js
└── products/
└── catalog.feature.spec.js
Add to .gitignore:
# Playwright BDD generated files
.features-gen/
// packages/e2e/playwright.config.ts
import { defineConfig } from '@playwright/test';
import { defineBddConfig } from 'playwright-bdd';
const testDir = defineBddConfig({
features: 'features/**/*.feature',
steps: 'steps/**/*.ts',
importTestFrom: 'steps/fixtures.ts',
});
export default defineConfig({
testDir,
use: {
baseURL: process.env.BASE_URL || 'http://localhost:3000',
},
});
import { defineConfig } from '@playwright/test';
import { defineBddConfig } from 'playwright-bdd';
const testDir = defineBddConfig({
features: 'features/components/**/*.feature',
steps: 'steps/components/**/*.ts',
});
export default defineConfig({
testDir,
use: {
ctPort: 3100,
},
});
import { defineConfig } from '@playwright/test';
import { defineBddConfig } from 'playwright-bdd';
const testDir = defineBddConfig({
features: 'features/api/**/*.feature',
steps: 'steps/api/**/*.ts',
});
export default defineConfig({
testDir,
use: {
baseURL: 'https://api.example.com',
},
});
If steps are not being matched:
steps confignpx bddgen export to see all registered stepsIf imports fail in generated files:
importTestFrom path is correcttest and step functionsIf bddgen fails:
verbose: true for detailsbddgen before tests in CIUse when typeScript utility types, mapped types, and advanced type manipulation. Use when creating flexible, type-safe TypeScript code.
Use when writing shell scripts that need to run across different systems, shells, or environments. Covers POSIX compatibility and platform differences.
Use when optimizing Tailwind CSS for production, reducing bundle size, and improving performance. Covers PurgeCSS, JIT mode, and build optimization.
Generate production-ready code from a Figma component or frame using the Figma MCP server
Use when integrating Dialyzer into development workflows and CI/CD pipelines for Erlang/Elixir projects.
Use when ruboCop configuration including YAML config, departments, inheritance, and customization.
Use when Elixir OTP patterns including GenServer, Supervisor, Agent, and Task. Use when building concurrent, fault-tolerant Elixir applications.
Use when creating custom Ameba rules for Crystal code analysis including rule development, AST traversal, issue reporting, and rule testing.
Use when swift's optional handling patterns including optional binding, chaining, nil coalescing, and modern approaches to safely working with optional values while avoiding common pitfalls and force unwrapping.
Use when annotating code with structured metadata, tags, and markers for AI-assisted development workflows. Covers annotation formats, semantic tags, and integration with development tools.
Use when scala collections including immutable/mutable variants, List, Vector, Set, Map operations, collection transformations, lazy evaluation with views, parallel collections, and custom collection builders for efficient data processing.
Use when creating custom React Flow nodes, edges, and handles. Covers custom node components, resizable nodes, toolbars, and advanced customization.
Generate, edit, and beat-sync AI video with leading models in one workspace.
The world's fastest calendar for remote work
Transform Your Design with AI Designer by ImgCreator.ai
Revolutionizing Video Production with AI-Powered Creativity
Extend an image past the frame and let AI fill the new aspect ratio.
Discover your celebrity doppelgänger with StarByFace!
ChainClarity explains 700+ crypto whitepapers in plain English, with layered summaries, comparisons, research tools, alerts, and a $4.99 Pro plan.
Opus.ai: Revolutionize Your Web Experience