cloud_v2

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Shiplight Cloud v2

Shiplight Cloud v2

Daily Skill Update Check

每日技能更新检查

Before starting this skill's work, opportunistically refresh Shiplight skills at most once per day:
  1. Check the timestamp file at
    .shiplight-agent-skills-last-update
    in the current project.
  2. If the timestamp file is missing or older than 24 hours, run
    npx -y skills@latest update -y
    , then create/update the timestamp file even if the command fails. Treat
    .shiplight-agent-skills-last-update
    as local cache and do not commit it.
  3. If the update command fails, continue with the currently installed skill and mention the failure briefly.
Use the Nova results API to publish and inspect Shiplight test results from local runs, CI runs, and hosted execution. The
/v1
path segment is the API contract version.
在开始使用该技能前,每天最多刷新一次Shiplight技能:
  1. 检查当前项目中
    .shiplight-agent-skills-last-update
    时间戳文件。
  2. 如果时间戳文件缺失或已超过24小时,运行
    npx -y skills@latest update -y
    ,然后创建/更新时间戳文件(即使命令执行失败也要操作)。将
    .shiplight-agent-skills-last-update
    视为本地缓存,不要提交到版本控制。
  3. 如果更新命令执行失败,继续使用当前已安装的技能,并简要提及失败情况。
使用Nova结果API从本地运行、CI运行和托管执行中发布和查看Shiplight测试结果。
/v1
路径段是API协议版本。

Setup

配置

Use a Nova API token in
SHIPLIGHT_API_TOKEN
and the Nova API base URL in
SHIPLIGHT_API_URL
.
bash
export SHIPLIGHT_API_URL=https://nova-api.shiplight.ai
All API calls require:
text
Authorization: Bearer $SHIPLIGHT_API_TOKEN
If the user provides a token, append it to the project's
.env
file as
SHIPLIGHT_API_TOKEN=<token>
and tell them to keep
.env
out of git.
使用
SHIPLIGHT_API_TOKEN
中的Nova API令牌,以及
SHIPLIGHT_API_URL
中的Nova API基础URL。
bash
export SHIPLIGHT_API_URL=https://nova-api.shiplight.ai
所有API调用都需要:
text
Authorization: Bearer $SHIPLIGHT_API_TOKEN
如果用户提供令牌,将其追加到项目的
.env
文件中,格式为
SHIPLIGHT_API_TOKEN=<token>
,并告知用户不要将
.env
提交到git。

Error Handling

错误处理

ErrorAction
400 Bad RequestFix the request body, IDs, or query parameters
401 UnauthorizedToken is missing, invalid, expired, or for the wrong Nova environment
403 ForbiddenToken lacks the required permission
404 Not FoundRun, result, or artifact was not found for this organization
422 ValidationShow the validation message and correct the payload
500 Server ErrorRetry only if the operation is idempotent; otherwise report the failure
错误处理方式
400 请求错误修正请求体、ID或查询参数
401 未授权令牌缺失、无效、过期或所属Nova环境错误
403 禁止访问令牌缺少所需权限
404 未找到该组织未找到对应的运行、结果或制品
422 验证失败显示验证信息并修正请求负载
500 服务器错误仅当操作是幂等的时重试;否则报告失败情况

REST API

REST API

Base URL:
$SHIPLIGHT_API_URL
基础URL:
$SHIPLIGHT_API_URL

Create Test Run

创建测试运行

Create a test run and result slots. The response includes presigned upload URLs for per-result video and trace artifacts.
bash
curl -X POST "$SHIPLIGHT_API_URL/v1/local-runs" \
  -H "Authorization: Bearer $SHIPLIGHT_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d @run.json
Request:
json
{
  "trigger": "local_cli",
  "startTime": "2026-05-27T10:00:00.000Z",
  "metadata": {
    "gitBranch": "main",
    "gitCommit": "abc1234",
    "gitRepo": "org/repo",
    "authorEmail": "dev@example.com",
    "ciProvider": "github_actions",
    "ciBuildId": "12345",
    "ciBuildUrl": "https://github.com/org/repo/actions/runs/12345",
    "commitTitle": "Fix checkout flow",
    "commitUrl": "https://github.com/org/repo/commit/abc1234",
    "prNumber": 42,
    "prTitle": "Fix checkout flow",
    "prUrl": "https://example.com/pr/42",
    "hostname": "runner-1",
    "nodeVersion": "v22.0.0"
  },
  "tests": [
    {
      "testCaseName": "checkout succeeds",
      "testCaseBaseName": "checkout succeeds",
      "suiteName": "Checkout",
      "file": "tests/checkout.test.yaml",
      "tags": ["smoke"],
      "suiteTags": ["commerce"],
      "baseUrl": "https://app.example.com",
      "skip": false,
      "slow": false,
      "timeout": 30000,
      "parameterSetName": "chromium",
      "videoMd5": "base64-encoded-md5",
      "traceMd5": "base64-encoded-md5"
    }
  ]
}
Response:
json
{
  "testRunId": 42,
  "testCaseResults": [
    {
      "testCaseName": "checkout succeeds",
      "testCaseResultId": 101,
      "uploadUrls": {
        "video": "https://...",
        "trace": "https://...",
        "screenshots": {}
      },
      "s3Uris": {
        "video": "s3://...",
        "trace": "s3://..."
      }
    }
  ]
}
Useful metadata keys include
gitBranch
,
gitCommit
,
gitRepo
,
authorEmail
,
commitTitle
,
commitUrl
,
ciProvider
,
ciBuildId
,
ciBuildUrl
,
prTitle
,
prNumber
,
prUrl
,
hostname
, and
nodeVersion
. Unknown metadata may be ignored.
创建测试运行和结果槽位。响应包含针对每个结果的视频和追踪制品的预签名上传URL。
bash
curl -X POST "$SHIPLIGHT_API_URL/v1/local-runs" \
  -H "Authorization: Bearer $SHIPLIGHT_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d @run.json
请求:
json
{
  "trigger": "local_cli",
  "startTime": "2026-05-27T10:00:00.000Z",
  "metadata": {
    "gitBranch": "main",
    "gitCommit": "abc1234",
    "gitRepo": "org/repo",
    "authorEmail": "dev@example.com",
    "ciProvider": "github_actions",
    "ciBuildId": "12345",
    "ciBuildUrl": "https://github.com/org/repo/actions/runs/12345",
    "commitTitle": "Fix checkout flow",
    "commitUrl": "https://github.com/org/repo/commit/abc1234",
    "prNumber": 42,
    "prTitle": "Fix checkout flow",
    "prUrl": "https://example.com/pr/42",
    "hostname": "runner-1",
    "nodeVersion": "v22.0.0"
  },
  "tests": [
    {
      "testCaseName": "checkout succeeds",
      "testCaseBaseName": "checkout succeeds",
      "suiteName": "Checkout",
      "file": "tests/checkout.test.yaml",
      "tags": ["smoke"],
      "suiteTags": ["commerce"],
      "baseUrl": "https://app.example.com",
      "skip": false,
      "slow": false,
      "timeout": 30000,
      "parameterSetName": "chromium",
      "videoMd5": "base64-encoded-md5",
      "traceMd5": "base64-encoded-md5"
    }
  ]
}
响应:
json
{
  "testRunId": 42,
  "testCaseResults": [
    {
      "testCaseName": "checkout succeeds",
      "testCaseResultId": 101,
      "uploadUrls": {
        "video": "https://...",
        "trace": "https://...",
        "screenshots": {}
      },
      "s3Uris": {
        "video": "s3://...",
        "trace": "s3://..."
      }
    }
  ]
}
有用的元数据键包括
gitBranch
gitCommit
gitRepo
authorEmail
commitTitle
commitUrl
ciProvider
ciBuildId
ciBuildUrl
prTitle
prNumber
prUrl
hostname
nodeVersion
。未知的元数据可能会被忽略。

Screenshot Upload URLs

截图上传URL

Generate presigned upload URLs for result screenshots.
bash
curl -X POST "$SHIPLIGHT_API_URL/v1/local-runs/$TEST_RUN_ID/results/$TEST_CASE_RESULT_ID/screenshot-urls" \
  -H "Authorization: Bearer $SHIPLIGHT_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"stepIds":["step-1"],"md5s":{"step-1":"base64-encoded-md5"}}'
Response:
json
{
  "screenshots": {
    "step-1": "https://..."
  },
  "screenshotS3Uris": {
    "step-1": "s3://..."
  }
}
为结果截图生成预签名上传URL。
bash
curl -X POST "$SHIPLIGHT_API_URL/v1/local-runs/$TEST_RUN_ID/results/$TEST_CASE_RESULT_ID/screenshot-urls" \
  -H "Authorization: Bearer $SHIPLIGHT_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"stepIds":["step-1"],"md5s":{"step-1":"base64-encoded-md5"}}'
响应:
json
{
  "screenshots": {
    "step-1": "https://..."
  },
  "screenshotS3Uris": {
    "step-1": "s3://..."
  }
}

Report Upload URL

报告上传URL

Generate a presigned upload URL for a result report.
bash
curl -X POST "$SHIPLIGHT_API_URL/v1/local-runs/$TEST_RUN_ID/results/$TEST_CASE_RESULT_ID/report-url" \
  -H "Authorization: Bearer $SHIPLIGHT_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"md5":"base64-encoded-md5"}'
Response:
json
{
  "reportUrl": "https://...",
  "reportS3Uri": "s3://..."
}
为结果报告生成预签名上传URL。
bash
curl -X POST "$SHIPLIGHT_API_URL/v1/local-runs/$TEST_RUN_ID/results/$TEST_CASE_RESULT_ID/report-url" \
  -H "Authorization: Bearer $SHIPLIGHT_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"md5":"base64-encoded-md5"}'
响应:
json
{
  "reportUrl": "https://...",
  "reportS3Uri": "s3://..."
}

Complete Test Run

完成测试运行

Mark a test run complete and attach final per-result status, timing, artifacts, and metadata. Common
result
values are
passed
,
failed
,
skipped
,
timedout
, and
flaky
.
bash
curl -X PUT "$SHIPLIGHT_API_URL/v1/local-runs/$TEST_RUN_ID/complete" \
  -H "Authorization: Bearer $SHIPLIGHT_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d @complete-run.json
Request:
json
{
  "status": "finished",
  "endTime": "2026-05-27T10:05:00.000Z",
  "totalDuration": 300000,
  "results": [
    {
      "testCaseResultId": 101,
      "result": "passed",
      "startTime": "2026-05-27T10:00:01.000Z",
      "endTime": "2026-05-27T10:00:10.000Z",
      "error": null,
      "reportS3Uri": "s3://...",
      "videoS3Uri": "s3://...",
      "traceS3Uri": "s3://...",
      "metadata": {}
    }
  ]
}
Response:
json
{
  "reportUrl": "/run-results/42"
}
标记测试运行为完成状态,并附加每个结果的最终状态、时间信息、制品和元数据。常见的
result
值包括
passed
failed
skipped
timedout
flaky
bash
curl -X PUT "$SHIPLIGHT_API_URL/v1/local-runs/$TEST_RUN_ID/complete" \
  -H "Authorization: Bearer $SHIPLIGHT_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d @complete-run.json
请求:
json
{
  "status": "finished",
  "endTime": "2026-05-27T10:05:00.000Z",
  "totalDuration": 300000,
  "results": [
    {
      "testCaseResultId": 101,
      "result": "passed",
      "startTime": "2026-05-27T10:00:01.000Z",
      "endTime": "2026-05-27T10:00:10.000Z",
      "error": null,
      "reportS3Uri": "s3://...",
      "videoS3Uri": "s3://...",
      "traceS3Uri": "s3://...",
      "metadata": {}
    }
  ]
}
响应:
json
{
  "reportUrl": "/run-results/42"
}

Artifact Read URL

制品读取URL

Generate a signed read URL for an uploaded artifact.
bash
curl "$SHIPLIGHT_API_URL/v1/local-runs/$TEST_RUN_ID/results/$TEST_CASE_RESULT_ID/artifact-url?type=trace" \
  -H "Authorization: Bearer $SHIPLIGHT_API_TOKEN"
Supported
type
values:
report
,
video
,
trace
,
screenshot
. For screenshots, include
stepId
.
bash
curl "$SHIPLIGHT_API_URL/v1/local-runs/$TEST_RUN_ID/results/$TEST_CASE_RESULT_ID/artifact-url?type=screenshot&stepId=step-1" \
  -H "Authorization: Bearer $SHIPLIGHT_API_TOKEN"
Response:
json
{
  "url": "https://...",
  "expiresIn": 3600
}
为已上传的制品生成签名读取URL。
bash
curl "$SHIPLIGHT_API_URL/v1/local-runs/$TEST_RUN_ID/results/$TEST_CASE_RESULT_ID/artifact-url?type=trace" \
  -H "Authorization: Bearer $SHIPLIGHT_API_TOKEN"
支持的
type
值:
report
video
trace
screenshot
。对于截图,需要包含
stepId
bash
curl "$SHIPLIGHT_API_URL/v1/local-runs/$TEST_RUN_ID/results/$TEST_CASE_RESULT_ID/artifact-url?type=screenshot&stepId=step-1" \
  -H "Authorization: Bearer $SHIPLIGHT_API_TOKEN"
响应:
json
{
  "url": "https://...",
  "expiresIn": 3600
}

Workflows

工作流

Publish a Run

发布测试运行

  1. Build the run payload with one entry per discovered test.
  2. POST /v1/local-runs
    and keep
    testRunId
    ,
    testCaseResultId
    , upload URLs, and S3 URIs.
  3. Upload videos and traces directly to the presigned URLs returned by create-run. If an MD5 was provided when requesting a URL, upload the matching content with the required checksum header.
  4. For screenshots, call
    screenshot-urls
    , then upload each file to its presigned URL.
  5. For reports, call
    report-url
    , then upload the report JSON to its presigned URL.
  6. PUT /v1/local-runs/{testRunId}/complete
    with each final result and uploaded artifact URI.
  7. Return the API response's
    reportUrl
    to the user.
  1. 构建包含每个已发现测试条目的运行负载。
  2. 调用
    POST /v1/local-runs
    并保存
    testRunId
    testCaseResultId
    、上传URL和S3 URI。
  3. 直接将视频和追踪文件上传到创建运行接口返回的预签名URL。如果请求URL时提供了MD5值,上传匹配内容时需附带所需的校验和头。
  4. 对于截图,调用
    screenshot-urls
    接口,然后将每个文件上传到对应的预签名URL。
  5. 对于报告,调用
    report-url
    接口,然后将报告JSON上传到对应的预签名URL。
  6. 调用
    PUT /v1/local-runs/{testRunId}/complete
    接口,传入每个结果的最终状态和已上传制品的URI。
  7. 将API响应中的
    reportUrl
    返回给用户。

Retrieve an Artifact

获取制品

  1. Call
    artifact-url
    with
    type=report
    ,
    video
    ,
    trace
    , or
    screenshot
    .
  2. Download from the returned signed URL before it expires.
  3. For binary artifacts, save with an appropriate filename extension.
  1. 调用
    artifact-url
    接口,指定
    type=report
    video
    trace
    screenshot
  2. 在URL过期前从返回的签名URL下载内容。
  3. 对于二进制制品,保存时使用合适的文件扩展名。