Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ The `api` command provides direct programmatic access to the QA Sphere public AP
**Key files**:

- `types.ts` — Defines `ApiEndpointSpec` as a discriminated union on `bodyMode` (`'none'` | `'json'` | `'file'`), plus supporting types (`ApiPathParamSpec`, `ApiFieldSpec`, `ApiQueryOptionSpec`, `ExecuteFn`)
- `manifests/` — One file per resource (e.g., `runs.ts`, `test-cases.ts`), each exporting an array of `ApiEndpointSpec` objects. `manifests/index.ts` aggregates all specs into a single `allSpecs` array. `manifests/utils.ts` has shared param definitions (e.g., `projectCodeParam`)
- `manifests/` — One file per resource (e.g., `runs.ts`, `test-cases.ts`), each exporting an array of `ApiEndpointSpec` objects. `manifests/index.ts` aggregates all specs into a single `allSpecs` array. `manifests/utils.ts` has shared param definitions (e.g., `projectCodeParam`) and `paginationOptions()` for list options
- `builder.ts` — `buildCommandsFromSpecs()` builds a yargs command tree from the flat specs array, handling nested command paths automatically. Creates yargs options from path params, query options, field options, and body mode
- `executor.ts` — `executeCommand()` orchestrates execution: collects and validates path params → processes body (based on `bodyMode` discriminant) → collects and validates query options → connects to API (lazy env loading) → executes with error mapping
- `main.ts` — Registers the `api` command, delegates to `buildCommandsFromSpecs()`
Expand All @@ -91,9 +91,9 @@ Important note: Online documentation is available at https://docs.qasphere.com.

Composable fetch wrappers using higher-order functions:

- `utils.ts` — `withBaseUrl`, `withAuth`, `withJson`, `withUserAgent`, `withHttpRetry` decorators that wrap `fetch` via middleware pattern; `jsonResponse<T>()` for parsing responses; `appendSearchParams()` for building query strings
- `utils.ts` — `withBaseUrl`, `withAuth`, `withJson`, `withUserAgent`, `withHttpRetry` decorators that wrap `fetch` via middleware pattern; `jsonResponse<T>()` for parsing responses; `appendSearchParams()` for building query strings; `fetchAllPages()` for reading every page of a paginated list
- `index.ts` — `createApi(baseUrl, token)` assembles the API client from all sub-modules using `withFetchMiddlewares`. All requests authenticate with `Authorization: Bearer <token>` (works for both API keys and OAuth access tokens)
- `schemas.ts` — Shared types (`ResourceId`, `ResultStatus`, `PaginatedResponse<T>`, `PaginatedRequest`, `MessageResponse`), `RequestValidationError` class, `validateRequest()` helper, and common Zod field definitions (`sortFieldParam`, `sortOrderParam`, `offsetParam`, `limitParam` etc.).
- `schemas.ts` — Shared types (`ResourceId`, `ResultStatus`, `PaginatedResponse<T>`, `MessageResponse`), `RequestValidationError` class, `validateRequest()` helper, the API limits (`MAX_PAGE_SIZE`, `MAX_BULK_ITEMS`) and common Zod field definitions (`paginationParams`, `sortFieldParam`, `sortOrderParam`, `offsetParam`, `limitParam` etc.). List endpoints use the `/paginated` routes; the older unpaginated routes are deprecated.
- One sub-module per resource (e.g., `projects.ts`, `runs.ts`, `tcases.ts`, `folders.ts`), each exporting a `create<Resource>Api(fetcher)` factory function. Each module defines Zod schemas for its request types (PascalCase, e.g., `CreateRunRequestSchema`), derives TypeScript types via `z.infer`, and validates inputs with `validateRequest()` inside API functions

### Configuration (src/utils/)
Expand Down
128 changes: 91 additions & 37 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,8 @@ qasphere api runs close --project-code PRJ --run-id "$RUN_ID"
**2. Run progress report** — list open runs with their pass/fail/open counts:

```bash
qasphere api runs list --project-code PRJ --closed false \
| jq '.[] | {title, passed: .statusCounts.passed, failed: .statusCounts.failed, open: .statusCounts.open, total: .statusCounts.all}'
qasphere api runs list --project-code PRJ --closed false --include statusCounts \
| jq '.data[] | {title, passed: .statusCounts.passed, failed: .statusCounts.failed, open: .statusCounts.open, total: .statusCounts.all}'
```

**3. Pair the API with the result uploader** — pre-create a run with custom metadata in CI, then upload automation results into it:
Expand All @@ -77,7 +77,7 @@ qasphere junit-upload -r "$QAS_URL/project/PRJ/run/$RUN_ID" ./test-results.xml

**4. AI agent workflows — reports and visualizations** — once the [skill](#ai-agent-skill) is registered with a coding agent (Claude Code, Cursor, etc.), the agent can drive ad-hoc reporting, dashboards, and charts in natural language. Under the hood it calls `qasphere api ...` to fetch the data, then renders it however the conversation needs (Markdown tables, matplotlib/Plotly charts, HTML/SVG, CSV exports, etc.). Example prompts:

- _"Plot the pass rate of the last 20 closed runs in project PRJ as a line chart."_ — agent calls `qasphere api runs list --project-code PRJ --closed true`, computes `passed / all` per run from `statusCounts`, renders the chart.
- _"Plot the pass rate of the last 20 closed runs in project PRJ as a line chart."_ — agent calls `qasphere api runs list --project-code PRJ --closed true --include statusCounts`, computes `passed / all` per run from `statusCounts`, renders the chart.
- _"Which folders in PRJ have the most failing tests this week?"_ — agent combines `runs list`, `runs test-cases list`, and `folders list` to aggregate failures by folder.
- _"Generate a markdown summary of run 42 with the pass/fail breakdown and a list of failing test case titles."_ — agent calls `runs test-cases list --project-code PRJ --run-id 42` and formats the output.

Expand Down Expand Up @@ -181,64 +181,118 @@ The `api` command provides direct access to the QA Sphere public API from the co
qasphere api <resource> <action> [options]
```

Each line lists the options a command requires. Commands that send a request body also take it whole with `--body '<json>'` or `--body-file <path>`, and their field options override its keys. Run any command with `-h` to see all of its options.

```
qasphere api
├── ai-rules
│ └── list --project-code # List AI rules that apply in a project
├── audit-logs
│ └── list # List audit log entries
│ └── list # List audit log entries
├── configurations
│ ├── list --project-code # List configurations
│ ├── get --project-code --configuration-id # Get configuration
│ ├── create --project-code --title # Create configuration
│ ├── update --project-code --configuration-id --title # Rename configuration
│ └── delete --project-code --configuration-id # Delete configuration
├── custom-fields
│ └── list --project-code # List custom fields
│ └── list --project-code # List custom fields
├── files
│ └── upload --file # Upload a file attachment
│ └── upload --file # Upload a file attachment
├── folders
│ ├── list --project-code # List folders
│ └── bulk-create --project-code --folders # Create/update folders
│ ├── list --project-code # List folders
│ ├── get --project-code --folder-id # Get folder
│ ├── tree --project-code # Get folder tree
│ ├── path --project-code --folder-id # Get folder path
│ ├── create --project-code --title # Create folder
│ ├── update --project-code --folder-id # Rename folder or edit its comment
│ ├── move --project-code --new-parent-id --items # Move folders
│ ├── copy --project-code --folder-ids # Copy folders
│ ├── delete --project-code --folder-ids # Delete folders (to trash)
│ └── bulk-create --project-code --folders # Create/update folders
├── milestones
│ ├── list --project-code # List milestones
│ └── create --project-code --title # Create milestone
│ ├── list --project-code # List milestones
│ └── create --project-code --title # Create milestone
├── projects
│ ├── list # List all projects
│ ├── get --project-code # Get project by code
│ └── create --code --title # Create project
│ ├── list # List all projects
│ ├── get --project-code # Get project by code
│ ├── create --code --title # Create project
│ ├── update --project-code # Update project (owner/admin)
│ └── users
│ └── list --project-code # List users with access to project
├── requirements
│ └── list --project-code # List requirements
│ ├── list --project-code # List requirements
│ ├── get --project-code --requirement-id # Get requirement
│ ├── create --project-code --text # Create requirement
│ ├── update --project-code --requirement-id # Update requirement
│ └── delete --project-code --requirement-id # Delete requirement
├── results
│ ├── create --project-code --run-id --tcase-id --status # Create result
│ └── batch-create --project-code --run-id --items # Batch create results
│ ├── create --project-code --run-id --tcase-id --status # Create result
│ └── batch-create --project-code --run-id --items # Batch create results
├── runs
│ ├── create --project-code --title --type --query-plans # Create run
│ ├── list --project-code # List runs
│ ├── clone --project-code --run-id --title # Clone run
│ ├── close --project-code --run-id # Close run
│ ├── create --project-code --title --type --query-plans # Create run
│ ├── list --project-code # List runs
│ ├── clone --project-code --run-id --title # Clone run
│ ├── close --project-code --run-id # Close run
│ ├── test-cases
│ │ ├── list --project-code --run-id # List test cases in run
│ │ └── get --project-code --run-id --tcase-id # Get test case in run
│ │ ├── list --project-code --run-id # List test cases in run
│ │ └── get --project-code --run-id --tcase-id # Get test case in run
│ └── logs
│ └── create --project-code --run-id --comment # Create run log
│ └── create --project-code --run-id --comment # Create run log
├── settings
│ ├── list-statuses # List result statuses
│ └── update-statuses --statuses # Update custom statuses
│ ├── list-statuses # List result statuses
│ └── update-statuses --statuses # Update custom statuses
├── shared-preconditions
│ ├── list --project-code # List shared preconditions
│ └── get --project-code --id # Get shared precondition
│ ├── list --project-code # List shared preconditions
│ ├── get --project-code --id # Get shared precondition
│ ├── create --project-code --title --text # Create shared precondition
│ ├── update --project-code --id # Update shared precondition
│ └── delete --project-code --id # Delete shared precondition
├── shared-steps
│ ├── list --project-code # List shared steps
│ └── get --project-code --id # Get shared step
│ ├── list --project-code # List shared steps
│ ├── get --project-code --id # Get shared step
│ ├── create --project-code --title --sub-steps # Create shared step
│ ├── update --project-code --id # Update shared step
│ └── delete --project-code --id # Delete shared step
├── tags
│ └── list --project-code # List tags
│ ├── list --project-code # List tags
│ ├── create --project-code --title # Create tag
│ ├── update --project-code --tag-id --title # Update tag
│ ├── rename --project-code --tags # Rename several tags
│ └── delete --project-code --tag-ids # Delete tags
├── test-cases
│ ├── list --project-code # List test cases
│ ├── get --project-code --tcase-id # Get test case
│ ├── count --project-code # Count test cases
│ ├── create --project-code --body # Create test case
│ └── update --project-code --tcase-id --body # Update test case
│ ├── list --project-code # List test cases
│ ├── get --project-code --tcase-id # Get test case
│ ├── get-version --project-code --tcase-id --tcase-version # Get a test case version
│ ├── count --project-code # Count test cases
│ ├── create --project-code --title --type --folder-id --priority # Create test case
│ ├── update --project-code --tcase-id # Update test case
│ ├── rollback --project-code --tcase-id --tcase-version # Roll back to a version
│ ├── move --project-code --new-parent-id --items # Move test cases
│ ├── copy --project-code --tcase-ids --target-folder-id # Copy test cases
│ ├── update-priority --project-code --tcase-ids --priority # Set priority
│ ├── update-tags --project-code --tcase-ids # Add/remove tags
│ ├── update-requirements --project-code --tcase-ids # Add/remove requirements
│ ├── delete --project-code --tcase-ids # Delete test cases (to trash)
│ └── results
│ └── list --project-code --tcase-id # List a test case's result history
├── test-plans
│ └── create --project-code --body # Create test plan
│ └── create --project-code --title --runs # Create test plan
├── trash
│ ├── list --project-code # List trash entries
│ └── restore --project-code --ids # Restore trash entries
└── users
└── list # List all users
└── list # List all users
```

Note: `qasphere api files upload --file ...` uses the public batch upload endpoint internally and returns the first uploaded file from that response.

Deleted folders and test cases go to the project's trash, where `qasphere api trash restore` brings them back within 60 days. Deleted tags, requirements, shared steps, shared preconditions and configurations can't be restored.

### Pagination

List commands that take `--offset` and `--limit` return one page, as `{"total": N, "offset": O, "limit": L, "data": [...]}`. `--offset` defaults to 0 and `--limit` to 100, at most 1000; `--limit 0` returns only the total. Use `--offset` to read further pages. Most also take `--sort-field` and `--sort-order` (asc/desc). The `audit-logs list` command uses cursor-based pagination with `--after` and `--count` instead.

## Commands: `junit-upload`, `playwright-json-upload`, `allure-upload`

The `junit-upload`, `playwright-json-upload`, and `allure-upload` commands upload test results to QA Sphere.
Expand Down
Loading
Loading