qamigrate
v0.1.1
Published
CLI-first migration assurance tool for Selenium to Playwright migrations.
Maintainers
Readme
qamigrate
qamigrate is a CLI-first migration assurance tool for safely moving Java Selenium projects to Playwright Java.
The MVP is intentionally narrow:
- Java
- Maven
- TestNG or JUnit 5
- Local-first analysis, planning, migration, verification, reporting, and rollback
Current Status
The MVP command chain is implemented for the current Java/Maven fixtures:
v0.1.1 hardens the published CLI based on initial user feedback:
- partial rollbacks remain retryable with
rollback --force - rollback removes empty generated package directories
--quietis honored by every implemented command- every registered subcommand supports
--help analyzerejects directories withoutpom.xmlbefore creating.qamigrate
node packages/cli/bin/qamigrate.mjs init --project <project-dir>
node packages/cli/bin/qamigrate.mjs analyze --project <project-dir>
node packages/cli/bin/qamigrate.mjs baseline --project <project-dir>
node packages/cli/bin/qamigrate.mjs plan --project <project-dir>
node packages/cli/bin/qamigrate.mjs migrate --project <project-dir> --mode hybrid
node packages/cli/bin/qamigrate.mjs verify --project <project-dir>
node packages/cli/bin/qamigrate.mjs report --project <project-dir>
node packages/cli/bin/qamigrate.mjs rollback --project <project-dir>Run a one-off post-migration smoke test without editing qamigrate.yml:
node packages/cli/bin/qamigrate.mjs verify --project <project-dir> --sample-tests --sample-command "mvn test -Dtest=SmokeTest" --sample-shell true --sample-timeout-ms 300000For migrated Playwright Java projects, verify also performs a browser-runtime preflight. It uses Playwright Java's install dry-run to check the exact browser revision, reports the Maven install command if the runtime is missing, and blocks configured browser smoke execution until the runtime is ready:
node packages/cli/bin/qamigrate.mjs verify --project <project-dir> --playwright-browser chromiumUse --sample-browser true for browser-driving smoke commands so qamigrate blocks them when the exact Playwright runtime is not ready. Non-browser smoke commands can use --sample-browser false.
If Playwright Java cannot access its runtime cache, the report includes a diagnostic code and recommendation, for example playwright-runtime-permission with guidance to run outside a restricted sandbox or set PLAYWRIGHT_BROWSERS_PATH to a writable project-local directory.
To let QAMigrate use a project-local browser cache and install the configured browser when it is missing:
node packages/cli/bin/qamigrate.mjs verify --project <project-dir> --browser-cache project --install-browsers --sample-browser true --sample-testsCurrent migration support includes:
- Playwright Java dependency insertion for Maven projects
- AST-driven JVM conversion for the supported BaseTest, Page Object, PageFactory, XPath-review, and inline-wait families
- DriverManager-backed browser lifecycle conversion for layered framework projects
- Evidence-gated delegated-factory lifecycle adaptation for the safe subset with no remaining non-lifecycle
getDriver()consumers, only fully-covered native consumers, or fully-covered bridge-supported consumers when running inhybrid/compat - Evidence-gated delegated direct-owner conversion when those owners only use already-supported low-risk or review-marked operations
- Factory-chain profiling and source annotations for local launch branches, retained remote branches, option factories, and delegation edges
- BasePage helper conversion plus stored
Bylocator field conversion - Safe Page Object conversion for selected inline locators/actions, including
By.id,By.cssSelector,By.name,By.className,By.tagName,getText,getAttribute, andisEnabled - Basic
@FindByPageFactory conversion to PlaywrightLocatormethods - Safe inline explicit-wait conversion for supported Page Object patterns in both the default and JVM paths
- Low-risk DriverManager consumer conversion for navigation, current-page close, lifecycle null checks, logging-only driver stringification, page metadata, byte/base64 screenshots, provable file-copy screenshot flows, supported screenshot-helper boundaries, inline supported locator/action chains, and simple stored/local locator references
- Native DriverManager dialog listener support for basic alert-present waits plus alert accept, dismiss, text, and prompt input helpers
- Generated DriverManager frame context support for basic frame waits and default-content resets in hybrid migrations
- Static XPath locator chains are separated and can be rewritten with explicit review markers instead of being hidden inside generic opaque lookup counts
- Stored or local XPath locator variables are also separated and review-marked when they can be resolved statically
- Chained and two-line explicit waits with supported inline or stored/local simple locators now convert automatically; inline and stored/local XPath waits convert with review markers
- Inline window-size calls can convert to Playwright viewport sizing with explicit review markers
- Maximize, minimize, and native window-position helpers are split into explicit browser-window families with review-marked Playwright-safe replacements or no-ops
- Playwright-backed helper conversion for wait utilities, action utilities, and screenshot utilities
- Test constructor call-site updates for converted Page Objects
- Manual-review marker insertion for risky patterns outside the safe rewrite path
- Temporary compatibility adapter generation for
compatandhybridplans - Compatibility adapter support for the supported Selenium
Bysubset during incremental hybrid migrations - Compatibility adapter support for thin
WebElementandList<WebElement>bridge helpers that preserve temporary Selenium return contracts during hybrid migrations - Hybrid compatibility rewrites for parameterized visible, present, hidden, and statement-only clickable wait helpers over Selenium
By - Hybrid compatibility rewrites for provable hover helpers that route Selenium
Byparameters through a simple local element bridge - Hybrid compatibility rewrites for provable simple drag-and-drop helpers that route Selenium
Byparameters through a simple local element bridge - Hybrid/native rewrites for selected
Actionshelper shapes: hover-click, hover-release, move-by-offset, keyboard press, Ctrl+A/Delete clear, and context click - Hybrid compatibility rewrites for provable HTML5 validation helpers such as
required,validity.valid, andvalidationMessage - Hybrid compatibility rewrites for helpers that temporarily return Selenium
JavascriptExecutor - Hybrid compatibility rewrites for one-shot
By-based and temporaryWebElementscroll helpers when qamigrate can prove the local element bridge and no later executor reuse in the method - Hybrid compatibility rewrites for known scroll-then-DOM-click helpers when qamigrate can prove the same local
Bybridge on both executor calls - Native rewrites for dedicated local-storage helper bridges when every executor use is one of the supported
getItem,setItem,removeItem,clear, orlengthoperations - Native rewrites for known page, jQuery, and Angular readiness wait helpers
- Remote lifecycle detection and review guidance for Selenium Grid, Selenoid/Moon-style grids, and common cloud-provider hints; provider-specific cloud conversion is deferred from the local-first MVP
- Fail-closed validation for opt-in Playwright remote endpoints so Selenium
/wd/hubURLs are rejected instead of treated as Playwright WebSocket endpoints - Pre-migration baseline validation with post-migration comparison in reports
- Configurable sample test execution during
verify, including project-defined smoke commands inqamigrate.yml - Playwright browser-runtime preflight during
baselineandverify, with clear install guidance before browser smoke execution - CLI quiet/verbose output modes
- Reports now show both analysis confidence and effective confidence after migration/verification evidence is available
- Patch generation, backups, rollback manifest, verification, and reports
- JVM transformer path for supported BaseTest, Page Object, PageFactory, and inline-wait subsets, enabled with
QAMIGRATE_JAVA_ENGINE=1after buildingjava-engine - Real TestNG and JUnit 5 fixture coverage
- Package validation via
npm run package:check,npm pack --dry-run, and isolated install smoke from the packed tarball
Current MVP readiness:
- Feature-complete for the documented local-first MVP scope
- About 9/10 for local production-grade assisted migration
- Not a universal one-click converter for every Selenium project
- Cloud-provider-specific conversion is deferred/post-MVP
See docs/qamigrate-support-matrix.md for the current support matrix and known limitations. See docs/qamigrate-production-hardening-plan.md for the next phase focused on large custom Java frameworks.
What is working now:
- The core supported flow works end to end on both the TestNG and JUnit 5 sample projects:
init -> analyze -> baseline -> plan -> migrate -> verify -> report -> rollback - The same flow now works on the layered
samples/selenium-java-projectframework with native conversions across driver management, BasePage helpers, stored locators, waits, actions, and screenshots - Real Maven
test-compileverification passes on the migrated sample - Rollback restores migrated samples back to the original file hashes
- The JVM path now owns review-marker insertion as well as supported structural transforms
Current production-hardening status:
- qamigrate can analyze, baseline, plan, migrate, verify, report, and rollback
samples/AutomationFrameworkSelenium - fresh-copy E2E validation now passes on
samples/AutomationFrameworkSelenium, including baseline, migration, build, test discovery, report generation, and a browser-driving Playwright sample smoke - a fresh public ZeroBank Selenium/Cucumber/TestNG clone migrates with build/test-discovery verification passing and required manual review reduced from 10 to 0
- a fresh public
Thangarajtk/selenium-automation-frameworkclone now preserves compilation and three-test discovery as an explicit limited migration; nested factories plus Selenium Grid/Selenoid managers remain review work - a fresh public
in28minutes/automation-testing-with-java-and-seleniumlocal PageFactory module now migrates with baseline compile, post-migration compile, five-test discovery, and no manual review items - packed npm output is now allowlisted and validated: the tarball excludes
.tmp, build outputs, generated reports,node_modules, and sample run artifacts, and an isolated consumer install can run the fullinit -> analyze -> baseline -> plan -> migrate -> verify -> reportsmoke flow - reports now separate validation status from rollout risk:
passedmeans configured verification succeeded, whilerisk,confidence, and review markers describe remaining rollout exposure - compile-preserving guardrails now block unsafe lifecycle rewrites instead of injecting unresolved imports into custom enterprise frameworks
- planner/report output now marks lifecycle readiness explicitly, including when a delegated-factory project is an adapter candidate instead of safe for native conversion
- delegated-factory projects can now auto-apply when external Selenium consumers are absent, fully covered by native families, or fully covered by supported compatibility-bridge families in
hybrid/compat, and delegated direct owners are themselves fully low-risk or review-marked - planner/report output now profiles delegated factory chains, and migration annotates retained factory source branches, including local launch branches, retained remote branches, option factories, and delegation edges such as
TargetFactory -> BrowserFactory - planner/report output now includes provider-specific remote migration guidance so Selenium Grid, Selenoid/Moon-style grids, cloud providers, and unknown endpoints get separate required-action text
examples/java-maven-remote-provider-factorynow validates local delegated lifecycle migration while retaining Selenium Grid and BrowserStack-style branches with provider-specific guidance and fail-closed/wd/hubendpoint validation- planner/report output now decomposes driver-accessor consumers into file-level and method-level families, and distinguishes eligible low-risk work from deferred work
- planner/report output now separates direct-driver ownership variants, byte/base64/file-copy screenshot consumers, inline safe element chains, compatibility-backed Selenium element-return and simple assignment contracts, parameterized, simple attribute, exact link-text, readiness, alert, frame, and window-count wait families, browser-window review families, explicit new-window creation, indexed/last/title/URL window switching, narrow print/PDF wrappers, DevTools, specific advanced frame/window flows, native basic alert interactions, dedicated local-storage bridges, hover/drag/keyboard/context-click action helpers, direct page-scroll scripts, compatibility-backed
JavascriptExecutorreturn helpers, and JavaScript executor subfamilies from higher-risk flows - planner output now exposes when a framework still depends on a Selenium
Bylocator contract and therefore needs a compatibility bridge before native conversion - inherited Selenium
Byhelper contracts now block unsafe stored-locator rewrites even when the helper delegates through a projectDriverManager - planner/report output now profiles direct-driver usage families and method-level hotspots, and simple direct owners with private or protected driver fields use the same safe lifecycle rewrite path
- the project is ready for MVP assisted migration, but it is not a universal one-click converter for every Selenium project
- cloud-provider Selenium branches are detected, retained, and reported for manual provider-specific migration rather than automatically converted
- the next validation phase is broader real-repository coverage across unrelated architectures and more full browser smoke executions
init creates the local workspace:
.qamigrate/
|-- analysis/
|-- plans/
|-- patches/
|-- reports/
|-- backups/
|-- logs/
`-- state.jsonIt also creates a root qamigrate.yml if one does not already exist.
Development
Run tests:
npm testBuild the JVM engine:
mvn -f java-engine/pom.xml packageRun the CLI:
npm start -- --help
npm start -- init --project ./examples/java-maven-testng-basic
npm start -- analyze --project ./examples/java-maven-testng-basic
npm start -- baseline --project ./examples/java-maven-testng-basic
npm start -- plan --project ./examples/java-maven-testng-basic
npm start -- migrate --project ./examples/java-maven-testng-basic --mode hybrid --dry-run