Skip to content
Closed
Show file tree
Hide file tree
Changes from 5 commits
Commits
Show all changes
76 commits
Select commit Hold shift + click to select a range
c39a1a2
feat: added artifacts upload support for jest reporter
miguelangarano Feb 19, 2026
f0d844a
feat: add artifacts upload support for junit xml (vitest sample)
miguelangarano Feb 19, 2026
8f9a729
chore: update lock file
miguelangarano Feb 19, 2026
4c035e0
chore: added unit test for artifacts convert command
miguelangarano Feb 19, 2026
212cae5
chore: added unit tests for jest reporter artifacts upload
miguelangarano Feb 19, 2026
f078d00
chore: refactor artifact functions
miguelangarano Feb 20, 2026
2df7588
chore: no artifacts on empty instance
miguelangarano Feb 20, 2026
47c80fc
chore: import artifact
miguelangarano Feb 20, 2026
f6ba824
chore: extract to function
miguelangarano Feb 20, 2026
dc9d6fa
chore: use path package
miguelangarano Feb 20, 2026
575e395
chore: remove md files
miguelangarano Feb 23, 2026
b825c4d
chore: add attachment prefix
miguelangarano Feb 23, 2026
694e597
chore: rename logs
miguelangarano Feb 23, 2026
87150c9
chore: attachments
miguelangarano Feb 23, 2026
50e5ef8
chore: extract repetitive code
miguelangarano Feb 23, 2026
927d009
chore: refactor functions
miguelangarano Feb 23, 2026
eeefc91
chore: fix stdout upload
miguelangarano Feb 23, 2026
f77eedd
chore: add more artifacts
miguelangarano Feb 23, 2026
5c87d5d
chore: fix stdout upload and add attachment sample in jest
miguelangarano Feb 23, 2026
430e2cc
chore: set stderr in junit and added vitest example
miguelangarano Feb 23, 2026
d97172f
chore: mark stderr for those logs
miguelangarano Feb 24, 2026
cb5c86c
chore: combine stdout with stderr logs
miguelangarano Feb 25, 2026
dd55724
feat: implemented multiple level artifacts support
miguelangarano Feb 26, 2026
5d1253b
chore: include support for level in log artifacts
miguelangarano Feb 26, 2026
91d92b1
chore: fix snapshot test
miguelangarano Feb 26, 2026
680e34e
chore: fix attempts artifacts
miguelangarano Feb 26, 2026
c355849
chore: add gitignore
miguelangarano Feb 26, 2026
1fdc612
chore: added artifacts helper functions
miguelangarano Feb 27, 2026
65de857
chore: fix mermaid doc
miguelangarano Feb 27, 2026
95e240e
chore: fix example
miguelangarano Feb 27, 2026
660e6cc
chore: type helper functions
miguelangarano Feb 27, 2026
b34dc04
chore: update prefix log mark
miguelangarano Feb 27, 2026
8c652ef
chore: remove file
miguelangarano Feb 27, 2026
a54907a
chore: use env variables for keys
miguelangarano Feb 27, 2026
54bdf28
chore: await for request
miguelangarano Feb 27, 2026
bb10c15
chore: remove unused function
miguelangarano Feb 27, 2026
e241443
chore: fix attempts and urls message
miguelangarano Feb 27, 2026
35280a0
chore: fix default
miguelangarano Feb 27, 2026
47758e9
chore: add comment, fix prefix
miguelangarano Feb 27, 2026
c61cafe
chore: take all attempts
miguelangarano Feb 27, 2026
90b164a
chore: restart ount attempt
miguelangarano Feb 27, 2026
19ec86c
chore: fix infer
miguelangarano Feb 27, 2026
65781f0
chore: fix docs
miguelangarano Feb 27, 2026
0dc8d52
chore: add webm
miguelangarano Feb 27, 2026
00aaae4
chore: add webm
miguelangarano Feb 27, 2026
d238b96
chore: veirfy artifact paths
miguelangarano Feb 27, 2026
63a130d
chore: use void
miguelangarano Feb 27, 2026
27fc884
chore: temp dirs
miguelangarano Feb 27, 2026
f0a9a19
chore: update readme instructions
miguelangarano Feb 27, 2026
cef0e17
chore: reuse artifacts dir
miguelangarano Feb 27, 2026
df3b165
chore: refactor long function
miguelangarano Feb 27, 2026
5e7f295
chore: extract types
miguelangarano Feb 27, 2026
4bd7c9f
chore: refactor of artifacts logic
miguelangarano Feb 27, 2026
a98af92
chore: replaced for loops
miguelangarano Feb 27, 2026
3afeee4
chore: map types with extensions
miguelangarano Feb 27, 2026
c60d595
chore: change api file name
miguelangarano Feb 27, 2026
cad0c1f
chore: use maps instead of for
miguelangarano Feb 27, 2026
9f193c9
chore: extract function
miguelangarano Feb 27, 2026
8364c9c
chore: extract and flatmap
miguelangarano Feb 27, 2026
6080123
chore: early exit
miguelangarano Feb 27, 2026
9df50c0
chore: add jsdoc for function
miguelangarano Feb 27, 2026
505689e
chore: updated comment
miguelangarano Feb 27, 2026
376d4eb
chore: refactors from jest reporter
miguelangarano Feb 27, 2026
420fddc
chore: refactor utils
miguelangarano Feb 27, 2026
9327e23
chore: dedup code
miguelangarano Feb 27, 2026
20b32ab
chore: refactor helper
miguelangarano Feb 27, 2026
6fff265
chore: move to different file
miguelangarano Feb 27, 2026
6b7a5ad
chore: updated docs
miguelangarano Feb 27, 2026
bd0922f
chore: remove stdout endpoint uploads
miguelangarano Feb 27, 2026
552200e
chore: fix vitest example
miguelangarano Mar 2, 2026
862ae5c
chore: removed function
miguelangarano Mar 2, 2026
60f4cf6
chore: remove unnecessary files
miguelangarano Mar 2, 2026
041f293
chore: update guide documents
miguelangarano Mar 2, 2026
0cc5bbd
chore: use regex patterns as constants
miguelangarano Mar 2, 2026
4da8099
chore: refactor functions
miguelangarano Mar 2, 2026
119dcda
chore: added unit tests for artifacts functions
miguelangarano Mar 2, 2026
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
49 changes: 49 additions & 0 deletions .trae/documents/plan_20260213_171101.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
I will implement artifact upload support for both the Jest reporter and the Vitest/JUnit converter. The implementation will follow the backend contract described in the implementation report.

### 1. Update Types
I will update the TypeScript definitions to include the `artifacts` array in the report structures.

* **Files**:
* `packages/jest/src/types.ts`
* `packages/cmd/src/types.ts`
* **Changes**:
* Define `Artifact` interface (path, type, contentType, etc.).
* Add `artifacts?: Artifact[]` to `InstanceReportTest` (test-level) and `InstanceReportTestAttempt` (attempt-level).
* Add `artifactUploadUrls` to `CreateRunResponse` type in `packages/cmd/src/api/create-run.ts`.

### 2. Jest Reporter (`packages/jest`)
I will modify the Jest reporter to extract `stdout` and `stderr` as artifacts.

* **File**: `packages/jest/src/reporter.ts`
* **Logic**:
* In `onTestFileResult`, before saving the JSON report:
* Iterate through tests and attempts.
* If `stdout` or `stderr` is present, write the content to a file in a new `artifacts/` subdirectory (e.g., `artifacts/<hash>-stdout.txt`).
* Add an entry to the `artifacts` array of the attempt: `{ path: 'artifacts/<hash>-stdout.txt', type: 'stdout', contentType: 'text/plain' }`.
* This ensures `stdout` is treated as an uploaded artifact.

### 3. Vitest / JUnit Converter (`packages/cmd`)
I will modify the conversion logic to handle artifacts for Vitest (and other JUnit) reports.

* **Files**:
* `packages/cmd/src/services/convert/utils.ts` (to initialize empty `artifacts` array).
* `packages/cmd/src/services/convert/index.ts` (to process artifacts).
* **Logic**:
* In `handleConvert`, after generating the `InstanceReport` map (but before writing to disk):
* Iterate through all instances, tests, and attempts.
* Extract `stdout` / `stderr` content.
* Write content to `artifacts/` subdirectory.
* Attach `Artifact` objects to the corresponding attempts.

### 4. Upload Logic (`packages/cmd`)
I will implement the file upload process in the CLI.

* **File**: `packages/cmd/src/services/upload/index.ts`
* **Logic**:
* Update `createRun` to capture `artifactUploadUrls` from the API response.
* If upload URLs are present, iterate through them.
* Resolve the local file path using the `path` property (relative to the report directory).
* Upload the file content to the provided `uploadUrl` using `PUT`.
* Handle errors gracefully (log and continue) as per requirements.

This approach ensures that both Jest and Vitest runs can upload `stdout`/`stderr` (and easily extended for other files) as artifacts, fulfilling the "any artifact" capability.
73 changes: 73 additions & 0 deletions docs/generic-reporter-artifact-upload-client-investigation.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
# Generic reporter artifact upload – client-side investigation

**Date:** 2026-02-13
**Scope:** Client that uploads artifacts for generic (Jest) runs; server/director/API behavior is confirmed.

---

## Summary

Artifact **links and signing work**. The problem is **what gets uploaded**: the object stored at the artifact URL is plain text `"dummy screenshot content"` instead of the real file (e.g. PNG screenshot, MP4 video). Investigation should focus on the **client** that performs the PUT to the presigned `uploadUrl`.

---

## Context

- **Flow:** Generic reporter (e.g. currents-reporter for Jest) creates a run via director `POST /v1/runs`, receives `artifactUploadUrls[]` with `uploadUrl` and `readUrl` per artifact. The client must **PUT the file** to each `uploadUrl`. Later, the dashboard requests a signed URL from the API and loads the artifact (image/video) from R2.
- **Server side (this repo):** Director, artifact package, storage, and API signer were checked. Upload URL generation, read URL storage, and signing all use the same R2 config and domain. Logs confirm director and API use the same endpoint and bucket; signing uses R2 and the correct host.

---

## Observed behavior

- **Request:** GET to signed URL, e.g.
`https://currents-staging.e8d8fcf9734e9ea0a5c511fc6813faf3.r2.cloudflarestorage.com/6893758239b2717e8ea6496c/8e7f658269549490/test/lPiDn9hKGchS3jSs?X-Amz-...`
- **Response:** 200 OK.
- **Body:** Plain text `"dummy screenshot content"` instead of PNG (or other binary) image data.
- **Effect:** Dashboard shows broken image because the resource is text, not an image.

So the object at that key was **uploaded with that text content**. The client that did the PUT to the corresponding `uploadUrl` is the one that sent "dummy screenshot content".

---

## What the client must do (expected contract)

1. After creating a run, use the `artifactUploadUrls` (or equivalent) from the create-run response.
2. For each entry, **PUT the real artifact file** to `uploadUrl`:
- Body: **binary file content** (screenshot PNG, video MP4, etc.), not a string like `"dummy screenshot content"`.
- Headers: set `Content-Type` to the artifact’s type (e.g. `image/png`, `video/mp4`, `application/octet-stream` as appropriate).
3. Use the same artifact (same path / same file) that is declared in the run payload (e.g. in `instances[].artifacts` or `instances[].results.tests[].artifacts`).

---

## Where to look (client codebase)

- **Repo:** Likely `currents-dev/currents-reporter` or the repo that implements the generic/Jest reporter.
- **Search for:**
- Usage of `uploadUrl` or `artifactUploadUrls` from the run-creation response.
- The code that performs the HTTP PUT (or equivalent) to that URL.
- Any place that sends **string or mock content** (e.g. "dummy screenshot content", "dummy", "placeholder") in the request body.
- Test/mock implementations that might be used in local or Jest runs and that upload dummy content instead of real files.
- **Verify:**
- That the body of the PUT is the **actual file buffer/stream** (e.g. from `fs.readFile` or the path reported in the artifact metadata).
- That there is no branch (e.g. env flag, test mode) that substitutes dummy text for the real file when uploading.

---

## Useful references (server-side, this repo)

- Director generic run creation and artifact instructions:
`packages/director/src/genericAPI/artifacts.ts`
`packages/director/src/genericAPI/create.run.ts` (where `processArtifacts` is used).
- Artifact creation (returns `uploadUrl` and `readUrl`):
`packages/artifact/src/createArtifact.ts`,
`packages/artifact/src/handler.ts` (`createInstanceArtifactAndCache`).
- Run response shape (e.g. `artifactUploadUrls`) is defined by the API/director contract used by the client.

---

## Request for the client-side agent

1. Locate where the generic reporter (or client) **uploads** artifact files using the `uploadUrl` from the run-creation response.
2. Confirm whether the **body of that PUT** is the real file content or a placeholder string (e.g. "dummy screenshot content").
3. If it is placeholder/mock content, change it to upload the **actual artifact file** (correct path, binary body, correct `Content-Type`) and ensure no test/local path keeps uploading dummy content for these artifacts.
Loading