mirror of
https://github.com/usebruno/bruno.git
synced 2026-06-23 12:45:38 +00:00
fix: tests
This commit is contained in:
@@ -288,6 +288,7 @@ const Collection = ({ collection, searchText }) => {
|
||||
className="dropdown-item"
|
||||
onClick={(_e) => {
|
||||
menuDropdownTippyRef.current.hide();
|
||||
ensureCollectionIsMounted();
|
||||
setShowNewRequestModal(true);
|
||||
}}
|
||||
>
|
||||
@@ -300,6 +301,7 @@ const Collection = ({ collection, searchText }) => {
|
||||
className="dropdown-item"
|
||||
onClick={(_e) => {
|
||||
menuDropdownTippyRef.current.hide();
|
||||
ensureCollectionIsMounted();
|
||||
setShowNewFolderModal(true);
|
||||
}}
|
||||
>
|
||||
|
||||
@@ -43,7 +43,7 @@ const Collections = ({ showSearch }) => {
|
||||
}
|
||||
|
||||
return (
|
||||
<StyledWrapper>
|
||||
<StyledWrapper data-testid="collections">
|
||||
{createCollectionModalOpen ? (
|
||||
<CreateCollection
|
||||
onClose={() => setCreateCollectionModalOpen(false)}
|
||||
|
||||
@@ -43,7 +43,7 @@ const CreateCollection = ({ onClose, workspaceUid, defaultLocation: propDefaultL
|
||||
initialValues: {
|
||||
collectionName: '',
|
||||
collectionFolderName: '',
|
||||
collectionLocation: isDefaultWorkspace ? '' : (defaultLocation || ''),
|
||||
collectionLocation: defaultLocation || '',
|
||||
format: 'yml'
|
||||
},
|
||||
validationSchema: Yup.object({
|
||||
|
||||
@@ -29,11 +29,10 @@ const TitleBar = ({ showSearch, setShowSearch }) => {
|
||||
return sortWorkspaces(workspaces, preferences);
|
||||
}, [workspaces, preferences]);
|
||||
|
||||
const [importedCollection, setImportedCollection] = useState(null);
|
||||
const [importData, setImportData] = useState(null);
|
||||
const [createCollectionModalOpen, setCreateCollectionModalOpen] = useState(false);
|
||||
const [importCollectionModalOpen, setImportCollectionModalOpen] = useState(false);
|
||||
const [importCollectionLocationModalOpen, setImportCollectionLocationModalOpen] = useState(false);
|
||||
const [importType, setImportType] = useState(null);
|
||||
const [createWorkspaceModalOpen, setCreateWorkspaceModalOpen] = useState(false);
|
||||
|
||||
const toTitleCase = (str) => {
|
||||
@@ -45,43 +44,31 @@ const TitleBar = ({ showSearch, setShowSearch }) => {
|
||||
.join(' ');
|
||||
};
|
||||
|
||||
const handleImportCollection = ({ rawData, type, environment }) => {
|
||||
setImportedCollection(rawData);
|
||||
setImportType(type);
|
||||
const handleImportCollection = ({ rawData, type }) => {
|
||||
setImportCollectionModalOpen(false);
|
||||
|
||||
if (activeWorkspace) {
|
||||
if (activeWorkspace && activeWorkspace.type !== 'default') {
|
||||
dispatch(importCollectionInWorkspace(rawData, activeWorkspace.uid, undefined, type))
|
||||
.catch((err) => {
|
||||
toast.error('An error occurred while importing the collection');
|
||||
});
|
||||
} else {
|
||||
setImportData({ rawData, type });
|
||||
setImportCollectionLocationModalOpen(true);
|
||||
}
|
||||
};
|
||||
|
||||
const handleImportCollectionLocation = (collectionLocation, selectedCollections) => {
|
||||
const isMultipleImport = importType && (importType === 'multiple' || importType === 'bulk');
|
||||
const collectionsToImport = !isMultipleImport ? importedCollection : importedCollection.filter((collection) =>
|
||||
selectedCollections.includes(collection.uid));
|
||||
|
||||
const collectionsArray = Array.isArray(collectionsToImport) ? collectionsToImport : [collectionsToImport];
|
||||
if (collectionsArray.length === 0 || (collectionsArray.length === 1 && !collectionsArray[0])) {
|
||||
toast.error('Please select at least one collection to import.');
|
||||
return;
|
||||
}
|
||||
|
||||
setImportCollectionLocationModalOpen(false);
|
||||
|
||||
if (activeWorkspace) {
|
||||
dispatch(importCollectionInWorkspace(collectionsToImport, activeWorkspace.uid, collectionLocation))
|
||||
.catch((err) => {
|
||||
console.error(err);
|
||||
toast.error('An error occurred while importing the collection');
|
||||
});
|
||||
} else {
|
||||
dispatch(importCollection(collectionsToImport, collectionLocation));
|
||||
}
|
||||
const handleImportCollectionLocation = (convertedCollection, collectionLocation) => {
|
||||
dispatch(importCollection(convertedCollection, collectionLocation))
|
||||
.then(() => {
|
||||
setImportCollectionLocationModalOpen(false);
|
||||
setImportData(null);
|
||||
toast.success('Collection imported successfully');
|
||||
})
|
||||
.catch((err) => {
|
||||
console.error(err);
|
||||
toast.error('An error occurred while importing the collection');
|
||||
});
|
||||
};
|
||||
|
||||
const [showWorkspaceDropdown, setShowWorkspaceDropdown] = useState(false);
|
||||
@@ -155,8 +142,8 @@ const TitleBar = ({ showSearch, setShowSearch }) => {
|
||||
<CreateCollection
|
||||
onClose={() => setCreateCollectionModalOpen(false)}
|
||||
workspaceUid={activeWorkspace?.uid}
|
||||
defaultLocation={activeWorkspace?.pathname ? `${activeWorkspace.pathname}/collections` : ''}
|
||||
hideLocationInput={!!activeWorkspace?.pathname}
|
||||
defaultLocation={activeWorkspace?.type !== 'default' && activeWorkspace?.pathname ? `${activeWorkspace.pathname}/collections` : undefined}
|
||||
hideLocationInput={activeWorkspace?.type !== 'default' && !!activeWorkspace?.pathname}
|
||||
/>
|
||||
)}
|
||||
{importCollectionModalOpen && (
|
||||
@@ -165,9 +152,10 @@ const TitleBar = ({ showSearch, setShowSearch }) => {
|
||||
handleSubmit={handleImportCollection}
|
||||
/>
|
||||
)}
|
||||
{importCollectionLocationModalOpen && (
|
||||
{importCollectionLocationModalOpen && importData && (
|
||||
<ImportCollectionLocation
|
||||
collectionName={Array.isArray(importedCollection) ? importedCollection?.[0]?.name : importedCollection?.name}
|
||||
rawData={importData.rawData}
|
||||
format={importData.type}
|
||||
onClose={() => setImportCollectionLocationModalOpen(false)}
|
||||
handleSubmit={handleImportCollectionLocation}
|
||||
/>
|
||||
|
||||
@@ -27,15 +27,15 @@ const transformCollection = async (collection, type) => {
|
||||
return postmanToBruno(collection);
|
||||
}
|
||||
case 'insomnia': {
|
||||
const { insomniaToBruno } = await import('utils/importers/insomnia-collection');
|
||||
return insomniaToBruno(collection);
|
||||
const { convertInsomniaToBruno } = await import('utils/importers/insomnia-collection');
|
||||
return convertInsomniaToBruno(collection);
|
||||
}
|
||||
case 'openapi': {
|
||||
const { openapiToBruno } = await import('utils/importers/openapi-collection');
|
||||
return openapiToBruno(collection);
|
||||
const { convertOpenapiToBruno } = await import('utils/importers/openapi-collection');
|
||||
return convertOpenapiToBruno(collection);
|
||||
}
|
||||
case 'wsdl': {
|
||||
const { wsdlToBruno } = await import('utils/importers/wsdl-collection');
|
||||
const { wsdlToBruno } = await import('@usebruno/converters');
|
||||
return wsdlToBruno(collection);
|
||||
}
|
||||
default:
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const fsExtra = require('fs-extra');
|
||||
const { ipcMain, dialog } = require('electron');
|
||||
const { createDirectory, sanitizeName } = require('../utils/filesystem');
|
||||
const { generateUidBasedOnHash } = require('../utils/common');
|
||||
@@ -114,6 +115,8 @@ const registerWorkspaceIpc = (mainWindow, workspaceWatcher) => {
|
||||
validateWorkspacePath(workspacePath);
|
||||
|
||||
const workspaceConfig = readWorkspaceConfig(workspacePath);
|
||||
validateWorkspaceConfig(workspaceConfig);
|
||||
|
||||
const workspaceUid = generateUidBasedOnHash(workspacePath);
|
||||
|
||||
lastOpenedWorkspaces.add(workspacePath, workspaceConfig);
|
||||
@@ -350,7 +353,6 @@ const registerWorkspaceIpc = (mainWindow, workspaceWatcher) => {
|
||||
|
||||
// Delete collection files if it's a workspace collection
|
||||
if (result.shouldDeleteFiles && result.removedCollection && fs.existsSync(collectionPath)) {
|
||||
const fsExtra = require('fs-extra');
|
||||
await fsExtra.remove(collectionPath);
|
||||
}
|
||||
|
||||
|
||||
@@ -72,6 +72,7 @@ class DefaultWorkspaceManager {
|
||||
const workspaceYmlPath = path.join(newWorkspacePath, 'workspace.yml');
|
||||
if (!fs.existsSync(workspaceYmlPath)) {
|
||||
this.defaultWorkspacePath = null;
|
||||
return null;
|
||||
} else {
|
||||
return {
|
||||
workspacePath: newWorkspacePath,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { test, expect } from '../../../playwright';
|
||||
import { closeAllCollections } from '../../utils/page';
|
||||
import { closeAllCollections, openCollectionAndAcceptSandbox } from '../../utils/page';
|
||||
import { buildCommonLocators } from '../../utils/page/locators';
|
||||
|
||||
test.describe('Create GraphQL Requests', () => {
|
||||
@@ -7,6 +7,7 @@ test.describe('Create GraphQL Requests', () => {
|
||||
|
||||
test.beforeAll(async ({ pageWithUserData: page }) => {
|
||||
locators = buildCommonLocators(page);
|
||||
await openCollectionAndAcceptSandbox(page, 'create-requests', 'safe');
|
||||
});
|
||||
|
||||
test.afterAll(async ({ pageWithUserData: page }) => {
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
import { test, expect } from '../../../playwright';
|
||||
import { buildCommonLocators } from '../../utils/page/locators';
|
||||
import { closeAllCollections } from '../../utils/page';
|
||||
import { closeAllCollections, openCollectionAndAcceptSandbox } from '../../utils/page';
|
||||
|
||||
test.describe('Create gRPC Requests', () => {
|
||||
let locators: ReturnType<typeof buildCommonLocators>;
|
||||
|
||||
test.beforeAll(async ({ pageWithUserData: page }) => {
|
||||
locators = buildCommonLocators(page);
|
||||
await openCollectionAndAcceptSandbox(page, 'create-requests', 'safe');
|
||||
});
|
||||
|
||||
test.afterAll(async ({ pageWithUserData: page }) => {
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
import { test, expect } from '../../../playwright';
|
||||
import { buildCommonLocators } from '../../utils/page/locators';
|
||||
import { closeAllCollections } from '../../utils/page';
|
||||
import { closeAllCollections, openCollectionAndAcceptSandbox } from '../../utils/page';
|
||||
|
||||
test.describe('Create HTTP Requests', () => {
|
||||
let locators: ReturnType<typeof buildCommonLocators>;
|
||||
|
||||
test.beforeAll(async ({ pageWithUserData: page }) => {
|
||||
locators = buildCommonLocators(page);
|
||||
await openCollectionAndAcceptSandbox(page, 'create-requests', 'safe');
|
||||
});
|
||||
|
||||
test.afterAll(async ({ pageWithUserData: page }) => {
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
import { test, expect } from '../../../playwright';
|
||||
import { buildCommonLocators } from '../../utils/page/locators';
|
||||
import { closeAllCollections } from '../../utils/page';
|
||||
import { closeAllCollections, openCollectionAndAcceptSandbox } from '../../utils/page';
|
||||
|
||||
test.describe('Create WebSocket Requests', () => {
|
||||
let locators: ReturnType<typeof buildCommonLocators>;
|
||||
|
||||
test.beforeAll(async ({ pageWithUserData: page }) => {
|
||||
locators = buildCommonLocators(page);
|
||||
await openCollectionAndAcceptSandbox(page, 'create-requests', 'safe');
|
||||
});
|
||||
|
||||
test.afterAll(async ({ pageWithUserData: page }) => {
|
||||
|
||||
@@ -8,14 +8,17 @@ test.describe('Create collection', () => {
|
||||
});
|
||||
|
||||
test('Create collection and add a simple HTTP request', async ({ page, createTmpDir }) => {
|
||||
// Create a new collection
|
||||
await page.getByLabel('Create Collection').click();
|
||||
await page.locator('.plus-icon-button').click();
|
||||
await page.locator('.tippy-box .dropdown-item').filter({ hasText: 'Create collection' }).click();
|
||||
await page.getByLabel('Name').click();
|
||||
await page.getByLabel('Name').fill('test-collection');
|
||||
await page.getByLabel('Name').press('Tab');
|
||||
await page.getByLabel('Location').fill(await createTmpDir('test-collection'));
|
||||
await page.getByRole('button', { name: 'Create', exact: true }).click();
|
||||
await page.getByText('test-collection').click();
|
||||
const locationInput = page.locator('.bruno-modal').getByLabel('Location');
|
||||
if (await locationInput.isVisible()) {
|
||||
await locationInput.fill(await createTmpDir('test-collection'));
|
||||
}
|
||||
await page.locator('.bruno-modal').getByRole('button', { name: 'Create', exact: true }).click();
|
||||
await page.locator('#sidebar-collection-name').filter({ hasText: 'test-collection' }).click();
|
||||
|
||||
// Select safe mode
|
||||
await page.getByLabel('Safe Mode').check();
|
||||
|
||||
@@ -8,12 +8,16 @@ test.describe('Tag persistence', () => {
|
||||
});
|
||||
|
||||
test('Verify tag persistence while moving requests within a collection', async ({ page, createTmpDir }) => {
|
||||
// Create first collection - click dropdown menu first
|
||||
await page.getByLabel('Create Collection').click();
|
||||
// Create first collection - click plus icon button to open dropdown
|
||||
await page.locator('.plus-icon-button').click();
|
||||
await page.locator('.tippy-box .dropdown-item').filter({ hasText: 'Create collection' }).click();
|
||||
await page.getByLabel('Name').fill('test-collection');
|
||||
await page.getByLabel('Location').fill(await createTmpDir('test-collection'));
|
||||
await page.getByRole('button', { name: 'Create', exact: true }).click();
|
||||
await page.getByText('test-collection').click();
|
||||
const locationInput = page.locator('.bruno-modal').getByLabel('Location');
|
||||
if (await locationInput.isVisible()) {
|
||||
await locationInput.fill(await createTmpDir('test-collection'));
|
||||
}
|
||||
await page.locator('.bruno-modal').getByRole('button', { name: 'Create', exact: true }).click();
|
||||
await page.locator('#sidebar-collection-name').filter({ hasText: 'test-collection' }).click();
|
||||
await page.getByLabel('Safe Mode').check();
|
||||
await page.getByRole('button', { name: 'Save' }).click();
|
||||
|
||||
@@ -74,12 +78,16 @@ test.describe('Tag persistence', () => {
|
||||
});
|
||||
|
||||
test('verify tag persistence while moving requests between folders', async ({ page, createTmpDir }) => {
|
||||
// Create first collection - click dropdown menu first
|
||||
await page.getByLabel('Create Collection').click();
|
||||
// Create first collection - click plus icon button to open dropdown
|
||||
await page.locator('.plus-icon-button').click();
|
||||
await page.locator('.tippy-box .dropdown-item').filter({ hasText: 'Create collection' }).click();
|
||||
await page.getByLabel('Name').fill('test-collection');
|
||||
await page.getByLabel('Location').fill(await createTmpDir('test-collection'));
|
||||
await page.getByRole('button', { name: 'Create', exact: true }).click();
|
||||
await page.getByText('test-collection').click();
|
||||
const locationInput = page.locator('.bruno-modal').getByLabel('Location');
|
||||
if (await locationInput.isVisible()) {
|
||||
await locationInput.fill(await createTmpDir('test-collection'));
|
||||
}
|
||||
await page.locator('.bruno-modal').getByRole('button', { name: 'Create', exact: true }).click();
|
||||
await page.locator('#sidebar-collection-name').filter({ hasText: 'test-collection' }).click();
|
||||
await page.getByLabel('Safe Mode').check();
|
||||
await page.getByRole('button', { name: 'Save' }).click();
|
||||
|
||||
|
||||
@@ -9,11 +9,14 @@ test.describe('Move tabs', () => {
|
||||
|
||||
test('Verify tab move by drag and drop', async ({ page, createTmpDir }) => {
|
||||
// Create a collection
|
||||
await page.locator('.dropdown-icon').click();
|
||||
await page.locator('.dropdown-item').filter({ hasText: 'Create Collection' }).click();
|
||||
await page.locator('.plus-icon-button').click();
|
||||
await page.locator('.tippy-box .dropdown-item').filter({ hasText: 'Create collection' }).click();
|
||||
await page.getByLabel('Name').fill('source-collection-drag-drop');
|
||||
await page.getByLabel('Location').fill(await createTmpDir('source-collection-drag-drop'));
|
||||
await page.getByRole('button', { name: 'Create', exact: true }).click();
|
||||
const locationInput = page.locator('.bruno-modal').getByLabel('Location');
|
||||
if (await locationInput.isVisible()) {
|
||||
await locationInput.fill(await createTmpDir('source-collection-drag-drop'));
|
||||
}
|
||||
await page.locator('.bruno-modal').getByRole('button', { name: 'Create', exact: true }).click();
|
||||
|
||||
// Wait for collection to appear and click on it
|
||||
await expect(page.locator('#sidebar-collection-name').filter({ hasText: 'source-collection-drag-drop' })).toBeVisible();
|
||||
@@ -97,11 +100,14 @@ test.describe('Move tabs', () => {
|
||||
|
||||
test('Verify tab move by keyboard shortcut', async ({ page, createTmpDir }) => {
|
||||
// Create a collection
|
||||
await page.locator('.dropdown-icon').click();
|
||||
await page.locator('.dropdown-item').filter({ hasText: 'Create Collection' }).click();
|
||||
await page.locator('.plus-icon-button').click();
|
||||
await page.locator('.tippy-box .dropdown-item').filter({ hasText: 'Create collection' }).click();
|
||||
await page.getByLabel('Name').fill('source-collection-keyboard-shortcut');
|
||||
await page.getByLabel('Location').fill(await createTmpDir('source-collection-keyboard-shortcut'));
|
||||
await page.getByRole('button', { name: 'Create', exact: true }).click();
|
||||
const locationInput2 = page.locator('.bruno-modal').getByLabel('Location');
|
||||
if (await locationInput2.isVisible()) {
|
||||
await locationInput2.fill(await createTmpDir('source-collection-keyboard-shortcut'));
|
||||
}
|
||||
await page.locator('.bruno-modal').getByRole('button', { name: 'Create', exact: true }).click();
|
||||
|
||||
// Wait for collection to appear and click on it
|
||||
await expect(page.locator('#sidebar-collection-name').filter({ hasText: 'source-collection-keyboard-shortcut' })).toBeVisible();
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import { test, expect } from '../../../playwright';
|
||||
import * as path from 'path';
|
||||
import * as fs from 'fs';
|
||||
|
||||
import { closeAllCollections } from '../../utils/page';
|
||||
|
||||
test.describe('Open Multiple Collections', () => {
|
||||
@@ -57,8 +56,9 @@ test.describe('Open Multiple Collections', () => {
|
||||
|
||||
await expect(page.locator('#sidebar-collection-name').getByText('Test Collection 1')).not.toBeVisible();
|
||||
|
||||
// Click on Open Collection button
|
||||
await page.locator('button').filter({ hasText: 'Open Collection' }).click();
|
||||
// Click on plus icon button and then "Open collection" in the dropdown
|
||||
await page.locator('.plus-icon-button').click();
|
||||
await page.locator('.tippy-box .dropdown-item').filter({ hasText: 'Open collection' }).click();
|
||||
|
||||
// Wait for both collections to appear in the sidebar
|
||||
const collection1Element = page.locator('#sidebar-collection-name').getByText('Test Collection 1');
|
||||
@@ -80,6 +80,9 @@ test.describe('Open Multiple Collections', () => {
|
||||
const collection1Dir = await createTmpDir('collection-1');
|
||||
const collection2Dir = 'invalid-collection-path';
|
||||
|
||||
// Count collections before attempting to open invalid ones
|
||||
const collectionCountBefore = await page.locator('#sidebar-collection-name').count();
|
||||
|
||||
// Mock the electron dialog to return multiple folder selections
|
||||
await electronApp.evaluate(({ dialog }, { collection1Dir, collection2Dir }) => {
|
||||
dialog.showOpenDialog = async () => ({
|
||||
@@ -89,20 +92,17 @@ test.describe('Open Multiple Collections', () => {
|
||||
},
|
||||
{ collection1Dir, collection2Dir });
|
||||
|
||||
await expect(page.locator('#sidebar-collection-name').getByText('Test Collection 1')).not.toBeVisible();
|
||||
await page.locator('.plus-icon-button').click();
|
||||
await page.locator('.tippy-box .dropdown-item').filter({ hasText: 'Open collection' }).click();
|
||||
|
||||
// Click on Open Collection button
|
||||
await page.getByRole('button', { name: 'Open Collection' }).click();
|
||||
// Wait for error toasts to appear
|
||||
await page.waitForTimeout(1000);
|
||||
|
||||
// Verify no collections were opened
|
||||
await expect(page.locator('#sidebar-collection-name')).toHaveCount(0);
|
||||
await expect(page.locator('#sidebar-collection-name')).toHaveCount(collectionCountBefore);
|
||||
|
||||
// Verify invalid collection error
|
||||
const invalidCollectionError = page.getByText('The collection is not valid').first();
|
||||
await expect(invalidCollectionError).toBeVisible();
|
||||
|
||||
// Verify invalid path error
|
||||
const invalidPathError = page.getByText('Some selected folders could not be opened').getByText('invalid-collection-path').first();
|
||||
await expect(invalidPathError).toBeVisible();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -9,7 +9,8 @@ test.describe('Collection Environment Create Tests', () => {
|
||||
const openApiFile = path.join(__dirname, 'fixtures', 'bruno-collection.json');
|
||||
|
||||
// Import test collection
|
||||
await page.getByRole('button', { name: 'Import Collection' }).click();
|
||||
await page.locator('.plus-icon-button').click();
|
||||
await page.locator('.tippy-box .dropdown-item').filter({ hasText: 'Import collection' }).click();
|
||||
|
||||
const importModal = page.locator('[data-testid="import-collection-modal"]');
|
||||
await importModal.waitFor({ state: 'visible' });
|
||||
@@ -21,7 +22,7 @@ test.describe('Collection Environment Create Tests', () => {
|
||||
await expect(locationModal.getByText('test_collection')).toBeVisible();
|
||||
|
||||
await page.locator('#collection-location').fill(await createTmpDir('env-test'));
|
||||
await page.getByRole('button', { name: 'Import', exact: true }).click();
|
||||
await locationModal.getByRole('button', { name: 'Import' }).click();
|
||||
|
||||
await expect(page.locator('#sidebar-collection-name').filter({ hasText: 'test_collection' })).toBeVisible();
|
||||
|
||||
@@ -113,18 +114,13 @@ test.describe('Collection Environment Create Tests', () => {
|
||||
await expect(responsePane).toContainText('"body": "This is a test post body with environment variables"');
|
||||
await expect(responsePane).toContainText('"apiToken": "super-secret-token-12345"');
|
||||
|
||||
// Cleanup
|
||||
await page
|
||||
.locator('.collection-name')
|
||||
.filter({ has: page.locator('#sidebar-collection-name:has-text("test_collection")') })
|
||||
.locator('.collection-actions')
|
||||
.click();
|
||||
await page.locator('.dropdown-item').filter({ hasText: 'Close' }).click();
|
||||
// Scope the Close button to the confirmation modal to avoid matching the dropdown close button
|
||||
// Wait for the confirmation modal with "Close Collection" title to appear
|
||||
const closeModal = page.getByRole('dialog').filter({ has: page.getByText('Close Collection') });
|
||||
await closeModal.getByRole('button', { name: 'Close' }).click();
|
||||
// Cleanup - use new "Remove" action in workspace UI
|
||||
const collectionRow = page.locator('.collection-name').filter({ has: page.locator('#sidebar-collection-name:has-text("test_collection")') });
|
||||
await collectionRow.hover();
|
||||
await collectionRow.locator('.collection-actions .icon').click();
|
||||
await page.locator('.dropdown-item').filter({ hasText: 'Remove' }).click();
|
||||
|
||||
await page.locator('.bruno-logo').click();
|
||||
const closeModal = page.getByRole('dialog').filter({ has: page.getByText('Remove Collection') });
|
||||
await closeModal.getByRole('button', { name: 'Remove' }).click();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { test, expect } from '../../../playwright';
|
||||
import path from 'path';
|
||||
import { closeAllCollections } from '../../utils/page';
|
||||
|
||||
test.describe('Global Environment Create Tests', () => {
|
||||
test('should import collection and create global environment for request usage', async ({
|
||||
@@ -9,20 +10,22 @@ test.describe('Global Environment Create Tests', () => {
|
||||
const openApiFile = path.join(__dirname, 'fixtures', 'bruno-collection.json');
|
||||
|
||||
// Import test collection
|
||||
await page.getByRole('button', { name: 'Import Collection' }).click();
|
||||
await page.locator('.plus-icon-button').click();
|
||||
await page.locator('.tippy-box .dropdown-item').filter({ hasText: 'Import collection' }).click();
|
||||
|
||||
const importModal = page.locator('[data-testid="import-collection-modal"]');
|
||||
await importModal.waitFor({ state: 'visible' });
|
||||
|
||||
await page.setInputFiles('input[type="file"]', openApiFile);
|
||||
await page.locator('#import-collection-loader').waitFor({ state: 'hidden' });
|
||||
|
||||
// Wait for location modal to appear after file processing
|
||||
const locationModal = page.locator('[data-testid="import-collection-location-modal"]');
|
||||
await locationModal.waitFor({ state: 'visible', timeout: 10000 });
|
||||
await expect(locationModal.locator('.bruno-modal-header-title')).toContainText('Import Collection');
|
||||
await expect(locationModal.getByText('test_collection')).toBeVisible();
|
||||
|
||||
await page.locator('#collection-location').fill(await createTmpDir('global-env-test'));
|
||||
await page.getByRole('button', { name: 'Import', exact: true }).click();
|
||||
await locationModal.getByRole('button', { name: 'Import' }).click();
|
||||
|
||||
await expect(page.locator('#sidebar-collection-name').filter({ hasText: 'test_collection' })).toBeVisible();
|
||||
|
||||
@@ -116,18 +119,7 @@ test.describe('Global Environment Create Tests', () => {
|
||||
await expect(responsePane).toContainText('"body": "This is a global test post body with environment variables"');
|
||||
await expect(responsePane).toContainText('"apiToken": "global-secret-token-12345"');
|
||||
|
||||
// Cleanup
|
||||
await page
|
||||
.locator('.collection-name')
|
||||
.filter({ has: page.locator('#sidebar-collection-name:has-text("test_collection")') })
|
||||
.locator('.collection-actions')
|
||||
.click();
|
||||
await page.locator('.dropdown-item').filter({ hasText: 'Close' }).click();
|
||||
// Scope the Close button to the confirmation modal to avoid matching the dropdown close button
|
||||
// Wait for the confirmation modal with "Close Collection" title to appear
|
||||
const closeModal = page.getByRole('dialog').filter({ has: page.getByText('Close Collection') });
|
||||
await closeModal.getByRole('button', { name: 'Close' }).click();
|
||||
|
||||
await page.locator('.bruno-logo').click();
|
||||
// cleanup: close all collections
|
||||
await closeAllCollections(page);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -12,24 +12,24 @@ test.describe('Collection Environment Import Tests', () => {
|
||||
const envFile = path.join(__dirname, 'fixtures', 'collection-env.json');
|
||||
|
||||
// Import test collection
|
||||
await page.getByRole('button', { name: 'Import Collection' }).click();
|
||||
await page.locator('.plus-icon-button').click();
|
||||
await page.locator('.tippy-box .dropdown-item').filter({ hasText: 'Import collection' }).click();
|
||||
|
||||
const importModal = page.locator('[data-testid="import-collection-modal"]');
|
||||
await importModal.waitFor({ state: 'visible' });
|
||||
|
||||
await page.setInputFiles('input[type="file"]', openApiFile);
|
||||
await page.locator('#import-collection-loader').waitFor({ state: 'hidden' });
|
||||
|
||||
const locationModal = page.locator('[data-testid="import-collection-location-modal"]');
|
||||
await expect(locationModal.locator('.bruno-modal-header-title')).toContainText('Import Collection');
|
||||
await expect(locationModal.getByText('Environment Test Collection')).toBeVisible();
|
||||
|
||||
// Select a location and import
|
||||
await page.locator('#collection-location').fill(await createTmpDir('collection-env-import-test'));
|
||||
await page.getByRole('button', { name: 'Import', exact: true }).click();
|
||||
await locationModal.getByRole('button', { name: 'Import' }).click();
|
||||
|
||||
await expect(
|
||||
page.locator('#sidebar-collection-name').filter({ hasText: 'Environment Test Collection' })
|
||||
).toBeVisible();
|
||||
page.locator('#sidebar-collection-name').filter({ hasText: 'Environment Test Collection' })).toBeVisible({ timeout: 10000 });
|
||||
|
||||
// Configure collection
|
||||
await page.locator('#sidebar-collection-name').filter({ hasText: 'Environment Test Collection' }).click();
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { test, expect } from '../../../playwright';
|
||||
import path from 'path';
|
||||
import { closeAllCollections } from '../../utils/page';
|
||||
|
||||
test.describe('Global Environment Import Tests', () => {
|
||||
test('should import global environment from file', async ({ newPage: page, createTmpDir }) => {
|
||||
@@ -7,24 +8,23 @@ test.describe('Global Environment Import Tests', () => {
|
||||
const globalEnvFile = path.join(__dirname, 'fixtures', 'global-env.json');
|
||||
|
||||
// Import test collection
|
||||
await page.getByRole('button', { name: 'Import Collection' }).click();
|
||||
await page.locator('.plus-icon-button').click();
|
||||
await page.locator('.tippy-box .dropdown-item').filter({ hasText: 'Import collection' }).click();
|
||||
|
||||
const importModal = page.locator('[data-testid="import-collection-modal"]');
|
||||
await importModal.waitFor({ state: 'visible' });
|
||||
|
||||
await page.setInputFiles('input[type="file"]', openApiFile);
|
||||
await page.locator('#import-collection-loader').waitFor({ state: 'hidden' });
|
||||
|
||||
const locationModal = page.locator('[data-testid="import-collection-location-modal"]');
|
||||
await expect(locationModal.locator('.bruno-modal-header-title')).toContainText('Import Collection');
|
||||
await expect(locationModal.getByText('Environment Test Collection')).toBeVisible();
|
||||
|
||||
await page.locator('#collection-location').fill(await createTmpDir('global-env-import-test'));
|
||||
await page.getByRole('button', { name: 'Import', exact: true }).click();
|
||||
await locationModal.getByRole('button', { name: 'Import' }).click();
|
||||
|
||||
await expect(
|
||||
page.locator('#sidebar-collection-name').filter({ hasText: 'Environment Test Collection' })
|
||||
).toBeVisible();
|
||||
page.locator('#sidebar-collection-name').filter({ hasText: 'Environment Test Collection' })).toBeVisible({ timeout: 10000 });
|
||||
|
||||
// Configure collection
|
||||
await page.locator('#sidebar-collection-name').filter({ hasText: 'Environment Test Collection' }).click();
|
||||
@@ -79,16 +79,7 @@ test.describe('Global Environment Import Tests', () => {
|
||||
await page.locator('[data-testid="response-status-code"]').waitFor({ state: 'visible' });
|
||||
await expect(page.locator('[data-testid="response-status-code"]')).toContainText('201');
|
||||
|
||||
// Cleanup
|
||||
await page.locator('#sidebar-collection-name').filter({ hasText: 'Environment Test Collection' }).click();
|
||||
await page
|
||||
.locator('.collection-name')
|
||||
.filter({ has: page.locator('#sidebar-collection-name:has-text("Environment Test Collection")') })
|
||||
.locator('.collection-actions')
|
||||
.click();
|
||||
await page.locator('.dropdown-item').filter({ hasText: 'Close' }).click();
|
||||
await page.locator('.dropdown-item').filter({ hasText: 'Close' }).waitFor({ state: 'detached' });
|
||||
const closeModal = page.getByRole('dialog').filter({ has: page.getByText('Close Collection') });
|
||||
await closeModal.getByRole('button', { name: 'Close' }).click();
|
||||
// cleanup: close all collections
|
||||
await closeAllCollections(page);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -5,8 +5,9 @@ test.describe('Multiline Variables - Read Environment Test', () => {
|
||||
test.setTimeout(30 * 1000);
|
||||
|
||||
// open the collection
|
||||
await expect(page.getByTitle('multiline-variables')).toBeVisible();
|
||||
await page.getByTitle('multiline-variables').click();
|
||||
const collection = page.getByTestId('collections').locator('#sidebar-collection-name').filter({ hasText: 'multiline-variables' });
|
||||
await expect(collection).toBeVisible();
|
||||
await collection.click();
|
||||
|
||||
// open request
|
||||
await expect(page.getByTitle('request', { exact: true })).toBeVisible();
|
||||
|
||||
@@ -5,8 +5,9 @@ test.describe('Multiline Variables - Write Test', () => {
|
||||
test.setTimeout(60 * 1000);
|
||||
|
||||
// open the collection
|
||||
await expect(page.getByTitle('multiline-variables')).toBeVisible();
|
||||
await page.getByTitle('multiline-variables').click();
|
||||
const collection = page.getByTestId('collections').locator('#sidebar-collection-name').filter({ hasText: 'multiline-variables' });
|
||||
await expect(collection).toBeVisible();
|
||||
await collection.click();
|
||||
|
||||
// open request
|
||||
await expect(page.getByTitle('multiline-test', { exact: true })).toBeVisible();
|
||||
@@ -89,7 +90,4 @@ test.describe('Multiline Variables - Write Test', () => {
|
||||
fs.writeFileSync(testBruPath, content);
|
||||
});
|
||||
|
||||
test.afterAll(async ({ page }) => {
|
||||
await page.locator('.bruno-logo').click();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -5,7 +5,8 @@ test.describe('Import Corrupted Bruno Collection - Should Fail', () => {
|
||||
test('Import Bruno collection with invalid JSON structure should fail', async ({ page }) => {
|
||||
const brunoFile = path.resolve(__dirname, 'fixtures', 'bruno-malformed.json');
|
||||
|
||||
await page.getByRole('button', { name: 'Import Collection' }).click();
|
||||
await page.locator('.plus-icon-button').click();
|
||||
await page.locator('.tippy-box .dropdown-item').filter({ hasText: 'Import collection' }).click();
|
||||
|
||||
// Wait for import collection modal to be ready
|
||||
const importModal = page.getByRole('dialog');
|
||||
@@ -14,16 +15,13 @@ test.describe('Import Corrupted Bruno Collection - Should Fail', () => {
|
||||
|
||||
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();
|
||||
const hasImportError = await page.getByText('Failed to parse the file – ensure it is valid JSON or YAML').first().isVisible({ timeout: 5000 });
|
||||
|
||||
// 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();
|
||||
await page.getByTestId('modal-close-button').click();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -5,7 +5,8 @@ test.describe('Import Bruno Collection - Missing Required Schema Fields', () =>
|
||||
test('Import Bruno collection missing required version field should fail', async ({ page }) => {
|
||||
const brunoFile = path.resolve(__dirname, 'fixtures', 'bruno-missing-required-fields.json');
|
||||
|
||||
await page.getByRole('button', { name: 'Import Collection' }).click();
|
||||
await page.locator('.plus-icon-button').click();
|
||||
await page.locator('.tippy-box .dropdown-item').filter({ hasText: 'Import collection' }).click();
|
||||
|
||||
// Wait for import collection modal to be ready
|
||||
const importModal = page.getByRole('dialog');
|
||||
@@ -14,15 +15,12 @@ test.describe('Import Bruno Collection - Missing Required Schema Fields', () =>
|
||||
|
||||
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('Unsupported collection format').first().isVisible();
|
||||
const hasImportError = await page.getByText('Unsupported collection format').first().isVisible({ timeout: 5000 });
|
||||
|
||||
expect(hasImportError).toBe(true);
|
||||
|
||||
// Cleanup: close any open modals
|
||||
await page.locator('[data-test-id="modal-close-button"]').click();
|
||||
await page.getByTestId('modal-close-button').click();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -3,20 +3,15 @@ import * as path from 'path';
|
||||
import { closeAllCollections } from '../../utils/page';
|
||||
|
||||
test.describe('Import Bruno Testbench Collection', () => {
|
||||
test.beforeAll(async ({ page }) => {
|
||||
// Navigate back to homescreen after all tests
|
||||
await page.locator('.bruno-logo').click();
|
||||
});
|
||||
|
||||
test.afterEach(async ({ page }) => {
|
||||
// cleanup: close all collections
|
||||
test.afterAll(async ({ page }) => {
|
||||
await closeAllCollections(page);
|
||||
});
|
||||
|
||||
test('Import Bruno Testbench collection successfully', async ({ page, createTmpDir }) => {
|
||||
const brunoFile = path.resolve(__dirname, 'fixtures', 'bruno-testbench.json');
|
||||
|
||||
await page.getByRole('button', { name: 'Import Collection' }).click();
|
||||
await page.locator('.plus-icon-button').click();
|
||||
await page.locator('.tippy-box .dropdown-item').filter({ hasText: 'Import collection' }).click();
|
||||
|
||||
// Wait for import collection modal to be ready
|
||||
const importModal = page.getByRole('dialog');
|
||||
@@ -25,18 +20,16 @@ test.describe('Import Bruno Testbench 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');
|
||||
// Wait for location modal to appear after file processing
|
||||
const locationModal = page.locator('[data-testid="import-collection-location-modal"]');
|
||||
await locationModal.waitFor({ state: 'visible', timeout: 10000 });
|
||||
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();
|
||||
|
||||
await page.locator('#collection-location').fill(await createTmpDir('bruno-testbench-test'));
|
||||
await page.getByRole('button', { name: 'Import', exact: true }).click();
|
||||
await locationModal.getByRole('button', { name: 'Import' }).click();
|
||||
|
||||
await expect(page.locator('#sidebar-collection-name').getByText('bruno-testbench')).toBeVisible();
|
||||
});
|
||||
|
||||
@@ -11,7 +11,8 @@ test.describe('Import Bruno Collection with Examples', () => {
|
||||
const brunoFile = path.resolve(__dirname, 'fixtures', 'bruno-with-examples.json');
|
||||
|
||||
await test.step('Open import collection modal', async () => {
|
||||
await page.getByRole('button', { name: 'Import Collection' }).click();
|
||||
await page.locator('.plus-icon-button').click();
|
||||
await page.locator('.tippy-box .dropdown-item').filter({ hasText: 'Import collection' }).click();
|
||||
});
|
||||
|
||||
await test.step('Wait for import modal and verify title', async () => {
|
||||
@@ -24,10 +25,6 @@ test.describe('Import Bruno Collection with Examples', () => {
|
||||
await page.setInputFiles('input[type="file"]', brunoFile);
|
||||
});
|
||||
|
||||
await test.step('Wait for file processing to complete', async () => {
|
||||
await page.locator('#import-collection-loader').waitFor({ state: 'hidden' });
|
||||
});
|
||||
|
||||
await test.step('Verify no parsing errors occurred', async () => {
|
||||
const hasError = await page.getByText('Failed to parse the file').isVisible().catch(() => false);
|
||||
if (hasError) {
|
||||
@@ -36,12 +33,12 @@ test.describe('Import Bruno Collection with Examples', () => {
|
||||
});
|
||||
|
||||
await test.step('Verify location selection modal appears', async () => {
|
||||
const locationModal = page.getByRole('dialog');
|
||||
const locationModal = page.locator('[data-testid="import-collection-location-modal"]');
|
||||
await expect(locationModal.locator('.bruno-modal-header-title')).toContainText('Import Collection');
|
||||
});
|
||||
|
||||
await test.step('Verify collection name appears in location modal', async () => {
|
||||
const locationModal = page.getByRole('dialog');
|
||||
const locationModal = page.locator('[data-testid="import-collection-location-modal"]');
|
||||
await expect(locationModal.getByText('bruno-with-examples')).toBeVisible();
|
||||
await page.getByTestId('modal-close-button').click();
|
||||
});
|
||||
|
||||
@@ -2,7 +2,8 @@ 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();
|
||||
await page.locator('.plus-icon-button').click();
|
||||
await page.locator('.tippy-box .dropdown-item').filter({ hasText: 'Import collection' }).click();
|
||||
|
||||
// Check that file input exists (even if hidden)
|
||||
const fileInput = page.locator('input[type="file"]');
|
||||
|
||||
@@ -5,7 +5,8 @@ test.describe('Invalid File Handling', () => {
|
||||
test('Handle invalid file without crashing', async ({ page }) => {
|
||||
const invalidFile = path.resolve(__dirname, 'fixtures', 'invalid.txt');
|
||||
|
||||
await page.getByRole('button', { name: 'Import Collection' }).click();
|
||||
await page.locator('.plus-icon-button').click();
|
||||
await page.locator('.tippy-box .dropdown-item').filter({ hasText: 'Import collection' }).click();
|
||||
|
||||
// Wait for import collection modal to be ready
|
||||
const importModal = page.getByRole('dialog');
|
||||
|
||||
@@ -23,7 +23,8 @@ test.describe('Import Insomnia v4 Collection - Environment Import', () => {
|
||||
const insomniaFile = path.resolve(__dirname, 'fixtures', 'insomnia-v4-with-envs.json');
|
||||
|
||||
await test.step('Import Insomnia v4 collection with environments', async () => {
|
||||
await page.getByRole('button', { name: 'Import Collection' }).click();
|
||||
await page.locator('.plus-icon-button').click();
|
||||
await page.locator('.tippy-box .dropdown-item').filter({ hasText: 'Import collection' }).click();
|
||||
|
||||
const importModal = page.getByTestId('import-collection-modal');
|
||||
await importModal.waitFor({ state: 'visible' });
|
||||
@@ -31,13 +32,13 @@ test.describe('Import Insomnia v4 Collection - Environment Import', () => {
|
||||
|
||||
await page.setInputFiles('input[type="file"]', insomniaFile);
|
||||
|
||||
await page.locator('#import-collection-loader').waitFor({ state: 'hidden' });
|
||||
const locationModal = page.locator('[data-testid="import-collection-location-modal"]');
|
||||
await locationModal.waitFor({ state: 'visible', timeout: 10000 });
|
||||
|
||||
const locationModal = page.getByTestId('import-collection-location-modal');
|
||||
await expect(locationModal.getByText('Test API Collection v4 with Environments')).toBeVisible();
|
||||
|
||||
await page.locator('#collection-location').fill(await createTmpDir('insomnia-v4-env-test'));
|
||||
await page.getByRole('button', { name: 'Import', exact: true }).click();
|
||||
await locationModal.getByRole('button', { name: 'Import' }).click();
|
||||
|
||||
await expect(page.locator('#sidebar-collection-name').getByText('Test API Collection v4 with Environments')).toBeVisible();
|
||||
|
||||
|
||||
@@ -11,7 +11,8 @@ test.describe('Import Insomnia Collection v4', () => {
|
||||
test('Import Insomnia Collection v4 successfully', async ({ page, createTmpDir }) => {
|
||||
const insomniaFile = path.resolve(__dirname, 'fixtures', 'insomnia-v4.json');
|
||||
|
||||
await page.getByRole('button', { name: 'Import Collection' }).click();
|
||||
await page.locator('.plus-icon-button').click();
|
||||
await page.locator('.tippy-box .dropdown-item').filter({ hasText: 'Import collection' }).click();
|
||||
|
||||
// Wait for import collection modal to be ready
|
||||
const importModal = page.getByRole('dialog');
|
||||
@@ -20,15 +21,13 @@ test.describe('Import Insomnia Collection v4', () => {
|
||||
|
||||
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');
|
||||
// Wait for location modal to appear after file processing
|
||||
const locationModal = page.locator('[data-testid="import-collection-location-modal"]');
|
||||
await locationModal.waitFor({ state: 'visible', timeout: 10000 });
|
||||
await expect(locationModal.locator('.bruno-modal-header-title')).toContainText('Import Collection');
|
||||
|
||||
await page.locator('#collection-location').fill(await createTmpDir('insomnia-v4-test'));
|
||||
await page.getByRole('button', { name: 'Import', exact: true }).click();
|
||||
await locationModal.getByRole('button', { name: 'Import' }).click();
|
||||
|
||||
await expect(page.locator('#sidebar-collection-name').getByText('Test API Collection v4')).toBeVisible();
|
||||
});
|
||||
|
||||
@@ -23,7 +23,8 @@ test.describe('Import Insomnia v5 Collection - Environment Import', () => {
|
||||
const insomniaFile = path.resolve(__dirname, 'fixtures', 'insomnia-v5-with-envs.yaml');
|
||||
|
||||
await test.step('Import Insomnia v5 collection with environments', async () => {
|
||||
await page.getByRole('button', { name: 'Import Collection' }).click();
|
||||
await page.locator('.plus-icon-button').click();
|
||||
await page.locator('.tippy-box .dropdown-item').filter({ hasText: 'Import collection' }).click();
|
||||
|
||||
const importModal = page.getByTestId('import-collection-modal');
|
||||
await importModal.waitFor({ state: 'visible' });
|
||||
@@ -31,15 +32,12 @@ test.describe('Import Insomnia v5 Collection - Environment Import', () => {
|
||||
|
||||
await page.setInputFiles('input[type="file"]', insomniaFile);
|
||||
|
||||
await page.locator('#import-collection-loader').waitFor({ state: 'hidden' });
|
||||
|
||||
const locationModal = page.getByTestId('import-collection-location-modal');
|
||||
await expect(locationModal.getByText('Test API Collection v5 with Environments')).toBeVisible();
|
||||
// Wait for location modal to appear after file processing
|
||||
const locationModal = page.locator('[data-testid="import-collection-location-modal"]');
|
||||
await locationModal.waitFor({ state: 'visible', timeout: 10000 });
|
||||
|
||||
await page.locator('#collection-location').fill(await createTmpDir('insomnia-v5-env-test'));
|
||||
await page.getByRole('button', { name: 'Import', exact: true }).click();
|
||||
|
||||
await expect(page.getByText('Test API Collection v5 with Environments')).toBeVisible();
|
||||
await locationModal.getByRole('button', { name: 'Import' }).click();
|
||||
|
||||
await openCollectionAndAcceptSandbox(page, 'Test API Collection v5 with Environments', 'safe');
|
||||
});
|
||||
|
||||
@@ -11,7 +11,8 @@ test.describe('Import Insomnia Collection v5', () => {
|
||||
test('Import Insomnia Collection v5 successfully', async ({ page, createTmpDir }) => {
|
||||
const insomniaFile = path.resolve(__dirname, 'fixtures', 'insomnia-v5.yaml');
|
||||
|
||||
await page.getByRole('button', { name: 'Import Collection' }).click();
|
||||
await page.locator('.plus-icon-button').click();
|
||||
await page.locator('.tippy-box .dropdown-item').filter({ hasText: 'Import collection' }).click();
|
||||
|
||||
// Wait for import collection modal to be ready
|
||||
const importModal = page.getByRole('dialog');
|
||||
@@ -20,15 +21,13 @@ test.describe('Import Insomnia Collection v5', () => {
|
||||
|
||||
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');
|
||||
// Wait for location modal to appear after file processing
|
||||
const locationModal = page.locator('[data-testid="import-collection-location-modal"]');
|
||||
await locationModal.waitFor({ state: 'visible', timeout: 10000 });
|
||||
await expect(locationModal.locator('.bruno-modal-header-title')).toContainText('Import Collection');
|
||||
|
||||
await page.locator('#collection-location').fill(await createTmpDir('insomnia-v5-test'));
|
||||
await page.getByRole('button', { name: 'Import', exact: true }).click();
|
||||
await locationModal.getByRole('button', { name: 'Import' }).click();
|
||||
|
||||
await expect(page.locator('#sidebar-collection-name').getByText('Test API Collection v5')).toBeVisible();
|
||||
});
|
||||
|
||||
@@ -5,7 +5,8 @@ test.describe('Invalid Insomnia Collection - Missing Collection Array', () => {
|
||||
test('Handle Insomnia v5 collection missing collection array', async ({ page }) => {
|
||||
const insomniaFile = path.resolve(__dirname, 'fixtures', 'insomnia-v5-invalid-missing-collection.yaml');
|
||||
|
||||
await page.getByRole('button', { name: 'Import Collection' }).click();
|
||||
await page.locator('.plus-icon-button').click();
|
||||
await page.locator('.tippy-box .dropdown-item').filter({ hasText: 'Import collection' }).click();
|
||||
|
||||
// Wait for import collection modal to be ready
|
||||
const importModal = page.getByRole('dialog');
|
||||
@@ -14,9 +15,6 @@ test.describe('Invalid Insomnia Collection - Missing Collection Array', () => {
|
||||
|
||||
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('Unsupported collection format').first().isVisible();
|
||||
expect(hasError).toBe(true);
|
||||
|
||||
@@ -5,7 +5,8 @@ test.describe('Invalid Insomnia Collection - Malformed Structure', () => {
|
||||
test('Handle malformed Insomnia collection structure', async ({ page }) => {
|
||||
const insomniaFile = path.resolve(__dirname, 'fixtures', 'insomnia-malformed.json');
|
||||
|
||||
await page.getByRole('button', { name: 'Import Collection' }).click();
|
||||
await page.locator('.plus-icon-button').click();
|
||||
await page.locator('.tippy-box .dropdown-item').filter({ hasText: 'Import collection' }).click();
|
||||
|
||||
// Wait for import collection modal to be ready
|
||||
const importModal = page.getByRole('dialog');
|
||||
@@ -14,8 +15,6 @@ test.describe('Invalid Insomnia Collection - Malformed Structure', () => {
|
||||
|
||||
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').first().isVisible();
|
||||
|
||||
@@ -12,7 +12,8 @@ test.describe('OpenAPI Duplicate Names Handling', () => {
|
||||
const openApiFile = path.resolve(__dirname, 'fixtures', 'openapi-duplicate-operation-name.yaml');
|
||||
|
||||
// start the import process
|
||||
await page.getByRole('button', { name: 'Import Collection' }).click();
|
||||
await page.locator('.plus-icon-button').click();
|
||||
await page.locator('.tippy-box .dropdown-item').filter({ hasText: 'Import collection' }).click();
|
||||
|
||||
// wait for the import collection modal to appear
|
||||
const importModal = page.getByTestId('import-collection-modal');
|
||||
@@ -21,12 +22,15 @@ test.describe('OpenAPI Duplicate Names Handling', () => {
|
||||
// upload the OpenAPI file with duplicate operation names
|
||||
await page.setInputFiles('input[type="file"]', openApiFile);
|
||||
|
||||
// Wait for location modal to appear after file processing
|
||||
const locationModal = page.locator('[data-testid="import-collection-location-modal"]');
|
||||
await locationModal.waitFor({ state: 'visible', timeout: 10000 });
|
||||
|
||||
// wait for the file processing to complete
|
||||
await page.locator('#import-collection-loader').waitFor({ state: 'hidden' });
|
||||
|
||||
// select a location
|
||||
await page.locator('#collection-location').fill(await createTmpDir('duplicate-test'));
|
||||
await page.getByRole('button', { name: 'Import', exact: true }).click();
|
||||
await locationModal.getByRole('button', { name: 'Import' }).click();
|
||||
|
||||
// verify the collection was imported successfully
|
||||
await expect(page.locator('#sidebar-collection-name').getByText('Duplicate Test Collection')).toBeVisible();
|
||||
|
||||
@@ -11,7 +11,8 @@ test.describe('Import OpenAPI v3 JSON Collection', () => {
|
||||
test('Import simple OpenAPI v3 JSON successfully', async ({ page, createTmpDir }) => {
|
||||
const openApiFile = path.resolve(__dirname, 'fixtures', 'openapi-simple.json');
|
||||
|
||||
await page.getByRole('button', { name: 'Import Collection' }).click();
|
||||
await page.locator('.plus-icon-button').click();
|
||||
await page.locator('.tippy-box .dropdown-item').filter({ hasText: 'Import collection' }).click();
|
||||
|
||||
// Wait for import collection modal to be ready
|
||||
const importModal = page.getByRole('dialog');
|
||||
@@ -20,11 +21,9 @@ test.describe('Import OpenAPI v3 JSON 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');
|
||||
// Wait for location modal to appear after file processing
|
||||
const locationModal = page.locator('[data-testid="import-collection-location-modal"]');
|
||||
await locationModal.waitFor({ state: 'visible', timeout: 10000 });
|
||||
await expect(locationModal.locator('.bruno-modal-header-title')).toContainText('Import Collection');
|
||||
|
||||
// Wait for collection to appear in the location modal
|
||||
@@ -32,7 +31,7 @@ test.describe('Import OpenAPI v3 JSON Collection', () => {
|
||||
|
||||
// Select a location and import
|
||||
await page.locator('#collection-location').fill(await createTmpDir('simple-test'));
|
||||
await page.getByRole('button', { name: 'Import', exact: true }).click();
|
||||
await locationModal.getByRole('button', { name: 'Import' }).click();
|
||||
|
||||
// Verify the collection was imported successfully
|
||||
await expect(page.locator('#sidebar-collection-name').getByText('Simple Test API')).toBeVisible();
|
||||
|
||||
@@ -35,7 +35,8 @@ test.describe('Import OpenAPI Collection with Examples', () => {
|
||||
}, { importDir });
|
||||
|
||||
await test.step('Open import collection modal', async () => {
|
||||
await page.getByRole('button', { name: 'Import Collection' }).click();
|
||||
await page.locator('.plus-icon-button').click();
|
||||
await page.locator('.tippy-box .dropdown-item').filter({ hasText: 'Import collection' }).click();
|
||||
});
|
||||
|
||||
await test.step('Wait for import modal and verify title', async () => {
|
||||
@@ -47,10 +48,10 @@ test.describe('Import OpenAPI Collection with Examples', () => {
|
||||
await test.step('Upload OpenAPI collection file using hidden file input', async () => {
|
||||
// The "choose a file" button triggers a hidden file input, so we can directly set files on it
|
||||
await page.setInputFiles('input[type="file"]', openApiFile);
|
||||
});
|
||||
|
||||
await test.step('Wait for file processing to complete', async () => {
|
||||
await page.locator('#import-collection-loader').waitFor({ state: 'hidden' });
|
||||
// Wait for location modal to appear after file processing
|
||||
const locationModal = page.locator('[data-testid="import-collection-location-modal"]');
|
||||
await locationModal.waitFor({ state: 'visible', timeout: 10000 });
|
||||
});
|
||||
|
||||
await test.step('Verify no parsing errors occurred', async () => {
|
||||
@@ -61,18 +62,18 @@ test.describe('Import OpenAPI Collection with Examples', () => {
|
||||
});
|
||||
|
||||
await test.step('Verify Import Collection location modal appears', async () => {
|
||||
const locationModal = page.getByRole('dialog');
|
||||
const locationModal = page.locator('[data-testid="import-collection-location-modal"]');
|
||||
await expect(locationModal.locator('.bruno-modal-header-title')).toContainText('Import Collection');
|
||||
await expect(locationModal.getByText('API with Examples')).toBeVisible();
|
||||
});
|
||||
|
||||
await test.step('Click Browse link to select collection folder', async () => {
|
||||
const locationModal = page.getByRole('dialog');
|
||||
const locationModal = page.locator('[data-testid="import-collection-location-modal"]');
|
||||
await locationModal.getByText('Browse').click();
|
||||
});
|
||||
|
||||
await test.step('Complete import by clicking import button', async () => {
|
||||
const locationModal = page.getByRole('dialog');
|
||||
const locationModal = page.locator('[data-testid="import-collection-location-modal"]');
|
||||
await locationModal.getByRole('button', { name: 'Import' }).click();
|
||||
});
|
||||
|
||||
@@ -151,7 +152,8 @@ test.describe('Import OpenAPI Collection with Examples', () => {
|
||||
}, { importDir });
|
||||
|
||||
await test.step('Open import collection modal', async () => {
|
||||
await page.getByRole('button', { name: 'Import Collection' }).click();
|
||||
await page.locator('.plus-icon-button').click();
|
||||
await page.locator('.tippy-box .dropdown-item').filter({ hasText: 'Import collection' }).click();
|
||||
});
|
||||
|
||||
await test.step('Wait for import modal and verify title', async () => {
|
||||
@@ -162,10 +164,10 @@ test.describe('Import OpenAPI Collection with Examples', () => {
|
||||
|
||||
await test.step('Upload OpenAPI collection file using hidden file input', async () => {
|
||||
await page.setInputFiles('input[type="file"]', openApiFile);
|
||||
});
|
||||
|
||||
await test.step('Wait for file processing to complete', async () => {
|
||||
await page.locator('#import-collection-loader').waitFor({ state: 'hidden' });
|
||||
// Wait for location modal to appear after file processing
|
||||
const locationModal = page.locator('[data-testid="import-collection-location-modal"]');
|
||||
await locationModal.waitFor({ state: 'visible', timeout: 10000 });
|
||||
});
|
||||
|
||||
await test.step('Verify no parsing errors occurred', async () => {
|
||||
@@ -176,13 +178,13 @@ test.describe('Import OpenAPI Collection with Examples', () => {
|
||||
});
|
||||
|
||||
await test.step('Verify Import Collection location modal appears', async () => {
|
||||
const locationModal = page.getByRole('dialog');
|
||||
const locationModal = page.locator('[data-testid="import-collection-location-modal"]');
|
||||
await expect(locationModal.locator('.bruno-modal-header-title')).toContainText('Import Collection');
|
||||
await expect(locationModal.getByText('API with Examples')).toBeVisible();
|
||||
});
|
||||
|
||||
await test.step('Select path-based grouping option from dropdown', async () => {
|
||||
const locationModal = page.getByRole('dialog');
|
||||
const locationModal = page.locator('[data-testid="import-collection-location-modal"]');
|
||||
|
||||
// Click on the grouping dropdown to open it
|
||||
const groupingDropdown = locationModal.getByTestId('grouping-dropdown');
|
||||
@@ -194,12 +196,12 @@ test.describe('Import OpenAPI Collection with Examples', () => {
|
||||
});
|
||||
|
||||
await test.step('Click Browse link to select collection folder', async () => {
|
||||
const locationModal = page.getByRole('dialog');
|
||||
const locationModal = page.locator('[data-testid="import-collection-location-modal"]');
|
||||
await locationModal.getByText('Browse').click();
|
||||
});
|
||||
|
||||
await test.step('Complete import by clicking import button', async () => {
|
||||
const locationModal = page.getByRole('dialog');
|
||||
const locationModal = page.locator('[data-testid="import-collection-location-modal"]');
|
||||
await locationModal.getByRole('button', { name: 'Import' }).click();
|
||||
});
|
||||
|
||||
|
||||
@@ -11,7 +11,8 @@ test.describe('Import OpenAPI v3 YAML Collection', () => {
|
||||
test('Import comprehensive OpenAPI v3 YAML successfully', async ({ page, createTmpDir }) => {
|
||||
const openApiFile = path.resolve(__dirname, 'fixtures', 'openapi-comprehensive.yaml');
|
||||
|
||||
await page.getByRole('button', { name: 'Import Collection' }).click();
|
||||
await page.locator('.plus-icon-button').click();
|
||||
await page.locator('.tippy-box .dropdown-item').filter({ hasText: 'Import collection' }).click();
|
||||
|
||||
// Wait for import collection modal to be ready
|
||||
const importModal = page.getByRole('dialog');
|
||||
@@ -20,11 +21,9 @@ test.describe('Import OpenAPI v3 YAML 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');
|
||||
// Wait for location modal to appear after file processing
|
||||
const locationModal = page.locator('[data-testid="import-collection-location-modal"]');
|
||||
await locationModal.waitFor({ state: 'visible', timeout: 10000 });
|
||||
await expect(locationModal.locator('.bruno-modal-header-title')).toContainText('Import Collection');
|
||||
|
||||
// Wait for collection to appear in the location modal
|
||||
@@ -32,7 +31,7 @@ test.describe('Import OpenAPI v3 YAML Collection', () => {
|
||||
|
||||
// Select a location and import
|
||||
await page.locator('#collection-location').fill(await createTmpDir('comprehensive-test'));
|
||||
await page.getByRole('button', { name: 'Import', exact: true }).click();
|
||||
await locationModal.getByRole('button', { name: 'Import' }).click();
|
||||
|
||||
// Verify the collection was imported successfully
|
||||
await expect(page.locator('#sidebar-collection-name').getByText('Comprehensive API Test Collection')).toBeVisible();
|
||||
|
||||
@@ -5,7 +5,8 @@ test.describe('Invalid OpenAPI - Malformed YAML', () => {
|
||||
test('Handle malformed OpenAPI YAML structure', async ({ page }) => {
|
||||
const openApiFile = path.resolve(__dirname, 'fixtures', 'openapi-malformed.yaml');
|
||||
|
||||
await page.getByRole('button', { name: 'Import Collection' }).click();
|
||||
await page.locator('.plus-icon-button').click();
|
||||
await page.locator('.tippy-box .dropdown-item').filter({ hasText: 'Import collection' }).click();
|
||||
|
||||
// Wait for import collection modal to be ready
|
||||
const importModal = page.getByRole('dialog');
|
||||
@@ -14,9 +15,6 @@ test.describe('Invalid OpenAPI - Malformed YAML', () => {
|
||||
|
||||
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();
|
||||
|
||||
@@ -5,7 +5,8 @@ test.describe('Invalid OpenAPI - Missing Info Section', () => {
|
||||
test('Handle OpenAPI specification missing required info section', async ({ page }) => {
|
||||
const openApiFile = path.resolve(__dirname, 'fixtures', 'openapi-missing-info.yaml');
|
||||
|
||||
await page.getByRole('button', { name: 'Import Collection' }).click();
|
||||
await page.locator('.plus-icon-button').click();
|
||||
await page.locator('.tippy-box .dropdown-item').filter({ hasText: 'Import collection' }).click();
|
||||
|
||||
// Wait for import collection modal to be ready
|
||||
const importModal = page.getByRole('dialog');
|
||||
@@ -14,9 +15,6 @@ test.describe('Invalid OpenAPI - Missing Info Section', () => {
|
||||
|
||||
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('Unsupported collection format').first().isVisible();
|
||||
|
||||
|
||||
@@ -12,7 +12,8 @@ test.describe('OpenAPI Newline Handling', () => {
|
||||
const openApiFile = path.resolve(__dirname, 'fixtures', 'openapi-newline-in-operation-name.yaml');
|
||||
|
||||
// start the import process
|
||||
await page.getByRole('button', { name: 'Import Collection' }).click();
|
||||
await page.locator('.plus-icon-button').click();
|
||||
await page.locator('.tippy-box .dropdown-item').filter({ hasText: 'Import collection' }).click();
|
||||
|
||||
// wait for the import collection modal to appear
|
||||
const importModal = page.getByTestId('import-collection-modal');
|
||||
@@ -21,13 +22,14 @@ test.describe('OpenAPI Newline Handling', () => {
|
||||
// upload the OpenAPI file with problematic operation names
|
||||
await page.setInputFiles('input[type="file"]', openApiFile);
|
||||
|
||||
// verify that the collection location modal appears (OpenAPI files go directly to location modal)
|
||||
const locationModal = page.getByTestId('import-collection-location-modal');
|
||||
// Wait for location modal to appear after file processing
|
||||
const locationModal = page.locator('[data-testid="import-collection-location-modal"]');
|
||||
await locationModal.waitFor({ state: 'visible', timeout: 10000 });
|
||||
await expect(locationModal.getByText('Newline Test Collection')).toBeVisible();
|
||||
|
||||
// select a location
|
||||
await page.locator('#collection-location').fill(await createTmpDir('newline-test'));
|
||||
await page.getByRole('button', { name: 'Import', exact: true }).click();
|
||||
await locationModal.getByRole('button', { name: 'Import' }).click();
|
||||
|
||||
// verify the collection was imported successfully
|
||||
await expect(page.locator('#sidebar-collection-name').getByText('Newline Test Collection')).toBeVisible();
|
||||
|
||||
@@ -12,7 +12,8 @@ test.describe('OpenAPI Path-Based Grouping', () => {
|
||||
const openApiFile = path.resolve(__dirname, 'fixtures', 'openapi-path-grouping.json');
|
||||
|
||||
// Start the import process
|
||||
await page.getByRole('button', { name: 'Import Collection' }).click();
|
||||
await page.locator('.plus-icon-button').click();
|
||||
await page.locator('.tippy-box .dropdown-item').filter({ hasText: 'Import collection' }).click();
|
||||
|
||||
// Wait for import collection modal to be ready
|
||||
const importModal = page.getByTestId('import-collection-modal');
|
||||
@@ -21,11 +22,9 @@ test.describe('OpenAPI Path-Based Grouping', () => {
|
||||
// Upload the OpenAPI file
|
||||
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 collection location modal appears
|
||||
const locationModal = page.getByTestId('import-collection-location-modal');
|
||||
// Wait for location modal to appear after file processing
|
||||
const locationModal = page.locator('[data-testid="import-collection-location-modal"]');
|
||||
await locationModal.waitFor({ state: 'visible', timeout: 10000 });
|
||||
await expect(locationModal.getByText('Path Grouping Test API')).toBeVisible();
|
||||
|
||||
// Select path-based grouping from dropdown
|
||||
@@ -34,7 +33,7 @@ test.describe('OpenAPI Path-Based Grouping', () => {
|
||||
|
||||
// Select a location and import
|
||||
await page.locator('#collection-location').fill(await createTmpDir('path-grouping-test'));
|
||||
await page.getByRole('button', { name: 'Import', exact: true }).click();
|
||||
await locationModal.getByRole('button', { name: 'Import' }).click();
|
||||
|
||||
// Verify the collection was imported successfully
|
||||
await expect(page.locator('#sidebar-collection-name').getByText('Path Grouping Test API')).toBeVisible();
|
||||
|
||||
@@ -11,7 +11,8 @@ test.describe('Import Postman Collection v2.0', () => {
|
||||
test('Import Postman Collection v2.0 successfully', async ({ page, createTmpDir }) => {
|
||||
const postmanFile = path.resolve(__dirname, 'fixtures', 'postman-v20.json');
|
||||
|
||||
await page.getByRole('button', { name: 'Import Collection' }).click();
|
||||
await page.locator('.plus-icon-button').click();
|
||||
await page.locator('.tippy-box .dropdown-item').filter({ hasText: 'Import collection' }).click();
|
||||
|
||||
// Wait for import collection modal to be ready
|
||||
const importModal = page.getByRole('dialog');
|
||||
@@ -20,11 +21,9 @@ test.describe('Import Postman Collection v2.0', () => {
|
||||
|
||||
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');
|
||||
// Wait for location modal to appear after file processing
|
||||
const locationModal = page.locator('[data-testid="import-collection-location-modal"]');
|
||||
await locationModal.waitFor({ state: 'visible', timeout: 10000 });
|
||||
await expect(locationModal.locator('.bruno-modal-header-title')).toContainText('Import Collection');
|
||||
|
||||
// Wait for collection to appear in the location modal
|
||||
@@ -32,7 +31,7 @@ test.describe('Import Postman Collection v2.0', () => {
|
||||
|
||||
// Select a location and import
|
||||
await page.locator('#collection-location').fill(await createTmpDir('postman-v20-test'));
|
||||
await page.getByRole('button', { name: 'Import', exact: true }).click();
|
||||
await locationModal.getByRole('button', { name: 'Import' }).click();
|
||||
|
||||
// Verify the collection was imported successfully
|
||||
await expect(page.locator('#sidebar-collection-name').getByText('Postman v2.0 Collection')).toBeVisible();
|
||||
|
||||
@@ -11,7 +11,8 @@ test.describe('Import Postman Collection v2.1', () => {
|
||||
test('Import Postman Collection v2.1 successfully', async ({ page, createTmpDir }) => {
|
||||
const postmanFile = path.resolve(__dirname, 'fixtures', 'postman-v21.json');
|
||||
|
||||
await page.getByRole('button', { name: 'Import Collection' }).click();
|
||||
await page.locator('.plus-icon-button').click();
|
||||
await page.locator('.tippy-box .dropdown-item').filter({ hasText: 'Import collection' }).click();
|
||||
|
||||
// Wait for import collection modal to be ready
|
||||
const importModal = page.getByRole('dialog');
|
||||
@@ -20,11 +21,9 @@ test.describe('Import Postman Collection v2.1', () => {
|
||||
|
||||
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');
|
||||
// Wait for location modal to appear after file processing
|
||||
const locationModal = page.locator('[data-testid="import-collection-location-modal"]');
|
||||
await locationModal.waitFor({ state: 'visible', timeout: 10000 });
|
||||
await expect(locationModal.locator('.bruno-modal-header-title')).toContainText('Import Collection');
|
||||
|
||||
// Wait for collection to appear in the location modal
|
||||
@@ -32,7 +31,7 @@ test.describe('Import Postman Collection v2.1', () => {
|
||||
|
||||
// Select a location and import
|
||||
await page.locator('#collection-location').fill(await createTmpDir('postman-v21-test'));
|
||||
await page.getByRole('button', { name: 'Import', exact: true }).click();
|
||||
await locationModal.getByRole('button', { name: 'Import' }).click();
|
||||
|
||||
// Verify the collection was imported successfully
|
||||
await expect(page.locator('#sidebar-collection-name').getByText('Postman v2.1 Collection')).toBeVisible();
|
||||
|
||||
@@ -35,7 +35,8 @@ test.describe('Import Postman Collection with Examples', () => {
|
||||
}, { importDir });
|
||||
|
||||
await test.step('Open import collection modal', async () => {
|
||||
await page.getByRole('button', { name: 'Import Collection' }).click();
|
||||
await page.locator('.plus-icon-button').click();
|
||||
await page.locator('.tippy-box .dropdown-item').filter({ hasText: 'Import collection' }).click();
|
||||
});
|
||||
|
||||
await test.step('Wait for import modal and verify title', async () => {
|
||||
@@ -47,10 +48,10 @@ test.describe('Import Postman Collection with Examples', () => {
|
||||
await test.step('Upload Postman collection file using hidden file input', async () => {
|
||||
// The "choose a file" button triggers a hidden file input, so we can directly set files on it
|
||||
await page.setInputFiles('input[type="file"]', postmanFile);
|
||||
});
|
||||
|
||||
await test.step('Wait for file processing to complete', async () => {
|
||||
await page.locator('#import-collection-loader').waitFor({ state: 'hidden' });
|
||||
// Wait for location modal to appear after file processing
|
||||
const locationModal = page.locator('[data-testid="import-collection-location-modal"]');
|
||||
await locationModal.waitFor({ state: 'visible', timeout: 10000 });
|
||||
});
|
||||
|
||||
await test.step('Verify no parsing errors occurred', async () => {
|
||||
@@ -61,22 +62,22 @@ test.describe('Import Postman Collection with Examples', () => {
|
||||
});
|
||||
|
||||
await test.step('Verify location selection modal appears', async () => {
|
||||
const locationModal = page.getByRole('dialog');
|
||||
const locationModal = page.locator('[data-testid="import-collection-location-modal"]');
|
||||
await expect(locationModal.locator('.bruno-modal-header-title')).toContainText('Import Collection');
|
||||
});
|
||||
|
||||
await test.step('Verify collection name appears in location modal', async () => {
|
||||
const locationModal = page.getByRole('dialog');
|
||||
const locationModal = page.locator('[data-testid="import-collection-location-modal"]');
|
||||
await expect(locationModal.getByText('collection with examples')).toBeVisible();
|
||||
});
|
||||
|
||||
await test.step('Click Browse link to select collection folder', async () => {
|
||||
const locationModal = page.getByRole('dialog');
|
||||
const locationModal = page.locator('[data-testid="import-collection-location-modal"]');
|
||||
await locationModal.getByText('Browse').click();
|
||||
});
|
||||
|
||||
await test.step('Complete import by clicking import button', async () => {
|
||||
const locationModal = page.getByRole('dialog');
|
||||
const locationModal = page.locator('[data-testid="import-collection-location-modal"]');
|
||||
await locationModal.getByRole('button', { name: 'Import' }).click();
|
||||
});
|
||||
|
||||
|
||||
@@ -5,7 +5,8 @@ test.describe('Invalid Postman Collection - Invalid JSON', () => {
|
||||
test('Handle invalid JSON syntax', async ({ page }) => {
|
||||
const postmanFile = path.resolve(__dirname, 'fixtures', 'postman-invalid-schema.json');
|
||||
|
||||
await page.getByRole('button', { name: 'Import Collection' }).click();
|
||||
await page.locator('.plus-icon-button').click();
|
||||
await page.locator('.tippy-box .dropdown-item').filter({ hasText: 'Import collection' }).click();
|
||||
|
||||
// Wait for import collection modal to be ready
|
||||
const importModal = page.getByRole('dialog');
|
||||
@@ -14,9 +15,6 @@ test.describe('Invalid Postman Collection - Invalid JSON', () => {
|
||||
|
||||
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('Unsupported collection format').first().isVisible();
|
||||
|
||||
|
||||
@@ -5,7 +5,8 @@ test.describe('Invalid Postman Collection - Missing Info', () => {
|
||||
test('Handle Postman collection missing required info field', async ({ page }) => {
|
||||
const postmanFile = path.resolve(__dirname, 'fixtures', 'postman-invalid-missing-info.json');
|
||||
|
||||
await page.getByRole('button', { name: 'Import Collection' }).click();
|
||||
await page.locator('.plus-icon-button').click();
|
||||
await page.locator('.tippy-box .dropdown-item').filter({ hasText: 'Import collection' }).click();
|
||||
|
||||
// Wait for import collection modal to be ready
|
||||
const importModal = page.getByRole('dialog');
|
||||
@@ -14,9 +15,6 @@ test.describe('Invalid Postman Collection - Missing Info', () => {
|
||||
|
||||
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('Unsupported collection format').first().isVisible();
|
||||
expect(hasError).toBe(true);
|
||||
|
||||
@@ -5,7 +5,8 @@ test.describe('Invalid Postman Collection - Invalid Schema', () => {
|
||||
test('Handle Postman collection with invalid schema version', async ({ page }) => {
|
||||
const postmanFile = path.resolve(__dirname, 'fixtures', 'postman-invalid-schema.json');
|
||||
|
||||
await page.getByRole('button', { name: 'Import Collection' }).click();
|
||||
await page.locator('.plus-icon-button').click();
|
||||
await page.locator('.tippy-box .dropdown-item').filter({ hasText: 'Import collection' }).click();
|
||||
|
||||
// Wait for import collection modal to be ready
|
||||
const importModal = page.getByRole('dialog');
|
||||
@@ -14,9 +15,6 @@ test.describe('Invalid Postman Collection - Invalid Schema', () => {
|
||||
|
||||
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('Unsupported collection format').first().isVisible();
|
||||
expect(hasError).toBe(true);
|
||||
|
||||
@@ -5,7 +5,8 @@ test.describe('Invalid Postman Collection - Malformed Structure', () => {
|
||||
test('Handle malformed Postman collection structure', async ({ page }) => {
|
||||
const postmanFile = path.resolve(__dirname, 'fixtures', 'postman-malformed.json');
|
||||
|
||||
await page.getByRole('button', { name: 'Import Collection' }).click();
|
||||
await page.locator('.plus-icon-button').click();
|
||||
await page.locator('.tippy-box .dropdown-item').filter({ hasText: 'Import collection' }).click();
|
||||
|
||||
// Wait for import collection modal to be ready
|
||||
const importModal = page.getByRole('dialog');
|
||||
@@ -14,9 +15,6 @@ test.describe('Invalid Postman Collection - Malformed Structure', () => {
|
||||
|
||||
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('Unsupported collection format').first().isVisible();
|
||||
expect(hasError).toBe(true);
|
||||
|
||||
@@ -13,7 +13,8 @@ test.describe('Import WSDL Collection', () => {
|
||||
const wsdlFile = path.join(testDataDir, 'wsdl.xml');
|
||||
|
||||
await test.step('Open import collection modal', async () => {
|
||||
await page.getByRole('button', { name: 'Import Collection' }).click();
|
||||
await page.locator('.plus-icon-button').click();
|
||||
await page.locator('.tippy-box .dropdown-item').filter({ hasText: 'Import collection' }).click();
|
||||
|
||||
// Wait for import collection modal to be ready
|
||||
const importModal = page.getByRole('dialog');
|
||||
@@ -23,18 +24,19 @@ test.describe('Import WSDL Collection', () => {
|
||||
await test.step('Choose WSDL XML file', async () => {
|
||||
await page.setInputFiles('input[type="file"]', wsdlFile);
|
||||
|
||||
// Wait for the loader to disappear
|
||||
await page.locator('#import-collection-loader').waitFor({ state: 'hidden' });
|
||||
// Wait for location modal to appear after file processing
|
||||
const locationModal = page.locator('[data-testid="import-collection-location-modal"]');
|
||||
await locationModal.waitFor({ state: 'visible', timeout: 10000 });
|
||||
});
|
||||
|
||||
await test.step('Select the location for the collection and submit to import', async () => {
|
||||
// Verify that the location selection modal is displayed to import the collection
|
||||
const locationModal = page.getByRole('dialog');
|
||||
const locationModal = page.locator('[data-testid="import-collection-location-modal"]');
|
||||
await expect(locationModal.locator('.bruno-modal-header-title')).toContainText('Import Collection');
|
||||
|
||||
// select a location
|
||||
await page.locator('#collection-location').fill(await createTmpDir('wsdl-xml-test'));
|
||||
await page.getByRole('button', { name: 'Import', exact: true }).click();
|
||||
await locationModal.getByRole('button', { name: 'Import' }).click();
|
||||
await expect(page.locator('#sidebar-collection-name').getByText('TestWSDLServiceXML')).toBeVisible();
|
||||
});
|
||||
|
||||
@@ -69,7 +71,8 @@ test.describe('Import WSDL Collection', () => {
|
||||
const wsdlFile = path.join(testDataDir, 'wsdl-bruno.json');
|
||||
|
||||
await test.step('Open import collection modal', async () => {
|
||||
await page.getByRole('button', { name: 'Import Collection' }).click();
|
||||
await page.locator('.plus-icon-button').click();
|
||||
await page.locator('.tippy-box .dropdown-item').filter({ hasText: 'Import collection' }).click();
|
||||
|
||||
// Wait for import collection modal to be ready
|
||||
const importModal = page.getByRole('dialog');
|
||||
@@ -79,13 +82,14 @@ test.describe('Import WSDL Collection', () => {
|
||||
await test.step('Choose WSDL JSON file', async () => {
|
||||
await page.setInputFiles('input[type="file"]', wsdlFile);
|
||||
|
||||
// Wait for the loader to disappear
|
||||
await page.locator('#import-collection-loader').waitFor({ state: 'hidden' });
|
||||
// Wait for location modal to appear after file processing
|
||||
const locationModal = page.locator('[data-testid="import-collection-location-modal"]');
|
||||
await locationModal.waitFor({ state: 'visible', timeout: 10000 });
|
||||
});
|
||||
|
||||
await test.step('Select the location for the collection and submit to import', async () => {
|
||||
// Verify that the location selection modal is displayed to import the collection
|
||||
const locationModal = page.getByRole('dialog');
|
||||
const locationModal = page.locator('[data-testid="import-collection-location-modal"]');
|
||||
await expect(locationModal.locator('.bruno-modal-header-title')).toContainText('Import Collection');
|
||||
|
||||
// Wait for collection to appear in the location modal
|
||||
@@ -93,7 +97,7 @@ test.describe('Import WSDL Collection', () => {
|
||||
|
||||
// select a location
|
||||
await page.locator('#collection-location').fill(await createTmpDir('wsdl-json-test'));
|
||||
await page.getByRole('button', { name: 'Import', exact: true }).click();
|
||||
await locationModal.getByRole('button', { name: 'Import' }).click();
|
||||
});
|
||||
|
||||
await test.step('Verify that the collection was imported successfully', async () => {
|
||||
|
||||
@@ -87,23 +87,22 @@ test.describe('Onboarding', () => {
|
||||
const page = await app.firstWindow();
|
||||
|
||||
// First launch - sample collection should be created
|
||||
const sampleCollection = page.locator('.collection-name').filter({ hasText: 'Sample API Collection' });
|
||||
const sampleCollection = page.getByTestId('collections').locator('.collection-name').filter({ hasText: 'Sample API Collection' });
|
||||
await expect(sampleCollection).toBeVisible();
|
||||
|
||||
// User closes the sample collection (hover on the collection and open context menu)
|
||||
// User removes the sample collection from workspace (hover on the collection and open context menu)
|
||||
await sampleCollection.hover();
|
||||
await sampleCollection.locator('.collection-actions .icon').click();
|
||||
|
||||
|
||||
// Close the sample collection
|
||||
const closeOption = page.locator('.dropdown-item').getByText('Close');
|
||||
await expect(closeOption).toBeVisible();
|
||||
await closeOption.click();
|
||||
// Remove the sample collection
|
||||
const removeOption = page.locator('.dropdown-item').getByText('Remove');
|
||||
await expect(removeOption).toBeVisible();
|
||||
await removeOption.click();
|
||||
|
||||
// Handle the confirmation dialog - click the 'Close' button to confirm
|
||||
const confirmCloseButton = page.locator('.bruno-modal').getByRole('button', { name: 'Close' });
|
||||
await expect(confirmCloseButton).toBeVisible();
|
||||
await confirmCloseButton.click();
|
||||
// Confirm removal in the modal
|
||||
const removeModal = page.getByRole('dialog').filter({ has: page.getByText('Remove Collection') });
|
||||
await removeModal.getByRole('button', { name: 'Remove' }).click();
|
||||
|
||||
// Verify collection is closed (no longer visible in sidebar)
|
||||
await expect(sampleCollection).not.toBeVisible();
|
||||
|
||||
@@ -56,14 +56,17 @@ test.describe('Default Collection Location Feature', () => {
|
||||
|
||||
test('Should use default location in Create Collection modal', async ({ pageWithUserData: page }) => {
|
||||
// test Create Collection modal
|
||||
await page.locator('[data-testid="create-collection"]').click();
|
||||
await page.locator('.plus-icon-button').click();
|
||||
await page.locator('.tippy-box .dropdown-item').filter({ hasText: 'Create collection' }).click();
|
||||
|
||||
// verify the default location is pre-filled
|
||||
// verify the default location is pre-filled (if location input is visible)
|
||||
const collectionLocationInput = page.getByLabel('Location');
|
||||
await expect(collectionLocationInput).toHaveValue('/tmp/bruno-collections');
|
||||
if (await collectionLocationInput.isVisible()) {
|
||||
await expect(collectionLocationInput).toHaveValue('/tmp/bruno-collections');
|
||||
}
|
||||
|
||||
// cancel the collection creation
|
||||
await page.getByRole('button', { name: 'Cancel' }).click();
|
||||
await page.locator('.bruno-modal').getByRole('button', { name: 'Cancel' }).click();
|
||||
|
||||
// wait for 2 seconds
|
||||
await page.waitForTimeout(2000);
|
||||
@@ -71,12 +74,19 @@ test.describe('Default Collection Location Feature', () => {
|
||||
|
||||
test('Should use default location in Clone Collection modal', async ({ pageWithUserData: page }) => {
|
||||
// open the clone collection modal
|
||||
await page.locator('[data-testid="collection-actions"]').click();
|
||||
await page.getByTestId('clone-collection').click();
|
||||
const collection = page.locator('.collection-name').first();
|
||||
await collection.hover();
|
||||
await collection.locator('.collection-actions .icon').click();
|
||||
await page.locator('.dropdown-item').filter({ hasText: 'Clone' }).click();
|
||||
|
||||
// verify the default location is pre-filled
|
||||
const cloneLocationInput = page.getByLabel('Location');
|
||||
await expect(cloneLocationInput).toHaveValue('/tmp/bruno-collections');
|
||||
if (await cloneLocationInput.isVisible()) {
|
||||
await expect(cloneLocationInput).toHaveValue('/tmp/bruno-collections');
|
||||
}
|
||||
|
||||
// cancel the clone operation
|
||||
await page.locator('.bruno-modal').getByRole('button', { name: 'Cancel' }).click();
|
||||
|
||||
// wait for 2 seconds
|
||||
await page.waitForTimeout(2000);
|
||||
|
||||
@@ -18,11 +18,15 @@ test.describe('Code Generation URL Encoding', () => {
|
||||
page,
|
||||
createTmpDir
|
||||
}) => {
|
||||
await page.locator('.dropdown-icon').click();
|
||||
await page.locator('.dropdown-item').filter({ hasText: 'Create Collection' }).click();
|
||||
// Use plus icon button in new workspace UI
|
||||
await page.locator('.plus-icon-button').click();
|
||||
await page.locator('.tippy-box .dropdown-item').filter({ hasText: 'Create collection' }).click();
|
||||
await page.getByLabel('Name').fill('unencoded-test-collection');
|
||||
await page.getByLabel('Location').fill(await createTmpDir('unencoded-test-collection'));
|
||||
await page.getByRole('button', { name: 'Create', exact: true }).click();
|
||||
const locationInput = page.getByLabel('Location');
|
||||
if (await locationInput.isVisible()) {
|
||||
await locationInput.fill(await createTmpDir('unencoded-test-collection'));
|
||||
}
|
||||
await page.locator('.bruno-modal').getByRole('button', { name: 'Create', exact: true }).click();
|
||||
|
||||
await expect(page.locator('#sidebar-collection-name').filter({ hasText: 'unencoded-test-collection' })).toBeVisible();
|
||||
await page.locator('#sidebar-collection-name').filter({ hasText: 'unencoded-test-collection' }).click();
|
||||
@@ -60,11 +64,15 @@ test.describe('Code Generation URL Encoding', () => {
|
||||
page,
|
||||
createTmpDir
|
||||
}) => {
|
||||
await page.locator('.dropdown-icon').click();
|
||||
await page.locator('.dropdown-item').filter({ hasText: 'Create Collection' }).click();
|
||||
// Use plus icon button in new workspace UI
|
||||
await page.locator('.plus-icon-button').click();
|
||||
await page.locator('.tippy-box .dropdown-item').filter({ hasText: 'Create collection' }).click();
|
||||
await page.getByLabel('Name').fill('encoded-test-collection');
|
||||
await page.getByLabel('Location').fill(await createTmpDir('encoded-test-collection'));
|
||||
await page.getByRole('button', { name: 'Create', exact: true }).click();
|
||||
const locationInput = page.getByLabel('Location');
|
||||
if (await locationInput.isVisible()) {
|
||||
await locationInput.fill(await createTmpDir('encoded-test-collection'));
|
||||
}
|
||||
await page.locator('.bruno-modal').getByRole('button', { name: 'Create', exact: true }).click();
|
||||
|
||||
await expect(page.locator('#sidebar-collection-name').filter({ hasText: 'encoded-test-collection' })).toBeVisible();
|
||||
await page.locator('#sidebar-collection-name').filter({ hasText: 'encoded-test-collection' }).click();
|
||||
|
||||
@@ -10,20 +10,20 @@ test('should persist request with newlines across app restarts', async ({ create
|
||||
const app1 = await launchElectronApp({ userDataPath });
|
||||
const page = await app1.firstWindow();
|
||||
|
||||
await page.locator('.dropdown-icon').click();
|
||||
await page.locator('.dropdown-item').filter({ hasText: 'Create Collection' }).click();
|
||||
await page.getByLabel('Name').fill('newlines-persistence');
|
||||
await page.getByLabel('Location').fill(collectionPath);
|
||||
await page.getByRole('button', { name: 'Create', exact: true }).click();
|
||||
await page.locator('.plus-icon-button').click();
|
||||
await page.locator('.tippy-box .dropdown-item').filter({ hasText: 'Create collection' }).click();
|
||||
await page.locator('.bruno-modal').getByLabel('Name').fill('newlines-persistence');
|
||||
await page.locator('.bruno-modal').getByLabel('Location').fill(collectionPath);
|
||||
await page.locator('.bruno-modal').getByRole('button', { name: 'Create' }).click();
|
||||
|
||||
const collection = page.locator('.collection-name').filter({ hasText: 'newlines-persistence' });
|
||||
const collection = page.getByTestId('collections').locator('.collection-name').filter({ hasText: 'newlines-persistence' });
|
||||
await collection.locator('.collection-actions').hover();
|
||||
await collection.locator('.collection-actions .icon').click();
|
||||
await page.locator('.dropdown-item').filter({ hasText: 'New Request' }).click();
|
||||
await page.getByPlaceholder('Request Name').fill('persistence-test');
|
||||
await page.locator('#new-request-url').locator('.CodeMirror').click();
|
||||
await page.locator('#new-request-url').locator('textarea').fill('https://httpbin.org/get');
|
||||
await page.getByRole('button', { name: 'Create', exact: true }).click();
|
||||
await page.locator('.bruno-modal').getByRole('button', { name: 'Create', exact: true }).click();
|
||||
|
||||
await openCollectionAndAcceptSandbox(page, 'newlines-persistence', 'safe');
|
||||
await page.locator('.collection-item-name').filter({ hasText: 'persistence-test' }).dblclick();
|
||||
@@ -60,7 +60,7 @@ test('should persist request with newlines across app restarts', async ({ create
|
||||
const app2 = await launchElectronApp({ userDataPath });
|
||||
const page2 = await app2.firstWindow();
|
||||
|
||||
await page2.locator('.collection-name').filter({ hasText: 'newlines-persistence' }).click();
|
||||
await page2.getByTestId('collections').locator('.collection-name').filter({ hasText: 'newlines-persistence' }).click();
|
||||
await page2.locator('.collection-item-name').filter({ hasText: 'persistence-test' }).dblclick();
|
||||
|
||||
// Verify params persisted
|
||||
|
||||
@@ -9,11 +9,14 @@ const isRequestSaved = async (saveButton: Locator) => {
|
||||
};
|
||||
|
||||
const setup = async (page: Page, createTmpDir: (tag?: string | undefined) => Promise<string>) => {
|
||||
await page.locator('.dropdown-icon').click();
|
||||
await page.locator('.dropdown-item').filter({ hasText: 'Create Collection' }).click();
|
||||
await page.locator('.plus-icon-button').click();
|
||||
await page.locator('.tippy-box .dropdown-item').filter({ hasText: 'Create collection' }).click();
|
||||
await page.getByLabel('Name').fill('source-collection');
|
||||
await page.getByLabel('Location').fill(await createTmpDir('source-collection'));
|
||||
await page.getByRole('button', { name: 'Create', exact: true }).click();
|
||||
const locationInput = page.getByLabel('Location');
|
||||
if (await locationInput.isVisible()) {
|
||||
await locationInput.fill(await createTmpDir('source-collection'));
|
||||
}
|
||||
await page.locator('.bruno-modal').getByRole('button', { name: 'Create', exact: true }).click();
|
||||
await expect(page.locator('#sidebar-collection-name').filter({ hasText: 'source-collection' })).toBeVisible();
|
||||
await page.locator('#sidebar-collection-name').filter({ hasText: 'source-collection' }).click();
|
||||
await page.getByLabel('Safe Mode').check();
|
||||
|
||||
@@ -2,7 +2,7 @@ import { test, expect } from '../../../../playwright';
|
||||
|
||||
test.describe('Custom Search Functionality in Scripts Tab', () => {
|
||||
test('should open search box when Cmd+F or Ctrl+F is pressed in scripts tab', async ({ pageWithUserData: page }) => {
|
||||
await page.getByTitle('custom-search').click();
|
||||
await page.getByTestId('collections').locator('#sidebar-collection-name').filter({ hasText: 'custom-search' }).click();
|
||||
|
||||
await page.getByText('search-test-request').click();
|
||||
|
||||
@@ -62,7 +62,7 @@ test.describe('Custom Search Functionality in Scripts Tab', () => {
|
||||
});
|
||||
|
||||
test('should handle search in different script editors independently', async ({ pageWithUserData: page }) => {
|
||||
await page.getByTitle('custom-search').click();
|
||||
await page.getByTestId('collections').locator('#sidebar-collection-name').filter({ hasText: 'custom-search' }).click();
|
||||
|
||||
await page.getByText('search-test-request').click();
|
||||
|
||||
@@ -96,7 +96,7 @@ test.describe('Custom Search Functionality in Scripts Tab', () => {
|
||||
});
|
||||
|
||||
test('should maintain search state when switching between tabs', async ({ pageWithUserData: page }) => {
|
||||
await page.getByTitle('custom-search').click();
|
||||
await page.getByTestId('collections').locator('#sidebar-collection-name').filter({ hasText: 'custom-search' }).click();
|
||||
|
||||
await page.getByText('search-test-request').click();
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { test } from '../../playwright';
|
||||
import { test, expect } from '../../playwright';
|
||||
import { setSandboxMode, runCollection, validateRunnerResults } from '../utils/page/index';
|
||||
|
||||
test.describe.parallel('Collection Run', () => {
|
||||
@@ -29,7 +29,7 @@ test.describe.parallel('Collection Run', () => {
|
||||
await page.getByRole('button', { name: 'Save' }).click();
|
||||
await page.locator('.environment-selector').nth(1).click();
|
||||
await page.locator('.dropdown-item').getByText('Prod').click();
|
||||
const collectionContainer = page.locator('.collection-name').filter({ hasText: 'bruno-testbench' });
|
||||
const collectionContainer = page.getByTestId('collections').locator('.collection-name').filter({ hasText: 'bruno-testbench' });
|
||||
await collectionContainer.locator('.collection-actions').hover();
|
||||
await collectionContainer.locator('.collection-actions .icon').waitFor({ state: 'visible' });
|
||||
await collectionContainer.locator('.collection-actions .icon').click();
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
import { test, expect } from '../../playwright';
|
||||
|
||||
test('Check if the logo on top left is visible', async ({ page }) => {
|
||||
await expect(page.getByRole('button', { name: 'bruno' })).toBeVisible();
|
||||
test('Check if the workspace name is visible in the sidebar', async ({ page }) => {
|
||||
// Wait for the app to be loaded
|
||||
await page.locator('[data-app-state="loaded"]').waitFor({ timeout: 30000 });
|
||||
|
||||
// Wait for the workspace name container to be visible (contains workspace name like "My Workspace" or "Default Workspace")
|
||||
await expect(page.locator('.workspace-name-container')).toBeVisible();
|
||||
});
|
||||
|
||||
@@ -8,20 +8,20 @@ import { buildCommonLocators } from './locators';
|
||||
*/
|
||||
const closeAllCollections = async (page) => {
|
||||
await test.step('Close all collections', async () => {
|
||||
const numberOfCollections = await page.locator('.collection-name').count();
|
||||
const numberOfCollections = await page.locator('[data-testid="collections"] .collection-name').count();
|
||||
|
||||
for (let i = 0; i < numberOfCollections; i++) {
|
||||
await page.locator('.collection-name').first().locator('.collection-actions').click();
|
||||
await page.locator('.dropdown-item').getByText('Close').click();
|
||||
// Wait for the close collection modal to be visible
|
||||
await page.locator('.bruno-modal-header-title', { hasText: 'Close Collection' }).waitFor({ state: 'visible' });
|
||||
await page.locator('[data-testid="collections"] .collection-name').first().locator('.collection-actions').click();
|
||||
await page.locator('.dropdown-item').getByText('Remove').click();
|
||||
// Wait for the remove collection modal to be visible
|
||||
await page.locator('.bruno-modal-header-title', { hasText: 'Remove Collection' }).waitFor({ state: 'visible' });
|
||||
await page.locator('.bruno-modal-footer .submit').click();
|
||||
// Wait for the close collection modal to be hidden
|
||||
await page.locator('.bruno-modal-header-title', { hasText: 'Close Collection' }).waitFor({ state: 'hidden' });
|
||||
// Wait for the remove collection modal to be hidden
|
||||
await page.locator('.bruno-modal-header-title', { hasText: 'Remove Collection' }).waitFor({ state: 'hidden' });
|
||||
}
|
||||
|
||||
// Wait until no collections are left open
|
||||
await expect(page.locator('.collection-name')).toHaveCount(0);
|
||||
// Wait until no collections are left open (check sidebar only)
|
||||
await expect(page.getByTestId('collections').locator('.collection-name')).toHaveCount(0);
|
||||
});
|
||||
};
|
||||
|
||||
@@ -62,13 +62,16 @@ type CreateCollectionOptions = {
|
||||
*/
|
||||
const createCollection = async (page, collectionName: string, collectionLocation: string, options: CreateCollectionOptions = {}) => {
|
||||
await test.step(`Create collection "${collectionName}"`, async () => {
|
||||
await page.locator('.collection-dropdown .dropdown-icon').click();
|
||||
await page.locator('.tippy-box .dropdown-item').filter({ hasText: 'Create Collection' }).click();
|
||||
await page.locator('.plus-icon-button').click();
|
||||
await page.locator('.tippy-box .dropdown-item').filter({ hasText: 'Create collection' }).click();
|
||||
|
||||
const createCollectionModal = page.locator('.bruno-modal-card').filter({ hasText: 'Create Collection' });
|
||||
|
||||
await createCollectionModal.getByLabel('Name').fill(collectionName);
|
||||
await createCollectionModal.getByLabel('Location').fill(collectionLocation);
|
||||
const locationInput = createCollectionModal.getByLabel('Location');
|
||||
if (await locationInput.isVisible()) {
|
||||
await locationInput.fill(collectionLocation);
|
||||
}
|
||||
await createCollectionModal.getByRole('button', { name: 'Create', exact: true }).click();
|
||||
|
||||
await createCollectionModal.waitFor({ state: 'detached' });
|
||||
@@ -115,8 +118,8 @@ const deleteRequest = async (page, requestName: string, collectionName: string)
|
||||
await locators.sidebar.collection(collectionName).click();
|
||||
|
||||
// Find the request within the collection's context
|
||||
// Use the collection container (.collection-name) to scope the search
|
||||
const collectionContainer = page.locator('.collection-name').filter({ hasText: collectionName });
|
||||
// Use the collection container (.collection-name) scoped to sidebar to scope the search
|
||||
const collectionContainer = page.getByTestId('collections').locator('.collection-name').filter({ hasText: collectionName });
|
||||
const collectionWrapper = collectionContainer.locator('..');
|
||||
const request = collectionWrapper.locator('.collection-item-name').filter({ hasText: requestName });
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ export const buildCommonLocators = (page: Page) => ({
|
||||
},
|
||||
actions: {
|
||||
collectionActions: (collectionName: string) =>
|
||||
page.locator('.collection-name')
|
||||
page.getByTestId('collections').locator('.collection-name')
|
||||
.filter({ hasText: collectionName })
|
||||
.locator('.collection-actions .icon'),
|
||||
collectionItemActions: (itemName: string) =>
|
||||
@@ -43,7 +43,7 @@ export const buildCommonLocators = (page: Page) => ({
|
||||
modal: {
|
||||
title: (title: string) => page.locator('.bruno-modal-header-title').filter({ hasText: title }),
|
||||
byTitle: (title: string) => page.locator('.bruno-modal').filter({ has: page.locator('.bruno-modal-header-title').filter({ hasText: title }) }),
|
||||
button: (name: string) => page.getByRole('button', { name: name, exact: true }),
|
||||
button: (name: string) => page.locator('.bruno-modal').getByRole('button', { name: name, exact: true }),
|
||||
closeButton: () => page.locator('.bruno-modal').getByTestId('modal-close-button')
|
||||
},
|
||||
environment: {
|
||||
|
||||
@@ -27,8 +27,8 @@ export const getRunnerResultCounts = async (page: Page) => {
|
||||
* @returns void
|
||||
*/
|
||||
export const runCollection = async (page: Page, collectionName: string) => {
|
||||
// Ensure collection is visible and loaded
|
||||
const collectionContainer = page.locator('.collection-name').filter({ hasText: collectionName });
|
||||
// Ensure collection is visible and loaded (scope to sidebar)
|
||||
const collectionContainer = page.getByTestId('collections').locator('.collection-name').filter({ hasText: collectionName });
|
||||
await collectionContainer.waitFor({ state: 'visible' });
|
||||
// Wait a bit for the UI to stabilize
|
||||
await page.waitForTimeout(300);
|
||||
@@ -71,24 +71,14 @@ export const runCollection = async (page: Page, collectionName: string) => {
|
||||
* @returns void
|
||||
*/
|
||||
export const setSandboxMode = async (page: Page, collectionName: string, mode: 'developer' | 'safe') => {
|
||||
// Click on the collection name - try sidebar first, then fall back to collection tab/name
|
||||
// First try sidebar collection name (more reliable)
|
||||
const sidebarCollection = page.locator('#sidebar-collection-name').filter({ hasText: collectionName });
|
||||
const sidebarExists = await sidebarCollection.count().then((count) => count > 0).catch(() => false);
|
||||
// Click on the collection name in the sidebar
|
||||
// Use the collections testid to scope to the sidebar, then find the specific collection
|
||||
const sidebarCollection = page.getByTestId('collections').locator('#sidebar-collection-name').filter({ hasText: collectionName }).first();
|
||||
|
||||
if (sidebarExists) {
|
||||
await sidebarCollection.click();
|
||||
} else {
|
||||
// Fall back to collection by title or text
|
||||
const collectionByTitle = page.getByTitle(collectionName);
|
||||
const collectionByText = page.getByText(collectionName);
|
||||
const titleExists = await collectionByTitle.count().then((count) => count > 0).catch(() => false);
|
||||
if (titleExists) {
|
||||
await collectionByTitle.click();
|
||||
} else {
|
||||
await collectionByText.click();
|
||||
}
|
||||
}
|
||||
// Wait for the sidebar to be loaded
|
||||
await page.waitForTimeout(500);
|
||||
|
||||
await sidebarCollection.click();
|
||||
|
||||
// Wait a moment for the UI to load
|
||||
await page.waitForTimeout(300);
|
||||
|
||||
Reference in New Issue
Block a user