Skip to main content

AI-powered Selenium to Playwright migration tool

Project description

QAMigrate

AI-powered test framework migration

PyPI version Python 3.11+ License: MIT

A QATonic Innovations product.


QAMigrate converts test suites between frameworks automatically. It parses your code with Tree-sitter, generates equivalent code with Claude, and produces a full migration report with per-file diffs, confidence scores, and estimated time savings.

Today: Selenium Java -> Playwright Java Next: Cypress -> Playwright, TestNG -> JUnit 5, RestAssured -> Karate, and more.

Why QAMigrate

You don't just get generated code. You get evidence:

  • Per-file diffs -- every pattern we touched, why, and side-by-side before/after
  • Confidence score -- how sure we are about each file, 0 to 100
  • Batch report -- HTML, JSON, and Markdown; share with your team
  • Time-saved estimate -- how many hours of manual work you avoided
  • Dry-run mode -- preview what would change without calling the LLM

What it does

Give it a Selenium file:

// Selenium
@FindBy(id = "username")
private WebElement usernameInput;

public void login(String user, String pass) {
    usernameInput.clear();
    usernameInput.sendKeys(user);
    passwordInput.sendKeys(pass);
    wait.until(ExpectedConditions.elementToBeClickable(loginButton));
    loginButton.click();
}

Get Playwright back:

// Playwright (generated by QAMigrate)
private final Locator usernameInput;

public LoginPage(Page page) {
    this.usernameInput = page.locator("#username");
}

public void login(String user, String pass) {
    usernameInput.fill(user);
    passwordInput.fill(pass);
    loginButton.click(); // Playwright auto-waits
}

Supported patterns (Selenium -> Playwright Java)

  • @FindBy annotations (id, css, xpath, className, name, linkText)
  • PageFactory.initElements removal
  • WebDriverWait / ExpectedConditions removal (Playwright auto-waits)
  • sendKeys -> fill, clear removal, click direct conversion
  • Actions (hover, drag) -> Playwright equivalents
  • Select dropdowns -> selectOption
  • JavascriptExecutor -> page.evaluate()
  • Alert / iframe handling
  • File uploads -> setInputFiles
  • TestNG -> JUnit 5 lifecycle (@BeforeMethod -> @BeforeEach, etc.)
  • @DataProvider -> @MethodSource
  • Assert.assertEquals / assertTrue -> Playwright assertions
  • ChromeDriver setup -> Playwright.create() + browser.newContext()
  • Base class inheritance preservation

Quick start

Prerequisites

  • Python 3.11+
  • Java 17+ (for compilation validation; optional — see compiler.skip)
  • Anthropic API key

Install

pip install qamigrate

Configure

echo "ANTHROPIC_API_KEY=sk-ant-your-key" > .env

Migrate

# Dry-run: see what would happen without calling the LLM
qamigrate migrate --all --project ./my-selenium-project --dry-run

# Migrate a single file
qamigrate migrate src/test/java/LoginPage.java --project ./my-selenium-project

# Migrate everything with a full migration report
qamigrate migrate --all --project ./my-selenium-project --report ./qamigrate-report

Output goes to playwright/ subdirectories next to each original file. If you use --report <dir>, you get report.html, report.json, and report.md.

Example report summary

QAMigrate - Migrating 7 file(s)

-> [1/7] BaseTest.java
   OK src/.../playwright/BaseTest.java (14.1s, 75% confidence)
-> [2/7] LoginPage.java
   OK src/.../playwright/LoginPage.java (17.2s, 75% confidence)
...

Files             7 / 7
Patterns handled  149
Avg confidence    75%
Time              105.3s
Est. hours saved  ~37.2

Report written:
  HTML:     ./qamigrate-report/report.html
  JSON:     ./qamigrate-report/report.json
  Markdown: ./qamigrate-report/report.md

CLI commands

Command Description
qamigrate init Initialize QAMigrate in a project
qamigrate scan Analyze codebase, detect patterns, show complexity
qamigrate migrate Convert files to the target framework

Common flags for migrate:

  • <file> — migrate a single file
  • --all, -a — migrate all Java files under src/test or src/
  • --dry-run — analyze only, no LLM calls, no writes
  • --report <dir> — write HTML + JSON + Markdown report
  • --project, -p <path> — project root (default: current dir)

How it works

Scanner (Tree-sitter)     Deterministic AST parsing, pattern detection
       |
Coder (Claude API)        Generates Playwright Java via structured output
       |
Compiler (javac)          Validates generated code compiles
       |
Fixer (rules + Claude)    Fixes compilation errors, retries up to 3x
       |
Report                    Records everything that happened

Plain Python — no LangChain, no graph framework, no agents-of-agents. Each step is a clean module you can read in 5 minutes.

Configuration

Optional qamigrate.yaml in your project root:

pipeline:
  max_retries: 3

coder:
  model: "claude-sonnet-4-20250514"
  max_tokens: 8192

compiler:
  build_tool: "maven"    # or "gradle"
  java_version: "17"
  skip: false            # set true when Playwright JARs aren't on classpath

scanner:
  exclude_patterns:
    - "**/target/**"
    - "**/build/**"
    - "**/playwright/**"

You can also use environment variables with the QAMIGRATE_ prefix:

export QAMIGRATE_COMPILER__SKIP=true       # skip compilation check
export QAMIGRATE_PIPELINE__MAX_RETRIES=5   # more retries

Python API

from qamigrate.agents.pipeline import run_migration
from qamigrate.core.config import QAMigrateConfig
from qamigrate.core.report import MigrationReport

config = QAMigrateConfig()
report = MigrationReport()

result = run_migration(
    file_path=Path("src/test/java/LoginPage.java"),
    project_path=Path("."),
    config=config,
)

if result.record:
    report.add(result.record)

report.finish()
report.write_html(Path("./report.html"))

Development

pip install -e ".[dev]"
pytest tests -v
ruff check src tests

License

MIT — see LICENSE.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

qamigrate-0.2.2.tar.gz (92.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

qamigrate-0.2.2-py3-none-any.whl (54.4 kB view details)

Uploaded Python 3

File details

Details for the file qamigrate-0.2.2.tar.gz.

File metadata

  • Download URL: qamigrate-0.2.2.tar.gz
  • Upload date:
  • Size: 92.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.11

File hashes

Hashes for qamigrate-0.2.2.tar.gz
Algorithm Hash digest
SHA256 33634798b96df598ff422c0994885f4a37cbf602a59170386b8644573f0aea80
MD5 cd089c3bf9aabcc59cb99c6de3a6fec0
BLAKE2b-256 369dfc427760cbcaf579239bc77b90d577a4524f378bdcf084339389cc808e23

See more details on using hashes here.

File details

Details for the file qamigrate-0.2.2-py3-none-any.whl.

File metadata

  • Download URL: qamigrate-0.2.2-py3-none-any.whl
  • Upload date:
  • Size: 54.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.11

File hashes

Hashes for qamigrate-0.2.2-py3-none-any.whl
Algorithm Hash digest
SHA256 0f4d7a394d325cc520a14b4899310dadf0e42cc14cad4826b49b2c617eebd0f9
MD5 c7f1de35af9aaa63e8187b82cd213c82
BLAKE2b-256 1e96aeae540cbe362ebee62ec943d2e44bbcd231562f8b9b302babdb6db436fa

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page