feat: add preserve scripts option for Postman import/export#8726
feat: add preserve scripts option for Postman import/export#8726gopu-bruno wants to merge 7 commits into
Conversation
WalkthroughPostman import and export now support optional script preservation. Exporting uses a dedicated modal and Electron file-writing IPC, while importing propagates the option through UI, IPC, and conversion layers. Tests cover translation, round trips, validation, overwrite, and rename flows. ChangesPostman preservation and export
Estimated code review effort: 4 (Complex) | ~60 minutes Sequence Diagram(s)sequenceDiagram
participant User
participant ShareCollection
participant ExportToPostman
participant Converter
participant ElectronIPC
User->>ShareCollection: select Postman and proceed
ShareCollection->>ExportToPostman: show export modal
User->>ExportToPostman: submit filename, location, and options
ExportToPostman->>Converter: generate Postman JSON
ExportToPostman->>ElectronIPC: write JSON with overwrite policy
ElectronIPC-->>ExportToPostman: return success or conflict
ExportToPostman-->>User: show export or replace result
Possibly related PRs
Suggested reviewers: Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (5)
tests/import/postman/import-preserve-scripts.spec.ts (1)
23-32: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winRoute these test IDs through the page module. The spec inlines
page.getByTestId('preserve-scripts-toggle')andpage.getByTestId('show-advanced-options-toggle'), yetlocators.import.preserveScriptsToggle()andlocators.import.advancedOptionsToggle()already exist (seetests/utils/page/actions.tsL517-519). Reuse them so the spec only consumes locator groups.As per path instructions: "do not inline
page.locator(...)/page.getByTestId(...)in specs; keep locators and interaction helpers intests/utils/page/*".♻️ Suggested change
await test.step('Checkbox is hidden until Advanced Options is shown', async () => { - await expect(page.getByTestId('preserve-scripts-toggle')).toHaveCount(0); + await expect(locators.import.preserveScriptsToggle()).toHaveCount(0); }); await test.step('Advanced Options toggle reveals the Preserve scripts checkbox', async () => { const locationModal = locators.import.locationModal(); await locationModal.getByRole('button', { name: 'Options' }).click(); - await page.getByTestId('show-advanced-options-toggle').click(); - await expect(page.getByTestId('preserve-scripts-toggle')).toBeVisible(); + await locators.import.advancedOptionsToggle().click(); + await expect(locators.import.preserveScriptsToggle()).toBeVisible(); });🤖 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/import/postman/import-preserve-scripts.spec.ts` around lines 23 - 32, Replace the inline page.getByTestId calls in the “Checkbox is hidden until Advanced Options is shown” and “Advanced Options toggle reveals the Preserve scripts checkbox” steps with the existing locators.import.preserveScriptsToggle() and locators.import.advancedOptionsToggle() helpers. Keep the test interactions and assertions unchanged while routing all locator access through the page module.Source: Path instructions
tests/export/postman/export-preserve-scripts.spec.ts (1)
1-145: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winTerminate new TypeScript statements with semicolons.
tests/export/postman/export-preserve-scripts.spec.ts#L1-L145: add semicolons throughout the new spec.tests/import/postman/import-file-format-options.spec.ts#L34-L34: terminate the click statement.tests/import/postman/import-file-format-options.spec.ts#L52-L54: terminate the new declarations and assertions.As per coding guidelines, TypeScript statements must end with semicolons.
🤖 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/export/postman/export-preserve-scripts.spec.ts` around lines 1 - 145, Terminate all new TypeScript statements with semicolons in tests/export/postman/export-preserve-scripts.spec.ts, including declarations, calls, assertions, and test blocks. Also add semicolons to the click statement at tests/import/postman/import-file-format-options.spec.ts:34 and to the new declarations and assertions at lines 52-54; make no other changes.Source: Coding guidelines
tests/utils/page/locators.ts (1)
309-317: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winCentralize the new export and advanced-option selectors.
tests/utils/page/locators.ts#L309-L317: add modal-scoped conflict and validation-message locators toexport.tests/export/postman/export-preserve-scripts.spec.ts#L63-L64: use centralized conflict locators.tests/export/postman/export-preserve-scripts.spec.ts#L89-L90: use centralized required-field error locators.tests/export/postman/export-preserve-scripts.spec.ts#L107-L107: use a centralized invalid-name error locator.tests/export/postman/export-preserve-scripts.spec.ts#L127-L134: use centralized conflict and export-button locators.tests/import/postman/import-file-format-options.spec.ts#L34-L34: uselocators.import.advancedOptionsToggle().tests/import/postman/import-file-format-options.spec.ts#L52-L54: uselocators.import.advancedOptionsToggle().As per path instructions, specs must not inline raw selectors and new UI controls belong in
tests/utils/page/*.🤖 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/utils/page/locators.ts` around lines 309 - 317, Centralize the export modal conflict, validation-message, and export-button selectors in the export section of tests/utils/page/locators.ts, alongside postmanModal and the existing advanced-option locators. Update tests/export/postman/export-preserve-scripts.spec.ts at lines 63-64, 89-90, 107, and 127-134 to use those centralized locators instead of inline selectors. Update tests/import/postman/import-file-format-options.spec.ts at lines 34 and 52-54 to use locators.import.advancedOptionsToggle().Source: Path instructions
packages/bruno-app/src/components/Sidebar/Collections/Collection/ExportCollection/ExportToPostman/index.js (1)
97-106: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winDuplicated Advanced-Options dropdown pattern; consider extracting + dropping
forwardRef.This inline
AdvancedOptionsforwardRefcomponent mirrors nearly identical implementations inCreateCollection/index.jsandImportCollectionLocation/index.js(state + dropdown button + caret icon). Since the codebase is on React 19,forwardRefis no longer needed —refcan be received as a plain prop — and a shared<OptionsDropdownButton>component would remove the triplicated boilerplate across all three files.♻️ Example modernization (React 19 ref-as-prop)
- const AdvancedOptions = forwardRef((props, ref) => { - return ( - <div ref={ref} className="flex items-center text-link cursor-pointer"> - <button className="btn-advanced" type="button"> - Options - </button> - <IconCaretDown className="caret ml-1" size={14} strokeWidth={2} /> - </div> - ); - }); + const AdvancedOptions = ({ ref }) => ( + <div ref={ref} className="flex items-center text-link cursor-pointer"> + <button className="btn-advanced" type="button"> + Options + </button> + <IconCaretDown className="caret ml-1" size={14} strokeWidth={2} /> + </div> + );Based on React 19 release notes, "In React 19, forwardRef is no longer necessary. Pass ref as a prop instead."
🤖 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 `@packages/bruno-app/src/components/Sidebar/Collections/Collection/ExportCollection/ExportToPostman/index.js` around lines 97 - 106, Extract the duplicated AdvancedOptions dropdown markup from ExportToPostman, CreateCollection, and ImportCollectionLocation into a shared OptionsDropdownButton component. Replace each forwardRef wrapper with React 19 ref-as-a-prop handling, preserving the existing button styling, Options label, caret icon, and dropdown behavior.packages/bruno-app/src/components/Sidebar/Collections/Collection/ExportCollection/ExportToPostman/StyledWrapper.js (1)
19-27: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winDuplicate "checkbox option label/description" CSS added under two different class names. Both new blocks style the identical pattern (font-weight 500 label; 0.75rem subtext-colored description with top margin) but were named independently, so future style tweaks need to be applied twice.
packages/bruno-app/src/components/Sidebar/Collections/Collection/ExportCollection/ExportToPostman/StyledWrapper.js#L19-L27: rename.preserve-scripts-label/.preserve-scripts-description(and the matching JSX classNames in this modal'sindex.js) to the more generic.checkbox-option-label/.checkbox-option-descriptionalready used elsewhere, and drop this duplicate block.packages/bruno-app/src/components/Sidebar/ImportCollectionLocation/StyledWrapper.js#L25-L33: keep.checkbox-option-label/.checkbox-option-descriptionas the single shared definition that the Postman export modal now reuses.🤖 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 `@packages/bruno-app/src/components/Sidebar/Collections/Collection/ExportCollection/ExportToPostman/StyledWrapper.js` around lines 19 - 27, The checkbox label and description styles are duplicated under modal-specific class names. In packages/bruno-app/src/components/Sidebar/Collections/Collection/ExportCollection/ExportToPostman/StyledWrapper.js lines 19-27, remove the duplicate preserve-scripts styles; update the matching JSX classNames in that modal’s index.js to use checkbox-option-label and checkbox-option-description. In packages/bruno-app/src/components/Sidebar/ImportCollectionLocation/StyledWrapper.js lines 25-33, keep the existing shared definitions unchanged.
🤖 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/Sidebar/Collections/Collection/ExportCollection/ExportToPostman/index.js`:
- Around line 61-68: Update the catch handling in the ExportToPostman export
flow to detect file-exists failures using a structured backend error code or
flag rather than matching error.message text. When overwrite is disabled and
that structured indicator is present, keep calling formik.setFieldError with
FILE_EXISTS_ERROR and return; leave other errors on the existing generic
handling path.
---
Nitpick comments:
In
`@packages/bruno-app/src/components/Sidebar/Collections/Collection/ExportCollection/ExportToPostman/index.js`:
- Around line 97-106: Extract the duplicated AdvancedOptions dropdown markup
from ExportToPostman, CreateCollection, and ImportCollectionLocation into a
shared OptionsDropdownButton component. Replace each forwardRef wrapper with
React 19 ref-as-a-prop handling, preserving the existing button styling, Options
label, caret icon, and dropdown behavior.
In
`@packages/bruno-app/src/components/Sidebar/Collections/Collection/ExportCollection/ExportToPostman/StyledWrapper.js`:
- Around line 19-27: The checkbox label and description styles are duplicated
under modal-specific class names. In
packages/bruno-app/src/components/Sidebar/Collections/Collection/ExportCollection/ExportToPostman/StyledWrapper.js
lines 19-27, remove the duplicate preserve-scripts styles; update the matching
JSX classNames in that modal’s index.js to use checkbox-option-label and
checkbox-option-description. In
packages/bruno-app/src/components/Sidebar/ImportCollectionLocation/StyledWrapper.js
lines 25-33, keep the existing shared definitions unchanged.
In `@tests/export/postman/export-preserve-scripts.spec.ts`:
- Around line 1-145: Terminate all new TypeScript statements with semicolons in
tests/export/postman/export-preserve-scripts.spec.ts, including declarations,
calls, assertions, and test blocks. Also add semicolons to the click statement
at tests/import/postman/import-file-format-options.spec.ts:34 and to the new
declarations and assertions at lines 52-54; make no other changes.
In `@tests/import/postman/import-preserve-scripts.spec.ts`:
- Around line 23-32: Replace the inline page.getByTestId calls in the “Checkbox
is hidden until Advanced Options is shown” and “Advanced Options toggle reveals
the Preserve scripts checkbox” steps with the existing
locators.import.preserveScriptsToggle() and
locators.import.advancedOptionsToggle() helpers. Keep the test interactions and
assertions unchanged while routing all locator access through the page module.
In `@tests/utils/page/locators.ts`:
- Around line 309-317: Centralize the export modal conflict, validation-message,
and export-button selectors in the export section of
tests/utils/page/locators.ts, alongside postmanModal and the existing
advanced-option locators. Update
tests/export/postman/export-preserve-scripts.spec.ts at lines 63-64, 89-90, 107,
and 127-134 to use those centralized locators instead of inline selectors.
Update tests/import/postman/import-file-format-options.spec.ts at lines 34 and
52-54 to use locators.import.advancedOptionsToggle().
🪄 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: b2561b53-a6c4-4982-83b9-c00e1aa41990
📒 Files selected for processing (22)
packages/bruno-app/src/components/ShareCollection/index.jspackages/bruno-app/src/components/Sidebar/Collections/Collection/ExportCollection/ExportToPostman/StyledWrapper.jspackages/bruno-app/src/components/Sidebar/Collections/Collection/ExportCollection/ExportToPostman/index.jspackages/bruno-app/src/components/Sidebar/CreateCollection/index.jspackages/bruno-app/src/components/Sidebar/ImportCollectionLocation/StyledWrapper.jspackages/bruno-app/src/components/Sidebar/ImportCollectionLocation/index.jspackages/bruno-app/src/providers/ReduxStore/slices/collections/actions.jspackages/bruno-app/src/utils/exporters/postman-collection.jspackages/bruno-app/src/utils/importers/postman-collection.jspackages/bruno-converters/src/postman/bruno-to-postman.jspackages/bruno-converters/src/postman/postman-to-bruno.jspackages/bruno-converters/tests/postman/preserve-scripts.spec.jspackages/bruno-electron/src/ipc/collection.jstests/export/postman/export-preserve-scripts.spec.tstests/export/postman/fixtures/collection/bruno.jsontests/export/postman/fixtures/collection/login.brutests/export/postman/init-user-data/preferences.jsontests/import/postman/fixtures/postman-with-scripts.jsontests/import/postman/import-file-format-options.spec.tstests/import/postman/import-preserve-scripts.spec.tstests/utils/page/actions.tstests/utils/page/locators.ts
|
|
||
| if (i.event) { | ||
| if (useWorkers) { | ||
| if (useWorkers && !preserveScripts) { |
There was a problem hiding this comment.
This check seems to be redundant at 2 more places. If these methods are not called seperately and depend on each other, can you see if we can commpute the boolean value once and use that across ?
utkarsh-bruno
left a comment
There was a problem hiding this comment.
Check the comment once, the rest of the PR looks fine. If it needs to be computed at multiple places and resolve the comment.
Description
Adds support for preserving Postman scripts during import and export instead of translating them into Bruno scripts.
Introduce an optional preserve scripts mode that skips script translation while continuing to convert the rest of the collection collection structure, requests, variables, and settings.
Ref: BRU-2573
When enabled:
Screen Recording
Screen.Recording.2026-07-17.at.1.10.38.PM.mov
Screen.Recording.2026-07-17.at.1.11.45.PM.mov
Contribution Checklist:
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
Bug Fixes