Execution model: one complete source scope is supported.
pilotis optional calibration;/supervised-taskmay execute up to five autonomous remediation cycles without partitioning the source.
A .NET 10 CLI toolkit for turning Selenium test suites into measurable, reviewable Playwright migrations.
The Migrator parses Selenium tests, builds an intermediate representation, applies project-specific profile mappings, and renders Playwright tests plus reports. It is designed for teams that want to migrate large E2E suites without pretending that every selector, helper, wait, and PageObject can be guessed safely.
The main production path is Selenium C# → Playwright .NET with NUnit as the default target framework and xUnit as a supported target framework. Other source/target combinations are available as preview features and are clearly labeled below.
- Analyzes Selenium tests and reports unmapped targets, unsupported actions, and repeated migration patterns.
- Maps PageObjects, helper methods, table/list patterns, waits, and project conventions through reviewable JSON profiles.
- Generates Playwright .NET tests, or experimental Playwright TypeScript specs when a TS target is selected.
- Verifies generated output with syntax checks, project-aware compile checks, TypeScript type checks, quality gates, migration dashboards, and a migration-quality backlog with root cause / next-action tickets.
- Helps humans or coding agents iterate safely: source truth → profile/config → generated code → verification → next pattern.
The goal is not magic conversion. The goal is to make migration uncertainty visible and fixable.
public-preview-flow/v1 is the recommended public-preview route: install, run doctor install, start with playground or product start, migrate through an optional pilot and ordinary full-project runs, stop on gates, extract mapping research from noisy ordinary runs, and share a safe feedback-bundle/v1 instead of a private repository dump.
The safe-by-default rule is simple: generated output is a draft until the standard run report, real project verification, final gate, and artifact hygiene agree. When the run is red, fix one highest-payoff root cause per cycle, rerun the complete configured source scope, and continue automatically while progress and cycle budget remain. For the compact end-to-end route, see Public preview flow.
If you are inside a real product repository and do not want to choose the workflow by hand, start here:
npm install -g selenium-pw-migrator@preview
selenium-pw-migrator doctor install
selenium-pw-migrator start --input ./SeleniumTests --agent opencode --workspace migrationstart detects the source, creates migration/profiles/adapter-config.start.json, writes migration/next-commands.md, migration/current-ticket.md, and migration/state/start-dispatch.json, then points you to install diagnostics, agent bootstrap, pilot, doctor, and the dashboard after a run exists. Use --agent codex, --agent generic, or --agent manual to choose the handoff route.
npm install -g selenium-pw-migrator@preview
selenium-pw-migrator doctor install
selenium-pw-migrator playground --out playground --target-test-framework xunit --generation-policy conservativeOpen playground/try-this-first.md and run the generated commands. This is the safest disposable route.
npm install -g selenium-pw-migrator@preview
selenium-pw-migrator doctor install
selenium-pw-migrator kit bootstrap-opencode --workspace migration --source ./SeleniumTests --opencode-install autobootstrap-opencode now also copies the project command pack into the repository root (opencode.jsonc, .opencode/agents, .opencode/commands, and AGENTS.md when missing). Then open the repository in OpenCode and run:
/supervised-task
The command uses the configured source as a hard boundary and executes the same ordinary pipeline as the CLI:
- read source scope, adapter config, and project-local memory;
- run install diagnostics and an optional representative
pilot; - run the complete source through
selenium-pw-migrator run; - run a fresh matching
verify-projectwhen a target project is available; - execute up to five one-change remediation cycles, rerunning the complete pipeline after each cycle.
Plain /supervised-task starts or resumes this flow. /supervised-task continue opens a fresh five-cycle budget from the latest evidence. /supervised-task continuous advances automatically after progress. The first no-progress cycle switches to another independent candidate; two consecutive distinct no-progress cycles stop. There is no automatic source partition advancement or synthetic validation evidence. Tooling or verification failures are global blockers only when they prevent truthful progress on every remaining candidate.
For day-to-day details, see Standard migration flow and the compact /supervised-task reference.
npm install -g selenium-pw-migrator@preview
selenium-pw-migrator doctor install
selenium-pw-migrator kit bootstrap-agent --agent codex --workspace migration --source ./SeleniumTests
# or:
selenium-pw-migrator kit bootstrap-agent --agent generic --workspace migration --source ./SeleniumTestsThis writes migration/AGENT_HANDOFF.md, migration/AGENT_CONTRACT.md, and the kickoff prompts without pretending the workflow is OpenCode-specific.
Before scaling a real migration, let the CLI choose a small representative pilot slice:
selenium-pw-migrator pilot --input ./SeleniumTests --max-tests 10 --out migration/pilotpilot writes pilot-selection.md/json, selected-tests.txt, next-commands.md, and a copied selected-input/ directory. The generated next commands analyze/migrate selected-input/, not the full suite. The selection tries to cover simple smoke tests, PageObjects, table/filter patterns, waits, assertions, custom helpers, XPath, and data-driven tests.
After any real run, open the dashboard first:
selenium-pw-migrator report serve --input migration/runs/latest --static-only --out migration/dashboard/latest --format bothOpen migration/dashboard/latest/report-dashboard.html before digging through raw JSON/TXT artifacts. When TODOs remain, explain-todo also writes suggested-config-patch.md/json with grouped root causes, “fix this profile mapping first”, confidence/evidence badges, and draft UiTarget/Method/Table entries for review.
If the migrator produces many TODOs, syntax fallbacks, unresolved symbols, or a verify-project failure, you can help improve the tool without sending your private repository. From the product repo root, run:
migration/scripts/create-feedback-bundle.ps1 -Workspace migrationor on macOS/Linux/WSL:
migration/scripts/create-feedback-bundle.sh -Workspace migrationThe script writes a feedback-bundle/v1 zip under migration/state/feedback-bundles/. It includes reports/evidence such as mapping research memory, standard run reports, project-verify-report.*, project-verify-harness.csproj, migration-board.*, and explain-todo.md. It excludes project source and generated .cs samples by default. Review manifest.json before sharing the zip.
| Source frontend | Target backend | Status | Notes |
|---|---|---|---|
| Selenium C# / NUnit or xUnit | Playwright .NET / NUnit or xUnit | Stable public path | Full analyze/migrate/verify workflow with Roslyn-based recognition; NUnit remains the default target framework. |
| Selenium C# / NUnit | Playwright TypeScript | Experimental preview | Use --target ts; project-aware verification requires --ts-project. |
| Selenium Java | Playwright .NET / TypeScript | Experimental MVP | Useful for simple Java Selenium fixtures; no Java semantic model. |
| Selenium Python | Playwright .NET / TypeScript | Experimental spike | Useful for simple pytest/unittest Selenium diagnostics; not production-ready. |
The npm package is the default public path for frontend/test-automation teams. It is a thin wrapper over the same standalone release archives, so users do not need to install the .NET SDK.
npm install -g selenium-pw-migrator@preview
selenium-pw-migrator doctor installUpdate:
npm update -g selenium-pw-migrator
# or print the detected channel-specific command:
selenium-pw-migrator self updatedoctor install (mode-compatible form: --mode install-doctor) shows the resolved executable, version, channel, runtime, PATH candidates, and recommended install/update command. This is the first command to run when global npm, standalone, dotnet tool, or local tool installs may be shadowing each other. Use it to diagnose what your shell actually runs before checking package-manager state.
The CLI itself does not require PowerShell when installed through npm or standalone. The migration-kit lifecycle scripts are different: every repository .ps1 script has a same-name .sh companion, and thin Unix wrappers delegate to PowerShell 7 (pwsh) so Windows and Unix run the same implementation. On macOS/Linux/WSL, install PowerShell 7 before using migration/scripts/*.sh wrappers or release/package shell entrypoints: https://learn.microsoft.com/powershell/scripting/install/installing-powershell. selenium-pw-migrator kit doctor reports this as the powershell-7 check.
For locked-down environments or release smoke tests, the standalone distribution is still the most direct install path. The npm wrapper remains the default frontend-friendly route above, but standalone does not require the .NET SDK or .NET Runtime on the target machine. Use it when npm is not available or when you want a direct GitHub Release install.
Windows PowerShell:
$installer = Join-Path $env:TEMP "install-standalone.ps1"
Invoke-WebRequest "https://github.com/AlexanderLevenskikh/selenium-playwright-ast-migrator/releases/latest/download/install-standalone.ps1" -OutFile $installer
& $installer
selenium-pw-migrator --versionLinux/macOS/WSL:
curl -fsSL https://github.com/AlexanderLevenskikh/selenium-playwright-ast-migrator/releases/latest/download/install-standalone.sh -o /tmp/install-standalone.sh
bash /tmp/install-standalone.sh
export PATH="$HOME/.selenium-pw-migrator/bin:$PATH"
selenium-pw-migrator --versionThe Windows installer adds the standalone directory to the front of the user PATH by default, even if it was already present later. For troubleshooting install priority, use Get-Command selenium-pw-migrator -All on Windows or which -a selenium-pw-migrator on Unix-like shells. To remove an older dotnet global tool in the same install step, pass -RemoveDotnetTool.
To uninstall the standalone Windows install, run the same installer with -Uninstall. On Linux/macOS, run install-standalone.sh --uninstall and remove the PATH line from your shell profile.
For a pinned preview, install a specific npm version or use the matching GitHub Release asset:
npm install -g selenium-pw-migrator@0.0.0-preview.8
npm install -g https://github.com/AlexanderLevenskikh/selenium-playwright-ast-migrator/releases/download/v0.0.0-preview.8/selenium-pw-migrator-0.0.0-preview.8.tgzThe npm postinstall downloads the matching standalone archive for win-x64, linux-x64, osx-x64, or osx-arm64, verifies checksums.sha256 when available, and preserves the native CLI exit code. Corporate installs can use a Nexus npm proxy plus --selenium-pw-migrator-base-url for an internal standalone archive mirror. Isolated registry smoke scripts are available for npmjs and Nexus installs. See npm wrapper. Publishing instructions live in npm publishing.
Use the dotnet tool distribution when you want a global/local .NET tool or a project-pinned .config/dotnet-tools.json. This path requires the .NET SDK.
dotnet tool install --global SeleniumPlaywrightMigrator --source https://api.nuget.org/v3/index.json --prerelease
selenium-pw-migrator --helpClone the repository only if you want to contribute or build the tool from source.
There are three different local workflows. Pick one and do not mix the commands.
Use this when you are editing the repository and just want to run the CLI without installing anything:
dotnet restore
dotnet run --project ./Migrator.Cli/Migrator.Cli.csproj -- --helpUse this when you want to test the NuGet/dotnet-tool package produced by this repo. This path requires the .NET SDK and uses a local tool manifest, so run the CLI through dotnet tool run.
Windows PowerShell:
$version = "0.0.0-preview.20"
Unblock-File .\scripts\*.ps1
.\scripts\pack-tool.ps1 -Version $version
.\scripts\install-local-tool.ps1 -Version $version
dotnet tool run selenium-pw-migrator -- --helpThe install script now checks artifacts/nuget before calling dotnet tool install. The -Version value must match an existing local .nupkg. To install the newest local package without remembering its version, omit -Version:
.\scripts\pack-tool.ps1 -Version $version
.\scripts\install-local-tool.ps1macOS/Linux/WSL:
version="0.0.0-preview.20"
scripts/pack-tool.sh "$version"
dotnet new tool-manifest --force
dotnet tool install SeleniumPlaywrightMigrator --version "$version" --add-source ./artifacts/nuget
dotnet tool run selenium-pw-migrator -- --helpIf a local manifest already exists, install-local-tool.ps1 reuses it. Use selenium-pw-migrator --help only after a global install; repository-local tools should be invoked as dotnet tool run selenium-pw-migrator -- ....
Use this when you want to test the same self-contained standalone layout that is published in GitHub Releases. This is the local equivalent of installing the release artifact.
Windows PowerShell:
$version = "0.0.0-preview.20"
Unblock-File .\scripts\*.ps1
.\scripts\package-standalone.ps1 -Version $version -Runtimes win-x64
.\scripts\install-standalone.ps1 `
-Version $version `
-Runtime win-x64 `
-ArchivePath ".\artifacts\release\selenium-pw-migrator-$version-win-x64.zip" `
-ChecksumsPath ".\artifacts\release\checksums.sha256" `
-InstallDir "$env:LOCALAPPDATA\selenium-pw-migrator-dev"
& "$env:LOCALAPPDATA\selenium-pw-migrator-dev\bin\selenium-pw-migrator.exe" --help
Get-Command selenium-pw-migrator -Allinstall-standalone.ps1 updates user PATH by default. Open a new terminal if the bare selenium-pw-migrator command is not visible immediately. Add -SkipUserPathUpdate when you only want to test the executable by full path.
See Tool installation, Standalone installation, npm wrapper, and Packaging and distribution.
For the stable production path, keep it boring and small:
npm install -g selenium-pw-migrator@preview
selenium-pw-migrator doctor install
selenium-pw-migrator playground --out playground --target-test-framework xunit --generation-policy conservative
bash playground/commands.sh
selenium-pw-migrator playground verify --input playground --out playground-verify --format bothFor a real project, start with onboarding and a representative pilot slice:
selenium-pw-migrator start --input ./SeleniumTests --agent opencode --workspace migration
selenium-pw-migrator pilot --input ./SeleniumTests --max-tests 10 --out migration/pilotThen bootstrap the guarded workspace once and let the agent own the run lifecycle:
selenium-pw-migrator kit bootstrap-opencode --workspace migration --source ./SeleniumTests --opencode-install autoFor Codex or another agent, use the explicit non-OpenCode handoff:
selenium-pw-migrator kit bootstrap-agent --agent codex --workspace migration --source ./SeleniumTests
selenium-pw-migrator kit bootstrap-agent --agent generic --workspace migration --source ./SeleniumTestsThen run /supervised-task in OpenCode, or hand migration/AGENT_HANDOFF.md, migration/AGENT_CONTRACT.md, and migration/prompts/kickoff-prompt.txt to another agent. Do not create migration/runs/<run-id> manually; the standard CLI/agent flow does that.
Java, Python, and Playwright TypeScript paths are experimental. Keep release demos and production migration promises focused on Selenium C# -> Playwright .NET.
Start with a small pilot directory, not the whole suite:
dotnet tool run selenium-pw-migrator -- --mode doctor \
--input ./SeleniumTests \
--config ./adapter-config.json \
--out doctor
dotnet tool run selenium-pw-migrator -- run \
--input ./SeleniumTests \
--config ./adapter-config.json \
--out run-001 \
--format bothBy default, relative --out values are written under the migration/ workspace, for example migration/run-001.
Typical outputs:
migration/run-001/
analyze/
generated/
verify/
propose/
orchestration-report.md
orchestration-report.json
Try the five-minute playground:
dotnet tool run selenium-pw-migrator -- playground --out playground --target-test-framework xunit --generation-policy conservative
dotnet tool run selenium-pw-migrator -- playground verify --input playground --out playground-verify
cat playground/try-this-first.mdFor a file-by-file walkthrough, see:
- Quick start
- Init wizard
- Migration runbook
- Guarded OpenCode Desktop migration runbook
- End-to-end simple example
- Public demo and guided tutorial
- Public Demo / Playground
- Teaching demo: AST migration explained
- AST migration explained / RU
- Public demo files
- Migration workflow
- Extensibility and public API
For an agent-assisted migration, do not hand-create migration/ folders or migration/runs/<run-id>/. Start from the product onboarding state, run the representative pilot, then choose the matching agent handoff.
selenium-pw-migrator start --input ./SeleniumTests --agent opencode --workspace migration
selenium-pw-migrator pilot --input ./SeleniumTests --max-tests 10 --out migration/pilotOpenCode path:
selenium-pw-migrator kit bootstrap-opencode --workspace migration --source ./SeleniumTests --config migration/profiles/adapter-config.start.json --opencode-install autoCodex/generic/CI path:
selenium-pw-migrator kit bootstrap-agent --agent codex --workspace migration --source ./SeleniumTests --config migration/profiles/adapter-config.start.json
selenium-pw-migrator kit bootstrap-agent --agent generic --workspace migration --source ./SeleniumTests --config migration/profiles/adapter-config.start.jsonOpenCode install modes:
--project-desktop / --opencode-install project-desktop Windows OpenCode Desktop
--opencode-install project-local macOS/Linux/WSL OpenCode CLI
--opencode-install ci Legacy compatibility; prefer bootstrap-agent for non-OpenCode agents
Then start the selected agent environment and run /supervised-task, or give a non-OpenCode agent migration/AGENT_HANDOFF.md and migration/AGENT_CONTRACT.md. The orchestrator must read migration/current-ticket.md, migration/state/start-dispatch.json, and migration/pilot/next-commands.md; it should not ask the user for a broad menu when the state is clear.
The only manual bootstrap that remains is installing/updating the tool and project-local OpenCode config. Once those are present, the agent should manage the workspace lifecycle and run artifacts itself.
Developer smoke for the bootstrap template-root resolver:
pwsh .\scripts\run-kitroot-shadow-smoke.ps1 -CleanThis creates a fake product repository that contains its own templates/migration-kit folder and verifies that bootstrap-opencode still uses the bundled Migrator templates.
| Mode | Status | Purpose |
|---|---|---|
runbook |
Stable | Generate a practical migration plan with pilot scope, command chain, risk map, artifacts, and acceptance checklist. |
playground |
Stable | Create a five-minute public demo workspace with ready commands, expected outputs, dashboard sample, and PR pack sample. |
playground-verify |
Stable | Verify that the generated playground still has the manifest, command chain, demo input, expected output, and safety wording. |
memory |
Stable | Manage project-scoped migration memory (init/add/explain/doctor/summarize/recall) under migration/state/memory/** for supervised runs. |
run |
Stable | Execute the complete configured source through the standard analyze → generate → verify → proposal pipeline in one ordinary run directory. |
config merge-deltas / config validate-merge |
Stable | Merge run-local config-delta.json files into a reviewable candidate config and validate conflicts before promotion. |
doctor |
Stable | Preflight checks plus safe --fix repair plans for inputs, config layers, project files, and workspace hygiene. |
release-doctor |
Stable | Check NuGet preview readiness: package metadata, docs, scripts, workflow dry-run, secret references, and release hygiene. |
analyze |
Stable | Parse Selenium files and produce reports without generating target files. |
migrate |
Stable | Generate Playwright target files. |
verify |
Stable | Run lightweight generated-code verification. |
verify-project |
Stable | Compile generated Playwright .NET tests against a real project-aware harness. |
config-validate |
Stable | Validate profile structure and safety rules. |
config-diff |
Stable | Compare profile changes and highlight risky edits. |
guard |
Stable | Compare before/after migration metrics and catch regressions. |
index-pom |
Stable | Mine Selenium PageObjects plus target-side Playwright/Kontur POM selector evidence. |
selector-evidence |
Experimental | Explain Selenium selector → config mapping → generated locator provenance with confidence and unsafe/inferred flags. |
agent-contract |
Experimental | Generate a ticket-specific agent contract pack with allowed paths, stop policy, exact commands, and coordinator/migrator/verifier prompts. |
pr-pack |
Experimental | Create a PR/review bundle with PR summary, changed/generated files list, before/after metrics, risk summary, reviewer checklist, evidence references, and suggested PR description. |
learn-pack |
Experimental | Extract reusable migration knowledge from completed runs into a reviewable profile layer and learning changelog. |
config-author |
Experimental | Generate evidence-driven config proposals and a reviewable patch without applying it. |
helper-inventory |
Stable | Inspect helper/POM method bodies and infer MethodSemantics candidates. |
discover-target |
Stable | Scan an existing Playwright .NET project and create a reviewable target inventory. |
scaffold |
Stable | Generate a minimal compile-ready Playwright .NET project scaffold. |
bootstrap-project |
Stable | Create reusable migration profile skeletons for a new source project. |
capabilities |
Stable | List built-in source frontend / target backend capability reports. |
verify-ts-project |
Experimental | Type-check generated Playwright TS specs inside an existing TS project. |
orchestrate |
Experimental | Run analyze → migrate → verify → propose as one dry-run workflow. |
explain-todo / smoke-plan / runtime-classify / selector-evidence / migration-board / report-serve |
Experimental | Prioritize follow-up work from migration artifacts/runtime logs, classify runtime root causes, score readiness, explain selector provenance, and export triage decisions. |
evidence pack |
Stable | Create a redacted shareable zip with reports, generated artifacts, manifest, and checksums. |
profile list/search/inspect/install/diff |
Experimental | Use offline built-in profiles as reviewed config layers. |
Run command-specific help with:
selenium-pw-migrator --mode migrate --help- Never invent selectors.
- Prefer source truth: Selenium PageObject code, verified HTML attributes, existing target POM/tests, or project-owned helper semantics.
- Treat generated TODO comments as reviewable evidence, not as failure to hide.
- Do not manually patch generated files as the final fix; improve the profile, source-truth mapping, or migrator behavior.
- Use
index-pomandhelper-inventorybefore suppressing or manually rewriting repeated PageObject/helper patterns.
If Selenium POMs contain proven selectors such as ByTId("value"), CreateControlByTid(...), explicit data-tid, CSS, XPath, or resolved constants, prefer this order: existing target POM member → generated POM scaffold → raw Playwright locator from proven selector → explicit TODO.
- Complete user guide
- Полное руководство пользователя
- Documentation index
- Quick start
- Init wizard
- Migration runbook
- Guarded OpenCode Desktop migration runbook
- Teaching demo: AST migration explained
- AST migration explained / RU
- Framework matrix — static support table plus
framework matrixgenerated readiness reports - Doctor fix mode
- Report serve dashboard
- Profile marketplace
- Migration PR pack
- Migration learning pack
- Config Authoring Assistant
- Generation Policy
- Evidence pack workflow
- User guide
- Config and profile guide
- Guarded OpenCode Desktop migration runbook — canonical guarded agent launch procedure
- Limitations
- Troubleshooting
- Migration quality program
- Public roadmap
- Release process
dotnet restore
dotnet test --no-restoreThe test suite covers parser behavior, adapter mappings, snapshots, compile-smoke checks, orchestration, TypeScript target basics, safety guards, packaging guardrails, and regression cases for common migration blockers.
This project is currently prepared as a public preview. Stable commands are intended for external users; experimental commands may change between preview releases. See CHANGELOG.md, SECURITY.md, and CONTRIBUTING.md.
The supported execution model has one configured source scope and one ordinary run directory. For OpenCode:
selenium-pw-migrator kit bootstrap-opencode --workspace migration --source ./SeleniumTests --opencode-install autoThen run:
/supervised-task
For manual or CI use, the same flow is explicit:
selenium-pw-migrator pilot --input ./SeleniumTests --max-tests 10 --out migration/pilot
selenium-pw-migrator run --input ./SeleniumTests --config migration/profiles/adapter-config.json --out migration/runs/run-001 --format both
selenium-pw-migrator verify-project --input ./SeleniumTests --config migration/profiles/adapter-config.json --out migration/runs/run-001/verify-project --format both
selenium-pw-migrator report serve --input migration/runs/run-001 --static-only --out migration/dashboard/run-001 --format bothpilot is optional calibration only. run processes the complete configured source in a linear analyze → generate → verify → proposal pass. verify-project must use real target-project/toolchain evidence; missing prerequisites remain visible blockers.
Project-local memory can help choose a repeated root cause, but it is never validation evidence:
selenium-pw-migrator memory explain --workspace migration
selenium-pw-migrator memory doctor --workspace migrationReviewed config deltas may be merged into a candidate without changing the active config automatically:
selenium-pw-migrator config merge-deltas --base migration/adapter-config.json --deltas migration/state/memory/config-deltas --out migration/config-merge
selenium-pw-migrator config validate-merge --base migration/adapter-config.json --candidate migration/config-merge/adapter-config.merged.json --out migration/config-mergeThe standard final gate checks concrete run artifacts (orchestration-report.json, generated/report.json, and a real project-verification report when required). It never accepts hand-written replacement evidence.
In
continuousmode, the five-cycle limit is a checkpoint rather than a stop: the agent automatically starts the next five-cycle batch without requiring anothercontinuecommand and works until a real terminal condition.