Test Migration
Move tests and functional areas between Lastest instances -- e.g. from a staging deployment to production, or between self-hosted servers.
In-App UI
The easiest way to migrate tests:
- Go to Settings on the target instance
- Find the Test Migration card
- Enter the remote Lastest URL (e.g.
https://staging.example.com) - Enter an API key from the source instance (see API Tokens)
- Browse available remote repositories
- Select the source repo and import into your current repo
Migration is idempotent -- re-running updates existing tests by name match rather than creating duplicates.
REST API
Export: GET /api/v1/repos/:id/export
Returns all tests and functional areas for a repository in the format accepted by the import endpoint. Includes all fields: code, description, overrides, execution mode, capabilities, quarantine status.
curl -H "Authorization: Bearer $API_KEY" \
"$LASTEST_URL/api/v1/repos/$REPO_ID/export"
Response:
{
"functionalAreas": [
{
"name": "Login Flow",
"description": "User authentication flows",
"parentName": null,
"orderIndex": 0,
"isRouteFolder": false,
"agentPlan": null
}
],
"tests": [
{
"name": "Login happy path",
"code": "export async function test(page, ...) { ... }",
"description": "Tests successful login with valid credentials",
"targetUrl": "https://example.com/login",
"functionalAreaName": "Login Flow",
"executionMode": "procedural",
"agentPrompt": null,
"assertions": null,
"setupOverrides": null,
"teardownOverrides": null,
"stabilizationOverrides": null,
"viewportOverride": null,
"diffOverrides": null,
"playwrightOverrides": null,
"requiredCapabilities": null,
"quarantined": false,
"isPlaceholder": false
}
]
}
Import: POST /api/v1/repos/:id/import
Upserts functional areas and tests by name matching (case-insensitive). Handles parent-child area relationships automatically.
curl -X POST -H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d @export.json \
"$LASTEST_URL/api/v1/repos/$REPO_ID/import"
Response:
{
"success": true,
"areasCreated": 3,
"areasUpdated": 1,
"testsCreated": 12,
"testsUpdated": 2,
"errors": []
}
One-Liner: Pipe Export to Import
curl -H "Authorization: Bearer $SOURCE_KEY" \
"$SOURCE_URL/api/v1/repos/$SOURCE_REPO_ID/export" \
| curl -X POST -H "Authorization: Bearer $TARGET_KEY" \
-H "Content-Type: application/json" \
-d @- "$TARGET_URL/api/v1/repos/$TARGET_REPO_ID/import"
What Gets Migrated
- Functional areas (with parent-child hierarchy)
- Tests (code, description, target URL, all overrides, execution mode, capabilities)
- Area-to-test assignments (resolved by area name)
What Does NOT Migrate
- Test run history and results
- Visual diff baselines and screenshots
- Build history
- Scheduled runs
- Setup/teardown scripts (repository-level)
Notes
- Tests are matched by name + functional area (case-insensitive). If a test with the same name exists in the target, it's updated rather than duplicated.
- Functional areas are matched by name (case-insensitive). Existing areas are updated with any new description/metadata.
- Parent-child area relationships are resolved by name in two passes.
- Errors for individual tests/areas don't fail the entire import -- they're collected in the
errorsarray.