How to Use Multi-Framework Execution Without Migration
You have three test frameworks across your teams. Migrating to one takes 6 months and is risky. A framework abstraction layer means you keep all three. And adopt AI test generation today. Here is how.
The multi-framework problem
Real scenario: a 200-person engineering org.
Frontend team: Cypress (best DX, great for UI testing)
Mobile team: Appium (native mobile testing)
API team: Postman + Rest-Assured (lightweight, fast)
Legacy team: Selenium (massive test suite, cannot migrate)
Each team picked the right tool for their job. But now you have four frameworks.
Problem: you want to adopt AI test generation. But every AI test generation tool only supports one framework.
Solution: 'Pick one framework for the whole org.' Translation: migrate 3-6 months, retrain teams, risk breaking tests.
Better solution: an abstraction layer.
What is a framework abstraction layer?
An abstraction layer sits between your test specification and your test framework.
You write:
"Click the login button and verify the dashboard loads."
The abstraction layer translates this into:
Selenium: WebDriver.FindElement(...).Click() + WebDriverWait(...)
Cypress: cy.get(...).click() + cy.get(...).should('be.visible')
Playwright: await page.click(...) + await page.waitForSelector(...)
Same intent. Three different implementations.
How multi-framework execution works
Step 1: You specify a test in natural language or pseudocode.
Step 2: AI generates a framework-agnostic test (an intermediate representation).
Step 3: The abstraction layer transpiles this to your target framework.
Step 4: Your existing test runner executes the generated test.
Step 5: Results flow back to your dashboard.
The three frameworks explained
Selenium (the legacy standard)
Selenium
Native: driver.find_element(...).click()
Abstracted: abstraction.click(selector)
Selenium is:
Mature. Thousands of existing tests.
Slow. Heavy browser automation overhead.
Compatible. Works with any browser, any language.
Use Selenium when: you have a massive existing test suite and cannot migrate.
Cypress (the modern favourite)
Cypress
Native: cy.get(...).should('be.visible')
Abstracted: abstraction.verify(selector, 'visible')
Cypress is:
Fast. Tests run in the browser, not over the network.
Developer-friendly. Great error messages.
Limited. Only for web. Only for modern browsers.
Use Cypress when: you are testing modern web apps and want the best developer experience.
Playwright (the rising star)
Playwright
Native: await page.click(...)
Abstracted: await abstraction.click(selector)
Playwright is:
Fast. Equivalent speed to Cypress.
Comprehensive. Browser, mobile, API all in one.
Modern. Built for async/await patterns.
Use Playwright when: you need speed, comprehensiveness, and modern patterns.
Setting up multi-framework execution
Step 1: Declare your frameworks
Tell the system which frameworks your teams use:
Frontend team: Cypress
API team: Rest-Assured (or Playwright for API)
Legacy team: Selenium
You are not changing frameworks. You are declaring what you have.
Step 2: Generate tests
Write a test in natural language:
"Log in with valid credentials and verify dashboard has user name."
AI generates a framework-agnostic test.
Step 3: Transpile to each framework
The same generated test is transpiled to:
Cypress code (for frontend teams)
Selenium code (for legacy teams)
Playwright code (for API teams)
You now have three test implementations from one spec.
Step 4: Run on your infrastructure
Each team runs tests on their existing CI/CD:
Cypress team: runs in their existing Cypress infrastructure
Selenium team: runs in their existing Selenium grid
Playwright team: runs in their existing Playwright setup
No tool migration. No CI/CD changes.
Code example: login test
Here is what the generated test looks like in each framework:
Cypress version
describe('Login', () => {
it('logs in with valid credentials', () => {
cy.visit('/login')
cy.get('[data-testid=email]').type('user@test.com')
cy.get('[data-testid=password]').type('password123')
cy.get('[data-testid=login-btn]').click()
cy.get('[data-testid=dashboard]').should('be.visible')
cy.get('[data-testid=user-name]').should('contain', 'User')
})
})
Selenium version
public class LoginTest {
WebDriver driver = new ChromeDriver();
@Test
public void testLoginWithValidCredentials() {
driver.navigate().to('/login');
WebElement email = driver.findElement(By.id('email'));
email.sendKeys('user@test.com');
WebElement password = driver.findElement(By.id('password'));
password.sendKeys('password123');
WebElement loginBtn = driver.findElement(By.id('login-btn'));
WebElement dashboard = new WebDriverWait(driver, 10).until(
ExpectedConditions.visibilityOfElementLocated(By.id('dashboard'))
);
assertEquals('User', driver.findElement(By.id('user-name')).getText());
}
}
Playwright version
import { test, expect } from '@playwright/test';
test('logs in with valid credentials', async ({ page }) => {
await page.goto('/login');
await page.fill('[data-testid=email]', 'user@test.com');
await page.fill('[data-testid=password]', 'password123');
await page.click('[data-testid=login-btn]');
await page.waitForSelector('[data-testid=dashboard]');
await expect(page.locator('[data-testid=user-name]')).toContainText('User');
});
The cost comparison
Scenario: 200-person engineering org wants to adopt AI test generation.
Option 1: Migrate to one framework
Effort: 6-9 months of migration work
Cost: 2 engineers full-time for 6 months + retrain 3 teams
Risk: breaking tests, finding new bugs in migration
Total cost: ~$500K + downtime
Option 2: Multi-framework execution (keep all frameworks)
Effort: 2 weeks to set up abstraction layer
Cost: 1 engineer for 2 weeks + minimal training (how to write specs)
Risk: minimal (no existing tests change)
Total cost: ~$10K + instant adoption
Difference: 50x faster, 50x cheaper, zero risk.
Common concerns
Does code generated for Cypress work exactly the same as Selenium code?
No. Cypress and Selenium have different semantics. Cypress is in-process. Selenium is over the wire.
But both tests pass. Both test the same behavior. Slightly different implementation, same outcome.
What if my framework is not in the list?
If you use a framework not listed (JUnit, TestNG, Protractor, Katalon), you can:
Add it to the abstraction layer (2-3 weeks of work)
Or keep using your current framework + AI test generation
Or migrate to Selenium, Cypress, or Playwright
What if two teams are on the same framework?
Then they use the same generated tests. No translation needed.
You get the benefit of shared test code across teams.
Implementing multi-framework in your org
Step 1: Audit your current frameworks.
Which teams use which frameworks?
How many tests does each framework have?
Which frameworks are you willing to keep? Which would you migrate?
Step 2: Identify the top 5 test scenarios.
Tests that are repeated across frameworks
Tests that are a pain to maintain
Tests that would benefit most from AI generation
Step 3: Generate tests for those 5 scenarios.
Use natural language or pseudocode specs
Generate for each framework
Run generated tests in your existing CI/CD
Step 4: Compare results.
Do generated tests pass?
Is coverage the same across frameworks?
Is code quality acceptable?
Step 5: Scale to more tests.
Once you are confident, generate for 20, then 50, then 100 tests
The multi-framework future
Most enterprises have multiple test frameworks. It is just how organizations evolve.
The old way: pick one framework, migrate everyone, accept the migration cost.
The new way: keep multiple frameworks, use an abstraction layer, generate tests for all of them.
You avoid the migration cost. You keep team autonomy. You adopt AI test generation today.
Keep your frameworks. Adopt AI test generation today.https://www.walnutai.ai/


