Migrate from Selenium to TesterArmyRetire the page objects,
the waits, and the Grid
Most Selenium code works around one problem - scripted automation can't see the page. TesterArmy's agent can. Paste one prompt into Claude Code, Cursor, or Codex and it reads your suite, converts it, and verifies every test against your app.
Takes less than 2 minutes. No credit card required.
Hundreds of files exist
to work around one problem
Selenium suites are the oldest and usually the heaviest. The page objects, the waits, the driver factories, and the Grid all exist because scripted automation can't see the page.
Locator strategies break when the UI changes
By.id, By.xpath, and By.cssSelector lookups are spread across hundreds of files in Java, Python, or C#. A changed id or a restructured page ripples through every class that references it, and none of it means your product is broken.
WebDriverWait and ExpectedConditions accumulate
Every flaky run gets patched with another explicit wait, a Thread.sleep, or a longer timeout. The layer of ExpectedConditions grows with every fix, and all of it exists to approximate something an agent with vision does - waiting like a human for the page to be ready.
The page object layer is a codebase of its own
Every new flow needs a page object class with locators and methods written and then maintained, until the layer spreads across hundreds of files. The method names encode real user intent and domain knowledge, but everything else in those classes is workaround code for automation that can't see the page.
Grid and driver management is infrastructure work
Capabilities, driver binaries, driver factories, and Dockerized Grids all have to be provisioned, upgraded, and kept in sync with browser releases. That work tests nothing about your product.
What your suite reads like
after the conversion
The user intent in your test methods becomes act and assert steps, and the locators and waits are dropped. This is the same checkout flow in both languages.
@Test
public void checkoutWithSavedCard() {
driver.get(baseUrl + "/products/desk-lamp");
wait.until(ExpectedConditions.elementToBeClickable(
By.id("add-to-cart"))).click();
wait.until(ExpectedConditions.visibilityOfElementLocated(
By.cssSelector(".cart-count")));
driver.findElement(By.xpath("//a[@href='/cart']")).click();
wait.until(ExpectedConditions.urlContains("/cart"));
cartPage.startCheckout();
wait.until(ExpectedConditions.presenceOfElementLocated(
By.id("payment-form")));
driver.findElement(By.id("card-ending-4242")).click();
driver.findElement(By.id("place-order")).click();
wait.until(ExpectedConditions.visibilityOfElementLocated(
By.id("order-confirmation")));
assertEquals("$49.00",
driver.findElement(By.id("order-total")).getText());
}Locators, WebDriverWait calls, and the page objects behind them are dropped in conversion rather than translated. The agent finds elements visually and waits on its own, so there is nothing left for a changed id or a restructured page to break.
The whole migration
is one prompt
Paste this into your coding agent in the repository that contains your Selenium tests. It works for Java, Python, C#, Ruby, and JavaScript bindings, uses your page object method names as the guide to user intent, and verifies every converted test locally.
Migrate this repository's Selenium WebDriver test suite to TesterArmy using
the TesterArmy CLI (`ta`). Verify auth first with `ta status --json`, and
use `ta --help` plus subcommand help to discover commands. Prefer --json
output.
1. Discover: find all Selenium test classes/modules (JUnit/TestNG, pytest,
NUnit, RSpec, or Mocha bindings), page object classes, and the base URL
(config files, properties, env vars, or driver.get() calls).
2. Create a TesterArmy project (skip if one exists in `ta projects list`):
echo '{"name":"<repo name>","url":"<base URL>","projectType":"web"}' | ta projects create --json
3. Save durable context as project memories (category site_structure,
importance high): key routes, the login URL, and domain knowledge
encoded in page objects (e.g. "Admin settings live under /admin,
reachable only after login").
echo '{"category":"site_structure","title":"...","content":"...","importance":"high"}' | ta memories create --project <projectId> --json
4. Convert each test method into a TesterArmy test:
- Express the USER INTENT in plain English. Use page object method
names as a guide - submitValidCredentials() becomes "Log in with
valid credentials". Drop all locators (By.id, XPath, CSS),
WebDriverWait/ExpectedConditions, Thread.sleep, and retry logic - the
TesterArmy agent finds elements visually and waits on its own.
- driver.get / click() / sendKeys() / select -> steps with type "act"
- assertEquals/assertTrue/expect on page state -> steps with type "assert"
- login helpers and auth setup -> one step with type "login"
- Keep tests focused: 3-10 steps. Split long scenario methods into
separate tests.
- Skip pure API tests and unit tests of page object utilities.
Create each test:
echo '{"title":"<test name>","description":"Migrated from <class/file>","steps":[{"title":"Open /login","type":"act"},{"title":"Dashboard loads","type":"assert"}]}' | ta tests create --project <projectId> --json
Step types: act, assert, login, screenshot.
5. Never hardcode passwords in test steps. If the suite reads credentials
from properties files or env vars, tell me which credentials to add and
I will run:
echo '{"kind":"login","label":"...","username":"...","password":"..."}' | ta projects credentials-create <projectId> --json
6. Verify: run each migrated test locally with
`ta tests run <testId> --local --url <base URL> --json` and report results.
Exit code 0 = pass, 1 = fail.
7. Report a summary table: test class/method -> TesterArmy test ID -> run
result, plus a list of anything you intentionally skipped and why.Everything you built
has a place to land
Nothing in your suite gets orphaned. Every Selenium concept maps to a TesterArmy equivalent, and the heaviest layers - locators, waits, page objects, and the Grid - map to nothing at all.
Selenium and TesterArmy,
row by row
Selenium has been the standard for browser automation for twenty years, and nothing matches its ecosystem: it is free, open source, has bindings for every major language, and runs anywhere, including air-gapped networks. This table is about what owning the suite costs, and where each side genuinely wins.
- Who maintains the testsTesterArmyThe agent finds elements visually and waits on its own, so nobody owns a locator layer or a Grid.AdvantageSeleniumYour team owns page objects, locators, explicit waits, driver factories, and the Grid, often spread across hundreds of files.
- What breaks on a UI changeTesterArmyUsually nothing - a changed id or a restructured page is invisible to a vision agent.AdvantageSeleniumEvery locator that touched the changed markup, plus the page object classes that wrap it, and fixing them is manual work.
- Writing a new testTesterArmy3-10 plain-English steps that anyone on the team can write and review.SeleniumA page object class plus a test method with locators and waits, written by someone fluent in the suite's binding.
- Flaky failuresTesterArmyThe agent waits like a human, and every failure comes with a recording and a step trace.SeleniumHandled with WebDriverWait, ExpectedConditions, and Thread.sleep patches that accumulate inside the suite.
- Run verdictsTesterArmyThree verdicts - passed, failed, or blocked. Environment and setup stops land in blocked with the reason attached, so the failure count only holds real product failures.AdvantageSeleniumTwo verdicts. A dead Grid node, a stale element, and a real bug all surface as the same test failure in the runner.
- License and infrastructureTesterArmyA paid service - the agent, browsers, and infrastructure are included, with no Grid to run.SeleniumFree and open source, and it runs anywhere you can run a browser, including fully air-gapped networks.Advantage
- Ecosystem and bindingsTesterArmyOne CLI and plain-English tests - there is deliberately less to learn or extend.SeleniumTwo decades of tooling, official bindings for Java, Python, C#, Ruby, and JavaScript, and the largest ecosystem and Grid tooling in existence.Advantage
- Pull request workflowTesterArmyPR testing is built in - runs trigger from GitHub and report back on the pull request.SeleniumYou wire the suite into CI yourself and keep a Grid or driver fleet available for every run.
- Native mobile appsTesterArmyThe same plain-English tests run on iOS and Android via managed cloud simulators.AdvantageSeleniumWeb only by design - native apps are handled by Appium, its separate mobile sibling project.
- Entry priceTesterArmyFree trial without a credit card; Hobby is $99 per month with 250 test runs included.Selenium$0 forever - the cost is the engineering time and infrastructure in the rows above.
Facts checked August 2026. Spotted something out of date? Tell us and we will fix it.
From page objects to green runs in four steps
Install the CLI, hand the prompt to your coding agent, and review what comes back. The old suite and the Grid stay up until every TesterArmy run is green.
Point the agent at your repo
Install the TesterArmy CLI and authenticate, then paste the migration prompt into Claude Code, Cursor, or Codex. The agent finds your test classes, page objects, and base URL, and creates a matching web project.
The agent converts every test method
Each test becomes 3-10 plain-English steps, with page object method names as the guide - submitValidCredentials() becomes "Log in with valid credentials". Actions turn into act steps, assertions into assert steps, and auth helpers into a single login step backed by encrypted credentials.
Every migrated test runs locally
The agent verifies each test against your app with ta tests run --local and reports pass or fail through real exit codes, plus a summary of anything it intentionally skipped and why.
Wire CI and retire the Grid
Replace the Selenium CI job, and the Grid behind it, with ta tests run --group or a group webhook. Decommission driver binaries, Grid containers, and the page object layer once the TesterArmy runs are green.
What comes with you,
what stays behind
The page object pattern actually makes migration easier: method names like loginPage.submitValidCredentials() or cartPage.removeFirstItem() already describe user intent, which is exactly what TesterArmy steps are.
When Selenium is still the right call
- Your suite must run air-gapped or fully offline - Selenium runs anywhere you can run a browser, while TesterArmy tests need a real, reachable environment.
- Browser quirks themselves are what you test - if you need a genuine cross-engine matrix rather than behavior coverage, Grid is built for exactly that.
- Your remaining Selenium code is pure API tests or unit tests of page object utilities - the migration prompt skips those, and they stay where they are.
- You have engineers who genuinely enjoy owning the suite, your markup rarely churns, and the $0 license matters more than the maintenance time.
Nothing forces the choice on day one. Migrated tests run alongside the old suite, and the guide's own advice is to decommission the driver binaries, Grid containers, and page object layer only once the TesterArmy runs are green.
Frequently Asked Questions
Most of that code exists
to work around one problem
Your Selenium suite encodes years of knowledge about how your product is supposed to work. The migration keeps that knowledge and retires the machinery around it - the locators, the waits, the page objects, the Grid - because an agent that can see the page never needed any of it.