From eca062eddd146848ca7ae91fff9b39a303ff9637 Mon Sep 17 00:00:00 2001 From: Sharan Date: Wed, 24 Jun 2026 19:01:00 +0530 Subject: [PATCH 1/3] feat(import): set yml as a default file formal accross all type of imports --- .../BulkImportCollectionLocation/index.js | 4 +- packages/bruno-cli/src/utils/collection.js | 4 +- .../yml-as-default-file-format.spec.ts | 67 +++++++++++++++++++ tests/utils/page/locators.ts | 4 ++ 4 files changed, 76 insertions(+), 3 deletions(-) create mode 100644 tests/import/bulk-import/yml-as-default-file-format.spec.ts diff --git a/packages/bruno-app/src/components/Sidebar/BulkImportCollectionLocation/index.js b/packages/bruno-app/src/components/Sidebar/BulkImportCollectionLocation/index.js index f4f051637ad..d10dc835ee9 100644 --- a/packages/bruno-app/src/components/Sidebar/BulkImportCollectionLocation/index.js +++ b/packages/bruno-app/src/components/Sidebar/BulkImportCollectionLocation/index.js @@ -154,7 +154,7 @@ export const BulkImportCollectionLocation = ({ const [applyToGlobal, setApplyToGlobal] = useState(true); const [applyToCollection, setApplyToCollection] = useState(false); const [groupingType, setGroupingType] = useState('tags'); - const [collectionFormat, setCollectionFormat] = useState('bru'); + const [collectionFormat, setCollectionFormat] = useState('yml'); const [renamedCollectionNames, setRenamedCollectionNames] = useState({}); const [renamedEnvironmentNames, setRenamedEnvironmentNames] = useState({}); const [importIssues, setImportIssues] = useState({}); @@ -585,6 +585,7 @@ export const BulkImportCollectionLocation = ({ setCollectionFormat(e.target.value)} diff --git a/packages/bruno-cli/src/utils/collection.js b/packages/bruno-cli/src/utils/collection.js index c9d5fbb1e13..446db4654e0 100644 --- a/packages/bruno-cli/src/utils/collection.js +++ b/packages/bruno-cli/src/utils/collection.js @@ -539,7 +539,7 @@ const safeWriteFileSync = (filePath, content) => { * @param {string} dirPath - The output directory path */ const createCollectionFromBrunoObject = async (collection, dirPath, options = {}) => { - const { format = 'bru' } = options; + const { format = 'yml' } = options; // Create brunoConfig for yml format const brunoConfig = { version: '1', @@ -595,7 +595,7 @@ const createCollectionFromBrunoObject = async (collection, dirPath, options = {} * @param {"bru"|"yml"} options.format - Current directory path */ const processCollectionItems = async (items = [], currentPath, options = {}) => { - const { format = 'bru' } = options; + const { format = 'yml' } = options; for (const item of items) { if (item.type === 'folder') { // Create folder diff --git a/tests/import/bulk-import/yml-as-default-file-format.spec.ts b/tests/import/bulk-import/yml-as-default-file-format.spec.ts new file mode 100644 index 00000000000..03ff4d38cf0 --- /dev/null +++ b/tests/import/bulk-import/yml-as-default-file-format.spec.ts @@ -0,0 +1,67 @@ +import { test, expect } from '../../../playwright'; +import * as path from 'path'; +import * as fs from 'fs'; +import { closeAllCollections } from '../../utils/page'; +import { buildCommonLocators } from '../../utils/page/locators'; + +test.describe('Bulk Import default file format', () => { + const testDataDir = path.join(__dirname, '../test-data'); + + test.afterEach(async ({ page }) => { + await closeAllCollections(page); + }); + + const openBulkImportModal = async (page) => { + const locators = buildCommonLocators(page); + const postmanFile = path.join(testDataDir, 'sample-postman.json'); + const insomniaFile = path.join(testDataDir, 'sample-insomnia.json'); + + await locators.plusMenu.button().click(); + await locators.plusMenu.importCollection().click(); + await expect(locators.import.modal()).toBeVisible(); + + await locators.import.fileInput().setInputFiles([postmanFile, insomniaFile]); + + const bulkModal = locators.import.bulkModal(); + await expect(bulkModal).toBeVisible(); + return locators; + }; + + test('File Format selector defaults to OpenCollection (YAML)', async ({ page }) => { + const locators = await openBulkImportModal(page); + + const formatSelect = locators.import.bulkFormatSelect(); + await expect(formatSelect).toBeVisible(); + await expect(formatSelect).toHaveValue('yml'); + await expect(formatSelect.locator('option')).toHaveText(['OpenCollection (YAML)', 'BRU Format (.bru)']); + }); + + test('importing with the default format writes opencollection.yml collections', async ({ page, createTmpDir }) => { + const locators = await openBulkImportModal(page); + + await expect(locators.import.bulkFormatSelect()).toHaveValue('yml'); + + const importDir = await createTmpDir('bulk-import-default-format'); + await locators.import.bulkLocationInput().fill(importDir); + + await expect(locators.import.bulkSubmitButton()).toHaveText('Import'); + await locators.import.bulkSubmitButton().click(); + + await expect(locators.import.bulkSubmitButton()).toHaveText('Close'); + await locators.import.bulkSubmitButton().click(); + await expect(locators.import.bulkModal()).toBeHidden(); + + const collectionDirs = fs + .readdirSync(importDir, { withFileTypes: true }) + .filter((entry) => entry.isDirectory()) + .map((entry) => path.join(importDir, entry.name)); + + expect(collectionDirs.length).toBeGreaterThan(0); + + for (const dir of collectionDirs) { + const files = fs.readdirSync(dir); + expect(files).toContain('opencollection.yml'); + expect(files).not.toContain('bruno.json'); + } + }); +}); diff --git a/tests/utils/page/locators.ts b/tests/utils/page/locators.ts index 04f682caa1f..0b49b801b30 100644 --- a/tests/utils/page/locators.ts +++ b/tests/utils/page/locators.ts @@ -214,6 +214,10 @@ export const buildCommonLocators = (page: Page) => ({ locationModal: () => page.locator('[data-testid="import-collection-location-modal"]'), locationInput: () => page.locator('#collection-location'), fileInput: () => page.locator('input[type="file"]'), + bulkModal: () => page.getByTestId('bulk-import-collection-location-modal'), + bulkFormatSelect: () => page.getByTestId('bulk-import-collection-location-modal').getByTestId('collection-format-selector'), + bulkLocationInput: () => page.getByTestId('bulk-import-collection-location-modal').locator('#collection-location'), + bulkSubmitButton: () => page.getByTestId('bulk-import-collection-location-modal-submit-btn'), envOption: (name: string) => page.locator('.dropdown-item').getByText(name, { exact: true }), parsingError: () => page.getByTestId('import-error-message'), browseLink: (root?: Locator) => (root ?? page).getByTestId('import-collection-browse-link'), From 01ea132a06b895d6b2555f1d452ec4927a5711aa Mon Sep 17 00:00:00 2001 From: Sharan Date: Wed, 24 Jun 2026 19:39:30 +0530 Subject: [PATCH 2/3] addressed review comments --- .../yml-as-default-file-format.spec.ts | 80 +++++++++---------- tests/utils/page/actions.ts | 21 +++++ 2 files changed, 60 insertions(+), 41 deletions(-) diff --git a/tests/import/bulk-import/yml-as-default-file-format.spec.ts b/tests/import/bulk-import/yml-as-default-file-format.spec.ts index 03ff4d38cf0..59cc61696e4 100644 --- a/tests/import/bulk-import/yml-as-default-file-format.spec.ts +++ b/tests/import/bulk-import/yml-as-default-file-format.spec.ts @@ -1,67 +1,65 @@ import { test, expect } from '../../../playwright'; import * as path from 'path'; import * as fs from 'fs'; -import { closeAllCollections } from '../../utils/page'; +import { closeAllCollections, openBulkImportModal } from '../../utils/page'; import { buildCommonLocators } from '../../utils/page/locators'; test.describe('Bulk Import default file format', () => { const testDataDir = path.join(__dirname, '../test-data'); + const filesToImport = [ + path.join(testDataDir, 'sample-postman.json'), + path.join(testDataDir, 'sample-insomnia.json') + ]; test.afterEach(async ({ page }) => { await closeAllCollections(page); }); - const openBulkImportModal = async (page) => { - const locators = buildCommonLocators(page); - const postmanFile = path.join(testDataDir, 'sample-postman.json'); - const insomniaFile = path.join(testDataDir, 'sample-insomnia.json'); - - await locators.plusMenu.button().click(); - await locators.plusMenu.importCollection().click(); - await expect(locators.import.modal()).toBeVisible(); - - await locators.import.fileInput().setInputFiles([postmanFile, insomniaFile]); - - const bulkModal = locators.import.bulkModal(); - await expect(bulkModal).toBeVisible(); - return locators; - }; - test('File Format selector defaults to OpenCollection (YAML)', async ({ page }) => { - const locators = await openBulkImportModal(page); + await openBulkImportModal(page, filesToImport); + const locators = buildCommonLocators(page); - const formatSelect = locators.import.bulkFormatSelect(); - await expect(formatSelect).toBeVisible(); - await expect(formatSelect).toHaveValue('yml'); - await expect(formatSelect.locator('option')).toHaveText(['OpenCollection (YAML)', 'BRU Format (.bru)']); + await test.step('File Format defaults to OpenCollection (YAML)', async () => { + const formatSelect = locators.import.bulkFormatSelect(); + await expect(formatSelect).toBeVisible(); + await expect(formatSelect).toHaveValue('yml'); + await expect(formatSelect.locator('option')).toHaveText(['OpenCollection (YAML)', 'BRU Format (.bru)']); + }); }); test('importing with the default format writes opencollection.yml collections', async ({ page, createTmpDir }) => { - const locators = await openBulkImportModal(page); + await openBulkImportModal(page, filesToImport); + const locators = buildCommonLocators(page); + const importDir = await createTmpDir('bulk-import-default-format'); - await expect(locators.import.bulkFormatSelect()).toHaveValue('yml'); + await test.step('Check the File Format defaults to OpenCollection (YAML)', async () => { + await expect(locators.import.bulkFormatSelect()).toHaveValue('yml'); + }); - const importDir = await createTmpDir('bulk-import-default-format'); - await locators.import.bulkLocationInput().fill(importDir); + await test.step('Import with the default format and close the modal', async () => { + await locators.import.bulkLocationInput().fill(importDir); - await expect(locators.import.bulkSubmitButton()).toHaveText('Import'); - await locators.import.bulkSubmitButton().click(); + await expect(locators.import.bulkSubmitButton()).toHaveText('Import'); + await locators.import.bulkSubmitButton().click(); - await expect(locators.import.bulkSubmitButton()).toHaveText('Close'); - await locators.import.bulkSubmitButton().click(); - await expect(locators.import.bulkModal()).toBeHidden(); + await expect(locators.import.bulkSubmitButton()).toHaveText('Close'); + await locators.import.bulkSubmitButton().click(); + await expect(locators.import.bulkModal()).toBeHidden(); + }); - const collectionDirs = fs - .readdirSync(importDir, { withFileTypes: true }) - .filter((entry) => entry.isDirectory()) - .map((entry) => path.join(importDir, entry.name)); + await test.step('Verify each collection is written as opencollection.yml, not bruno.json', async () => { + const collectionDirs = fs + .readdirSync(importDir, { withFileTypes: true }) + .filter((entry) => entry.isDirectory()) + .map((entry) => path.join(importDir, entry.name)); - expect(collectionDirs.length).toBeGreaterThan(0); + expect(collectionDirs.length).toBeGreaterThan(0); - for (const dir of collectionDirs) { - const files = fs.readdirSync(dir); - expect(files).toContain('opencollection.yml'); - expect(files).not.toContain('bruno.json'); - } + for (const dir of collectionDirs) { + const files = fs.readdirSync(dir); + expect(files).toContain('opencollection.yml'); + expect(files).not.toContain('bruno.json'); + } + }); }); }); diff --git a/tests/utils/page/actions.ts b/tests/utils/page/actions.ts index 0d1cf018419..221cc2b4426 100644 --- a/tests/utils/page/actions.ts +++ b/tests/utils/page/actions.ts @@ -524,6 +524,26 @@ const importCollection = async ( }); }; +/** + * Open the Bulk Import modal by importing multiple files at once. + * Selecting more than one file routes the import flow to the Bulk Import modal + * (instead of the single-collection location modal). + * @param page - The page object + * @param filePaths - Absolute paths of the files to import (must be 2 or more) + */ +const openBulkImportModal = async (page: Page, filePaths: string[]) => { + await test.step('Open the Bulk Import modal', async () => { + const locators = buildCommonLocators(page); + + await locators.plusMenu.button().click(); + await locators.plusMenu.importCollection().click(); + await expect(locators.import.modal()).toBeVisible(); + + await locators.import.fileInput().setInputFiles(filePaths); + await expect(locators.import.bulkModal()).toBeVisible(); + }); +}; + /** * Remove a specific collection from the sidebar * @param page - The page object @@ -2099,6 +2119,7 @@ export { deleteRequest, deleteCollectionFromOverview, importCollection, + openBulkImportModal, removeCollection, createFolder, openEnvironmentSelector, From 7ba25e2c1b724ee0d23de47a3dac5ba14e4b6e88 Mon Sep 17 00:00:00 2001 From: Sharan Date: Thu, 25 Jun 2026 22:54:28 +0530 Subject: [PATCH 3/3] addressed review comments --- .../BulkImportCollectionLocation/index.js | 3 ++- .../yml-as-default-file-format.spec.ts | 20 ++++++------------- tests/utils/page/locators.ts | 4 ++-- 3 files changed, 10 insertions(+), 17 deletions(-) diff --git a/packages/bruno-app/src/components/Sidebar/BulkImportCollectionLocation/index.js b/packages/bruno-app/src/components/Sidebar/BulkImportCollectionLocation/index.js index d10dc835ee9..5313f9a5ec6 100644 --- a/packages/bruno-app/src/components/Sidebar/BulkImportCollectionLocation/index.js +++ b/packages/bruno-app/src/components/Sidebar/BulkImportCollectionLocation/index.js @@ -837,6 +837,7 @@ export const BulkImportCollectionLocation = ({
Location
setCollectionFormat(e.target.value)} diff --git a/tests/import/bulk-import/yml-as-default-file-format.spec.ts b/tests/import/bulk-import/yml-as-default-file-format.spec.ts index 59cc61696e4..48aacb85a5c 100644 --- a/tests/import/bulk-import/yml-as-default-file-format.spec.ts +++ b/tests/import/bulk-import/yml-as-default-file-format.spec.ts @@ -15,28 +15,20 @@ test.describe('Bulk Import default file format', () => { await closeAllCollections(page); }); - test('File Format selector defaults to OpenCollection (YAML)', async ({ page }) => { - await openBulkImportModal(page, filesToImport); + test('Bulk import defaults to OpenCollection (YAML) and writes opencollection.yml collections', async ({ page, createTmpDir }) => { const locators = buildCommonLocators(page); + const importDir = await createTmpDir('bulk-import-default-format'); + + await test.step('Open the bulk import modal and verify the File Format defaults to OpenCollection (YAML)', async () => { + await openBulkImportModal(page, filesToImport); - await test.step('File Format defaults to OpenCollection (YAML)', async () => { const formatSelect = locators.import.bulkFormatSelect(); await expect(formatSelect).toBeVisible(); await expect(formatSelect).toHaveValue('yml'); await expect(formatSelect.locator('option')).toHaveText(['OpenCollection (YAML)', 'BRU Format (.bru)']); }); - }); - - test('importing with the default format writes opencollection.yml collections', async ({ page, createTmpDir }) => { - await openBulkImportModal(page, filesToImport); - const locators = buildCommonLocators(page); - const importDir = await createTmpDir('bulk-import-default-format'); - - await test.step('Check the File Format defaults to OpenCollection (YAML)', async () => { - await expect(locators.import.bulkFormatSelect()).toHaveValue('yml'); - }); - await test.step('Import with the default format and close the modal', async () => { + await test.step('Set the location, Click Import, then close the modal', async () => { await locators.import.bulkLocationInput().fill(importDir); await expect(locators.import.bulkSubmitButton()).toHaveText('Import'); diff --git a/tests/utils/page/locators.ts b/tests/utils/page/locators.ts index 0b49b801b30..51b2438e90d 100644 --- a/tests/utils/page/locators.ts +++ b/tests/utils/page/locators.ts @@ -215,8 +215,8 @@ export const buildCommonLocators = (page: Page) => ({ locationInput: () => page.locator('#collection-location'), fileInput: () => page.locator('input[type="file"]'), bulkModal: () => page.getByTestId('bulk-import-collection-location-modal'), - bulkFormatSelect: () => page.getByTestId('bulk-import-collection-location-modal').getByTestId('collection-format-selector'), - bulkLocationInput: () => page.getByTestId('bulk-import-collection-location-modal').locator('#collection-location'), + bulkFormatSelect: () => page.getByTestId('bulk-import-collection-location-modal').getByTestId('bulk-import-collection-format-selector'), + bulkLocationInput: () => page.getByTestId('bulk-import-collection-location-modal').getByTestId('bulk-import-collection-location-input'), bulkSubmitButton: () => page.getByTestId('bulk-import-collection-location-modal-submit-btn'), envOption: (name: string) => page.locator('.dropdown-item').getByText(name, { exact: true }), parsingError: () => page.getByTestId('import-error-message'),