Skip to content

fix(timeline): scope scripted requests to their own request#8210

Open
pooja-bruno wants to merge 2 commits into
usebruno:mainfrom
pooja-bruno:fix/timeline-request-scope-leak
Open

fix(timeline): scope scripted requests to their own request#8210
pooja-bruno wants to merge 2 commits into
usebruno:mainfrom
pooja-bruno:fix/timeline-request-scope-leak

Conversation

@pooja-bruno

@pooja-bruno pooja-bruno commented Jun 9, 2026

Copy link
Copy Markdown
Collaborator

Description

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.

  • packages/bruno-app

    • UI/Timeline: small copy changes for empty states ("No Body", "No Headers") and added test hooks (data-testid) across Timeline components (Timeline, TimelineItem, Status, Headers, Body, entryMeta). ENTRY_KINDS now include an explicit stable kind field for main/oauth/pre/post which centralizes kind identity used by UI and test IDs.
    • Impact: these changes are UI-only and introduce stable test hooks that other packages/tests rely on.
  • packages/bruno-electron

    • collection.mergeScripts: revised logic for computing requestSegmentSource.displayPath — it now derives the request pathname from request.pathname with a fallback to the last item of requestTreePath. This adjusts how relative request display paths are built for stack-trace / source attribution shown in the app.
    • Impact: affects how script source filenames/paths are displayed and therefore interacts with Timeline source-link behavior and tests that assert source filenames.
  • tests (tests/request and tests/auth)

    • Reworked many Timeline Playwright tests to use data-testid selectors (timeline-container, timeline-entry, timeline-badge-, timeline-url, timeline-chip-, timeline-status, timeline-filter-bar, timeline-detail, timeline-source-link/file, etc.) instead of CSS classes.
    • Added tests verifying scoped request attribution: when a request-level pre-request script calls bru.sendRequest, the resulting Timeline entry is attributed to the request script (not collection/folder scripts), and the source link opens the correct request script tab.
    • Updated other timeline tests to reflect changed empty-state copy and to rely on new test IDs for more robust selection.
    • Impact: test suite now depends on the new data-testids and the revised displayPath behavior from mergeScripts for accurate source assertions.

Inter-package dependencies and notes

  • Tests in the monorepo were updated to depend on the new data-testid attributes in packages/bruno-app; the ENTRY_KINDS.kind addition and displayPath adjustments in packages/bruno-electron support those UI/source assertions.
  • The change in displayPath construction (bruno-electron) is relevant to Timeline source-link text and must align with the UI changes/tests that assert exact filenames/paths.
  • Changes appear non-breaking functionally (UI copy, test hooks, test updates, and a more robust displayPath fallback) but require coordinated updates across the app and test suites — reviewers should validate source-path rendering in the UI and CI tests that assert filenames/links.

Overall risk/effort

  • Code review effort: Low–Medium (mostly small UI tweaks and test updates; one logic tweak in collection merging).
  • Recommend validating Timeline source-link behavior manually and running the updated Playwright tests to ensure the displayPath change and new test hooks behave as expected.

@coderabbitai

coderabbitai Bot commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 242d130d-f9e9-47d0-a264-5a2b2effe4b0

📥 Commits

Reviewing files that changed from the base of the PR and between 4db16eb and c8b1709.

📒 Files selected for processing (1)
  • tests/auth/auth-mode/folder-no-auth-stops-inheritance.spec.ts
✅ Files skipped from review due to trivial changes (1)
  • tests/auth/auth-mode/folder-no-auth-stops-inheritance.spec.ts

Walkthrough

Adds data-testid attributes across Timeline UI, updates empty-state texts, extends ENTRY_KINDS with stable kind IDs, refactors Timeline tests to use getByTestId selectors (and adds scoped-attribution e2e tests), and updates request pathname fallback in script merging.

Changes

Timeline Test Infrastructure

Layer / File(s) Summary
Entry metadata and status test hooks
packages/bruno-app/src/components/ResponsePane/Timeline/entryMeta.js, packages/bruno-app/src/components/ResponsePane/Timeline/TimelineItem/Common/Status/index.js
ENTRY_KINDS entries now include stable kind identifiers; Status component renders with data-testid="timeline-status".
TimelineItem component test hooks
packages/bruno-app/src/components/ResponsePane/Timeline/TimelineItem/index.js
Adds data-testid attributes to rows (timeline-entry), URLs (timeline-url), badges (timeline-badge-${kind}), details (timeline-detail), and source links (timeline-source-link, timeline-source-file).
Timeline filter bar test hooks
packages/bruno-app/src/components/ResponsePane/Timeline/index.js
Conditionally renders the filter bar and adds data-testid attributes to the filter container, chip buttons (timeline-chip-${id}), and chip counts (uses counts[chip.id] ?? 0).
Empty state message updates
packages/bruno-app/src/components/ResponsePane/Timeline/TimelineItem/Common/Body/index.js, packages/bruno-app/src/components/ResponsePane/Timeline/TimelineItem/Common/Headers/index.js
Empty-state text changed from "No X found" to "No X" for Body and Headers sections.
Test selector migration—basic entries
tests/request/timeline/timeline-url-update.spec.ts, tests/request/timeline/timeline-runrequest-network-error.spec.ts, tests/request/timeline/timeline-runrequest-skip.spec.ts
Updates simple Timeline tests to use getByTestId selectors for entry, badge, and URL assertions.
Test selector migration—nested and scripted entries
tests/request/timeline/timeline-nested-runrequest.spec.ts, tests/request/timeline/timeline-scripted-requests.spec.ts
Refactors complex Timeline tests to use data-testid selectors for badge filtering, per-badge counting, and URL verification across multiple rows and filter interactions.
New scoped request attribution test suite
tests/request/timeline/timeline-scoped-request-attribution.spec.ts
Adds two e2e tests validating that Timeline entries created by request-level sendRequest are attributed to the request script (not collection/folder scripts) and that the source link opens the correct script tab.

Request Pathname Resolution

Layer / File(s) Summary
Request pathname resolution with fallback
packages/bruno-electron/src/utils/collection.js
Updates mergeScripts to derive request pathname from request.pathname with fallback to the last requestTreePath item's pathname; uses that for requestSegmentSource.displayPath calculation.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Suggested reviewers

  • helloanoop
  • lohit-bruno
  • naman-bruno
  • sid-bruno
  • bijin-bruno
🚥 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 objective of the PR: fixing timeline to properly scope scripted requests to their originating request rather than leaking to parent scopes.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

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


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.

@coderabbitai coderabbitai Bot left a comment

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.

Actionable comments posted: 1

🧹 Nitpick comments (5)
tests/request/timeline/timeline-scoped-request-attribution.spec.ts (2)

91-91: ⚡ Quick win

Avoid .collection-item-name with .first() for request selection.

Selecting by class + positional fallback can become flaky when sidebar ordering changes; use an existing helper (like openRequest) or a stable test-id-based locator.

As per coding guidelines, “Replace brittle text/index selectors with role, label, test id, or stable user-facing selectors.”

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/request/timeline/timeline-scoped-request-attribution.spec.ts` at line
91, Replace the brittle selector that uses
page.locator('.collection-item-name').filter({ hasText: requestName
}).first().click(): instead call the existing test helper
openRequest(requestName) or switch to a stable test-id/role-based locator (e.g.,
use getByTestId('request-item') or getByRole/getByLabel with the requestName) so
selection doesn't rely on class+position; update the call referencing the
requestName variable and remove use of '.collection-item-name' and .first() to
make the test robust.

Source: Coding guidelines


66-66: ⚡ Quick win

Use a stable selector instead of .request-tab.active.

This class-based assertion is brittle under UI refactors; prefer a test-id/role-based locator for the active request tab state.

As per coding guidelines, “Replace brittle text/index selectors with role, label, test id, or stable user-facing selectors.”

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/request/timeline/timeline-scoped-request-attribution.spec.ts` at line
66, The test uses a brittle class-based selector
page.locator('.request-tab.active') to assert the active request tab; replace it
with a stable role/test-id-based locator that targets the tab by its accessible
role or a data-testid and the request label (e.g., use the tab role with the
requestName or a data-testid like request-tab combined with an active attribute)
so the assertion checks the element with role "tab" (or data-testid
"request-tab") whose name/text equals requestName and is active; update the
locator in the spec to use that stable selector instead of
'.request-tab.active'.

Source: Coding guidelines

tests/request/timeline/timeline-url-update.spec.ts (1)

59-59: ⚡ Quick win

Replace hardcoded timeout with event-driven wait.

The 200ms timeout after typing the URL should be replaced with an explicit wait for CodeMirror to process the input or for the request to be saved. Consider waiting for a stable state indicator, debounce completion, or an observable change in the request configuration.

Suggested alternatives

Option 1: Wait for CodeMirror to stabilize by checking the value:

  await page.keyboard.type(secondUrl);
- await page.waitForTimeout(200);
+ await expect(urlEditor).toContainText(secondUrl, { timeout: 1000 });

Option 2: If there's a save indicator or debounce, wait for that specific element/state.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/request/timeline/timeline-url-update.spec.ts` at line 59, Replace the
hardcoded await page.waitForTimeout(200) with an event-driven wait: detect when
CodeMirror has processed the typed URL or when the request save completes (e.g.,
wait for the CodeMirror editor's value to equal the expected URL using
page.waitForFunction or wait for a save/debounce indicator selector to
appear/disappear). Update the test in timeline-url-update.spec.ts where
page.waitForTimeout(200) is used to instead wait for the editor state or save
indicator to be stable before proceeding so the assertion uses the final,
persisted request value.
tests/request/timeline/timeline-nested-runrequest.spec.ts (1)

76-77: 💤 Low value

Consider extracting the countFor helper to a shared utility.

This inline helper appears in both this file and timeline-scripted-requests.spec.ts (line 65-66). Since the pattern is identical and used across multiple test files, consider extracting it to a shared test utility (e.g., tests/utils/page/timeline.ts) to reduce duplication.

Example extraction

In tests/utils/page/timeline.ts:

export const getTimelineChipCount = (page, chipId: string) =>
  page.getByTestId(`timeline-chip-${chipId}`).getByTestId('timeline-chip-count');

Then in tests:

import { getTimelineChipCount } from '../../utils/page/timeline';

await expect(getTimelineChipCount(page, 'all')).toHaveText('3');
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/request/timeline/timeline-nested-runrequest.spec.ts` around lines 76 -
77, Extract the duplicate inline helper `countFor` into a shared test utility
(e.g., export a function named `getTimelineChipCount(page, chipId)` in a new
module like tests/utils/page/timeline.ts) and replace the local `countFor`
definitions in both `timeline-nested-runrequest.spec.ts` and
`timeline-scripted-requests.spec.ts` with an import of `getTimelineChipCount`;
update usages (e.g., countFor(page, 'all') -> getTimelineChipCount(page, 'all'))
and add the new import statement in each test file so the helper is centralized
and reused.
tests/request/timeline/timeline-scripted-requests.spec.ts (1)

65-66: 💤 Low value

Consider extracting the countFor helper to a shared utility.

This inline helper is duplicated from timeline-nested-runrequest.spec.ts (line 76-77). Since the pattern is identical and used across multiple test files, consider extracting it to a shared test utility (e.g., tests/utils/page/timeline.ts) to reduce duplication.

Example extraction

In tests/utils/page/timeline.ts:

export const getTimelineChipCount = (page, chipId: string) =>
  page.getByTestId(`timeline-chip-${chipId}`).getByTestId('timeline-chip-count');

Then in tests:

import { getTimelineChipCount } from '../../utils/page/timeline';

await expect(getTimelineChipCount(page, 'all')).toHaveText('4');
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/request/timeline/timeline-scripted-requests.spec.ts` around lines 65 -
66, Extract the duplicated inline helper countFor from
tests/request/timeline/timeline-scripted-requests.spec.ts into a shared test
utility (e.g., export function getTimelineChipCount(page, chipId) in
tests/utils/page/timeline.ts) and replace local countFor usages with imports of
getTimelineChipCount; also update timeline-nested-runrequest.spec.ts to import
the same utility so both tests use the single exported helper (ensure the helper
returns
page.getByTestId(`timeline-chip-${chipId}`).getByTestId('timeline-chip-count')).
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@packages/bruno-app/src/components/ResponsePane/Timeline/TimelineItem/Common/Headers/index.js`:
- Line 34: Update the failing E2E assertion to match the new empty-state copy:
in the test suite "folder-no-auth-stops-inheritance"
(tests/auth/auth-mode/folder-no-auth-stops-inheritance.spec.ts) locate the
assertion that currently expects "No Headers found" and change the expected
string to "No Headers" so it matches the TimelineItem Headers component's
updated output; run the test to confirm it passes.

---

Nitpick comments:
In `@tests/request/timeline/timeline-nested-runrequest.spec.ts`:
- Around line 76-77: Extract the duplicate inline helper `countFor` into a
shared test utility (e.g., export a function named `getTimelineChipCount(page,
chipId)` in a new module like tests/utils/page/timeline.ts) and replace the
local `countFor` definitions in both `timeline-nested-runrequest.spec.ts` and
`timeline-scripted-requests.spec.ts` with an import of `getTimelineChipCount`;
update usages (e.g., countFor(page, 'all') -> getTimelineChipCount(page, 'all'))
and add the new import statement in each test file so the helper is centralized
and reused.

In `@tests/request/timeline/timeline-scoped-request-attribution.spec.ts`:
- Line 91: Replace the brittle selector that uses
page.locator('.collection-item-name').filter({ hasText: requestName
}).first().click(): instead call the existing test helper
openRequest(requestName) or switch to a stable test-id/role-based locator (e.g.,
use getByTestId('request-item') or getByRole/getByLabel with the requestName) so
selection doesn't rely on class+position; update the call referencing the
requestName variable and remove use of '.collection-item-name' and .first() to
make the test robust.
- Line 66: The test uses a brittle class-based selector
page.locator('.request-tab.active') to assert the active request tab; replace it
with a stable role/test-id-based locator that targets the tab by its accessible
role or a data-testid and the request label (e.g., use the tab role with the
requestName or a data-testid like request-tab combined with an active attribute)
so the assertion checks the element with role "tab" (or data-testid
"request-tab") whose name/text equals requestName and is active; update the
locator in the spec to use that stable selector instead of
'.request-tab.active'.

In `@tests/request/timeline/timeline-scripted-requests.spec.ts`:
- Around line 65-66: Extract the duplicated inline helper countFor from
tests/request/timeline/timeline-scripted-requests.spec.ts into a shared test
utility (e.g., export function getTimelineChipCount(page, chipId) in
tests/utils/page/timeline.ts) and replace local countFor usages with imports of
getTimelineChipCount; also update timeline-nested-runrequest.spec.ts to import
the same utility so both tests use the single exported helper (ensure the helper
returns
page.getByTestId(`timeline-chip-${chipId}`).getByTestId('timeline-chip-count')).

In `@tests/request/timeline/timeline-url-update.spec.ts`:
- Line 59: Replace the hardcoded await page.waitForTimeout(200) with an
event-driven wait: detect when CodeMirror has processed the typed URL or when
the request save completes (e.g., wait for the CodeMirror editor's value to
equal the expected URL using page.waitForFunction or wait for a save/debounce
indicator selector to appear/disappear). Update the test in
timeline-url-update.spec.ts where page.waitForTimeout(200) is used to instead
wait for the editor state or save indicator to be stable before proceeding so
the assertion uses the final, persisted request value.
🪄 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: 8413b754-f0e2-4c0c-a8be-ad48e86b5201

📥 Commits

Reviewing files that changed from the base of the PR and between 240826e and 4db16eb.

📒 Files selected for processing (13)
  • packages/bruno-app/src/components/ResponsePane/Timeline/TimelineItem/Common/Body/index.js
  • packages/bruno-app/src/components/ResponsePane/Timeline/TimelineItem/Common/Headers/index.js
  • packages/bruno-app/src/components/ResponsePane/Timeline/TimelineItem/Common/Status/index.js
  • packages/bruno-app/src/components/ResponsePane/Timeline/TimelineItem/index.js
  • packages/bruno-app/src/components/ResponsePane/Timeline/entryMeta.js
  • packages/bruno-app/src/components/ResponsePane/Timeline/index.js
  • packages/bruno-electron/src/utils/collection.js
  • tests/request/timeline/timeline-nested-runrequest.spec.ts
  • tests/request/timeline/timeline-runrequest-network-error.spec.ts
  • tests/request/timeline/timeline-runrequest-skip.spec.ts
  • tests/request/timeline/timeline-scoped-request-attribution.spec.ts
  • tests/request/timeline/timeline-scripted-requests.spec.ts
  • tests/request/timeline/timeline-url-update.spec.ts

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.

1 participant