Migrate from Cypress to TesterArmyYour Cypress suite,
minus the flake-fighting
TesterArmy tests are natural-language steps executed by an AI agent with vision - no selectors to maintain, no waits to tune. Paste one prompt into Claude Code, Cursor, or Codex and the coding agent converts your specs and verifies every test against your app.
Takes less than 2 minutes. No credit card required.
Every UI change ripples
through cypress/e2e
Cypress suites grow into a web of cy.get() selectors, custom commands, fixtures, and intercepts. Every strand of that web is something a routine UI change can snap, which is why the suite turns red far more often than the app underneath it actually breaks.
cy.get() selectors break when the UI changes
Every cy.get() call pins a test to today's markup, so a renamed data-cy attribute or a restructured component turns specs red without a single bug shipping. The suite ends up guarding your DOM structure rather than the flows your users actually run.
Flake-fighting becomes its own workstream
Each flaky run gets patched with another cy.wait, a retry, or a { force: true } click. The workarounds pile up faster than anyone cleans them out, until no one can say which of them the suite still depends on.
Custom commands and fixtures bury the intent
What a test actually does hides behind cy.login(), commands.ts helpers, and fixture files. Reading one spec means chasing indirection across cypress/support and cypress/fixtures before the flow makes sense.
cy.intercept() keeps tests away from the real thing
Stubbed network calls make runs deterministic, but they also mean the suite exercises mocked responses instead of your real environment. The runs go green against fixtures while staging tells a different story.
What your suite reads like
after the conversion
The user intent behind each cy.* chain becomes an act or assert step, and your selector strategy - data-cy attributes included - is dropped. This is the same checkout flow in both languages.
it("checkout with saved card", () => {
cy.visit("/products/desk-lamp");
cy.get("[data-cy=add-to-cart]").click();
cy.wait(500);
cy.get("[data-cy=cart-link]").click({ force: true });
cy.url().should("include", "/cart");
cy.contains("button", "Checkout").click();
cy.get("#payment-form", { timeout: 15000 }).should("be.visible");
cy.get("[data-cy=saved-card-4242]").check();
cy.get("[data-cy=place-order]").click();
cy.get("[data-cy=order-confirmation]", { timeout: 30000 }).should(
"be.visible"
);
cy.get("[data-cy=order-total]").should("have.text", "$49.00");
});cy.get() selectors, cy.wait calls, and { force: true } workarounds are dropped in conversion. The agent finds elements visually and waits on its own, so the migrated test keeps passing through markup changes that would have broken every cy.get() call above.
The whole migration
is one prompt
Paste this into your coding agent in the repository that contains your Cypress tests. It reads your config, specs, custom commands, and fixtures, creates a TesterArmy project, converts each it(), and verifies every test locally with real exit codes.
Migrate this repository's Cypress 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: read cypress.config.* for the baseUrl, then find all specs
under cypress/e2e (*.cy.ts, *.cy.js). Also read
cypress/support/commands.* and cypress/support/e2e.* to understand
custom commands like cy.login(), and cypress/fixtures for test data.
2. Create a TesterArmy project (skip if one exists in `ta projects list`):
echo '{"name":"<repo name>","url":"<baseUrl>","projectType":"web"}' | ta projects create --json
3. Save durable context as project memories (category site_structure,
importance high): key routes, the login URL, and what shared custom
commands do in plain English.
echo '{"category":"site_structure","title":"...","content":"...","importance":"high"}' | ta memories create --project <projectId> --json
4. Convert each Cypress it() into a TesterArmy test:
- Express the USER INTENT of each command chain in plain English. Drop
all selectors (cy.get, data-cy attributes), cy.wait calls, and
{ force: true } workarounds - the TesterArmy agent finds elements
visually and waits on its own.
- cy.visit / cy.get().click() / cy.get().type() -> steps with type "act"
- cy.contains / should() assertions -> steps with type "assert"
- cy.login() custom commands or cy.session() setup -> one step with
type "login"
- Inline the meaning of fixture data ("Fill the form with a valid US
address") instead of referencing fixture files.
- Keep tests focused: 3-10 steps. Split it() blocks covering multiple
flows into separate tests.
- Skip component tests (cy.mount) and tests that only exercise
cy.intercept() stubs.
Create each test:
echo '{"title":"<test name>","description":"Migrated from <spec file>","steps":[{"title":"Visit /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 specs use Cypress.env() or
cypress.env.json for auth, 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 <baseUrl> --json` and report results.
Exit code 0 = pass, 1 = fail.
7. Report a summary table: spec file -> 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 Cypress concept maps to a TesterArmy equivalent, down to custom commands and fixtures - and your selector strategy, data-cy attributes included, is dropped.
Cypress and TesterArmy,
row by row
Cypress earned its huge community: the developer experience is excellent, and cy.intercept() network stubbing and component testing are still its home turf. 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 selector layer.AdvantageCypressYour team owns the cy.get() chains, custom commands, fixtures, and intercepts - maintenance scales with UI change.
- What breaks on a UI changeTesterArmyUsually nothing - a renamed data-cy attribute or a restructured component is invisible to a vision agent.AdvantageCypressEvery spec whose cy.get() call touched the changed markup, and fixing them is manual work.
- Writing a new testTesterArmy3-10 plain-English steps that anyone on the team can write and review.CypressA .cy.ts spec with cy.get() chains, custom commands, and fixtures, written by someone who knows the codebase.
- Flaky failuresTesterArmyThe agent waits on its own, and every failure comes with a recording and a step trace.CypressCypress Cloud offers flake detection; inside the suite, cy.wait calls, retries, and { force: true } workarounds still accumulate.
- 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.AdvantageCypressTwo verdicts. Cypress Cloud can flag flake, but a down environment and a product bug still produce the same red failure.
- License and infrastructureTesterArmyA paid service - the agent, browsers, and infrastructure are included.CypressThe runner is free and open source with full control of the code; Cypress Cloud adds the dashboard, parallelization, and flake detection as a paid product with a free tier.Advantage
- Mocking and component testsTesterArmyOut of scope - tests run against a real environment instead of stubs.CypressFirst class: cy.intercept() network stubbing and component testing with cy.mount are built in, well documented, and backed by a huge ecosystem.Advantage
- Pull request workflowTesterArmyPR testing is built in - runs trigger from GitHub and report back on the pull request.CypressYou wire cypress run into CI yourself; Cypress Cloud layers recorded runs and parallelization on top.
- Native mobile appsTesterArmyThe same plain-English tests run on iOS and Android via managed cloud simulators.AdvantageCypressCypress drives web browsers only, so covering a native app means standing up a second stack like Appium, Maestro, or Detox.
- Entry priceTesterArmyFree trial without a credit card; Hobby is $99 per month with 250 test runs included.CypressThe open-source runner is $0 forever; Cypress Cloud starts with a free tier, and paid plans scale with recorded test results.
Facts checked August 2026. Spotted something out of date? Tell us and we will fix it.
From cypress/e2e to green runs in four steps
Install the CLI, hand the prompt to your coding agent, and review what comes back. Your Cypress suite keeps running until every migrated test 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 reads cypress.config.ts for the baseUrl and your support files for custom commands, then creates a matching web project.
The agent converts every it()
Each spec becomes a test of 3-10 plain-English steps: cy.visit and cy.get() chains turn into act steps, should() assertions into assert steps, and cy.login() or cy.session() setup into a single login step backed by encrypted credentials. Fixture data is inlined as plain language instead of referenced.
Every migrated test runs locally
The agent runs each converted test against your baseUrl with ta tests run --local, where exit code 0 means pass and 1 means fail, then reports a summary table of spec file to test ID to run result, plus anything it intentionally skipped and why.
Wire the suite into CI
Replace the cypress run job with ta tests run --group or a group webhook and run migrated tests on every pull request. Remove the Cypress dependency once the TesterArmy runs are green.
What comes with you,
what stays behind
End-to-end specs translate directly, and the guide is explicit about what does not carry over. Cypress stays in your repo for the jobs it is best at.
When Cypress is still the right call
- Your suite leans on cy.intercept() stubbing or component tests with cy.mount - that is Cypress's home turf, and the migration guide says to keep them there.
- Your end-to-end flows must run air-gapped or fully offline - TesterArmy tests run against a real, reachable environment.
- A $0 open-source license with full control of the code is a hard requirement, and your team has the time to own the suite.
- Your frontend markup rarely churns, so the cy.get() selector layer is not actually costing you afternoons.
Nothing forces the choice on day one. Migrated tests run alongside your cypress run job, and the guide's own advice is to remove the Cypress dependency only once the TesterArmy runs are green.
Frequently Asked Questions
Flake-fighting should not be
its own workstream
Your Cypress suite encodes real knowledge about how your product is supposed to work. The migration keeps that knowledge and retires the web around it - the cy.get() selectors, the cy.wait calls, the { force: true } workarounds - so the next UI change stops rippling through cypress/e2e.