Skip to content

Commit 04c92d7

Browse files
author
DavertMik
committed
added docs for migrations
1 parent e6caee6 commit 04c92d7

4 files changed

Lines changed: 406 additions & 0 deletions

File tree

docs/migrate-from-cypress.md

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
---
2+
permalink: /migrate-from-cypress
3+
title: Migrate from Cypress to CodeceptJS
4+
---
5+
6+
# Migrate from Cypress to CodeceptJS
7+
8+
## Start here: what Cypress boxes you into
9+
10+
A Cypress test runs inside the browser, in the same tab as your app. That keeps a simple test short, but it fixes the test to one tab, one browser, and one origin. A second tab, a second logged-in user, a different domain, or an API call between two clicks each needs a special workaround: `cy.origin`, `cy.session`, request plumbing, tab stubbing. Cross-browser is limited the same way: Chromium first, WebKit partial.
11+
12+
CodeceptJS runs the test in Node and controls the browser from the outside. The test is a normal Node script, so a second tab, a second user, an API call in the middle of a flow, and Firefox or WebKit are ordinary steps instead of workarounds. It drives the browser through Playwright by default, or Puppeteer or WebDriver if you prefer.
13+
14+
Migrating a Cypress suite looks like a lot of work. It is not. We prepared a set of skills, so you can relax and [let an agent do the migration](#let-an-agent-do-the-migration).
15+
16+
## Comparison
17+
18+
The original test in Cypress:
19+
20+
```js
21+
// Cypress
22+
it('user can log in', () => {
23+
cy.visit('/login');
24+
cy.get('#username').type('alice');
25+
cy.get('#password').type('secret');
26+
cy.contains('Sign in').click();
27+
cy.url().should('include', '/dashboard');
28+
cy.contains('.welcome', 'Welcome, Alice');
29+
});
30+
```
31+
32+
Will look in CodeceptJS:
33+
34+
```js
35+
// CodeceptJS
36+
Scenario('user can log in', ({ I }) => {
37+
I.amOnPage('/login');
38+
I.fillField('Username', 'alice');
39+
I.fillField('Password', 'secret');
40+
I.click('Sign in');
41+
I.seeInCurrentUrl('/dashboard');
42+
I.see('Welcome, Alice', '.welcome');
43+
});
44+
```
45+
46+
The CSS lookups and the `.should(...)` assertion grammar are gone, and the steps no longer queue: they read as a sequence.
47+
48+
And here is how the test looks while it runs. Every step is printed live, in the same order it was written:
49+
50+
```text
51+
user can log in
52+
I am on page "/login"
53+
I fill field "Username", "alice"
54+
I fill field "Password", "secret"
55+
I click "Sign in"
56+
I see in current url "/dashboard"
57+
I see "Welcome, Alice", ".welcome"
58+
```
59+
60+
When a step fails, the output stays on that line, with the locator that missed and a screenshot attached. There is no separate report step before you know what happened.
61+
62+
## Let an agent do the migration
63+
64+
The conversions are mechanical, so you do not have to do them by hand, and the work does not cost you working time. Install the skills bundle, point an agent at the repo, and check back when it reports.
65+
66+
The **`migrate-cypress-to-codeceptjs`** skill in the [CodeceptJS skills bundle](https://github.com/codeceptjs/skills) does the whole port:
67+
68+
1. Inventories the shared logic, custom commands, and page modules.
69+
2. Sets up CodeceptJS beside the Cypress suite.
70+
3. Ports the custom commands and page objects.
71+
4. Converts each spec.
72+
5. Runs the full suite.
73+
74+
First runs fail, because locators drift and timing changes. The agent then uses the `debugging-codeceptjs-tests` skill to fix each failure against the live browser before moving on. Your Cypress suite keeps running in CI until the port is green, so nothing is at risk while the agent works.
75+
76+
Install the bundle in Claude Code:
77+
78+
```text
79+
/plugin marketplace add codeceptjs/skills
80+
/plugin install codeceptjs@codeceptjs-skills
81+
```
82+
83+
Or any other agent:
84+
85+
```bash
86+
npx skills add codeceptjs/skills
87+
```
88+
89+
Then ask: *"Migrate this Cypress suite to CodeceptJS."* The skill triggers on the Cypress signatures in your repo. Start it, do other work, and read the step output when it reports back.
90+
91+
## Pointers
92+
93+
- [/agents](/agents) for how the agent and MCP loop works
94+
- [/playwright](/playwright) for the default helper in this migration
95+
- [/locators](/locators) for semantic, ARIA, and `locate()` locators
96+
- [/auth](/auth) for replacing `cy.session()` and programmatic login
97+
- [/api](/api) for the REST helper used in `cy.request` ports
98+
- [/pageobjects](/pageobjects) for ported page objects

docs/migrate-from-java.md

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
---
2+
permalink: /migrate-from-java
3+
title: Migrate from Java Selenium to CodeceptJS
4+
---
5+
6+
# Migrate from Java Selenium to CodeceptJS
7+
8+
## Start here: what changes when you leave the JVM
9+
10+
On the JVM, an end-to-end suite is basically its own product. It has its own Maven or Gradle build, its own dependencies, and a JVM that has to warm up before anything runs. In practice it ends up with its own team too — application engineers stay on the app, QA stays on the tests, and the suite drifts whenever nobody is watching it.
11+
12+
In Node there is no compile or build step. Running tests in NodeJS saves time. NodeJS ecosystem is fastest growing opensource ecosystem, with awesome depenency management tools like npm, bun, pnpm. While Java tests still work JS ecosystem is richer and easier to use. Tools like Playwright and Puppeteer originally started on NodeJS.
13+
14+
Even migrating from Java to JavaScript seems like a huge task, it is actually not.
15+
We prepared a set of skills for, so you can relax and
16+
[let an agent do the migration](#let-an-agent-do-the-migration).
17+
18+
## Comparison
19+
20+
The original test in Java Selenium:
21+
22+
```java
23+
// Java + Selenium + JUnit
24+
@Test
25+
public void userCanLogin() {
26+
WebDriver driver = new ChromeDriver();
27+
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10));
28+
29+
driver.get("https://example.com/login");
30+
wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("username")));
31+
32+
driver.findElement(By.id("username")).sendKeys("alice");
33+
driver.findElement(By.id("password")).sendKeys("secret");
34+
driver.findElement(By.cssSelector("button[type=submit]")).click();
35+
36+
wait.until(ExpectedConditions.urlContains("/dashboard"));
37+
WebElement welcome = wait.until(
38+
ExpectedConditions.visibilityOfElementLocated(By.cssSelector(".welcome"))
39+
);
40+
assertEquals("Welcome, Alice", welcome.getText());
41+
}
42+
```
43+
44+
Will look in CodeceptJS:
45+
46+
```js
47+
// CodeceptJS
48+
Scenario('user can log in', ({ I }) => {
49+
I.amOnPage('/login');
50+
I.fillField('Username', 'alice');
51+
I.fillField('Password', 'secret');
52+
I.click('Sign in');
53+
I.seeInCurrentUrl('/dashboard');
54+
I.see('Welcome, Alice', '.welcome');
55+
});
56+
```
57+
58+
And here is how this test looks while running — every step is printed live, in the same order it was written:
59+
60+
```text
61+
user can log in
62+
I am on page "/login"
63+
I fill field "Username", "alice"
64+
I fill field "Password", "secret"
65+
I click "Sign in"
66+
I see in current url "/dashboard"
67+
I see "Welcome, Alice", ".welcome"
68+
```
69+
70+
## Let an agent do the migration
71+
72+
The conversions above are mechanical, so you do not have to do them by hand, and the work does not cost you working time. Install the skills bundle, point an agent at the repo, and check back when it reports.
73+
74+
The **`migrate-selenium-java-to-codeceptjs`** skill in the [CodeceptJS skills bundle](https://github.com/codeceptjs/skills) does the whole port:
75+
76+
1. Inventories the page objects, helper classes, hooks, and data providers.
77+
2. Sets up CodeceptJS beside the Java suite with the WebDriver helper.
78+
3. Ports the page objects and helpers.
79+
4. Converts each spec.
80+
5. Runs the full suite.
81+
82+
First runs fail, because locators drift and timing changes. The agent then uses the `debugging-codeceptjs-tests` skill to fix each failure against the live browser before moving on. Your Java suite keeps running in CI until the port is green, so nothing is at risk while the agent works.
83+
84+
Install the bundle in Claude Code:
85+
86+
```text
87+
/plugin marketplace add codeceptjs/skills
88+
/plugin install codeceptjs@codeceptjs-skills
89+
```
90+
91+
Or any other agent:
92+
93+
```bash
94+
npx skills add codeceptjs/skills
95+
```
96+
97+
Then ask: *"Migrate this Java Selenium suite to CodeceptJS."* The skill triggers on the Maven or Gradle and `org.openqa.selenium` signatures in your repo. Start it, do other work, and read the step output when it reports back.
98+
99+
## Pointers
100+
101+
- [/agents](/agents) for how the agent and MCP loop works
102+
- [/webdriver](/webdriver) for the default helper in this migration, with driver auto-start
103+
- [/playwright](/playwright) for the optional follow-up swap
104+
- [/locators](/locators) for semantic, ARIA, and `locate()` locators
105+
- [/pageobjects](/pageobjects) for ported `@FindBy` page objects
106+
- [/auth](/auth) for login and session reuse
107+
- [/api](/api) for the REST helper used in RestAssured ports
108+
- [/bdd](/bdd) for CodeceptJS BDD in Cucumber-JVM ports

docs/migrate-from-protractor.md

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
---
2+
permalink: /migrate-from-protractor
3+
title: Migrate from Protractor to CodeceptJS
4+
---
5+
6+
# Migrate from Protractor to CodeceptJS
7+
8+
## Start here: a dead dependency with an Angular wrapper
9+
10+
Protractor was end-of-lifed in April 2023 and has shipped nothing since. Its design wrapped Selenium with two things: `waitForAngular`, which blocked each action until Angular's digest cycle settled, and the ControlFlow promise manager, which ordered commands so test code could be written as if it were synchronous. That is why a Protractor suite pins an old Selenium version and threads results through `.then()`. The dependency only ages from here.
11+
12+
CodeceptJS drops the Angular coupling. The helper waits on the element you are acting on, not on Angular's digest, so the same test works on an Angular app, a React app, or a static page. It still speaks the WebDriver protocol, so an existing Selenium Grid keeps serving the new suite, or you switch the config to Playwright and run the same test code faster.
13+
14+
Migrating a Protractor suite looks like a lot of work. It is not. We prepared a set of skills, so you can relax and [let an agent do the migration](#let-an-agent-do-the-migration).
15+
16+
## Comparison
17+
18+
The original test in Protractor:
19+
20+
```js
21+
// Protractor + Jasmine
22+
describe('login', function () {
23+
it('user can log in', function () {
24+
browser.get('https://example.com/login');
25+
element(by.model('user.email')).sendKeys('alice@example.com');
26+
element(by.model('user.password')).sendKeys('secret');
27+
element(by.css('button[type=submit]')).click();
28+
expect(browser.getCurrentUrl()).toContain('/dashboard');
29+
expect(element(by.css('.welcome')).getText()).toContain('Welcome, Alice');
30+
});
31+
});
32+
```
33+
34+
Will look in CodeceptJS:
35+
36+
```js
37+
// CodeceptJS
38+
Scenario('user can log in', ({ I }) => {
39+
I.amOnPage('/login');
40+
I.fillField('Email', 'alice@example.com');
41+
I.fillField('Password', 'secret');
42+
I.click('Sign in');
43+
I.seeInCurrentUrl('/dashboard');
44+
I.see('Welcome, Alice', '.welcome');
45+
});
46+
```
47+
48+
The `describe`/`it` nesting, the `by.model` strategy, and the Jasmine assertions are gone. The steps read as a sequence instead of a chain of `.then()` calls.
49+
50+
And here is how the test looks while it runs. Every step is printed live, in the same order it was written:
51+
52+
```text
53+
user can log in
54+
I am on page "/login"
55+
I fill field "Email", "alice@example.com"
56+
I fill field "Password", "secret"
57+
I click "Sign in"
58+
I see in current url "/dashboard"
59+
I see "Welcome, Alice", ".welcome"
60+
```
61+
62+
When a step fails, the output stays on that line, with the locator that missed and a screenshot attached. There is no separate report step before you know what happened.
63+
64+
## Let an agent do the migration
65+
66+
The conversions are mechanical, so you do not have to do them by hand, and the work does not cost you working time. Install the skills bundle, point an agent at the repo, and check back when it reports.
67+
68+
The **`migrate-protractor-to-codeceptjs`** skill in the [CodeceptJS skills bundle](https://github.com/codeceptjs/skills) does the whole port:
69+
70+
1. Inventories the page objects, shared helpers, and config hooks.
71+
2. Sets up CodeceptJS beside the Protractor suite.
72+
3. Ports the page objects and helpers.
73+
4. Converts each spec.
74+
5. Runs the full suite.
75+
76+
First runs fail, because locators drift and timing changes. The agent then uses the `debugging-codeceptjs-tests` skill to fix each failure against the live browser before moving on. Your Protractor suite keeps running in CI until the port is green, so nothing is at risk while the agent works.
77+
78+
Install the bundle in Claude Code:
79+
80+
```text
81+
/plugin marketplace add codeceptjs/skills
82+
/plugin install codeceptjs@codeceptjs-skills
83+
```
84+
85+
Or any other agent:
86+
87+
```bash
88+
npx skills add codeceptjs/skills
89+
```
90+
91+
Then ask: *"Migrate this Protractor suite to CodeceptJS."* The skill triggers on the Protractor signatures in your repo. Start it, do other work, and read the step output when it reports back.
92+
93+
## Pointers
94+
95+
- [/agents](/agents) for how the agent and MCP loop works
96+
- [/playwright](/playwright) for the recommended target helper
97+
- [/webdriver](/webdriver) for the target if you keep a Selenium Grid
98+
- [/locators](/locators) for semantic, ARIA, `locate()`, and the `customLocator` plugin
99+
- [/pageobjects](/pageobjects) for ported Protractor page objects
100+
- [/auth](/auth) for programmatic login and session reuse
101+
- [/api](/api) for the REST helper used in HTTP-call ports

0 commit comments

Comments
 (0)