Coming from Playwright
Try existing Playwright files on Retest, identify compatibility gaps and migrate a test.
Try --playwright to run an existing Playwright file through Retest's compatibility API. Start with one file and use the list of supported calls below to decide what to change before moving a larger suite.
If Retest is not installed in the project yet, follow the installation steps in Quick start first. Then try an existing spec before changing its imports or file name.
Try one file Link to Try one file
Keep the file's Playwright import and ordinary page fixture. This task test uses supported locators, actions and checks, so its body needs no changes:
import { expect, test } from '@playwright/test'test('saves a task', async ({ page }) => { await page.goto('/') await page.getByTestId('task-title').fill('Release checklist') await page.getByTestId('save-task').click() await expect(page.getByTestId('saved-task')).toHaveText('Release checklist')})For a first trial without a Retest config, supply the executable and app address directly. Use the path to an installed Chrome or Chromium binary on your machine.
npx retest run --playwright tests/task.spec.ts \ --browser "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome" \ --base-url http://127.0.0.1:4173Retest resolves @playwright/test and playwright/test to its own compatibility API. Playwright does not need to be installed for this run, and no Playwright driver runs. The report labels it playwright compatibility.
Move the configuration Link to Move the configuration
Retest does not read playwright.config.ts. Browser selection, app addresses, startup and budgets must come from Retest's config or command line, so a passing trial does not mean your Playwright configuration was applied.
import { chrome, defineConfig } from '@rehearsal-labs/retest'const config = defineConfig({ apps: { web: chrome({ baseUrl: 'http://127.0.0.1:4173' }) },})export default configdeclare module '@rehearsal-labs/retest' { interface Register { config: typeof config }}npx retest run --playwright tests/task.spec.tsWith this config, omit --browser; Retest refuses that flag alongside a config. With no file arguments, compatibility mode discovers .spec.ts, .spec.js, .spec.mts and .spec.mjs. Corresponding .test files work when named explicitly, but are not discovered automatically.
Check the supported subset Link to Check the supported subset
The compatibility API covers the calls listed below. A call or option outside this subset fails where you use it with unsupported, naming what needs to change.
| Area | Supported calls |
|---|---|
| Structure | test, test.describe, test.beforeEach, test.afterEach, test.step and the page fixture. |
| Page | goto, reload, goBack, goForward, title and keyboard.press. |
| Finders | getByRole, getByLabel, getByText, getByTestId, getByPlaceholder and CSS locator, with scoping, first, last and nth. |
| Actions | fill, click, hover, press, check, uncheck and single-option selectOption. |
| Checks | Visibility, checked state, enabled state, text, count, value, URL and title matchers; expect.soft and expect.poll. |
| Values | toBe, toEqual, toContain and toMatch. |
Common gaps include custom fixtures, test.use, Playwright's test.skip and test.only, page.url(), named table rows, file operations and options such as force or waitUntil. Compatibility file operations remain unsupported even though Retest's own API has uploads and downloads.
selectOption must identify one option by label or value. A bare string, array, index or null is refused, so make the intended selection explicit:
await page.getByLabel('Priority').selectOption({ label: 'High' })Navigation calls do not provide a usable Playwright response, and selectOption does not provide its selected values. Await those calls without reading their return values; accessing a member of the returned value fails by name.
Review behaviour differences Link to Review behaviour differences
Compatibility keeps Playwright's partial, case-insensitive string matching for text finders unless you set exact: true. Actions and checks still follow Retest's rules: input is sent once, ambiguous matches fail, and a test with no assertion fails.
Retest selects options with keyboard input, so your app hears keys as well as input and change events. Role names come from the browser's accessibility tree; named table rows are refused because they differ from Playwright's naming. Enabled-state checks also differ for aria-disabled on ordinary elements or ancestors.
The default test budget is 60 seconds, the action budget 10 seconds and the assertion budget 5 seconds. A call-specific timeout can shorten a budget but cannot extend it. History navigation without an entry fails rather than returning null.
Convert a test Link to Convert a test
Once a file works, change its import to @rehearsal-labs/retest, rename it to .retest.ts and run without --playwright. For the task example, the body stays the same. Review text finders because Retest's own default is exact and case-sensitive.
import { expect, test } from '@rehearsal-labs/retest'npx retest run tests/task.retest.tsUse Signing in and secrets to replace config-based Playwright storage state with Retest's named setup state. Keep files requiring unsupported behaviour on their existing runner until you can express the same check in Retest.