Skip to main content
Glama
lucad87

MCP Server - Test Migration (WDIO to Playwright)

by lucad87

MCP Server - Test Migration (WDIO to Playwright)

An MCP (Model Context Protocol) server that helps migrate test automation projects from WebDriverIO to Playwright test framework using AST-based transformations.

Features

This MCP server provides specialized tools for a complete migration workflow:

1. analyze_wdio_test

Analyzes WebDriverIO test files using AST parsing and extracts:

  • Import statements and dependencies

  • Test structure (describe blocks, test cases)

  • Selectors used (CSS, XPath, data-test-id, etc.)

  • WDIO commands and patterns

  • Assertions libraries

  • Hooks (before, after, etc.)

  • Page Object usage detection

  • Framework detection (WDIO, Playwright, or mixed)

  • Migration complexity assessment

  • Modern selector suggestions (getByTestId, getByRole, etc.)

2. migrate_to_playwright

Migrates WDIO tests to Playwright using AST transformation:

  • Converts WDIO syntax to Playwright syntax

  • Updates selectors to use Playwright locators

  • Suggests modern locators (getByTestId with data-test-id)

  • Replaces WDIO commands with Playwright equivalents

  • Uses latest Playwright v1.57 best practices

  • Removes unnecessary explicit waits (leverages auto-waiting)

  • Converts assertions to Playwright's expect

  • Preserves already-migrated code (supports partial migrations)

3. refactor_to_pom

Refactors migrated tests to use Page Object Model:

  • Extracts page interactions into page classes

  • Generates actual locator properties from test code

  • Creates reusable page object files

  • Applies Playwright POM patterns

  • Supports existing page objects

4. get_playwright_docs

Retrieves relevant Playwright documentation:

  • Selectors and locators (with data-test-id examples)

  • Assertions

  • Fixtures

  • Page Object Model

  • Auto-waiting behavior

  • Configuration

5. compare_frameworks

Provides side-by-side comparison:

  • 50+ WDIO commands → Playwright equivalents

  • Syntax differences

  • Best practice recommendations

  • Related commands table

6. detect_project_state (NEW)

Analyzes project structure to detect:

  • Existing Playwright configuration

  • Existing WDIO configuration

  • Already migrated tests

  • Partially migrated tests

  • Existing page objects

  • Project directory structure

  • Recommendations for migration strategy

7. migrate_config

Migrates wdio.conf.js to playwright.config.ts:

  • Extracts baseUrl, specs, capabilities

  • Generates proper Playwright config

  • Sets testIdAttribute: 'data-test-id'

  • Merges with existing Playwright config if present

8. register_custom_commands (NEW)

Registers project-specific custom WDIO commands:

  • Add custom command → Playwright mappings

  • Commands are used in subsequent migrations

  • Persists during server session

9. generate_migration_report (NEW)

Generates comprehensive migration report as markdown:

  • Migration statistics (total, migrated, pending, failed)

  • Tags summary with Playwright grep commands

  • File-by-file status

  • Detailed test list with tags

Tag Migration

The tool automatically migrates test tags from WDIO to Playwright format:

WDIO (tags in description):

it('should login successfully [SMOKE] [P1]', async () => { ... });
it('should validate form @regression', async () => { ... });

Playwright (tag annotations):

test('should login successfully', { tag: ['@smoke', '@p1'] }, async ({ page }) => { ... });
test('should validate form', { tag: ['@regression'] }, async ({ page }) => { ... });

Run tests by tag: npx playwright test --grep @smoke

Installation

npm install

Usage

As MCP Server (stdio - Local)

Add to your MCP client configuration (e.g., Claude Desktop, GitHub Copilot):

{
  "mcpServers": {
    "tests-migration": {
      "command": "node",
      "args": ["/path/to/mcp-server-tests-migration/index.js"]
    }
  }
}

Standalone (stdio)

npm start

HTTP Server (Remote/Docker)

Run the HTTP server for remote access:

npm run start:http

The server will be available at http://localhost:3000

Docker Deployment

Build and run with Docker:

# Build image
npm run docker:build
# or
docker build -t mcp-server-tests-migration:2.1.0 .

# Run container
npm run docker:run
# or
docker run -p 3000:3000 mcp-server-tests-migration:2.1.0

# Using docker-compose
npm run docker:compose
# or
docker-compose up -d

HTTP API Endpoints

When running in HTTP mode, the following endpoints are available:

Endpoint

Method

Description

/

GET

API documentation

/health

GET

Health check

/mcp

POST

MCP Streamable HTTP (recommended)

/mcp

GET

MCP SSE stream for responses

/mcp

DELETE

Close MCP session

/sse

GET

Legacy SSE connection

/api/analyze

POST

Analyze WDIO test

/api/migrate

POST

Migrate to Playwright

/api/refactor-pom

POST

Refactor to Page Object Model

/api/compare

POST

Compare WDIO/Playwright commands

/api/docs/:topic

GET

Get Playwright documentation

/api/detect-project

POST

Detect project state

/api/migrate-config

POST

Migrate wdio.conf.js

/api/register-commands

POST

Register custom commands

/api/generate-report

POST

Generate migration report

HTTP API Examples

# Analyze a test
curl -X POST http://localhost:3000/api/analyze \
  -H "Content-Type: application/json" \
  -d '{"testContent": "const { expect } = require(\"chai\");\ndescribe(\"Test\", () => { it(\"works\", async () => { await $(\"#btn\").click(); }); });"}'

# Migrate a test
curl -X POST http://localhost:3000/api/migrate \
  -H "Content-Type: application/json" \
  -d '{"testContent": "...", "outputFormat": "typescript"}'

# Get Playwright docs
curl http://localhost:3000/api/docs/selectors

Connecting MCP Clients to HTTP Server

For MCP clients that support Streamable HTTP transport (recommended):

http://your-server:3000/mcp

For legacy clients using SSE transport:

http://your-server:3000/sse

Example Configuration Files

See the examples/ directory for ready-to-use configuration files:

  • mcp-config-local.json - Local stdio mode

  • mcp-config-http-local.json - Local HTTP/SSE mode

  • mcp-config-http-remote.json - Remote HTTP/SSE mode

  • mcp-config-docker-stdio.json - Docker with stdio

For detailed configuration options, see docs/client-configuration.md

Migration Workflow

// Use detect_project_state tool to understand current migration status
// Provides insights on existing Playwright config, migrated tests, page objects

Step 1: Analyze

// Use analyze_wdio_test tool with your WDIO test content
// This provides insights into the test structure and complexity
// Detects if test is already partially migrated

Step 2: Migrate Config (if needed)

// Use migrate_config tool to convert wdio.conf.js to playwright.config.ts
// Preserves existing Playwright config if present

Step 3: Migrate Tests

// Use migrate_to_playwright tool to convert to Playwright
// AST-based transformation preserves already-migrated code
// Tests will use direct page interactions (no POM yet)

Step 4: Refactor to POM

// Use refactor_to_pom tool to apply Page Object Model
// This creates maintainable, reusable page classes
// Reuses existing page objects if present

Step 5: Verify

// Use get_playwright_docs and compare_frameworks for reference
// Review and adjust generated code as needed
// Run tests: npx playwright test

Example

Original WDIO Test:

describe('Login Test', () => {
  it('should login successfully', async () => {
    await browser.url('https://example.com/login');
    await $('#username').setValue('testuser');
    await $('#password').setValue('testpass');
    await $('#login-button').click();
    await $('#dashboard').waitForDisplayed();
    expect(await $('#welcome-message').getText()).to.equal('Welcome!');
  });
});

After Migration (Step 2):

import { test, expect } from '@playwright/test';

test.describe('Login Test', () => {
  test('should login successfully', async ({ page }) => {
    await page.goto('https://example.com/login');
    await page.locator('#username').fill('testuser');
    await page.locator('#password').fill('testpass');
    await page.locator('#login-button').click();
    await expect(page.locator('#dashboard')).toBeVisible();
    await expect(page.locator('#welcome-message')).toHaveText('Welcome!');
  });
});

After POM Refactoring (Step 3):

// login.spec.js
import { test, expect } from '@playwright/test';
import { LoginPage } from './pages/LoginPage';

test.describe('Login Test', () => {
  test('should login successfully', async ({ page }) => {
    const loginPage = new LoginPage(page);
    await loginPage.goto();
    await loginPage.login('testuser', 'testpass');
    await expect(loginPage.dashboardSection).toBeVisible();
    await expect(loginPage.welcomeMessage).toHaveText('Welcome!');
  });
});

// pages/LoginPage.js
export class LoginPage {
  constructor(page) {
    this.page = page;
    this.usernameInput = page.locator('#username');
    this.passwordInput = page.locator('#password');
    this.loginButton = page.locator('#login-button');
    this.dashboardSection = page.locator('#dashboard');
    this.welcomeMessage = page.locator('#welcome-message');
  }

  async goto() {
    await this.page.goto('https://example.com/login');
  }

  async login(username, password) {
    await this.usernameInput.fill(username);
    await this.passwordInput.fill(password);
    await this.loginButton.click();
  }
}

Key Migration Concepts

WDIO → Playwright Mapping

WDIO

Playwright

$('selector')

page.locator('selector') or page.getByTestId('id')

$$('selector')

page.locator('selector').all()

.setValue()

.fill()

.addValue()

.pressSequentially()

.click()

.click()

.getText()

.textContent()

.getValue()

.inputValue()

.waitForDisplayed()

.waitFor({ state: 'visible' }) or auto-waiting

.moveTo()

.hover()

.scrollIntoView()

.scrollIntoViewIfNeeded()

.selectByVisibleText()

.selectOption()

browser.url()

page.goto()

browser.pause()

page.waitForTimeout()

browser.execute()

page.evaluate()

browser.keys()

page.keyboard.press()

browser.refresh()

page.reload()

browser.takeScreenshot()

page.screenshot()

Playwright Advantages

  1. Auto-waiting: No need for explicit waits in most cases

  2. Web-first assertions: Built-in retry logic

  3. Modern selectors: getByRole, getByText, getByLabel, getByTestId

  4. data-test-id support: Configure with testIdAttribute: 'data-test-id'

  5. Better debugging: Playwright Inspector, trace viewer

  6. Parallel execution: Built-in support

  7. Multiple browsers: Chromium, Firefox, WebKit

  8. AST-based migration: Accurate code transformation

Key Improvements in v2.0

  • AST-based parsing: Uses Babel parser for accurate code analysis and transformation

  • Complete command mappings: 50+ WDIO commands mapped to Playwright equivalents

  • Modern locator suggestions: Recommends getByTestId, getByRole, getByLabel

  • data-test-id support: Uses data-test-id attribute (configurable)

  • Partial migration support: Detects and preserves already-migrated code

  • Project state detection: Understands existing Playwright setup

  • Config migration: Converts wdio.conf.js to playwright.config.ts

  • Smart POM generation: Extracts actual selectors into page object classes

  • TypeScript output: Full TypeScript support with type annotations

  • Tag migration: Converts [TAG], @tag, #tag to Playwright annotations

  • Custom commands: Register project-specific WDIO commands

  • Migration reports: Generate comprehensive markdown reports

Requirements

  • Node.js 18+

  • @modelcontextprotocol/sdk

  • @babel/parser, @babel/traverse, @babel/generator (for AST)

  • express (for HTTP server)

Project Structure

mcp-server-tests-migration/
├── index.js              # CLI entry point
├── server-http.js        # HTTP server (Docker/remote)
├── src/
│   ├── index.js          # Module exports
│   ├── server.js         # MCP server class
│   ├── constants/
│   │   └── mappings.js   # WDIO→Playwright command mappings
│   ├── handlers/
│   │   ├── tools.js      # Tool definitions (schema)
│   │   └── toolHandlers.js # Tool implementations
│   ├── transformers/
│   │   ├── migration.js  # AST-based migration
│   │   ├── pom.js        # Page Object Model
│   │   └── selectors.js  # Selector transformation
│   └── utils/
│       ├── config.js     # Config file parsing
│       ├── docs.js       # Playwright documentation
│       ├── parser.js     # AST parsing utilities
│       ├── report.js     # Migration report generation
│       └── tags.js       # Tag extraction utilities
├── examples/             # Example configs and tests
├── docs/                 # Documentation
├── Dockerfile
└── docker-compose.yml

License

MIT

Author

Luca Donnaloia

Contributing

Contributions welcome! Please feel free to submit pull requests or open issues.

Roadmap

  • AST-based parsing and transformation

  • Complete command mappings (50+)

  • Modern locator suggestions

  • Project state detection

  • Config migration

  • Partial migration support

  • TypeScript output support

  • Custom WDIO commands handling

  • Migrate tests tag [TAG], @tag, #tag to Playwright tag annotations

  • Migration report generation with tags summary

  • SOLID principles refactoring

  • WDIO services migration (custom services)

  • Visual comparison of test coverage by tags

  • Batch file processing

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/lucad87/mcp-server-tests-migration'

If you have feedback or need assistance with the MCP directory API, please join our Discord server