add: playwright test for import collection modal (#5487)

* add: playwright test for import collection modal
This commit is contained in:
Pooja
2025-09-03 19:14:08 +05:30
committed by GitHub
parent 457a2f83e7
commit de4674dcc4
42 changed files with 7488 additions and 2 deletions

View File

@@ -0,0 +1,38 @@
import { test, expect } from '../../../playwright';
import * as path from 'path';
test.describe('Import Bruno Testbench Collection', () => {
const testDataDir = path.join(__dirname, '../test-data');
test.beforeAll(async ({ page }) => {
// Navigate back to homescreen after all tests
await page.locator('.bruno-logo').click();
});
test('Import Bruno Testbench collection successfully', async ({ page }) => {
const brunoFile = path.join(testDataDir, 'bruno-testbench.json');
await page.getByRole('button', { name: 'Import Collection' }).click();
// Wait for import collection modal to be ready
const importModal = page.getByRole('dialog');
await importModal.waitFor({ state: 'visible' });
await expect(importModal.locator('.bruno-modal-header-title')).toContainText('Import Collection');
await page.setInputFiles('input[type="file"]', brunoFile);
// Wait for the loader to disappear
await page.locator('#import-collection-loader').waitFor({ state: 'hidden' });
// Verify that the Import Collection modal is displayed (for location selection)
const locationModal = page.getByRole('dialog');
await expect(locationModal.locator('.bruno-modal-header-title')).toContainText('Import Collection');
// Wait for collection to appear in the location modal
await expect(locationModal.getByText('bruno-testbench')).toBeVisible();
// Cleanup: close any open modals
await page.locator('[data-test-id="modal-close-button"]').click();
});
});

View File

@@ -0,0 +1,31 @@
import { test, expect } from '../../../playwright';
import * as path from 'path';
test.describe('Import Corrupted Bruno Collection - Should Fail', () => {
const testDataDir = path.join(__dirname, '../test-data');
test('Import Bruno collection with invalid JSON structure should fail', async ({ page }) => {
const brunoFile = path.join(testDataDir, 'bruno-malformed.json');
await page.getByRole('button', { name: 'Import Collection' }).click();
// Wait for import collection modal to be ready
const importModal = page.getByRole('dialog');
await importModal.waitFor({ state: 'visible' });
await expect(importModal.locator('.bruno-modal-header-title')).toContainText('Import Collection');
await page.setInputFiles('input[type="file"]', brunoFile);
// Wait for the loader to disappear
await page.locator('#import-collection-loader').waitFor({ state: 'hidden' });
// Check for JSON parsing error
const hasImportError = await page.getByText('Failed to parse the file ensure it is valid JSON or YAML').first().isVisible();
// Either parsing error or import error should be shown
expect(hasImportError).toBe(true);
// Cleanup: close any open modals
await page.locator('[data-test-id="modal-close-button"]').click();
});
});

View File

@@ -0,0 +1,30 @@
import { test, expect } from '../../../playwright';
import * as path from 'path';
test.describe('Import Bruno Collection - Missing Required Schema Fields', () => {
const testDataDir = path.join(__dirname, '../test-data');
test('Import Bruno collection missing required version field should fail', async ({ page }) => {
const brunoFile = path.join(testDataDir, 'bruno-missing-required-fields.json');
await page.getByRole('button', { name: 'Import Collection' }).click();
// Wait for import collection modal to be ready
const importModal = page.getByRole('dialog');
await importModal.waitFor({ state: 'visible' });
await expect(importModal.locator('.bruno-modal-header-title')).toContainText('Import Collection');
await page.setInputFiles('input[type="file"]', brunoFile);
// Wait for the loader to disappear
await page.locator('#import-collection-loader').waitFor({ state: 'hidden' });
// Check for schema validation error messages
const hasImportError = await page.getByText('Import collection failed').first().isVisible();
expect(hasImportError).toBe(true);
// Cleanup: close any open modals
await page.locator('[data-test-id="modal-close-button"]').click();
});
});

View File

@@ -0,0 +1,20 @@
import { test, expect } from '../../../playwright';
test.describe('File Input Acceptance', () => {
test('File input accepts expected file types', async ({ page }) => {
await page.getByRole('button', { name: 'Import Collection' }).click();
// Check that file input exists (even if hidden)
const fileInput = page.locator('input[type="file"]');
await expect(fileInput).toBeAttached();
// Verify it accepts the expected file types
const acceptValue = await fileInput.getAttribute('accept');
expect(acceptValue).toContain('.json');
expect(acceptValue).toContain('.yaml');
expect(acceptValue).toContain('.yml');
// Cleanup: close any open modals
await page.locator('[data-test-id="modal-close-button"]').click();
});
});

View File

@@ -0,0 +1,28 @@
import { test, expect } from '../../../playwright';
import * as path from 'path';
test.describe('Invalid File Handling', () => {
const testDataDir = path.join(__dirname, '../test-data');
test('Handle invalid file without crashing', async ({ page }) => {
const invalidFile = path.join(testDataDir, 'invalid.txt');
await page.getByRole('button', { name: 'Import Collection' }).click();
// Wait for import collection modal to be ready
const importModal = page.getByRole('dialog');
await importModal.waitFor({ state: 'visible' });
await expect(importModal.locator('.bruno-modal-header-title')).toContainText('Import Collection');
await page.setInputFiles('input[type="file"]', invalidFile);
// Wait for the loader to disappear
await page.locator('#import-collection-loader').waitFor({ state: 'hidden' });
const hasError = await page.getByText("Failed to parse the file ensure it is valid JSON or YAML").isVisible();
expect(hasError).toBe(true);
// Cleanup: close any open modals
await page.locator('[data-test-id="modal-close-button"]').click();
});
});

View File

@@ -0,0 +1,32 @@
import { test, expect } from '../../../playwright';
import * as path from 'path';
test.describe('Import Insomnia Collection v4', () => {
const testDataDir = path.join(__dirname, '../test-data');
test('Import Insomnia Collection v4 successfully', async ({ page }) => {
const insomniaFile = path.join(testDataDir, 'insomnia-v4.json');
await page.getByRole('button', { name: 'Import Collection' }).click();
// Wait for import collection modal to be ready
const importModal = page.getByRole('dialog');
await importModal.waitFor({ state: 'visible' });
await expect(importModal.locator('.bruno-modal-header-title')).toContainText('Import Collection');
await page.setInputFiles('input[type="file"]', insomniaFile);
// Wait for the loader to disappear
await page.locator('#import-collection-loader').waitFor({ state: 'hidden' });
// Verify that the Import Collection modal is displayed (for location selection)
const locationModal = page.getByRole('dialog');
await expect(locationModal.locator('.bruno-modal-header-title')).toContainText('Import Collection');
// Wait for collection to appear in the location modal
await expect(locationModal.getByText('Test API Collection v4')).toBeVisible();
// Cleanup: close any open modals
await page.locator('[data-test-id="modal-close-button"]').click();
});
});

View File

@@ -0,0 +1,32 @@
import { test, expect } from '../../../playwright';
import * as path from 'path';
test.describe('Import Insomnia Collection v5', () => {
const testDataDir = path.join(__dirname, '../test-data');
test('Import Insomnia Collection v5 successfully', async ({ page }) => {
const insomniaFile = path.join(testDataDir, 'insomnia-v5.yaml');
await page.getByRole('button', { name: 'Import Collection' }).click();
// Wait for import collection modal to be ready
const importModal = page.getByRole('dialog');
await importModal.waitFor({ state: 'visible' });
await expect(importModal.locator('.bruno-modal-header-title')).toContainText('Import Collection');
await page.setInputFiles('input[type="file"]', insomniaFile);
// Wait for the loader to disappear
await page.locator('#import-collection-loader').waitFor({ state: 'hidden' });
// Verify that the Import Collection modal is displayed (for location selection)
const locationModal = page.getByRole('dialog');
await expect(locationModal.locator('.bruno-modal-header-title')).toContainText('Import Collection');
// Wait for collection to appear in the location modal
await expect(locationModal.getByText('Test API Collection v5')).toBeVisible();
// Cleanup: close any open modals
await page.locator('[data-test-id="modal-close-button"]').click();
});
});

View File

@@ -0,0 +1,29 @@
import { test, expect } from '../../../playwright';
import * as path from 'path';
test.describe('Invalid Insomnia Collection - Missing Collection Array', () => {
const testDataDir = path.join(__dirname, '../test-data');
test('Handle Insomnia v5 collection missing collection array', async ({ page }) => {
const insomniaFile = path.join(testDataDir, 'insomnia-v5-invalid-missing-collection.yaml');
await page.getByRole('button', { name: 'Import Collection' }).click();
// Wait for import collection modal to be ready
const importModal = page.getByRole('dialog');
await importModal.waitFor({ state: 'visible' });
await expect(importModal.locator('.bruno-modal-header-title')).toContainText('Import Collection');
await page.setInputFiles('input[type="file"]', insomniaFile);
// Wait for the loader to disappear
await page.locator('#import-collection-loader').waitFor({ state: 'hidden' });
// Check for error message
const hasError = await page.getByText('Import collection failed').first().isVisible();
expect(hasError).toBe(true);
// Cleanup: close any open modals
await page.locator('[data-test-id="modal-close-button"]').click();
});
});

View File

@@ -0,0 +1,29 @@
import { test, expect } from '../../../playwright';
import * as path from 'path';
test.describe('Invalid Insomnia Collection - Malformed Structure', () => {
const testDataDir = path.join(__dirname, '../test-data');
test('Handle malformed Insomnia collection structure', async ({ page }) => {
const insomniaFile = path.join(testDataDir, 'insomnia-malformed.json');
await page.getByRole('button', { name: 'Import Collection' }).click();
// Wait for import collection modal to be ready
const importModal = page.getByRole('dialog');
await importModal.waitFor({ state: 'visible' });
await expect(importModal.locator('.bruno-modal-header-title')).toContainText('Import Collection');
await page.setInputFiles('input[type="file"]', insomniaFile);
// Wait for the loader to disappear
await page.locator('#import-collection-loader').waitFor({ state: 'hidden' });
// Check for error message - this should fail during JSON parsing
const hasError = await page.getByText('Failed to parse the file').isVisible();
expect(hasError).toBe(true);
// Cleanup: close any open modals
await page.locator('[data-test-id="modal-close-button"]').click();
});
});

View File

@@ -0,0 +1,32 @@
import { test, expect } from '../../../playwright';
import * as path from 'path';
test.describe('Import OpenAPI v3 YAML Collection', () => {
const testDataDir = path.join(__dirname, '../test-data');
test('Import comprehensive OpenAPI v3 YAML successfully', async ({ page }) => {
const openApiFile = path.join(testDataDir, 'openapi-comprehensive.yaml');
await page.getByRole('button', { name: 'Import Collection' }).click();
// Wait for import collection modal to be ready
const importModal = page.getByRole('dialog');
await importModal.waitFor({ state: 'visible' });
await expect(importModal.locator('.bruno-modal-header-title')).toContainText('Import Collection');
await page.setInputFiles('input[type="file"]', openApiFile);
// Wait for the loader to disappear
await page.locator('#import-collection-loader').waitFor({ state: 'hidden' });
// Verify that the Import Collection modal is displayed (for location selection)
const locationModal = page.getByRole('dialog');
await expect(locationModal.locator('.bruno-modal-header-title')).toContainText('Import Collection');
// Wait for collection to appear in the location modal
await expect(locationModal.getByText('Comprehensive API Test Collection')).toBeVisible();
// Cleanup: close any open modals
await page.locator('[data-test-id="modal-close-button"]').click();
});
});

View File

@@ -0,0 +1,32 @@
import { test, expect } from '../../../playwright';
import * as path from 'path';
test.describe('Import OpenAPI v3 JSON Collection', () => {
const testDataDir = path.join(__dirname, '../test-data');
test('Import simple OpenAPI v3 JSON successfully', async ({ page }) => {
const openApiFile = path.join(testDataDir, 'openapi-simple.json');
await page.getByRole('button', { name: 'Import Collection' }).click();
// Wait for import collection modal to be ready
const importModal = page.getByRole('dialog');
await importModal.waitFor({ state: 'visible' });
await expect(importModal.locator('.bruno-modal-header-title')).toContainText('Import Collection');
await page.setInputFiles('input[type="file"]', openApiFile);
// Wait for the loader to disappear
await page.locator('#import-collection-loader').waitFor({ state: 'hidden' });
// Verify that the Import Collection modal is displayed (for location selection)
const locationModal = page.getByRole('dialog');
await expect(locationModal.locator('.bruno-modal-header-title')).toContainText('Import Collection');
// Wait for collection to appear in the location modal
await expect(locationModal.getByText('Simple Test API')).toBeVisible();
// Cleanup: close any open modals
await page.locator('[data-test-id="modal-close-button"]').click();
});
});

View File

@@ -0,0 +1,31 @@
import { test, expect } from '../../../playwright';
import * as path from 'path';
test.describe('Invalid OpenAPI - Missing Info Section', () => {
const testDataDir = path.join(__dirname, '../test-data');
test('Handle OpenAPI specification missing required info section', async ({ page }) => {
const openApiFile = path.join(testDataDir, 'openapi-missing-info.yaml');
await page.getByRole('button', { name: 'Import Collection' }).click();
// Wait for import collection modal to be ready
const importModal = page.getByRole('dialog');
await importModal.waitFor({ state: 'visible' });
await expect(importModal.locator('.bruno-modal-header-title')).toContainText('Import Collection');
await page.setInputFiles('input[type="file"]', openApiFile);
// Wait for the loader to disappear
await page.locator('#import-collection-loader').waitFor({ state: 'hidden' });
// The OpenAPI parser might handle missing info gracefully with defaults
const hasError = await page.getByText('Import collection failed').first().isVisible();
// Either should show an error or create an "Untitled Collection"
expect(hasError).toBe(true);
// Cleanup: close any open modals
await page.locator('[data-test-id="modal-close-button"]').click();
});
});

View File

@@ -0,0 +1,32 @@
import { test, expect } from '../../../playwright';
import * as path from 'path';
test.describe('Invalid OpenAPI - Malformed YAML', () => {
const testDataDir = path.join(__dirname, '../test-data');
test('Handle malformed OpenAPI YAML structure', async ({ page }) => {
const openApiFile = path.join(testDataDir, 'openapi-malformed.yaml');
await page.getByRole('button', { name: 'Import Collection' }).click();
// Wait for import collection modal to be ready
const importModal = page.getByRole('dialog');
await importModal.waitFor({ state: 'visible' });
await expect(importModal.locator('.bruno-modal-header-title')).toContainText('Import Collection');
await page.setInputFiles('input[type="file"]', openApiFile);
// Wait for the loader to disappear
await page.locator('#import-collection-loader').waitFor({ state: 'hidden' });
// Check for error message - this should fail during YAML parsing
const hasParseError = await page.getByText('Failed to parse the file').isVisible();
const hasImportError = await page.getByText('Import collection failed').isVisible();
// Either parsing error or import error should be shown
expect(hasParseError || hasImportError).toBe(true);
// Cleanup: close any open modals
await page.locator('[data-test-id="modal-close-button"]').click();
});
});

View File

@@ -0,0 +1,32 @@
import { test, expect } from '../../../playwright';
import * as path from 'path';
test.describe('Import Postman Collection v2.1', () => {
const testDataDir = path.join(__dirname, '../test-data');
test('Import Postman Collection v2.1 successfully', async ({ page }) => {
const postmanFile = path.join(testDataDir, 'postman-v21.json');
await page.getByRole('button', { name: 'Import Collection' }).click();
// Wait for import collection modal to be ready
const importModal = page.getByRole('dialog');
await importModal.waitFor({ state: 'visible' });
await expect(importModal.locator('.bruno-modal-header-title')).toContainText('Import Collection');
await page.setInputFiles('input[type="file"]', postmanFile);
// Wait for the loader to disappear
await page.locator('#import-collection-loader').waitFor({ state: 'hidden' });
// Verify that the Import Collection modal is displayed (for location selection)
const locationModal = page.getByRole('dialog');
await expect(locationModal.locator('.bruno-modal-header-title')).toContainText('Import Collection');
// Wait for collection to appear in the location modal
await expect(locationModal.getByText('Postman v2.1 Collection')).toBeVisible();
// Cleanup: close any open modals
await page.locator('[data-test-id="modal-close-button"]').click();
});
});

View File

@@ -0,0 +1,32 @@
import { test, expect } from '../../../playwright';
import * as path from 'path';
test.describe('Import Postman Collection v2.0', () => {
const testDataDir = path.join(__dirname, '../test-data');
test('Import Postman Collection v2.0 successfully', async ({ page }) => {
const postmanFile = path.join(testDataDir, 'postman-v20.json');
await page.getByRole('button', { name: 'Import Collection' }).click();
// Wait for import collection modal to be ready
const importModal = page.getByRole('dialog');
await importModal.waitFor({ state: 'visible' });
await expect(importModal.locator('.bruno-modal-header-title')).toContainText('Import Collection');
await page.setInputFiles('input[type="file"]', postmanFile);
// Wait for the loader to disappear
await page.locator('#import-collection-loader').waitFor({ state: 'hidden' });
// Verify that the Import Collection modal is displayed (for location selection)
const locationModal = page.getByRole('dialog');
await expect(locationModal.locator('.bruno-modal-header-title')).toContainText('Import Collection');
// Wait for collection to appear in the location modal
await expect(locationModal.getByText('Postman v2.0 Collection')).toBeVisible();
// Cleanup: close any open modals
await page.locator('[data-test-id="modal-close-button"]').click();
});
});

View File

@@ -0,0 +1,29 @@
import { test, expect } from '../../../playwright';
import * as path from 'path';
test.describe('Invalid Postman Collection - Missing Info', () => {
const testDataDir = path.join(__dirname, '../test-data');
test('Handle Postman collection missing required info field', async ({ page }) => {
const postmanFile = path.join(testDataDir, 'postman-invalid-missing-info.json');
await page.getByRole('button', { name: 'Import Collection' }).click();
// Wait for import collection modal to be ready
const importModal = page.getByRole('dialog');
await importModal.waitFor({ state: 'visible' });
await expect(importModal.locator('.bruno-modal-header-title')).toContainText('Import Collection');
await page.setInputFiles('input[type="file"]', postmanFile);
// Wait for the loader to disappear
await page.locator('#import-collection-loader').waitFor({ state: 'hidden' });
// Check for error message
const hasError = await page.getByText('Import collection failed').isVisible();
expect(hasError).toBe(true);
// Cleanup: close any open modals
await page.locator('[data-test-id="modal-close-button"]').click();
});
});

View File

@@ -0,0 +1,29 @@
import { test, expect } from '../../../playwright';
import * as path from 'path';
test.describe('Invalid Postman Collection - Invalid Schema', () => {
const testDataDir = path.join(__dirname, '../test-data');
test('Handle Postman collection with invalid schema version', async ({ page }) => {
const postmanFile = path.join(testDataDir, 'postman-invalid-schema.json');
await page.getByRole('button', { name: 'Import Collection' }).click();
// Wait for import collection modal to be ready
const importModal = page.getByRole('dialog');
await importModal.waitFor({ state: 'visible' });
await expect(importModal.locator('.bruno-modal-header-title')).toContainText('Import Collection');
await page.setInputFiles('input[type="file"]', postmanFile);
// Wait for the loader to disappear
await page.locator('#import-collection-loader').waitFor({ state: 'hidden' });
// Check for error message
const hasError = await page.getByText('Conversion failed').isVisible();
expect(hasError).toBe(true);
// Cleanup: close any open modals
await page.locator('[data-test-id="modal-close-button"]').click();
});
});

View File

@@ -0,0 +1,29 @@
import { test, expect } from '../../../playwright';
import * as path from 'path';
test.describe('Invalid Postman Collection - Malformed Structure', () => {
const testDataDir = path.join(__dirname, '../test-data');
test('Handle malformed Postman collection structure', async ({ page }) => {
const postmanFile = path.join(testDataDir, 'postman-malformed.json');
await page.getByRole('button', { name: 'Import Collection' }).click();
// Wait for import collection modal to be ready
const importModal = page.getByRole('dialog');
await importModal.waitFor({ state: 'visible' });
await expect(importModal.locator('.bruno-modal-header-title')).toContainText('Import Collection');
await page.setInputFiles('input[type="file"]', postmanFile);
// Wait for the loader to disappear
await page.locator('#import-collection-loader').waitFor({ state: 'hidden' });
// Check for error message
const hasError = await page.getByText('Import collection failed').first().isVisible();
expect(hasError).toBe(true);
// Cleanup: close any open modals
await page.locator('[data-test-id="modal-close-button"]').click();
});
});

View File

@@ -0,0 +1,29 @@
import { test, expect } from '../../../playwright';
import * as path from 'path';
test.describe('Invalid Postman Collection - Invalid JSON', () => {
const testDataDir = path.join(__dirname, '../test-data');
test('Handle invalid JSON syntax', async ({ page }) => {
const postmanFile = path.join(testDataDir, 'postman-invalid-schema.json');
await page.getByRole('button', { name: 'Import Collection' }).click();
// Wait for import collection modal to be ready
const importModal = page.getByRole('dialog');
await importModal.waitFor({ state: 'visible' });
await expect(importModal.locator('.bruno-modal-header-title')).toContainText('Import Collection');
await page.setInputFiles('input[type="file"]', postmanFile);
// Wait for the loader to disappear
await page.locator('#import-collection-loader').waitFor({ state: 'hidden' });
// Check for error message
const hasError = await page.getByText('Conversion failed').first().isVisible();
expect(hasError).toBe(true);
// Cleanup: close any open modals
await page.locator('[data-test-id="modal-close-button"]').click();
});
});

View File

@@ -0,0 +1,66 @@
{
"version": "1",
"uid": "corrupted_bruno_collection",
"name": "Corrupted Bruno Collection",
"items": [
{
"uid": "corrupted_request",
"type": "invalid-request-type",
"name": "Invalid Request Type",
"seq": 1,
"request": {
"url": "https://example.com/api",
"method": "INVALID_METHOD",
"headers": "this should be an array not a string",
"params": null,
"body": {
"mode": "invalid-mode",
"invalidField": "this field doesn't exist in schema"
},
"auth": {
"mode": "unknown-auth-type",
"invalidAuth": {
"badField": "invalid value"
}
},
"script": "this should be an object not a string",
"vars": "this should be an object not a string",
"assertions": "this should be an array not a string",
"tests": 12345,
"docs": true
}
},
{
"uid": "missing_required_fields",
"type": "http-request",
"name": "Missing Required Fields",
"seq": 2
}
],
"environments": [
{
"uid": "invalid_env",
"name": "Invalid Environment",
"variables": "this should be an array not a string"
}
],
"activeEnvironmentUid": "non_existent_environment_id",
"root": {
"request": {
"headers": "invalid headers format",
"auth": {
"mode": "completely-unknown-auth"
},
"script": 42,
"vars": false,
"tests": null
}
},
"invalidTopLevelField": "this field doesn't belong here",
"brunoConfig": {
"version": "999",
"name": "Invalid Config",
"type": "invalid-type",
"invalidConfigField": true
}
}

View File

@@ -0,0 +1,43 @@
{
"version": "1",
"uid": "malformed_bruno_collection",
"name": "Malformed Bruno Collection",
"items": [
{
"uid": "malformed_request",
"type": "http-request",
"name": "Malformed Request",
"seq": 1,
"request": {
"url": "https://example.com/api",
"method": "GET",
"headers": [],
"params": [],
"body": {
"mode": "none"
},
"auth": {
"mode": "none"
},
"script": {},
"vars": {},
"assertions": [],
"tests": "",
"docs": ""
}
}
],
"environments": [],
"activeEnvironmentUid": null,
"root": {
"request": {
"headers": [],
"auth": {
"mode": "none"
},
"script": {},
"vars": {},
"tests": ""
}
}
// Missing comma and closing bracket - this makes it malformed JSON

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,19 @@
{
"_type": "export",
"__export_format": 4,
"resources": [
{
"_id": "req_123",
"parentId": "wrk_456",
"url": "https://api.example.com/users",
"name": "Get Users",
"method": "GET",
"_type": "request"
},
{
"_id": "wrk_456",
"name": "Test Collection",
"_type": "workspace"
// Missing comma and closing bracket - malformed JSON
}
]

View File

@@ -0,0 +1,113 @@
{
"_type": "export",
"__export_format": 4,
"__export_date": "2025-01-01T12:00:00.000Z",
"__export_source": "insomnia.desktop.app:v10.3.1",
"resources": [
{
"_id": "req_fdedb34f7d5541d0aa7a917ce37ec067",
"parentId": "wrk_398c634c4fbc4774bcff39cbff44b31b",
"modified": 1689952276171,
"created": 1689951240510,
"url": "{{baseUrl}}/api/users",
"name": "Get Users",
"description": "Fetch all users from the API",
"method": "GET",
"body": {},
"parameters": [],
"headers": [
{
"name": "Accept",
"value": "application/json"
}
],
"authentication": {},
"metaSortKey": -1689951414329,
"isPrivate": false,
"settingStoreCookies": true,
"settingSendCookies": true,
"settingDisableRenderRequestBody": false,
"settingEncodeUrl": true,
"settingRebuildPath": true,
"settingFollowRedirects": "global",
"_type": "request"
},
{
"_id": "req_c920d219404144e8bc6b6bd36f442974",
"parentId": "fld_ab2a1533f2be48c194883bf07d693292",
"modified": 1689952281595,
"created": 1689951281897,
"url": "{{baseUrl}}/api/auth/login",
"name": "Login User",
"description": "User authentication endpoint",
"method": "POST",
"body": {
"mimeType": "application/json",
"text": "{\n \"username\": \"admin\",\n \"password\": \"password123\"\n}"
},
"parameters": [],
"headers": [
{
"name": "Content-Type",
"value": "application/json"
}
],
"authentication": {},
"metaSortKey": -1689951404530.5625,
"isPrivate": false,
"settingStoreCookies": true,
"settingSendCookies": true,
"settingDisableRenderRequestBody": false,
"settingEncodeUrl": true,
"settingRebuildPath": true,
"settingFollowRedirects": "global",
"_type": "request"
},
{
"_id": "fld_ab2a1533f2be48c194883bf07d693292",
"parentId": "wrk_398c634c4fbc4774bcff39cbff44b31b",
"modified": 1743683080329,
"created": 1743683080329,
"name": "Authentication",
"description": "Authentication related endpoints",
"environment": {},
"environmentPropertyOrder": null,
"metaSortKey": -1743683080329,
"_type": "request_group"
},
{
"_id": "wrk_398c634c4fbc4774bcff39cbff44b31b",
"parentId": null,
"modified": 1743678539806,
"created": 1743678539806,
"name": "Test API Collection v4",
"description": "Test collection for Insomnia v4 format",
"scope": "collection",
"_type": "workspace"
},
{
"_id": "env_93781eb62f074459bb67692112b76da0",
"parentId": "wrk_398c634c4fbc4774bcff39cbff44b31b",
"modified": 1743681240772,
"created": 1689951235312,
"name": "Base Environment",
"data": {
"baseUrl": "https://api.example.com"
},
"dataPropertyOrder": null,
"color": null,
"isPrivate": false,
"metaSortKey": 1689951235312,
"_type": "environment"
},
{
"_id": "jar_09963a0322c24b698ecd2f866ae9a6ab",
"parentId": "wrk_398c634c4fbc4774bcff39cbff44b31b",
"modified": 1689951235313,
"created": 1689951235313,
"name": "Default Jar",
"cookies": [],
"_type": "cookie_jar"
}
]
}

View File

@@ -0,0 +1,23 @@
type: collection.insomnia.rest/5.0
name: Invalid v5 Collection
meta:
id: wrk_7faf891d273e4b7ea82bdbaa641ee17a
created: 1743683067888
modified: 1743683067888
# Missing collection array - this should cause import to fail
cookieJar:
name: Default Jar
meta:
id: jar_25f97142fa796ae37f7f4937c0ebf3a07869d0a8
created: 1743683067908
modified: 1743683833282
cookies: []
environments:
name: Base Environment
meta:
id: env_25f97142fa796ae37f7f4937c0ebf3a07869d0a8
created: 1743683067895
modified: 1743683476058
isPrivate: false
data:
base_url: https://api.example.com

View File

@@ -0,0 +1,129 @@
type: collection.insomnia.rest/5.0
name: Test API Collection v5
meta:
id: wrk_7faf891d273e4b7ea82bdbaa641ee17a
created: 1743683067888
modified: 1743683067888
collection:
- name: API Tests
meta:
id: fld_ab2a1533f2be48c194883bf07d693292
created: 1743683080329
modified: 1743683080329
sortKey: -1743683080329
children:
- name: Authentication
meta:
id: fld_e7bcaad160254179a9c86e39a58c6893
created: 1743683088154
modified: 1743683090190
sortKey: -1743683090140
children:
- url: "{{ _.base_url }}/api/auth/login"
name: Login User
meta:
id: req_d48ab8553cff4eb486b816e064cf99a4
created: 1743683199141
modified: 1743683342872
isPrivate: false
sortKey: -1743683199141
method: POST
body:
mimeType: application/json
text: |-
{
"username": "testuser",
"password": "testpass123"
}
headers:
- name: Content-Type
value: application/json
- name: User-Agent
value: insomnia/10.3.1
settings:
renderRequestBody: true
encodeUrl: true
followRedirects: global
cookies:
send: true
store: true
rebuildPath: true
- url: "{{ _.base_url }}/api/users"
name: Get Users
meta:
id: req_0393b8ff4ee1454daddacdda33fd33ea
created: 1743683426423
modified: 1743683632735
isPrivate: false
description: Retrieve all users from the system
sortKey: -1743683429031
method: GET
headers:
- name: Authorization
value: Bearer {{ _.auth_token }}
- name: User-Agent
value: insomnia/10.3.1
settings:
renderRequestBody: true
encodeUrl: true
followRedirects: global
cookies:
send: true
store: true
rebuildPath: true
- name: Data Management
meta:
id: fld_4736de73a1634b16960fa9e90d78f868
created: 1743683403969
modified: 1743683403969
sortKey: -1743683403969
children:
- url: "{{ _.base_url }}/api/posts"
name: Create Post
meta:
id: req_10db7ec1332d4444aa551e70a1bfae33
created: 1743683795359
modified: 1743683832200
isPrivate: false
sortKey: -1743683429131
method: POST
body:
mimeType: application/json
text: |-
{
"title": "Test Post",
"content": "This is a test post content",
"author": "Test Author"
}
headers:
- name: Content-Type
value: application/json
- name: Authorization
value: Bearer {{ _.auth_token }}
- name: User-Agent
value: insomnia/10.3.1
settings:
renderRequestBody: true
encodeUrl: true
followRedirects: global
cookies:
send: true
store: true
rebuildPath: true
cookieJar:
name: Default Jar
meta:
id: jar_25f97142fa796ae37f7f4937c0ebf3a07869d0a8
created: 1743683067908
modified: 1743683833282
cookies: []
environments:
name: Base Environment
meta:
id: env_25f97142fa796ae37f7f4937c0ebf3a07869d0a8
created: 1743683067895
modified: 1743683476058
isPrivate: false
data:
base_url: https://api.example.com
auth_token: your_auth_token_here

View File

@@ -0,0 +1 @@
{ "invalid": json syntax }

View File

@@ -0,0 +1 @@
This is not a valid collection file

View File

@@ -0,0 +1,374 @@
openapi: 3.0.3
info:
title: Comprehensive API Test Collection
description: A comprehensive API for testing OpenAPI v3 imports with various features
version: 2.1.0
contact:
name: API Support
email: support@example.com
license:
name: MIT
url: https://opensource.org/licenses/MIT
servers:
- url: https://api.example.com/v1
description: Production server
- url: https://staging-api.example.com/v1
description: Staging server
- url: http://localhost:3000/v1
description: Development server
security:
- bearerAuth: []
- apiKey: []
paths:
/users:
get:
summary: Get all users
description: Retrieve a paginated list of all users
tags:
- Users
parameters:
- name: page
in: query
description: Page number for pagination
schema:
type: integer
minimum: 1
default: 1
- name: limit
in: query
description: Number of items per page
schema:
type: integer
minimum: 1
maximum: 100
default: 20
- name: filter
in: query
description: Filter users by name or email
schema:
type: string
responses:
'200':
description: List of users retrieved successfully
content:
application/json:
schema:
type: object
properties:
users:
type: array
items:
$ref: '#/components/schemas/User'
pagination:
$ref: '#/components/schemas/Pagination'
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
post:
summary: Create a new user
description: Create a new user account
tags:
- Users
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/CreateUserRequest'
responses:
'201':
description: User created successfully
content:
application/json:
schema:
$ref: '#/components/schemas/User'
'400':
$ref: '#/components/responses/BadRequest'
'409':
description: User already exists
/users/{userId}:
get:
summary: Get user by ID
description: Retrieve a specific user by their ID
tags:
- Users
parameters:
- name: userId
in: path
required: true
description: The user ID
schema:
type: string
format: uuid
responses:
'200':
description: User retrieved successfully
content:
application/json:
schema:
$ref: '#/components/schemas/User'
'404':
$ref: '#/components/responses/NotFound'
put:
summary: Update user
description: Update an existing user
tags:
- Users
parameters:
- name: userId
in: path
required: true
description: The user ID
schema:
type: string
format: uuid
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/UpdateUserRequest'
responses:
'200':
description: User updated successfully
content:
application/json:
schema:
$ref: '#/components/schemas/User'
'404':
$ref: '#/components/responses/NotFound'
delete:
summary: Delete user
description: Delete a user account
tags:
- Users
parameters:
- name: userId
in: path
required: true
description: The user ID
schema:
type: string
format: uuid
responses:
'204':
description: User deleted successfully
'404':
$ref: '#/components/responses/NotFound'
/auth/login:
post:
summary: User login
description: Authenticate user and get access token
tags:
- Authentication
security: [] # No security required for login
requestBody:
required: true
content:
application/json:
schema:
type: object
required:
- email
- password
properties:
email:
type: string
format: email
password:
type: string
minLength: 8
responses:
'200':
description: Login successful
content:
application/json:
schema:
type: object
properties:
token:
type: string
expiresIn:
type: integer
user:
$ref: '#/components/schemas/User'
'401':
description: Invalid credentials
/posts:
get:
summary: Get all posts
description: Retrieve all blog posts
tags:
- Posts
parameters:
- name: author
in: query
description: Filter by author ID
schema:
type: string
- name: category
in: query
description: Filter by category
schema:
type: string
responses:
'200':
description: List of posts
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/Post'
post:
summary: Create a new post
description: Create a new blog post
tags:
- Posts
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/CreatePostRequest'
responses:
'201':
description: Post created successfully
content:
application/json:
schema:
$ref: '#/components/schemas/Post'
components:
securitySchemes:
bearerAuth:
type: http
scheme: bearer
bearerFormat: JWT
apiKey:
type: apiKey
in: header
name: X-API-Key
schemas:
User:
type: object
properties:
id:
type: string
format: uuid
email:
type: string
format: email
name:
type: string
avatar:
type: string
format: uri
createdAt:
type: string
format: date-time
updatedAt:
type: string
format: date-time
CreateUserRequest:
type: object
required:
- email
- name
- password
properties:
email:
type: string
format: email
name:
type: string
minLength: 2
password:
type: string
minLength: 8
avatar:
type: string
format: uri
UpdateUserRequest:
type: object
properties:
name:
type: string
minLength: 2
avatar:
type: string
format: uri
Post:
type: object
properties:
id:
type: string
format: uuid
title:
type: string
content:
type: string
author:
$ref: '#/components/schemas/User'
category:
type: string
publishedAt:
type: string
format: date-time
createdAt:
type: string
format: date-time
CreatePostRequest:
type: object
required:
- title
- content
- category
properties:
title:
type: string
minLength: 5
content:
type: string
minLength: 10
category:
type: string
Pagination:
type: object
properties:
page:
type: integer
limit:
type: integer
total:
type: integer
totalPages:
type: integer
Error:
type: object
properties:
error:
type: string
message:
type: string
code:
type: integer
responses:
BadRequest:
description: Bad request
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
Unauthorized:
description: Unauthorized
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
NotFound:
description: Resource not found
content:
application/json:
schema:
$ref: '#/components/schemas/Error'

View File

@@ -0,0 +1,16 @@
openapi: 2.0 # Invalid version - only v3 is supported
info:
title: Invalid OpenAPI Version
description: This uses OpenAPI v2 which is not supported
version: 1.0.0
host: api.example.com
basePath: /v1
schemes:
- https
paths:
/users:
get:
summary: Get users
responses:
'200':
description: List of users

View File

@@ -0,0 +1,16 @@
openapi: 3.0.0
info:
title: Malformed OpenAPI
version: 1.0.0
paths:
/test:
get:
summary: Test endpoint
responses:
'200':
description: Success
# Missing closing quotes and malformed YAML
'400':
description: Bad request
malformed: yaml here
extra: indentation

View File

@@ -0,0 +1,9 @@
openapi: 3.0.0
# Missing required info section
paths:
/test:
get:
summary: Test endpoint
responses:
'200':
description: Success

View File

@@ -0,0 +1,116 @@
{
"openapi": "3.0.0",
"info": {
"title": "Simple Test API",
"description": "A simple API for basic OpenAPI testing",
"version": "1.0.0"
},
"servers": [
{
"url": "https://httpbin.org",
"description": "HTTPBin test server"
}
],
"paths": {
"/get": {
"get": {
"summary": "HTTP GET test",
"description": "Test HTTP GET request",
"responses": {
"200": {
"description": "Successful response",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"args": {
"type": "object"
},
"headers": {
"type": "object"
},
"origin": {
"type": "string"
},
"url": {
"type": "string"
}
}
}
}
}
}
}
}
},
"/post": {
"post": {
"summary": "HTTP POST test",
"description": "Test HTTP POST request",
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"data": {
"type": "string"
}
}
}
}
}
},
"responses": {
"200": {
"description": "Successful response",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"json": {
"type": "object"
},
"origin": {
"type": "string"
},
"url": {
"type": "string"
}
}
}
}
}
}
}
}
},
"/status/{code}": {
"get": {
"summary": "Return status code",
"description": "Return a specific HTTP status code",
"parameters": [
{
"name": "code",
"in": "path",
"required": true,
"description": "HTTP status code to return",
"schema": {
"type": "integer",
"minimum": 100,
"maximum": 599
}
}
],
"responses": {
"default": {
"description": "Returns the specified status code"
}
}
}
}
}
}

View File

@@ -0,0 +1,11 @@
{
"item": [
{
"name": "Request without info",
"request": {
"method": "GET",
"url": "https://example.com"
}
}
]
}

View File

@@ -0,0 +1,7 @@
{
"info": {
"name": "Invalid Schema Collection",
"schema": "https://schema.getpostman.com/json/collection/v999.0.0/collection.json"
},
"item": []
}

View File

@@ -0,0 +1,6 @@
{
"info": {
"name": "Malformed Collection"
},
"item": "this should be an array, not a string"
}

View File

@@ -0,0 +1,17 @@
{
"info": {
"name": "Postman v2.0 Collection",
"description": "Test collection using Postman Collection Format v2.0",
"schema": "https://schema.getpostman.com/json/collection/v2.0.0/collection.json"
},
"item": [
{
"name": "Get Posts",
"request": {
"method": "GET",
"header": [],
"url": "https://jsonplaceholder.typicode.com/posts"
}
}
]
}

View File

@@ -0,0 +1,64 @@
{
"info": {
"name": "Postman v2.1 Collection",
"description": "Test collection using Postman Collection Format v2.1",
"schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json",
"_postman_id": "12345678-1234-1234-1234-123456789012"
},
"item": [
{
"name": "Get Users",
"request": {
"method": "GET",
"header": [
{
"key": "Authorization",
"value": "Bearer {{token}}",
"type": "text"
}
],
"url": {
"raw": "{{baseUrl}}/users",
"host": ["{{baseUrl}}"],
"path": ["users"],
"query": [
{
"key": "page",
"value": "1"
}
]
}
},
"response": []
},
{
"name": "Create User",
"request": {
"method": "POST",
"header": [
{
"key": "Content-Type",
"value": "application/json",
"type": "text"
}
],
"body": {
"mode": "raw",
"raw": "{\n \"name\": \"John Doe\",\n \"email\": \"john@example.com\"\n}"
},
"url": {
"raw": "{{baseUrl}}/users",
"host": ["{{baseUrl}}"],
"path": ["users"]
}
},
"response": []
}
],
"variable": [
{
"key": "baseUrl",
"value": "https://api.example.com"
}
]
}

View File

@@ -9,7 +9,7 @@ const ModalHeader = ({ title, handleCancel, customHeader, hideClose }) => (
<div className="bruno-modal-header">
{customHeader ? customHeader : <>{title ? <div className="bruno-modal-header-title">{title}</div> : null}</>}
{handleCancel && !hideClose ? (
<div className="close cursor-pointer" onClick={handleCancel ? () => handleCancel() : null}>
<div className="close cursor-pointer" onClick={handleCancel ? () => handleCancel() : null} data-test-id="modal-close-button">
×
</div>
) : null}

View File

@@ -78,7 +78,7 @@ const TitleBar = () => {
) : null}
<div className="flex items-center">
<button className="flex items-center gap-2 text-sm font-medium" onClick={handleTitleClick}>
<button className="bruno-logo flex items-center gap-2 text-sm font-medium" onClick={handleTitleClick}>
<span aria-hidden>
<Bruno width={30} />
</span>