mirror of
https://github.com/usebruno/bruno.git
synced 2026-06-25 21:55:49 +00:00
* add: env's as tabs * fix: test * fix: tests * fixes * fix: test * fixes * fixes * fix * fix: styling * fixes
408 lines
17 KiB
TypeScript
408 lines
17 KiB
TypeScript
import { test, expect } from '../../../../playwright';
|
|
import path from 'path';
|
|
import fs from 'fs';
|
|
|
|
// Helper function to load expected fixtures
|
|
function loadExpectedFixture(fixturePath: string) {
|
|
const fullPath = path.join(__dirname, '..', '../fixtures', 'environment-exports', fixturePath);
|
|
console.log(fullPath);
|
|
return JSON.parse(fs.readFileSync(fullPath, 'utf8'));
|
|
}
|
|
|
|
// Helper function to normalize dynamic fields for comparison
|
|
function normalizeExportedContent(content: any) {
|
|
if (content.info) {
|
|
// Replace dynamic fields with fixed values for comparison
|
|
content.info.exportedAt = '2024-01-01T00:00:00.000Z';
|
|
content.info.exportedUsing = 'Bruno/v1.0.0';
|
|
}
|
|
return content;
|
|
}
|
|
|
|
test.describe.serial('Collection Environment Export Tests', () => {
|
|
test.describe.serial('folder exports', () => {
|
|
test('should export single collection environment', async ({
|
|
pageWithUserData: page,
|
|
createTmpDir
|
|
}) => {
|
|
const exportDir = await createTmpDir('collection-env-export-single');
|
|
|
|
await test.step('Open collection and navigate to environment settings', async () => {
|
|
// Open the collection from sidebar
|
|
await page.locator('#sidebar-collection-name').filter({ hasText: 'Environment Export Test Collection' }).click();
|
|
|
|
// Open environment settings
|
|
await page.getByTestId('environment-selector-trigger').click();
|
|
await page.getByTestId('env-tab-collection').click();
|
|
await page.getByText('Configure', { exact: true }).click();
|
|
|
|
const envTab = page.locator('.request-tab').filter({ hasText: 'Environments' });
|
|
await expect(envTab).toBeVisible();
|
|
});
|
|
|
|
await test.step('Open export modal and configure export settings', async () => {
|
|
// Click export button
|
|
await page.locator('button[title="Export environment"]').click();
|
|
|
|
// Verify export modal opens
|
|
const exportModal = page.locator('.bruno-modal').filter({ hasText: 'Export Environments' });
|
|
await expect(exportModal).toBeVisible();
|
|
|
|
// Deselect all environments first
|
|
await page.getByText('Deselect All').click();
|
|
|
|
// Select only "local" environment
|
|
const localEnvCheckbox = page.locator('label').filter({ hasText: 'local' }).locator('input[type="checkbox"]');
|
|
await localEnvCheckbox.check();
|
|
|
|
// Set export directory
|
|
await page.locator('input[id="export-location"]').fill(exportDir);
|
|
});
|
|
|
|
await test.step('Execute export and close modal', async () => {
|
|
// Export the environment
|
|
await page.getByRole('button', { name: 'Export 1 Environment' }).click();
|
|
});
|
|
|
|
await test.step('Verify exported file and content', async () => {
|
|
// Verify exported file exists
|
|
const exportedFile = path.join(exportDir, 'local.json');
|
|
|
|
expect(fs.existsSync(exportedFile)).toBe(true);
|
|
|
|
// Verify file content matches expected fixture
|
|
const exportedContent = JSON.parse(fs.readFileSync(exportedFile, 'utf8'));
|
|
const expectedContent = loadExpectedFixture('bruno-collection-environments/local.json');
|
|
|
|
expect(normalizeExportedContent(exportedContent)).toEqual(expectedContent);
|
|
});
|
|
});
|
|
|
|
test('should export multiple collection environments', async ({
|
|
pageWithUserData: page,
|
|
createTmpDir
|
|
}) => {
|
|
const exportDir = await createTmpDir('collection-env-export-multiple');
|
|
|
|
await test.step('Open collection and navigate to environment settings', async () => {
|
|
// Open the collection from sidebar
|
|
await page.locator('#sidebar-collection-name').filter({ hasText: 'Environment Export Test Collection' }).click();
|
|
|
|
// Open environment settings
|
|
await page.getByTestId('environment-selector-trigger').click();
|
|
await page.getByTestId('env-tab-collection').click();
|
|
await page.getByText('Configure', { exact: true }).click();
|
|
|
|
const envTab = page.locator('.request-tab').filter({ hasText: 'Environments' });
|
|
await expect(envTab).toBeVisible();
|
|
});
|
|
|
|
await test.step('Configure export settings for multiple environments', async () => {
|
|
// Click export button
|
|
await page.locator('button[title="Export environment"]').click();
|
|
|
|
// Verify all environments are selected by default
|
|
await expect(page.getByRole('checkbox', { name: 'Local' })).toBeChecked();
|
|
await expect(page.getByRole('checkbox', { name: 'Prod' })).toBeChecked();
|
|
|
|
// Select folder export format (default might be single JSON file)
|
|
await page.getByText('Separate files in folder').click();
|
|
|
|
// Set export directory
|
|
await page.locator('input[id="export-location"]').fill(exportDir);
|
|
});
|
|
|
|
await test.step('Execute export and close modal', async () => {
|
|
// Export all environments
|
|
await page.getByRole('button', { name: /Export \d+ Environments?/ }).click();
|
|
});
|
|
|
|
await test.step('Verify exported files and content', async () => {
|
|
// Verify exported files exist
|
|
const exportPath = path.join(exportDir, 'bruno-collection-environments');
|
|
expect(fs.existsSync(exportPath)).toBe(true);
|
|
|
|
const expectedFiles = [
|
|
'local.json',
|
|
'prod.json'
|
|
];
|
|
|
|
for (const fileName of expectedFiles) {
|
|
const filePath = path.join(exportPath, fileName);
|
|
expect(fs.existsSync(filePath)).toBe(true);
|
|
|
|
// Verify file content matches expected fixture
|
|
const content = JSON.parse(fs.readFileSync(filePath, 'utf8'));
|
|
const expectedContent = loadExpectedFixture(`bruno-collection-environments/${fileName}`);
|
|
expect(normalizeExportedContent(content)).toEqual(expectedContent);
|
|
}
|
|
});
|
|
});
|
|
|
|
test('should generate unique names when the export directory already contains previously exported contents', async ({
|
|
pageWithUserData: page,
|
|
createTmpDir
|
|
}) => {
|
|
const exportDir = await createTmpDir('collection-env-export-conflict');
|
|
|
|
await test.step('Setup existing export directory to simulate conflict', async () => {
|
|
// Create existing export directory and file to simulate conflict
|
|
const existingExportPath = path.join(exportDir, 'bruno-collection-environments');
|
|
fs.mkdirSync(existingExportPath, { recursive: true });
|
|
fs.writeFileSync(path.join(existingExportPath, 'local.json'), '{}');
|
|
});
|
|
|
|
await test.step('Open collection and navigate to environment settings', async () => {
|
|
// Open the collection from sidebar
|
|
await page.locator('#sidebar-collection-name').filter({ hasText: 'Environment Export Test Collection' }).click();
|
|
|
|
// Open environment settings
|
|
await page.getByTestId('environment-selector-trigger').click();
|
|
await page.getByTestId('env-tab-collection').click();
|
|
await page.getByText('Configure', { exact: true }).click();
|
|
|
|
const envTab = page.locator('.request-tab').filter({ hasText: 'Environments' });
|
|
await expect(envTab).toBeVisible();
|
|
});
|
|
|
|
await test.step('Configure export settings with folder format', async () => {
|
|
// Click export button
|
|
await page.locator('button[title="Export environment"]').click();
|
|
|
|
// Select folder export format (default might be single JSON file)
|
|
await page.getByText('Separate files in folder').click();
|
|
|
|
// Set export directory
|
|
await page.locator('input[id="export-location"]').fill(exportDir);
|
|
});
|
|
|
|
await test.step('Execute export and close modal', async () => {
|
|
// Export should succeed with unique names
|
|
await page.getByRole('button', { name: 'Export 2 Environment' }).click();
|
|
});
|
|
|
|
await test.step('Verify unique naming and file content', async () => {
|
|
// Verify original folder still exists
|
|
const existingExportPath = path.join(exportDir, 'bruno-collection-environments');
|
|
expect(fs.existsSync(existingExportPath)).toBe(true);
|
|
expect(fs.existsSync(path.join(existingExportPath, 'local.json'))).toBe(true);
|
|
|
|
// Verify new folder with unique name was created
|
|
const uniqueExportPath = path.join(exportDir, 'bruno-collection-environments copy');
|
|
expect(fs.existsSync(uniqueExportPath)).toBe(true);
|
|
|
|
// Verify the new file exists in the unique folder
|
|
const newExportedFile = path.join(uniqueExportPath, 'local.json');
|
|
expect(fs.existsSync(newExportedFile)).toBe(true);
|
|
|
|
// Verify file content matches expected fixture
|
|
const exportedContent = JSON.parse(fs.readFileSync(newExportedFile, 'utf8'));
|
|
const expectedContent = loadExpectedFixture('bruno-collection-environments/local.json');
|
|
expect(normalizeExportedContent(exportedContent)).toEqual(expectedContent);
|
|
});
|
|
});
|
|
});
|
|
|
|
test.describe.serial('json file exports', () => {
|
|
test('should export single collection environment as object', async ({
|
|
pageWithUserData: page,
|
|
createTmpDir
|
|
}) => {
|
|
const exportDir = await createTmpDir('collection-env-export-single-object');
|
|
|
|
await test.step('Open collection and navigate to environment settings', async () => {
|
|
// Open the collection from sidebar
|
|
await page.locator('#sidebar-collection-name').filter({ hasText: 'Environment Export Test Collection' }).click();
|
|
|
|
// Open collection environment settings
|
|
await page.getByTestId('environment-selector-trigger').click();
|
|
await page.getByTestId('env-tab-collection').click();
|
|
await page.getByText('Configure', { exact: true }).click();
|
|
|
|
const envTab = page.locator('.request-tab').filter({ hasText: 'Environments' });
|
|
await expect(envTab).toBeVisible();
|
|
});
|
|
|
|
await test.step('Configure export settings for single JSON file', async () => {
|
|
await page.locator('button[title="Export environment"]').click();
|
|
|
|
// Deselect all environments first
|
|
await page.getByText('Deselect All').click();
|
|
|
|
// Select only "local" environment
|
|
const localEnvCheckbox = page.locator('label').filter({ hasText: 'local' }).locator('input[type="checkbox"]');
|
|
await localEnvCheckbox.check();
|
|
|
|
await page.getByText('Single JSON file').click();
|
|
|
|
// Set export directory
|
|
await page.locator('input[id="export-location"]').fill(exportDir);
|
|
});
|
|
|
|
await test.step('Execute export and verify success', async () => {
|
|
// Export the environment
|
|
await page.getByRole('button', { name: 'Export 1 Environment' }).click();
|
|
|
|
// Verify success message
|
|
await expect(page.getByText('Environment(s) exported successfully', { exact: false }).first()).toBeVisible();
|
|
});
|
|
|
|
await test.step('Verify exported file and content', async () => {
|
|
// Verify exported file exists
|
|
const exportedFile = path.join(exportDir, 'local.json');
|
|
expect(fs.existsSync(exportedFile)).toBe(true);
|
|
|
|
// Verify file content matches expected fixture
|
|
const content = JSON.parse(fs.readFileSync(exportedFile, 'utf8'));
|
|
const expectedContent = loadExpectedFixture('local.json');
|
|
expect(normalizeExportedContent(content)).toEqual(expectedContent);
|
|
});
|
|
});
|
|
|
|
test('should export multiple collection environments as single JSON file', async ({
|
|
pageWithUserData: page,
|
|
createTmpDir
|
|
}) => {
|
|
const exportDir = await createTmpDir('collection-env-export-single-file');
|
|
|
|
await test.step('Open collection and navigate to environment settings', async () => {
|
|
// Open the collection from sidebar
|
|
await page.locator('#sidebar-collection-name').filter({ hasText: 'Environment Export Test Collection' }).click();
|
|
|
|
// Open collection environment settings
|
|
await page.getByTestId('environment-selector-trigger').click();
|
|
await page.getByTestId('env-tab-collection').click();
|
|
await page.getByText('Configure', { exact: true }).click();
|
|
|
|
const envTab = page.locator('.request-tab').filter({ hasText: 'Environments' });
|
|
await expect(envTab).toBeVisible();
|
|
});
|
|
|
|
await test.step('Configure export settings for single JSON file', async () => {
|
|
await page.locator('button[title="Export environment"]').click();
|
|
|
|
// Select single JSON file format
|
|
await page.getByText('Single JSON file').click();
|
|
|
|
// Set export directory
|
|
await page.locator('input[id="export-location"]').fill(exportDir);
|
|
});
|
|
|
|
await test.step('Execute export and verify success', async () => {
|
|
// Export the environments
|
|
await page.getByRole('button', { name: 'Export 2 Environments' }).click();
|
|
|
|
// Verify success message
|
|
await expect(page.getByText('Environment(s) exported successfully', { exact: false }).first()).toBeVisible();
|
|
});
|
|
|
|
await test.step('Verify exported file and content', async () => {
|
|
// Verify exported file exists
|
|
const exportedFile = path.join(exportDir, 'bruno-collection-environments.json');
|
|
expect(fs.existsSync(exportedFile)).toBe(true);
|
|
|
|
// Verify file content matches expected fixture
|
|
const content = JSON.parse(fs.readFileSync(exportedFile, 'utf8'));
|
|
const expectedContent = loadExpectedFixture('bruno-collection-environments.json');
|
|
expect(normalizeExportedContent(content)).toEqual(expectedContent);
|
|
});
|
|
});
|
|
|
|
test('should generate unique names when the export directory already contains previously exported contents', async ({
|
|
pageWithUserData: page,
|
|
createTmpDir
|
|
}) => {
|
|
const exportDir = await createTmpDir('collection-env-export-single-object');
|
|
|
|
await test.step('Setup existing export file to simulate conflict', async () => {
|
|
// Create existing export directory and file to simulate conflict
|
|
const existingExportJsonPath = path.join(exportDir, 'local.json');
|
|
fs.writeFileSync(existingExportJsonPath, '{}');
|
|
});
|
|
|
|
await test.step('Open collection and navigate to environment settings', async () => {
|
|
// Open the collection from sidebar
|
|
await page.locator('#sidebar-collection-name').filter({ hasText: 'Environment Export Test Collection' }).click();
|
|
|
|
// Open collection environment settings
|
|
await page.getByTestId('environment-selector-trigger').click();
|
|
await page.getByTestId('env-tab-collection').click();
|
|
await page.getByText('Configure', { exact: true }).click();
|
|
|
|
const envTab = page.locator('.request-tab').filter({ hasText: 'Environments' });
|
|
await expect(envTab).toBeVisible();
|
|
});
|
|
|
|
await test.step('Configure export settings for single JSON file', async () => {
|
|
await page.locator('button[title="Export environment"]').click();
|
|
|
|
// Deselect all environments first
|
|
await page.getByText('Deselect All').click();
|
|
|
|
// Select only "local" environment
|
|
const localEnvCheckbox = page.locator('label').filter({ hasText: 'local' }).locator('input[type="checkbox"]');
|
|
await localEnvCheckbox.check();
|
|
|
|
await page.getByText('Single JSON file').click();
|
|
|
|
// Set export directory
|
|
await page.locator('input[id="export-location"]').fill(exportDir);
|
|
});
|
|
|
|
await test.step('Execute export and close modal', async () => {
|
|
// Export should succeed with unique names
|
|
await page.getByRole('button', { name: 'Export 1 Environment' }).click();
|
|
});
|
|
|
|
await test.step('Verify unique naming and file content', async () => {
|
|
// Verify original file still exists
|
|
const existingExportJsonPath = path.join(exportDir, 'local.json');
|
|
expect(fs.existsSync(existingExportJsonPath)).toBe(true);
|
|
|
|
// Verify new file with unique name was created
|
|
const uniqueExportPath = path.join(exportDir, 'local copy.json');
|
|
expect(fs.existsSync(uniqueExportPath)).toBe(true);
|
|
|
|
// Verify file content matches expected fixture
|
|
const exportedContent = JSON.parse(fs.readFileSync(uniqueExportPath, 'utf8'));
|
|
const expectedContent = loadExpectedFixture('local.json');
|
|
expect(normalizeExportedContent(exportedContent)).toEqual(expectedContent);
|
|
});
|
|
});
|
|
});
|
|
|
|
// common tests
|
|
test('should not be able to export, when no environments are selected', async ({
|
|
pageWithUserData: page,
|
|
createTmpDir
|
|
}) => {
|
|
const exportDir = await createTmpDir('collection-env-export-no-selection');
|
|
|
|
await test.step('Open collection and navigate to environment settings', async () => {
|
|
// Open the collection from sidebar
|
|
await page.locator('#sidebar-collection-name').filter({ hasText: 'Environment Export Test Collection' }).click();
|
|
|
|
// Open environment settings
|
|
await page.getByTestId('environment-selector-trigger').click();
|
|
await page.getByTestId('env-tab-collection').click();
|
|
await page.getByText('Configure', { exact: true }).click();
|
|
|
|
const envTab = page.locator('.request-tab').filter({ hasText: 'Environments' });
|
|
await expect(envTab).toBeVisible();
|
|
});
|
|
|
|
await test.step('Open export modal and deselect all environments', async () => {
|
|
// Click export button
|
|
await page.getByRole('button', { name: 'Export Environment' }).click();
|
|
|
|
// Deselect all environments
|
|
await page.getByText('Deselect All').click();
|
|
});
|
|
|
|
await test.step('Verify export button is disabled when no environments selected', async () => {
|
|
// Verify export button is disabled
|
|
await expect(page.getByRole('button', { name: 'Export Environments' })).toBeDisabled();
|
|
});
|
|
});
|
|
});
|