Skip to content

fix: add size and duration fields to CLI bru.runRequest() response#7429

Merged
bijin-bruno merged 3 commits intousebruno:mainfrom
chirag-bruno:fix/cli-runrequest-response-consistency
Apr 2, 2026
Merged

fix: add size and duration fields to CLI bru.runRequest() response#7429
bijin-bruno merged 3 commits intousebruno:mainfrom
chirag-bruno:fix/cli-runrequest-response-consistency

Conversation

@chirag-bruno
Copy link
Copy Markdown
Collaborator

@chirag-bruno chirag-bruno commented Mar 10, 2026

Description

Add size and duration fields to the response object in CLI to match GUI behavior, ensuring consistent API for bru.runRequest() across both environments.

  • duration is an alias for responseTime for GUI compatibility
  • size is the byte length of the response buffer (0 for errors/skipped)

Fixes #7352
JIRA

Contribution Checklist:

  • I've used AI significantly to create this pull request
  • The pull request only addresses one issue or adds one feature.
  • The pull request does not introduce any breaking changes
  • I have added screenshots or gifs to help explain the change if applicable.
  • I have read the contribution guidelines.
  • Create an issue and link to the pull request.

Note: Keeping the PR small and focused helps make it easier to review and merge. If you have multiple changes you want to make, please consider submitting them as separate pull requests.

Publishing to New Package Managers

Please see here for more information.

Summary by CodeRabbit

  • New Features

    • Request results now include duration and size metrics alongside response time for improved performance insight.
  • Bug Fixes

    • Metrics reliably default to 0 for skipped or failed requests; response time is normalized from headers when available and used to populate duration.
  • Tests

    • Added tests validating duration, size, and responseTime behavior for skipped, successful, and error scenarios.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Mar 10, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 1ec1e1aa-28b2-4735-b5ec-027929d0acff

📥 Commits

Reviewing files that changed from the base of the PR and between b3ccd79 and 0a4b14f.

📒 Files selected for processing (1)
  • packages/bruno-cli/tests/runner/response-fields.spec.js
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/bruno-cli/tests/runner/response-fields.spec.js

Walkthrough

Adds duration and size fields to CLI request results, normalizes parsing of the request-duration header into a numeric responseTime, ensures responseTime, duration, and size are populated consistently across skipped, success, and error branches, and computes size from response.dataBuffer when present.

Changes

Cohort / File(s) Summary
CLI request runner
packages/bruno-cli/src/runner/run-single-request.js
Expanded response shape to always include duration and size; normalized request-duration header parsing to a numeric responseTime (default 0); set duration = responseTime on success; compute size from Buffer.byteLength(response.dataBuffer) when available; ensured early-return/error branches set numeric 0s.
Tests — response fields
packages/bruno-cli/tests/runner/response-fields.spec.js
New Jest test suite exercising skipped, successful, and error flows for response.responseTime, response.duration, and response.size; adds extensive mocks to isolate runner behavior.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Suggested reviewers

  • helloanoop
  • lohit-bruno
  • naman-bruno
  • bijin-bruno

Poem

✨ Bytes and time in tidy rows align,
CLI and GUI now sing the same line.
Headers parsed, sizes counted true,
Results reconciled — concise and new. 🎉

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: adding size and duration fields to the CLI bru.runRequest() response object.
Linked Issues check ✅ Passed The PR successfully implements all requirements from issue #7352: adds size field (as Buffer.byteLength) and duration field (as alias for responseTime) to CLI response, achieving GUI/CLI parity.
Out of Scope Changes check ✅ Passed All changes are directly scoped to the linked objective: response field additions in run-single-request.js and corresponding test coverage in response-fields.spec.js.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@packages/bruno-cli/src/runner/run-single-request.js`:
- Around line 968-970: The duration field is sometimes a string because
responseTime is read from response.headers.get('request-duration'); coerce it to
a numeric type before assigning to the result object (where duration is
currently set alongside responseTime and size) so arithmetic works downstream.
Update the code that reads and assigns responseTime (the variable named
responseTime from response.headers.get(...)) to parse/Number-coerce it (with a
fallback of 0) and then use that numeric value for both responseTime and
duration in the object being returned/recorded.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 8c62a001-dbcf-4b30-b8ab-e4fcde3196d7

📥 Commits

Reviewing files that changed from the base of the PR and between f123a2b and 288c995.

📒 Files selected for processing (1)
  • packages/bruno-cli/src/runner/run-single-request.js

Comment thread packages/bruno-cli/src/runner/run-single-request.js
Copy link
Copy Markdown
Collaborator

@sanish-bruno sanish-bruno left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PR Review

Found 1 issue(s): 0 major, 0 minor, 1 suggestion.

Summary

  • All 6 response object locations are consistently updated with duration and size — no missed spots.
  • size calculation using Buffer.byteLength(response.dataBuffer) matches the GUI implementation.
  • The dataBuffer guard (response.dataBuffer ? ... : 0) is safe since parseDataFromResponse always returns a Buffer, but it's fine as defensive code.
  • One semantic note about duration vs responseTime — see inline comment.

url: response.request ? response.request.protocol + '//' + response.request.host + response.request.path : null,
responseTime
responseTime,
duration: responseTime,
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion: In the GUI (bruno-electron/src/ipc/network/index.js), duration and responseTime are actually different values:

  • duration = timeEnd - timeStart (wall-clock elapsed time measured around the axios call)
  • responseTime = from the custom request-duration header injected by the axios interceptor

Setting duration: responseTime here makes them identical in the CLI, which is a reasonable approximation since the CLI doesn't have the same timeStart/timeEnd timing wrapper. But it might be worth adding a brief comment so future readers understand this is intentional:

// In the GUI, duration is wall-clock time (timeEnd - timeStart).
// In the CLI we use responseTime as a close approximation.
duration: responseTime,

This also means scripts using bru.runRequest() will see identical duration and responseTime values in the CLI but potentially different values in the GUI. Probably fine for most use cases, but worth documenting.

@sanish-bruno
Copy link
Copy Markdown
Collaborator

@chirag-bruno can we have test cases to verify this?

cchirag added 2 commits April 2, 2026 12:13
Add `size` and `duration` fields to the response object in CLI to match
GUI behavior, ensuring consistent API for bru.runRequest() across both
environments.

- `duration` is an alias for `responseTime` for GUI compatibility
- `size` is the byte length of the response buffer (0 for errors/skipped)

Fixes usebruno#7352
- Coerce responseTime header to number (was string from headers.get())
- Add comment explaining duration vs responseTime difference between
  GUI (wall-clock) and CLI (approximation using responseTime)
- Add integration tests for duration/size fields across skipped,
  success, and network error response paths
@chirag-bruno chirag-bruno force-pushed the fix/cli-runrequest-response-consistency branch from 288c995 to b3ccd79 Compare April 2, 2026 06:43
@pull-request-size pull-request-size Bot added size/L and removed size/S labels Apr 2, 2026
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
packages/bruno-cli/tests/runner/response-fields.spec.js (1)

138-140: Remove the unused mockHeaders variable and its self-recursive delete override.

The mockHeaders variable (lines 138–139) is dead code and is never used in the test. The self-recursive delete function is also a footgun that would cause infinite recursion if called. The proper headers object below already provides the correct mock.

Suggested cleanup
   it('should return numeric duration and size on successful request', async () => {
     const responseBody = JSON.stringify({ message: 'ok' });
-    const mockHeaders = new Map([['request-duration', '253']]);
-    mockHeaders.delete = function (key) { this.delete(key); };
     // Use a plain object with get/delete to simulate axios headers
     const headers = {
       get: (key) => key === 'request-duration' ? '253' : null,
       delete: jest.fn()
     };
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/bruno-cli/tests/runner/response-fields.spec.js` around lines 138 -
140, Remove the unused mockHeaders declaration and its self-recursive delete
override in the test: delete the lines that define const mockHeaders = new
Map([...]) and the mockHeaders.delete = function (key) { this.delete(key); }; so
the test relies on the existing headers object that already provides the proper
get/delete behavior; ensure no references to mockHeaders remain and run tests to
confirm nothing else uses that variable.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@packages/bruno-cli/tests/runner/response-fields.spec.js`:
- Around line 138-140: Remove the unused mockHeaders declaration and its
self-recursive delete override in the test: delete the lines that define const
mockHeaders = new Map([...]) and the mockHeaders.delete = function (key) {
this.delete(key); }; so the test relies on the existing headers object that
already provides the proper get/delete behavior; ensure no references to
mockHeaders remain and run tests to confirm nothing else uses that variable.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 1d1c1297-3e72-43f6-8cfc-58865f8249cc

📥 Commits

Reviewing files that changed from the base of the PR and between 288c995 and b3ccd79.

📒 Files selected for processing (2)
  • packages/bruno-cli/src/runner/run-single-request.js
  • packages/bruno-cli/tests/runner/response-fields.spec.js
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/bruno-cli/src/runner/run-single-request.js

The success path calls setupProxyAgents which was missing from the
proxy-util mock, causing CI failure.
Copy link
Copy Markdown
Collaborator

@sanish-bruno sanish-bruno left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PR Review

Found 1 issue(s): 0 major, 0 minor, 1 nit.

Summary

  • Production code changes are clean and correct — all 6 return paths consistently include duration and size fields
  • Good fix coercing request-duration header from string to number with Number(...) || 0
  • duration as an alias for responseTime in CLI is a reasonable approximation (documented with a comment)
  • Buffer.byteLength(response.dataBuffer) is the correct way to compute response size
  • Test coverage hits the three key paths (skipped, success, error)

prepareRequest.mockResolvedValue({
method: 'GET',
url: 'http://example.com/api',
headers: {},
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: Dead code — mockHeaders Map is created but never used (the plain headers object on line 153 is what gets passed to the mock response).

Also, the delete override on line 150 would cause infinite recursion if called (this.delete(key) calls itself since this.delete was just replaced).

Suggested fix: remove lines 149-150.

// Remove these two lines:
const mockHeaders = new Map([['request-duration', '253']]);
mockHeaders.delete = function (key) { this.delete(key); };

@bijin-bruno bijin-bruno merged commit 765c9f1 into usebruno:main Apr 2, 2026
12 checks passed
@coderabbitai coderabbitai Bot mentioned this pull request Apr 2, 2026
6 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Result object of bru.runRequest() is inconsistent between GUI and CLI

4 participants