Skip to content

fix: prevent rerun flicker and fix runner configuration list order#7639

Merged
bijin-bruno merged 1 commit intousebruno:mainfrom
gopu-bruno:bugfix/runner-config-order-and-rerun-flicker
Apr 1, 2026
Merged

fix: prevent rerun flicker and fix runner configuration list order#7639
bijin-bruno merged 1 commit intousebruno:mainfrom
gopu-bruno:bugfix/runner-config-order-and-rerun-flicker

Conversation

@gopu-bruno
Copy link
Copy Markdown
Collaborator

@gopu-bruno gopu-bruno commented Mar 31, 2026

Description

Update Run Configuration ordering to mirror sidebar behavior by sorting folders and requests consistently, and avoid transient panel flicker during Run Again by guarding empty-result rerun transitions.

Screenshots

image

  • Run Again button issue and fix
Screen.Recording.2026-03-31.at.1.55.18.PM.mov
Screen.Recording.2026-03-31.at.2.03.48.PM.mov

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

  • Bug Fixes
    • Enhanced the organization and sorting of test folders and requests during execution to provide clearer and more consistent result presentations
    • Fixed UI behavior during test reruns to prevent the "no items yet" message from appearing while rerun operations are actively in progress

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Mar 31, 2026

Walkthrough

Request-flattening logic now explicitly separates folder and request items during traversal, sorting folders by name and requests by sequence, then recursively processing each folder's contents. A ref-based flag tracks "Run Again" operations to prevent premature display of empty-state UI during reruns.

Changes

Cohort / File(s) Summary
Request Flattening Logic
packages/bruno-app/src/components/RunnerResults/RunConfigurationPanel/index.jsx
Reorganized request-flattening traversal to explicitly filter and sort folders (via isItemAFolder and sortByNameThenSequence) separately from request items (sorted by seq), then recursively process each folder's items while maintaining folderPath consistency.
Rerun State Tracking
packages/bruno-app/src/components/RunnerResults/index.jsx
Added isReRunningRef to track "Run Again" operation status; updated early-return render guard to prevent displaying "no items" UI while a rerun is in progress (`(!items

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Possibly related PRs

  • #6320: Modifies collection item traversal and flattening to distinguish folders from requests with sequence-aware ordering.
  • #7581: Updates item traversal logic with folder/request separation and applies the same sorting helpers for folder-first, sequence-aware ordering.
  • #7505: Modifies the same RunConfigurationPanel file to refine request-item selection and traversal behavior.

Suggested reviewers

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

Poem

🎀 Folders sorted, requests aligned,
Hierarchies thoughtfully designed,
Rerun's ref keeps track with care,
No false empties floating there,
Traversal's logic, crystalline! 🌟

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes both main changes: fixing rerun flicker and correcting runner configuration list ordering.

✏️ 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

🧹 Nitpick comments (1)
packages/bruno-app/src/components/RunnerResults/index.jsx (1)

169-174: Defensive status check includes unused 'cancelled' value.

Per the runFolderEvent reducer (context snippet 1), only 'started' and 'ended' statuses are set—'cancelled' is never assigned at the runner info level. The check for 'cancelled' is effectively dead code today but provides forward-compatibility if that status is added later.

The logic correctly handles the edge case where all requests are filtered out (empty items but status becomes 'ended').

📝 Optional: Add comment explaining the defensive check
   useEffect(() => {
     if (isReRunningRef.current
+      // 'cancelled' not currently set by reducer but included for future-proofing
       && (items?.length > 0 || runnerInfo?.status === 'ended' || runnerInfo?.status === 'cancelled')) {
       isReRunningRef.current = false;
     }
   }, [items, runnerInfo?.status]);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/bruno-app/src/components/RunnerResults/index.jsx` around lines 169 -
174, The useEffect block that checks isReRunningRef.current and (items?.length >
0 || runnerInfo?.status === 'ended' || runnerInfo?.status === 'cancelled')
contains a defensive check for a 'cancelled' status that isn't currently set by
the runFolderEvent reducer; add a concise inline comment above this condition
(near the useEffect and isReRunningRef usage) explaining that 'cancelled' is
included intentionally for forward-compatibility because the reducer currently
only emits 'started' and 'ended' but a future change may introduce 'cancelled',
so the branch should remain to handle filtered-out items when runs terminate.
🤖 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-app/src/components/RunnerResults/RunConfigurationPanel/index.jsx`:
- Around line 192-194: The current sort for requestItems uses a comparator (a,
b) => a.seq - b.seq which yields NaN when seq is undefined; update the
comparator used when building requestItems so it defensively handles missing seq
(similar to sortByNameThenSequence for folders) by treating undefined seq as a
large value or falling back to sequence 0 and/or comparing names when seqs are
equal; adjust the sort call in the requestItems construction (the
.filter(...).sort(...) chain where isItemARequest is used) to use a comparator
that normalizes a.seq and b.seq (e.g., coerce to finite numbers or use nullish
coalescing) and ties break deterministically.

---

Nitpick comments:
In `@packages/bruno-app/src/components/RunnerResults/index.jsx`:
- Around line 169-174: The useEffect block that checks isReRunningRef.current
and (items?.length > 0 || runnerInfo?.status === 'ended' || runnerInfo?.status
=== 'cancelled') contains a defensive check for a 'cancelled' status that isn't
currently set by the runFolderEvent reducer; add a concise inline comment above
this condition (near the useEffect and isReRunningRef usage) explaining that
'cancelled' is included intentionally for forward-compatibility because the
reducer currently only emits 'started' and 'ended' but a future change may
introduce 'cancelled', so the branch should remain to handle filtered-out items
when runs terminate.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: a728eb0c-b9e9-435f-8388-30c9de76caf8

📥 Commits

Reviewing files that changed from the base of the PR and between 4a78f63 and cc16788.

📒 Files selected for processing (2)
  • packages/bruno-app/src/components/RunnerResults/RunConfigurationPanel/index.jsx
  • packages/bruno-app/src/components/RunnerResults/index.jsx

Comment on lines +192 to +194
const requestItems = items
.filter((item) => isItemARequest(item) && !item.partial && !item.isTransient)
.sort((a, b) => a.seq - b.seq);
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot Mar 31, 2026

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Check if there are request items in the codebase that might lack a seq property
# Search for item creation patterns that might not set seq
rg -n --type=js --type=jsx -C3 'type:\s*["\x27](http-request|graphql-request)["\x27]' | head -100

Repository: usebruno/bruno

Length of output: 85


🏁 Script executed:

cd packages/bruno-app/src/components/RunnerResults/RunConfigurationPanel && wc -l index.jsx

Repository: usebruno/bruno

Length of output: 71


🏁 Script executed:

cd packages/bruno-app/src/components/RunnerResults/RunConfigurationPanel && sed -n '185,215p' index.jsx

Repository: usebruno/bruno

Length of output: 1013


🏁 Script executed:

rg -n --type=js -C3 '"http-request"|"graphql-request"' packages/bruno-app --max-count=20

Repository: usebruno/bruno

Length of output: 3171


🏁 Script executed:

rg -n 'seq.*=' packages/bruno-app/src --type=js --type=ts -A2 | grep -E '(seq|new.*Request|createItem)' | head -40

Repository: usebruno/bruno

Length of output: 4801


🏁 Script executed:

rg -n "sortByNameThenSequence" packages/bruno-app/src --type=js --type=ts -A5 | head -50

Repository: usebruno/bruno

Length of output: 5794


🏁 Script executed:

rg -n "const isSeqValid|isSeqValid" packages/bruno-app/src/utils/common/index.js -A2 -B2

Repository: usebruno/bruno

Length of output: 607


🏁 Script executed:

rg -n "sortItemsBySequence" packages/bruno-app/src --type=js -A5 | head -40

Repository: usebruno/bruno

Length of output: 3021


🏁 Script executed:

rg -n "isItemARequest" packages/bruno-app/src/utils --type=js -B2 -A5 | head -50

Repository: usebruno/bruno

Length of output: 4361


Use defensive sort for request items to handle potentially undefined seq.

The sort comparator (a, b) => a.seq - b.seq returns NaN when either seq is undefined, leading to non-deterministic ordering. While sortByNameThenSequence (used for folders) validates seq explicitly, this direct sort does not. The importer logic shows seq can be missing in imported/legacy items and is conditionally assigned during hydration. Apply the defensive fix to align with folder handling:

       const requestItems = items
         .filter((item) => isItemARequest(item) && !item.partial && !item.isTransient)
-        .sort((a, b) => a.seq - b.seq);
+        .sort((a, b) => (a.seq ?? Infinity) - (b.seq ?? Infinity));
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@packages/bruno-app/src/components/RunnerResults/RunConfigurationPanel/index.jsx`
around lines 192 - 194, The current sort for requestItems uses a comparator (a,
b) => a.seq - b.seq which yields NaN when seq is undefined; update the
comparator used when building requestItems so it defensively handles missing seq
(similar to sortByNameThenSequence for folders) by treating undefined seq as a
large value or falling back to sequence 0 and/or comparing names when seqs are
equal; adjust the sort call in the requestItems construction (the
.filter(...).sort(...) chain where isItemARequest is used) to use a comparator
that normalizes a.seq and b.seq (e.g., coerce to finite numbers or use nullish
coalescing) and ties break deterministically.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

The requestItems here is from redux store which is populated from parsed files. All the existing parsers already default missing seq fields (.bru → Number(sequence) || 1, .yml → info?.seq || 1) . Also, the sidebar component already uses the same (a, b) => a.seq - b.seq sorting logic without issues.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

@gopu-bruno, that's a fair point — since all items flow through the parsers before reaching the Redux store and both the .bru and .yml parsers guarantee a numeric fallback for seq, the undefined scenario I flagged won't occur in practice. The consistency with the sidebar's existing sort also confirms this is the right approach. Thanks for the clarification!


✏️ Learnings added
Learnt from: gopu-bruno
Repo: usebruno/bruno PR: 7639
File: packages/bruno-app/src/components/RunnerResults/RunConfigurationPanel/index.jsx:192-194
Timestamp: 2026-04-01T08:12:04.363Z
Learning: In Bruno's RunConfigurationPanel (`packages/bruno-app/src/components/RunnerResults/RunConfigurationPanel/index.jsx`), the sort comparator `(a, b) => a.seq - b.seq` used for request items is safe without a defensive `?? Infinity` guard. All request items in the Redux store are populated via parsers (`.bru` uses `Number(sequence) || 1`, `.yml` uses `info?.seq || 1`) which always assign a numeric default for `seq`. The sidebar component uses the identical comparator without issues.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.


🧠 Learnings used
Learnt from: sanish-bruno
Repo: usebruno/bruno PR: 6890
File: packages/bruno-electron/src/ipc/network/index.js:770-776
Timestamp: 2026-01-22T19:44:28.678Z
Learning: In Bruno's Electron IPC network handler (packages/bruno-electron/src/ipc/network/index.js), runner control signals from hooks (`skipRequest`, `nextRequestName`, `stopExecution`) are only relevant and handled in the `run-collection-folder` IPC event for collection/folder runs. For standalone request execution via `send-http-request` handler, these signals are intentionally not processed since they don't apply to single request runs where the user explicitly triggered one request.

Learnt from: abhishek-bruno
Repo: usebruno/bruno PR: 7483
File: packages/bruno-electron/src/ipc/openapi-sync.js:540-546
Timestamp: 2026-03-13T19:40:22.222Z
Learning: In `packages/bruno-electron/src/ipc/openapi-sync.js`, `compareRequestFields()` intentionally uses case-sensitive header name comparison. Both `specItem.request` and `actualRequest` originate from the same `openApiToBruno()` converter (for spec-vs-spec and spec-vs-disk comparisons), so casing is always consistent. A case difference can only arise from a manual user edit to a `.bru` file, which is a real collection change that drift detection should surface. Do not suggest normalizing header names to lowercase in this function.

@bijin-bruno bijin-bruno merged commit bcc1b53 into usebruno:main Apr 1, 2026
11 of 12 checks passed
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.

3 participants