From ce69193491bdb39f278a2674dc80ad7da25f04da Mon Sep 17 00:00:00 2001 From: Sharan Date: Thu, 25 Jun 2026 16:01:31 +0530 Subject: [PATCH 1/4] fix(import): Import fails for gRPC request without URL in exported collection --- .../bruno-schema/src/collections/index.js | 2 +- .../bruno-grpc-request-missing-url.json | 51 +++++++++++++++++++ .../bruno-http-request-missing-url.json | 50 ++++++++++++++++++ .../import-bruno-request-missing-url.spec.ts | 30 +++++++++++ 4 files changed, 132 insertions(+), 1 deletion(-) create mode 100644 tests/import/bruno/fixtures/bruno-grpc-request-missing-url.json create mode 100644 tests/import/bruno/fixtures/bruno-http-request-missing-url.json create mode 100644 tests/import/bruno/import-bruno-request-missing-url.spec.ts diff --git a/packages/bruno-schema/src/collections/index.js b/packages/bruno-schema/src/collections/index.js index 36a140f331c..c9f928cd90d 100644 --- a/packages/bruno-schema/src/collections/index.js +++ b/packages/bruno-schema/src/collections/index.js @@ -129,7 +129,7 @@ const varsSchema = Yup.object({ .noUnknown(true) .strict(); -const requestUrlSchema = Yup.string().min(0).defined(); +const requestUrlSchema = Yup.string().optional(); const requestMethodSchema = Yup.string() .min(1, 'method is required') .required('method is required'); diff --git a/tests/import/bruno/fixtures/bruno-grpc-request-missing-url.json b/tests/import/bruno/fixtures/bruno-grpc-request-missing-url.json new file mode 100644 index 00000000000..fdbb4047e04 --- /dev/null +++ b/tests/import/bruno/fixtures/bruno-grpc-request-missing-url.json @@ -0,0 +1,51 @@ +{ + "name": "GRPC Collection", + "version": "1", + "items": [ + { + "type": "grpc", + "name": "request without url", + "filename": "request-without-url.bru", + "seq": 2, + "settings": {}, + "tags": [], + "examples": [], + "request": { + "method": "", + "headers": [], + "body": { + "mode": "grpc", + "formUrlEncoded": [], + "multipartForm": [], + "file": [], + "grpc": [ + { + "name": "message 1", + "content": "{}" + } + ] + }, + "script": {}, + "vars": {}, + "assertions": [], + "tests": "", + "docs": "", + "auth": { + "mode": "none" + } + } + } + ], + "environments": [], + "brunoConfig": { + "version": "1", + "name": "GRPC Collection", + "type": "collection", + "ignore": [ + "node_modules", + ".git" + ], + "size": 0, + "filesCount": 0 + } +} \ No newline at end of file diff --git a/tests/import/bruno/fixtures/bruno-http-request-missing-url.json b/tests/import/bruno/fixtures/bruno-http-request-missing-url.json new file mode 100644 index 00000000000..c99744f3d72 --- /dev/null +++ b/tests/import/bruno/fixtures/bruno-http-request-missing-url.json @@ -0,0 +1,50 @@ +{ + "name": "HTTP Collection", + "version": "1", + "items": [ + { + "type": "http", + "name": "request without url", + "filename": "request-without-url.bru", + "seq": 2, + "settings": {}, + "tags": [], + "examples": [], + "request": { + "method": "GET", + "headers": [], + "params": [], + "body": { + "mode": "none", + "json": null, + "text": null, + "xml": null, + "sparql": null, + "formUrlEncoded": [], + "multipartForm": [], + "file": [] + }, + "script": {}, + "vars": {}, + "assertions": [], + "tests": "", + "docs": "", + "auth": { + "mode": "none" + } + } + } + ], + "environments": [], + "brunoConfig": { + "version": "1", + "name": "HTTP Collection", + "type": "collection", + "ignore": [ + "node_modules", + ".git" + ], + "size": 0, + "filesCount": 0 + } +} \ No newline at end of file diff --git a/tests/import/bruno/import-bruno-request-missing-url.spec.ts b/tests/import/bruno/import-bruno-request-missing-url.spec.ts new file mode 100644 index 00000000000..c76736f2760 --- /dev/null +++ b/tests/import/bruno/import-bruno-request-missing-url.spec.ts @@ -0,0 +1,30 @@ +import { test, expect } from '../../../playwright'; +import * as path from 'path'; +import { importCollection, closeAllCollections, buildCommonLocators } from '../../utils/page'; + +test.describe.serial('Import Bruno Collection - request with missing URL', () => { + test.afterAll(async ({ page }) => { + await closeAllCollections(page); + }); + + const cases = [ + { fixture: 'bruno-http-request-missing-url.json', collectionName: 'HTTP Collection', type: 'HTTP' }, + { fixture: 'bruno-grpc-request-missing-url.json', collectionName: 'GRPC Collection', type: 'gRPC' } + ]; + + for (const { fixture, collectionName, type } of cases) { + test(`imports a ${type} request without a URL`, async ({ page, createTmpDir }) => { + const brunoFile = path.resolve(__dirname, 'fixtures', fixture); + const location = await createTmpDir(collectionName); + + await importCollection(page, brunoFile, location, { + expectedCollectionName: collectionName + }); + }); + + test(`${type} collection appears in the sidebar after import`, async ({ page }) => { + const locators = buildCommonLocators(page); + await expect(locators.sidebar.collection(collectionName)).toBeVisible(); + }); + } +}); From 3ead2431a7816042d45976418b7abd4cff136247 Mon Sep 17 00:00:00 2001 From: Sharan Date: Thu, 25 Jun 2026 23:29:48 +0530 Subject: [PATCH 2/4] changed the approach for import request with missing url --- packages/bruno-app/src/utils/importers/common.js | 5 +++++ packages/bruno-schema/src/collections/index.js | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/packages/bruno-app/src/utils/importers/common.js b/packages/bruno-app/src/utils/importers/common.js index 8ed2c9c0c40..d98a00ab2a0 100644 --- a/packages/bruno-app/src/utils/importers/common.js +++ b/packages/bruno-app/src/utils/importers/common.js @@ -98,6 +98,7 @@ export const transformItemsInCollection = (collection) => { item.type = `${item.type}-request`; const isGrpcRequest = item.type === 'grpc-request'; const isWSRequest = item.type === 'ws-request'; + item.request.url = item.request.url ?? ''; if (item.request.query) { item.request.params = item.request.query.map((queryItem) => ({ @@ -137,6 +138,10 @@ export const transformItemsInCollection = (collection) => { const isGrpcExample = example.type === 'grpc-request'; const isWSExample = example.type === 'ws-request'; + if (example.request) { + example.request.url = example.request.url ?? ''; + } + if (example.request && example.request.query) { example.request.params = example.request.query.map((queryItem) => ({ ...queryItem, diff --git a/packages/bruno-schema/src/collections/index.js b/packages/bruno-schema/src/collections/index.js index c9f928cd90d..36a140f331c 100644 --- a/packages/bruno-schema/src/collections/index.js +++ b/packages/bruno-schema/src/collections/index.js @@ -129,7 +129,7 @@ const varsSchema = Yup.object({ .noUnknown(true) .strict(); -const requestUrlSchema = Yup.string().optional(); +const requestUrlSchema = Yup.string().min(0).defined(); const requestMethodSchema = Yup.string() .min(1, 'method is required') .required('method is required'); From 6be3386a87e04d24bdfde886607df66bc1bdaa31 Mon Sep 17 00:00:00 2001 From: Sharan Date: Fri, 26 Jun 2026 16:05:17 +0530 Subject: [PATCH 3/4] addressed review comment --- packages/bruno-app/src/utils/importers/common.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/bruno-app/src/utils/importers/common.js b/packages/bruno-app/src/utils/importers/common.js index d98a00ab2a0..1643b96b736 100644 --- a/packages/bruno-app/src/utils/importers/common.js +++ b/packages/bruno-app/src/utils/importers/common.js @@ -11,6 +11,7 @@ import { BrunoError } from 'utils/common/error'; import { isOpenApiSpec } from './openapi-collection'; import { isPostmanCollection } from './postman-collection'; import { isInsomniaCollection } from './insomnia-collection'; +import { valueToString } from '@usebruno/common/utils'; export const validateSchema = async (collections = []) => { collections = Array.isArray(collections) ? collections : [collections]; @@ -98,7 +99,7 @@ export const transformItemsInCollection = (collection) => { item.type = `${item.type}-request`; const isGrpcRequest = item.type === 'grpc-request'; const isWSRequest = item.type === 'ws-request'; - item.request.url = item.request.url ?? ''; + item.request.url = valueToString(item.request.url); if (item.request.query) { item.request.params = item.request.query.map((queryItem) => ({ @@ -139,7 +140,7 @@ export const transformItemsInCollection = (collection) => { const isWSExample = example.type === 'ws-request'; if (example.request) { - example.request.url = example.request.url ?? ''; + example.request.url = valueToString(example.request.url); } if (example.request && example.request.query) { From be07e022961865ef35366d538c79bf5f3ac5bfad Mon Sep 17 00:00:00 2001 From: Sharan Date: Fri, 26 Jun 2026 16:58:13 +0530 Subject: [PATCH 4/4] added a fixture for http example request --- ...runo-http-example-request-missing-url.json | 83 +++++++++++++++++++ .../import-bruno-request-missing-url.spec.ts | 3 +- 2 files changed, 85 insertions(+), 1 deletion(-) create mode 100644 tests/import/bruno/fixtures/bruno-http-example-request-missing-url.json diff --git a/tests/import/bruno/fixtures/bruno-http-example-request-missing-url.json b/tests/import/bruno/fixtures/bruno-http-example-request-missing-url.json new file mode 100644 index 00000000000..e78ecbe90ba --- /dev/null +++ b/tests/import/bruno/fixtures/bruno-http-example-request-missing-url.json @@ -0,0 +1,83 @@ +{ + "name": "HTTP Example Collection", + "version": "1", + "items": [ + { + "type": "http", + "name": "request with example", + "filename": "request-with-example.bru", + "seq": 1, + "settings": {}, + "tags": [], + "examples": [ + { + "uid": "ex0011223344556677889", + "itemUid": "it0011223344556677889", + "name": "Successful response", + "description": "Example whose request has no url", + "type": "http", + "request": { + "method": "GET", + "headers": [], + "params": [], + "body": { + "mode": "none" + } + }, + "response": { + "status": 200, + "statusText": "OK", + "headers": [ + { + "uid": "hd0011223344556677889", + "name": "content-type", + "value": "application/json", + "enabled": true + } + ], + "body": { + "type": "json", + "content": "{\n \"message\": \"hello\"\n}" + } + } + } + ], + "request": { + "method": "GET", + "headers": [], + "url": "", + "params": [], + "body": { + "mode": "none", + "json": null, + "text": null, + "xml": null, + "sparql": null, + "formUrlEncoded": [], + "multipartForm": [], + "file": [] + }, + "script": {}, + "vars": {}, + "assertions": [], + "tests": "", + "docs": "", + "auth": { + "mode": "none" + } + } + } + ], + "environments": [], + "brunoConfig": { + "version": "1", + "name": "HTTP Example Collection", + "type": "collection", + "ignore": [ + "node_modules", + ".git" + ], + "size": 0, + "filesCount": 0 + } +} \ No newline at end of file diff --git a/tests/import/bruno/import-bruno-request-missing-url.spec.ts b/tests/import/bruno/import-bruno-request-missing-url.spec.ts index c76736f2760..7c849433fb1 100644 --- a/tests/import/bruno/import-bruno-request-missing-url.spec.ts +++ b/tests/import/bruno/import-bruno-request-missing-url.spec.ts @@ -9,7 +9,8 @@ test.describe.serial('Import Bruno Collection - request with missing URL', () => const cases = [ { fixture: 'bruno-http-request-missing-url.json', collectionName: 'HTTP Collection', type: 'HTTP' }, - { fixture: 'bruno-grpc-request-missing-url.json', collectionName: 'GRPC Collection', type: 'gRPC' } + { fixture: 'bruno-grpc-request-missing-url.json', collectionName: 'GRPC Collection', type: 'gRPC' }, + { fixture: 'bruno-http-example-request-missing-url.json', collectionName: 'HTTP Example Collection', type: 'HTTP example' } ]; for (const { fixture, collectionName, type } of cases) {