Environment's as tabs (#6407)

* add: env's as tabs

* fix: test

* fix: tests

* fixes

* fix: test

* fixes

* fixes

* fix

* fix: styling

* fixes
This commit is contained in:
naman-bruno
2025-12-18 16:10:00 +05:30
committed by GitHub
parent 678fa88a7c
commit bc2efb9686
66 changed files with 2198 additions and 1951 deletions

View File

@@ -28,9 +28,14 @@ test.describe.serial('bru.setEnvVar(name, value, { persist: true })', () => {
await page.getByTestId('environment-selector-trigger').click();
// open environment configuration
await page.locator('#configure-env').click();
const envTab = page.locator('.request-tab').filter({ hasText: 'Environments' });
await expect(envTab).toBeVisible();
await expect(page.getByRole('row', { name: 'token' }).getByRole('cell').nth(1)).toBeVisible();
await expect(page.getByRole('row', { name: 'secret' }).getByRole('cell').nth(2)).toBeVisible();
await page.getByTestId('modal-close-button').click();
await envTab.hover();
await envTab.getByTestId('request-tab-close-icon').click();
// we restart the app to confirm that the environment variable is persisted
const newApp = await restartApp();
@@ -43,11 +48,15 @@ test.describe.serial('bru.setEnvVar(name, value, { persist: true })', () => {
// open environment dropdown
await newPage.getByTestId('environment-selector-trigger').click();
await newPage.locator('#configure-env').click();
const newEnvTab = newPage.locator('.request-tab').filter({ hasText: 'Environments' });
await expect(newEnvTab).toBeVisible();
await expect(newPage.getByRole('row', { name: 'token' }).getByRole('cell').nth(1)).toBeVisible();
await expect(newPage.getByRole('row', { name: 'secret' }).getByRole('cell').nth(2)).toBeVisible();
// close the environment modal
await newPage.getByTestId('modal-close-button').click();
await newEnvTab.hover();
await newEnvTab.getByTestId('request-tab-close-icon').click();
// Restore the original Stage.bru file
fs.writeFileSync(originalStageBruPath, originalStageBruContent);

View File

@@ -21,9 +21,14 @@ test.describe.serial('bru.setEnvVar(name, value)', () => {
// confirm that the environment variable is set
await page.getByTestId('environment-selector-trigger').click();
await page.locator('#configure-env').click();
const envTab = page.locator('.request-tab').filter({ hasText: 'Environments' });
await expect(envTab).toBeVisible();
await expect(page.getByRole('row', { name: 'token' }).getByRole('cell').nth(1)).toBeVisible();
await expect(page.getByRole('row', { name: 'secret' }).getByRole('cell').nth(2)).toBeVisible();
await page.getByTestId('modal-close-button').click();
await envTab.hover();
await envTab.getByTestId('request-tab-close-icon').click();
// we restart the app to confirm that the environment variable is not persisted
const newApp = await restartApp();
@@ -37,11 +42,13 @@ test.describe.serial('bru.setEnvVar(name, value)', () => {
await newPage.getByTestId('environment-selector-trigger').click();
await newPage.locator('#configure-env').click();
// ensure that the environment variable is not persisted
await expect(newPage.locator('table.environment-variables tbody')).not.toContainText('token');
const newEnvTab = newPage.locator('.request-tab').filter({ hasText: 'Environments' });
await expect(newEnvTab).toBeVisible();
// close the environment variable modal
await newPage.getByTestId('modal-close-button').click();
await expect(newPage.locator('.table-container tbody')).not.toContainText('token');
await newEnvTab.hover();
await newEnvTab.getByTestId('request-tab-close-icon').click();
await newPage.close();
});
});

View File

@@ -14,18 +14,20 @@ test.describe.serial('bru.setEnvVar multiple persistent variables', () => {
await page.locator('#configure-env').click();
await page.waitForTimeout(200);
// Remove the test environment variables
const envTab = page.locator('.request-tab').filter({ hasText: 'Environments' });
const key1Row = page.getByRole('row', { name: 'multiple-persist-vars-key1' });
if (await key1Row.isVisible()) {
await key1Row.getByRole('button').click(); // Click the delete button
await key1Row.getByRole('button').click();
}
const key2Row = page.getByRole('row', { name: 'multiple-persist-vars-key2' });
if (await key2Row.isVisible()) {
await key2Row.getByRole('button').click(); // Click the delete button
await key2Row.getByRole('button').click();
}
await page.getByTestId('modal-close-button').click();
await envTab.hover();
await envTab.getByTestId('request-tab-close-icon').click();
}
} catch (error) {
// Ignore cleanup errors to avoid masking test failures
@@ -74,11 +76,16 @@ test.describe.serial('bru.setEnvVar multiple persistent variables', () => {
await page.waitForTimeout(200);
await page.locator('#configure-env').click();
await page.waitForTimeout(200);
const envTab = page.locator('.request-tab').filter({ hasText: 'Environments' });
await expect(envTab).toBeVisible();
await expect(page.getByRole('row', { name: 'multiple-persist-vars-key1' }).getByRole('cell').nth(1)).toBeVisible();
await expect(page.getByRole('row', { name: 'value1' }).getByRole('cell').nth(2)).toBeVisible();
await expect(page.getByRole('row', { name: 'multiple-persist-vars-key2' }).getByRole('cell').nth(1)).toBeVisible();
await expect(page.getByRole('row', { name: 'value2' }).getByRole('cell').nth(2)).toBeVisible();
await page.getByTestId('modal-close-button').click();
await envTab.hover();
await envTab.getByTestId('request-tab-close-icon').click();
});
await test.step('Verify variables are persisted to file', async () => {

View File

@@ -28,15 +28,13 @@ test.describe('Collection Environment Configuration Selection Tests', () => {
await page.getByTestId('env-tab-collection').click();
await page.getByText('Configure', { exact: true }).click();
// Verify the config modal opens with the currently active environment selected
const collectionEnvModal = page.locator('.bruno-modal').filter({ hasText: 'Environments' });
await expect(collectionEnvModal).toBeVisible();
const envTab = page.locator('.request-tab').filter({ hasText: 'Environments' });
await expect(envTab).toBeVisible();
// Check that the active environment in the config matches prod
const activeEnvItem = collectionEnvModal.locator('.environment-item.active');
const activeEnvItem = page.locator('.environment-item.active');
await expect(activeEnvItem).toContainText('prod');
// Close the collection environment config modal
await page.getByText('×').click();
await envTab.hover();
await envTab.getByTestId('request-tab-close-icon').click();
});
});

View File

@@ -5,7 +5,6 @@ import {
createEnvironment,
addEnvironmentVariables,
saveEnvironment,
closeEnvironmentPanel,
sendRequest,
expectResponseContains,
removeCollection
@@ -39,7 +38,6 @@ test.describe('Collection Environment Create Tests', () => {
]);
await saveEnvironment(page);
await closeEnvironmentPanel(page);
await expect(locators.environment.currentEnvironment()).toContainText('Test Environment');
});

View File

@@ -5,7 +5,6 @@ import {
createEnvironment,
addEnvironmentVariables,
saveEnvironment,
closeEnvironmentPanel,
sendRequest,
expectResponseContains,
closeAllCollections
@@ -41,7 +40,6 @@ test.describe('Global Environment Create Tests', () => {
]);
await saveEnvironment(page);
await closeEnvironmentPanel(page);
await expect(locators.environment.currentEnvironment()).toContainText('Test Global Environment');
});

View File

@@ -36,14 +36,13 @@ test.describe.serial('Collection Environment Export Tests', () => {
await page.getByTestId('env-tab-collection').click();
await page.getByText('Configure', { exact: true }).click();
// Verify the environment settings modal opens
const envModal = page.locator('.bruno-modal').filter({ hasText: 'Environments' });
await expect(envModal).toBeVisible();
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('.btn-import-environment').getByText('Export').click();
await page.locator('button[title="Export environment"]').click();
// Verify export modal opens
const exportModal = page.locator('.bruno-modal').filter({ hasText: 'Export Environments' });
@@ -63,8 +62,6 @@ test.describe.serial('Collection Environment Export Tests', () => {
await test.step('Execute export and close modal', async () => {
// Export the environment
await page.getByRole('button', { name: 'Export 1 Environment' }).click();
await page.getByTestId('modal-close-button').click();
});
await test.step('Verify exported file and content', async () => {
@@ -95,11 +92,14 @@ test.describe.serial('Collection Environment Export Tests', () => {
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('.btn-import-environment').getByText('Export').click();
await page.locator('button[title="Export environment"]').click();
// Verify all environments are selected by default
await expect(page.getByRole('checkbox', { name: 'Local' })).toBeChecked();
@@ -115,8 +115,6 @@ test.describe.serial('Collection Environment Export Tests', () => {
await test.step('Execute export and close modal', async () => {
// Export all environments
await page.getByRole('button', { name: /Export \d+ Environments?/ }).click();
await page.getByTestId('modal-close-button').click();
});
await test.step('Verify exported files and content', async () => {
@@ -162,11 +160,14 @@ test.describe.serial('Collection Environment Export Tests', () => {
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('.btn-import-environment').getByText('Export').click();
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();
@@ -178,8 +179,6 @@ test.describe.serial('Collection Environment Export Tests', () => {
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 page.getByTestId('modal-close-button').click();
});
await test.step('Verify unique naming and file content', async () => {
@@ -219,11 +218,13 @@ test.describe.serial('Collection Environment Export Tests', () => {
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 () => {
// Click export button
await page.locator('.btn-import-environment').getByText('Export').click();
await page.locator('button[title="Export environment"]').click();
// Deselect all environments first
await page.getByText('Deselect All').click();
@@ -244,8 +245,6 @@ test.describe.serial('Collection Environment Export Tests', () => {
// Verify success message
await expect(page.getByText('Environment(s) exported successfully', { exact: false }).first()).toBeVisible();
await page.getByTestId('modal-close-button').click();
});
await test.step('Verify exported file and content', async () => {
@@ -274,11 +273,13 @@ test.describe.serial('Collection Environment Export Tests', () => {
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 () => {
// Click export button
await page.locator('.btn-import-environment').getByText('Export').click();
await page.locator('button[title="Export environment"]').click();
// Select single JSON file format
await page.getByText('Single JSON file').click();
@@ -293,8 +294,6 @@ test.describe.serial('Collection Environment Export Tests', () => {
// Verify success message
await expect(page.getByText('Environment(s) exported successfully', { exact: false }).first()).toBeVisible();
await page.getByTestId('modal-close-button').click();
});
await test.step('Verify exported file and content', async () => {
@@ -329,11 +328,13 @@ test.describe.serial('Collection Environment Export Tests', () => {
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 () => {
// Click export button
await page.locator('.btn-import-environment').getByText('Export').click();
await page.locator('button[title="Export environment"]').click();
// Deselect all environments first
await page.getByText('Deselect All').click();
@@ -351,8 +352,6 @@ test.describe.serial('Collection Environment Export Tests', () => {
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 page.getByTestId('modal-close-button').click();
});
await test.step('Verify unique naming and file content', async () => {
@@ -387,11 +386,14 @@ test.describe.serial('Collection Environment Export Tests', () => {
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.locator('.btn-import-environment').getByText('Export').click();
await page.getByRole('button', { name: 'Export Environment' }).click();
// Deselect all environments
await page.getByText('Deselect All').click();

View File

@@ -40,14 +40,13 @@ test.describe.serial('Global Environment Export Tests', () => {
await page.getByTestId('env-tab-global').click();
await page.getByText('Configure', { exact: true }).click();
// Verify the global environment settings modal opens
const globalEnvModal = page.locator('.bruno-modal').filter({ hasText: 'Global Environments' });
await expect(globalEnvModal).toBeVisible();
const envTab = page.locator('.request-tab').filter({ hasText: 'Global Environments' });
await expect(envTab).toBeVisible();
});
await test.step('Open export modal and configure export settings', async () => {
// Click export button
await page.locator('.btn-import-environment').getByText('Export').click();
await page.locator('button[title="Export environment"]').click();
// Verify export modal opens
const exportModal = page.locator('.bruno-modal').filter({ hasText: 'Export Environments' });
@@ -67,8 +66,6 @@ test.describe.serial('Global Environment Export Tests', () => {
await test.step('Execute export and close modal', async () => {
// Export the environment
await page.getByRole('button', { name: 'Export 1 Environment' }).click();
await page.getByTestId('modal-close-button').click();
});
await test.step('Verify exported file and content', async () => {
@@ -99,11 +96,14 @@ test.describe.serial('Global Environment Export Tests', () => {
await page.getByTestId('environment-selector-trigger').click();
await page.getByTestId('env-tab-global').click();
await page.getByText('Configure', { exact: true }).click();
const envTab = page.locator('.request-tab').filter({ hasText: 'Global Environments' });
await expect(envTab).toBeVisible();
});
await test.step('Configure export settings for multiple environments', async () => {
// Click export button
await page.locator('.btn-import-environment').getByText('Export').click();
await page.locator('button[title="Export environment"]').click();
// Verify all environments are selected by default
await expect(page.getByRole('checkbox', { name: 'Local' })).toBeChecked();
@@ -119,8 +119,6 @@ test.describe.serial('Global Environment Export Tests', () => {
await test.step('Execute export and close modal', async () => {
// Export all environments
await page.getByRole('button', { name: /Export \d+ Environments?/ }).click();
await page.getByTestId('modal-close-button').click();
});
await test.step('Verify exported files and content', async () => {
@@ -166,11 +164,14 @@ test.describe.serial('Global Environment Export Tests', () => {
await page.getByTestId('environment-selector-trigger').click();
await page.getByTestId('env-tab-global').click();
await page.getByText('Configure', { exact: true }).click();
const envTab = page.locator('.request-tab').filter({ hasText: 'Global Environments' });
await expect(envTab).toBeVisible();
});
await test.step('Configure export settings with folder format', async () => {
// Click export button
await page.locator('.btn-import-environment').getByText('Export').click();
await page.locator('button[title="Export environment"]').click();
// Set export directory
await page.locator('input[id="export-location"]').fill(exportDir);
@@ -182,8 +183,6 @@ test.describe.serial('Global Environment Export Tests', () => {
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 page.getByTestId('modal-close-button').first().click();
});
await test.step('Verify unique naming and file content', async () => {
@@ -223,11 +222,13 @@ test.describe.serial('Global Environment Export Tests', () => {
await page.getByTestId('environment-selector-trigger').click();
await page.getByTestId('env-tab-global').click();
await page.getByText('Configure', { exact: true }).click();
const envTab = page.locator('.request-tab').filter({ hasText: 'Global Environments' });
await expect(envTab).toBeVisible();
});
await test.step('Configure export settings for single JSON file', async () => {
// Click export button
await page.locator('.btn-import-environment').getByText('Export').click();
await page.locator('button[title="Export environment"]').click();
// Deselect all environments first
await page.getByText('Deselect All').click();
@@ -250,8 +251,6 @@ test.describe.serial('Global Environment Export Tests', () => {
// Verify success message
await expect(page.getByText('Environment(s) exported successfully', { exact: false }).first()).toBeVisible();
await page.getByTestId('modal-close-button').click();
});
await test.step('Verify exported file and content', async () => {
@@ -280,11 +279,13 @@ test.describe.serial('Global Environment Export Tests', () => {
await page.getByTestId('environment-selector-trigger').click();
await page.getByTestId('env-tab-global').click();
await page.getByText('Configure', { exact: true }).click();
const envTab = page.locator('.request-tab').filter({ hasText: 'Global Environments' });
await expect(envTab).toBeVisible();
});
await test.step('Configure export settings for single JSON file', async () => {
// Click export button
await page.locator('.btn-import-environment').getByText('Export').click();
await page.locator('button[title="Export environment"]').click();
// Select single JSON file format
await page.getByText('Single JSON file').click();
@@ -299,8 +300,6 @@ test.describe.serial('Global Environment Export Tests', () => {
await page.waitForTimeout(200);
// Verify success message
await expect(page.getByText('Environment(s) exported successfully', { exact: false }).first()).toBeVisible();
await page.getByTestId('modal-close-button').click();
});
await test.step('Verify exported file and content', async () => {
@@ -335,11 +334,13 @@ test.describe.serial('Global Environment Export Tests', () => {
await page.getByTestId('environment-selector-trigger').click();
await page.getByTestId('env-tab-global').click();
await page.getByText('Configure', { exact: true }).click();
const envTab = page.locator('.request-tab').filter({ hasText: 'Global Environments' });
await expect(envTab).toBeVisible();
});
await test.step('Configure export settings for single JSON file', async () => {
// Click export button
await page.locator('.btn-import-environment').getByText('Export').click();
await page.locator('button[title="Export environment"]').click();
// Deselect all environments first
await page.getByText('Deselect All').click();
@@ -359,8 +360,6 @@ test.describe.serial('Global Environment Export Tests', () => {
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 page.getByTestId('modal-close-button').first().click();
});
await test.step('Verify unique naming and file content', async () => {
@@ -395,18 +394,18 @@ test.describe.serial('Global Environment Export Tests', () => {
await page.getByTestId('environment-selector-trigger').click();
await page.getByTestId('env-tab-global').click();
await page.getByText('Configure', { exact: true }).click();
const envTab = page.locator('.request-tab').filter({ hasText: 'Global Environments' });
await expect(envTab).toBeVisible();
});
await test.step('Open export modal and deselect all environments', async () => {
// Click export button
await page.locator('.btn-import-environment').getByText('Export').click();
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();
});
});

View File

@@ -21,15 +21,13 @@ test.describe('Global Environment Configuration Selection Tests', () => {
await page.getByTestId('env-tab-global').click();
await page.getByText('Configure', { exact: true }).click();
// Verify the config modal opens with the currently active environment selected
const globalEnvModal = page.locator('.bruno-modal').filter({ hasText: 'Global Environments' });
await expect(globalEnvModal).toBeVisible();
const envTab = page.locator('.request-tab').filter({ hasText: 'Global Environments' });
await expect(envTab).toBeVisible();
// Check that the active environment in the config matches the current environment
const activeEnvItem = globalEnvModal.locator('.environment-item.active');
const activeEnvItem = page.locator('.environment-item.active');
await expect(activeEnvItem).toContainText(currentEnvName);
// Close the global environment config modal and go to welcome page
await page.getByText('×').click();
await envTab.hover();
await envTab.getByTestId('request-tab-close-icon').click();
});
});

View File

@@ -39,16 +39,14 @@ test.describe.serial('Collection Environment Import Tests', () => {
});
await test.step('Verify imported environment and variables', async () => {
// The environment settings modal should now be visible with the imported environment
const envModal = page.locator('.bruno-modal').filter({ hasText: 'Environments' });
await expect(envModal).toBeVisible();
const envTab = page.locator('.request-tab').filter({ hasText: 'Environments' });
await expect(envTab).toBeVisible();
// Verify imported variables
await expect(page.getByRole('row', { name: 'host' }).getByRole('cell').nth(1)).toBeVisible();
await expect(page.getByRole('row', { name: 'secretToken' }).getByRole('cell').nth(1)).toBeVisible();
// Close modal
await page.getByText('×').click();
await envTab.hover();
await envTab.getByTestId('request-tab-close-icon').click();
});
await test.step('Clean up after test', async () => {
@@ -93,15 +91,11 @@ test.describe.serial('Collection Environment Import Tests', () => {
const fileChooser = await fileChooserPromise;
await fileChooser.setFiles(multiEnvFile);
// The environment settings modal should now be visible with the imported environments
const envModal = page.locator('.bruno-modal').filter({ hasText: 'Environments' });
await expect(envModal).toBeVisible();
const envTab = page.locator('.request-tab').filter({ hasText: 'Environments' });
await expect(envTab).toBeVisible();
});
await test.step('Verify both environments are available in selector', async () => {
// Check that both environments are available in the selector
await page.getByText('×').click(); // Close environment settings modal
await page.waitForTimeout(500);
await page.getByTestId('environment-selector-trigger').click();
@@ -118,15 +112,16 @@ test.describe.serial('Collection Environment Import Tests', () => {
// Verify prod environment variables by opening settings again
await page.getByTestId('environment-selector-trigger').click();
await page.getByText('Configure', { exact: true }).click();
const envModal = page.locator('.bruno-modal').filter({ hasText: 'Environments' });
await expect(envModal).toBeVisible();
const envTab = page.locator('.request-tab').filter({ hasText: 'Environments' });
await expect(envTab).toBeVisible();
// Verify prod environment variables
await expect(page.getByRole('row', { name: 'host' }).getByRole('cell').nth(1)).toBeVisible();
await expect(page.getByRole('row', { name: 'secretToken' }).getByRole('cell').nth(1)).toBeVisible();
// Close modal
await page.getByText('×').click();
await envTab.hover();
await envTab.getByTestId('request-tab-close-icon').click();
});
await test.step('Clean up after test', async () => {

View File

@@ -23,12 +23,10 @@ test.describe.serial('Global Environment Import Tests', () => {
// Delete all existing environments
for (let i = 0; i < count; i++) {
await page.getByTestId('delete-environment-button').click();
// Confirm deletion if there's a confirmation dialog
await page.locator('button[title="Delete"]').first().click();
const confirmButton = page.getByRole('button', { name: 'Delete' });
if (await confirmButton.isVisible()) {
await confirmButton.click();
await page.getByText('×').click();
}
}
@@ -56,16 +54,15 @@ test.describe.serial('Global Environment Import Tests', () => {
});
await test.step('Verify imported global environment and variables', async () => {
// The global environment settings modal should now be visible with the imported environment
const envModal = page.locator('.bruno-modal').filter({ hasText: 'Global Environments' });
await expect(envModal).toBeVisible();
const envTab = page.locator('.request-tab').filter({ hasText: 'Global Environments' });
await expect(envTab).toBeVisible();
// Verify imported variables
await expect(page.getByRole('row', { name: 'host' }).getByRole('cell').nth(1)).toBeVisible();
await expect(page.getByRole('row', { name: 'secretToken' }).getByRole('cell').nth(1)).toBeVisible();
// Close modal
await page.getByText('×').click();
await envTab.hover();
await envTab.getByTestId('request-tab-close-icon').click();
});
});
@@ -90,12 +87,10 @@ test.describe.serial('Global Environment Import Tests', () => {
// Delete all existing environments
for (let i = 0; i < count; i++) {
await page.getByTestId('delete-environment-button').click();
// Confirm deletion if there's a confirmation dialog
const confirmButton = page.getByRole('button', { name: 'Delete' });
await page.locator('button[title="Delete"]').first().click();
const confirmButton = page.getByText('Delete', { exact: true });
if (await confirmButton.isVisible()) {
await confirmButton.click();
await page.getByText('×').click();
}
}
@@ -120,14 +115,11 @@ test.describe.serial('Global Environment Import Tests', () => {
const fileChooser = await fileChooserPromise;
await fileChooser.setFiles(multiEnvFile);
// The global environment settings modal should now be visible with the imported environments
const envModal = page.locator('.bruno-modal').filter({ hasText: 'Global Environments' });
await expect(envModal).toBeVisible();
const envTab = page.locator('.request-tab').filter({ hasText: 'Global Environments' });
await expect(envTab).toBeVisible();
});
await test.step('Verify both global environments are available in selector', async () => {
// Check that both environments are available in the selector
await page.getByText('×').click(); // Close environment settings modal
await page.getByTestId('environment-selector-trigger').click();
await page.getByTestId('env-tab-global').click();
@@ -145,15 +137,15 @@ test.describe.serial('Global Environment Import Tests', () => {
await page.getByTestId('environment-selector-trigger').click();
await page.getByTestId('env-tab-global').click();
await page.getByText('Configure', { exact: true }).click();
const envModal = page.locator('.bruno-modal').filter({ hasText: 'Global Environments' });
await expect(envModal).toBeVisible();
const envTab = page.locator('.request-tab').filter({ hasText: 'Global Environments' });
await expect(envTab).toBeVisible();
// Verify imported variables
await expect(page.getByRole('row', { name: 'host' }).getByRole('cell').nth(1)).toBeVisible();
await expect(page.getByRole('row', { name: 'secretToken' }).getByRole('cell').nth(1)).toBeVisible();
// Close modal
await page.getByText('×').click();
await envTab.hover();
await envTab.getByTestId('request-tab-close-icon').click();
});
});
});

View File

@@ -52,21 +52,19 @@ test.describe('Collection Environment Import Tests', () => {
// Wait for import to complete and environment settings modal to open
await expect(page.locator('.current-environment')).toContainText('Test Collection Environment');
// The environment settings modal should now be visible with the imported environment
const envSettingsModal = page.locator('.bruno-modal').filter({ hasText: 'Environments' });
await expect(envSettingsModal).toBeVisible();
const envTab = page.locator('.request-tab').filter({ hasText: 'Environments' });
await expect(envTab).toBeVisible();
// Verify imported variables in Test Collection Environment settings
await expect(envSettingsModal.locator('input[name="0.name"]')).toHaveValue('host');
await expect(envSettingsModal.locator('input[name="1.name"]')).toHaveValue('userId');
await expect(envSettingsModal.locator('input[name="2.name"]')).toHaveValue('apiKey');
await expect(envSettingsModal.locator('input[name="3.name"]')).toHaveValue('postTitle');
await expect(envSettingsModal.locator('input[name="4.name"]')).toHaveValue('postBody');
await expect(envSettingsModal.locator('input[name="5.name"]')).toHaveValue('secretApiToken');
await expect(envSettingsModal.locator('input[name="5.secret"]')).toBeChecked();
await page.getByText('×').click();
await expect(page.locator('input[name="0.name"]')).toHaveValue('host');
await expect(page.locator('input[name="1.name"]')).toHaveValue('userId');
await expect(page.locator('input[name="2.name"]')).toHaveValue('apiKey');
await expect(page.locator('input[name="3.name"]')).toHaveValue('postTitle');
await expect(page.locator('input[name="4.name"]')).toHaveValue('postBody');
await expect(page.locator('input[name="5.name"]')).toHaveValue('secretApiToken');
await expect(page.locator('input[name="5.secret"]')).toBeChecked();
await envTab.hover();
await envTab.getByTestId('request-tab-close-icon').click();
// Test GET request with imported environment
await page.locator('.collection-item-name').first().click();
await expect(page.locator('#request-url .CodeMirror-line')).toContainText('{{host}}/posts/{{userId}}');
await page.locator('[data-testid="send-arrow-icon"]').click();

View File

@@ -47,21 +47,20 @@ test.describe('Global Environment Import Tests', () => {
// Wait for import to complete and global environment settings modal to open
await expect(page.locator('.current-environment')).toContainText('Test Global Environment');
// The global environment settings modal should now be visible with the imported environment
const globalEnvSettingsModal = page.locator('.bruno-modal').filter({ hasText: 'Global Environments' });
await expect(globalEnvSettingsModal).toBeVisible();
const envTab = page.locator('.request-tab').filter({ hasText: 'Global Environments' });
await expect(envTab).toBeVisible();
// Verify imported variables in Test Global Environment settings
await expect(globalEnvSettingsModal.locator('input[name="0.name"]')).toHaveValue('host');
await expect(globalEnvSettingsModal.locator('input[name="1.name"]')).toHaveValue('userId');
await expect(globalEnvSettingsModal.locator('input[name="2.name"]')).toHaveValue('apiKey');
await expect(globalEnvSettingsModal.locator('input[name="3.name"]')).toHaveValue('postTitle');
await expect(globalEnvSettingsModal.locator('input[name="4.name"]')).toHaveValue('postBody');
await expect(globalEnvSettingsModal.locator('input[name="5.name"]')).toHaveValue('secretApiToken');
await expect(globalEnvSettingsModal.locator('input[name="5.secret"]')).toBeChecked();
await page.getByText('×').click();
const variablesTable = page.locator('.table-container');
await expect(variablesTable.locator('input[name="0.name"]')).toHaveValue('host');
await expect(variablesTable.locator('input[name="1.name"]')).toHaveValue('userId');
await expect(variablesTable.locator('input[name="2.name"]')).toHaveValue('apiKey');
await expect(variablesTable.locator('input[name="3.name"]')).toHaveValue('postTitle');
await expect(variablesTable.locator('input[name="4.name"]')).toHaveValue('postBody');
await expect(variablesTable.locator('input[name="5.name"]')).toHaveValue('secretApiToken');
await expect(variablesTable.locator('input[name="5.secret"]')).toBeChecked();
await envTab.hover();
await envTab.getByTestId('request-tab-close-icon').click();
// Test GET request with global environment
await page.locator('#collection-environment-test-collection .collection-item-name').first().click();
await expect(page.locator('#request-url .CodeMirror-line')).toContainText('{{host}}/posts/{{userId}}');
await page.locator('[data-testid="send-arrow-icon"]').click();

View File

@@ -11,7 +11,7 @@ test.describe('Multiline Variables - Write Test', () => {
// open request
await expect(page.getByTitle('multiline-test', { exact: true })).toBeVisible();
await page.getByTitle('multiline-test', { exact: true }).click();
await page.getByTitle('multiline-test', { exact: true }).dblclick();
// open environment dropdown
await page.locator('div.current-environment').click();
@@ -28,10 +28,12 @@ test.describe('Multiline Variables - Write Test', () => {
await expect(page.getByText('Configure', { exact: true })).toBeVisible();
await page.getByText('Configure', { exact: true }).click();
// add variable
await page.getByRole('button', { name: /Add.*Variable/i }).click();
const valueTextarea = page.locator('.bruno-modal-card textarea').last();
await expect(valueTextarea).toBeVisible();
const envTab = page.locator('.request-tab').filter({ hasText: 'Environments' });
await expect(envTab).toBeVisible();
const emptyRowNameInput = page.locator('tbody tr').last().locator('input[placeholder="Name"]');
await expect(emptyRowNameInput).toBeVisible();
await emptyRowNameInput.fill('multiline_data_json');
const jsonValue = `{
"user": {
@@ -48,23 +50,17 @@ test.describe('Multiline Variables - Write Test', () => {
}
}`;
// fill variable value
await valueTextarea.fill(jsonValue);
await page.keyboard.press('Shift+Tab');
await page.keyboard.type('multiline_data_json');
const variableRow = page.locator('tbody tr').filter({ has: page.locator('input[value="multiline_data_json"]') });
const codeMirror = variableRow.locator('.CodeMirror');
await codeMirror.click();
await page.keyboard.insertText(jsonValue);
// save variable and close config
const saveVarButton = page.getByRole('button', { name: /Save/i });
await expect(saveVarButton).toBeVisible();
await saveVarButton.click();
await page.getByTestId('save-env').click();
await expect(page.locator('.close.cursor-pointer')).toBeVisible();
await page.locator('.close.cursor-pointer').click();
await envTab.hover();
await envTab.getByTestId('request-tab-close-icon').click();
// send request
const sendButton = page.locator('#send-request').getByRole('img').nth(2);
await expect(sendButton).toBeVisible();
await sendButton.click();
await page.getByTestId('send-arrow-icon').click();
// wait for response status
await expect(page.locator('.response-status-code.text-ok')).toBeVisible();

View File

@@ -3,7 +3,6 @@ import { closeAllCollections } from '../../utils/page';
test.describe('Global Environment Variable Update via Script', () => {
test.afterEach(async ({ pageWithUserData: page }) => {
// cleanup: close all collections
await closeAllCollections(page);
});
@@ -23,40 +22,43 @@ test.describe('Global Environment Variable Update via Script', () => {
await page.getByTestId('send-arrow-icon').click();
});
await test.step('Open the Global Environment Config modal', async () => {
await test.step('Open the Global Environment Config tab', async () => {
await page.getByTestId('environment-selector-trigger').click();
await page.getByTestId('env-tab-global').click();
await page.getByText('Configure', { exact: true }).click();
const envTab = page.locator('.request-tab').filter({ hasText: 'Global Environments' });
await expect(envTab).toBeVisible();
});
const globalEnvModal = page.locator('.bruno-modal').filter({ hasText: 'Global Environments' });
await test.step('Verify that the value of "existingEnvEnabled" is updated by the pre-request script', async () => {
const updatedExistingEnvEnabledInputDiv = await globalEnvModal.getByTestId('env-var-value-1');
const updatedExistingEnvEnabledValue = await updatedExistingEnvEnabledInputDiv.locator('.CodeMirror-line').textContent();
await expect(updatedExistingEnvEnabledValue).toContain('newExistingEnvEnabledValue');
const row = page.locator('tbody tr').filter({ has: page.locator('input[value="existingEnvEnabled"]') });
const value = await row.locator('.CodeMirror-line').first().textContent();
await expect(value).toContain('newExistingEnvEnabledValue');
});
await test.step('Verify that the value of "existingEnvDisabled" is updated by the pre-request script', async () => {
const updatedExistingEnvDisabledInputDiv = await globalEnvModal.getByTestId('env-var-value-2');
const updatedExistingEnvDisabledValue = await updatedExistingEnvDisabledInputDiv.locator('.CodeMirror-line').textContent();
await expect(updatedExistingEnvDisabledValue).toContain('newExistingEnvDisabledValue');
const row = page.locator('tbody tr').filter({ has: page.locator('input[value="existingEnvDisabled"]') });
const value = await row.locator('.CodeMirror-line').first().textContent();
await expect(value).toContain('newExistingEnvDisabledValue');
});
await test.step('Verify that a new env variable "newEnv" is added by the pre-request script to the global environment', async () => {
const newEnvInputDiv = await globalEnvModal.getByTestId('env-var-value-3');
const newEnvValue = await newEnvInputDiv.locator('.CodeMirror-line').textContent();
await expect(newEnvValue).toContain('newEnvValue');
const row = page.locator('tbody tr').filter({ has: page.locator('input[value="newEnv"]') });
const value = await row.locator('.CodeMirror-line').first().textContent();
await expect(value).toContain('newEnvValue');
});
await test.step('Verify that the value of "baseUrl" is unchanged.', async () => {
const currentBaseUrlInputDiv = await globalEnvModal.getByTestId('env-var-value-0');
const currentBaseUrlValue = await currentBaseUrlInputDiv.locator('.CodeMirror-line').textContent();
await expect(currentBaseUrlValue).toContain('https://echo.usebruno.com');
const row = page.locator('tbody tr').filter({ has: page.locator('input[value="baseUrl"]') });
const value = await row.locator('.CodeMirror-line').first().textContent();
await expect(value).toContain('https://echo.usebruno.com');
});
await test.step('Close the global environment config modal.', async () => {
await page.getByTestId('modal-close-button').click();
await test.step('Close the global environment config tab.', async () => {
const envTab = page.locator('.request-tab').filter({ hasText: 'Global Environments' });
await envTab.hover();
await envTab.getByTestId('request-tab-close-icon').click();
});
});
});

View File

@@ -1,5 +1,5 @@
import { test, expect } from '../../playwright';
import { openCollectionAndAcceptSandbox, closeAllCollections, sendRequest } from '../utils/page';
import { openCollectionAndAcceptSandbox, closeAllCollections, sendRequest, addEnvironmentVariables } from '../utils/page';
import { buildCommonLocators } from '../utils/page/locators';
test.describe('Global Environment Variables - Non-string Values', () => {
@@ -23,20 +23,19 @@ test.describe('Global Environment Variables - Non-string Values', () => {
await page.locator('#environment-name').fill('Test Env');
await page.getByRole('button', { name: 'Create', exact: true }).click();
// Add a string variable.
await page.getByTestId('add-variable').click();
const newRow = page.locator('tbody tr').last();
await newRow.locator('input[name$=".name"]').fill('stringVar');
await newRow.locator('.CodeMirror').click();
await page.keyboard.type('hello world');
const envTab = page.locator('.request-tab').filter({ hasText: 'Global Environments' });
await expect(envTab).toBeVisible();
await addEnvironmentVariables(page, [
{ name: 'stringVar', value: 'hello world' },
{ name: 'numericVar', value: '170001' },
{ name: 'booleanVar', value: 'true' }
]);
// Save
await page.getByTestId('save-env').click();
// Verify that the string variable value is saved and displayed correctly.
await expect(newRow.locator('.CodeMirror-line').first()).toContainText('hello world');
// Close the environment modal
await page.locator('[data-test-id="modal-close-button"]').click();
await envTab.hover();
await envTab.getByTestId('request-tab-close-icon').click();
});
// Request contains a script that sets the non-string global variables.
@@ -50,14 +49,13 @@ test.describe('Global Environment Variables - Non-string Values', () => {
await page.getByTestId('environment-selector-trigger').click();
await page.getByTestId('env-tab-global').click();
await page.getByRole('button', { name: 'Configure' }).click();
const envTab = page.locator('.request-tab').filter({ hasText: 'Global Environments' });
await expect(envTab).toBeVisible();
});
const envModal = page
.locator('.bruno-modal-card')
.filter({ has: page.locator('.bruno-modal-header-title', { hasText: 'Global Environments' }) });
const numericInput = envModal.locator('input[value="numericVar"]');
const booleanInput = envModal.locator('input[value="booleanVar"]');
const numericInput = page.locator('input[value="numericVar"]');
const booleanInput = page.locator('input[value="booleanVar"]');
await expect(numericInput).toBeVisible();
await expect(booleanInput).toBeVisible();
const numericRow = numericInput.locator('xpath=ancestor::tr');
@@ -74,9 +72,7 @@ test.describe('Global Environment Variables - Non-string Values', () => {
await page.keyboard.type('999');
await expect(numericRow.locator('.CodeMirror-line').first()).toContainText(/170001/);
// Hovering over the info icon reveals the tooltip.
// It is anchored to the info icon element id, so hover/click reveals it reliably.
const infoIcon = page.locator('#numericVar-disabled-info-icon');
const infoIcon = numericRow.locator('[id$="-disabled-info-icon"]').nth(0);
await infoIcon.hover();
// The tooltip explains why the field is locked.
@@ -103,8 +99,7 @@ test.describe('Global Environment Variables - Non-string Values', () => {
await page.keyboard.type('false');
await expect(booleanRow.locator('.CodeMirror-line').first()).toContainText(/true/);
// Hovering over the info icon reveals the tooltip.
const infoIcon = page.locator('#booleanVar-disabled-info-icon');
const infoIcon = booleanRow.locator('[id$="-disabled-info-icon"]').nth(0);
await infoIcon.hover();
// The tooltip explains why the field is locked.
@@ -114,8 +109,7 @@ test.describe('Global Environment Variables - Non-string Values', () => {
});
await test.step('Verify that stringVar remains editable', async () => {
// Unlike script-managed values above, this one is user-managed.
const stringInput = envModal.locator('input[value="stringVar"]');
const stringInput = page.locator('input[value="stringVar"]');
await expect(stringInput).toBeVisible();
const stringRow = stringInput.locator('xpath=ancestor::tr');
@@ -125,8 +119,12 @@ test.describe('Global Environment Variables - Non-string Values', () => {
// Verify the user edit persists in the UI.
await expect(stringRow.locator('.CodeMirror-line').first()).toContainText('hello world updated');
// Close the environment modal
await page.locator('[data-test-id="modal-close-button"]').click();
await page.getByTestId('save-env').click();
const envTab = page.locator('.request-tab').filter({ hasText: 'Global Environments' });
await envTab.hover();
await envTab.getByTestId('request-tab-close-icon').click();
});
});
});

View File

@@ -178,9 +178,10 @@ test.describe('Import Insomnia v4 Collection - Environment Import', () => {
await expect(page.getByTestId('env-var-row-newFeature.version').locator('.CodeMirror-line').first()).toHaveText('2.099123123');
});
await test.step('Close environment modal', async () => {
// Close the environment configuration modal to ensure clean state
await page.getByText('×').click();
await test.step('Close environment tab', async () => {
const envTab = page.locator('.request-tab').filter({ hasText: 'Environments' });
await envTab.hover();
await envTab.getByTestId('request-tab-close-icon').click();
});
});
});

View File

@@ -202,9 +202,10 @@ test.describe('Import Insomnia v5 Collection - Environment Import', () => {
await expect(page.getByTestId('env-var-row-user.roles[0]').locator('.CodeMirror-line').first()).toHaveText('admin');
});
await test.step('Close environment modal', async () => {
// Close the environment configuration modal to ensure clean state
await page.getByText('×').click();
await test.step('Close environment tab', async () => {
const envTab = page.locator('.request-tab').filter({ hasText: 'Environments' });
await envTab.hover();
await envTab.getByTestId('request-tab-close-icon').click();
});
});
});

View File

@@ -16,6 +16,8 @@ test('should persist request with newlines across app restarts', async ({ create
await page.locator('.bruno-modal').getByLabel('Location').fill(collectionPath);
await page.locator('.bruno-modal').getByRole('button', { name: 'Create' }).click();
await openCollectionAndAcceptSandbox(page, 'newlines-persistence', 'safe');
const collection = page.getByTestId('collections').locator('.collection-name').filter({ hasText: 'newlines-persistence' });
await collection.hover();
await collection.locator('.collection-actions .icon').click();
@@ -25,7 +27,6 @@ test('should persist request with newlines across app restarts', async ({ create
await page.locator('#new-request-url').locator('textarea').fill('https://httpbin.org/get');
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();
await page.getByRole('tab', { name: 'Params' }).click();

View File

@@ -390,10 +390,23 @@ const createEnvironment = async (
await page.locator('button[id="create-env"]').click();
const nameInput = page.locator('input[name="name"]');
const nameInput = type === 'collection'
? page.locator('input[name="name"]')
: page.locator('#environment-name');
await expect(nameInput).toBeVisible();
await nameInput.fill(environmentName);
await page.getByRole('button', { name: 'Create' }).click();
const tabLabel = type === 'collection' ? 'Environments' : 'Global Environments';
await expect(page.locator('.request-tab').filter({ hasText: tabLabel })).toBeVisible();
const locators = buildCommonLocators(page);
await locators.environment.selector().click();
if (type === 'global') {
await locators.environment.globalTab().click();
}
await locators.environment.envOption(environmentName).click();
await expect(page.locator('.current-environment')).toContainText(environmentName);
});
};
@@ -416,11 +429,6 @@ const addEnvironmentVariable = async (
index: number
) => {
await test.step(`Add environment variable "${variable.name}"`, async () => {
const addButton = page.locator('button[data-testid="add-variable"]');
await addButton.waitFor({ state: 'visible' });
await addButton.click();
// Wait for the new row to be added and the name input to be visible
const nameInput = page.locator(`input[name="${index}.name"]`);
await nameInput.waitFor({ state: 'visible' });
await nameInput.fill(variable.name);
@@ -466,13 +474,17 @@ const saveEnvironment = async (page: Page) => {
};
/**
* Close the environment modal/panel
* Close the environment tab
* @param page - The page object
* @param type - The type of environment tab to close
* @returns void
*/
const closeEnvironmentPanel = async (page: Page) => {
await test.step('Close environment panel', async () => {
await page.getByText('×').click();
const closeEnvironmentPanel = async (page: Page, type: EnvironmentType = 'collection') => {
await test.step('Close environment tab', async () => {
const tabLabel = type === 'collection' ? 'Environments' : 'Global Environments';
const envTab = page.locator('.request-tab').filter({ hasText: tabLabel });
await envTab.hover();
await envTab.getByTestId('request-tab-close-icon').click();
});
};

View File

@@ -39,7 +39,7 @@ export const buildCommonLocators = (page: Page) => ({
tabs: {
requestTab: (requestName: string) => page.locator('.request-tab .tab-label').filter({ hasText: requestName }),
activeRequestTab: () => page.locator('.request-tab.active'),
closeTab: (requestName: string) => page.locator('.request-tab').filter({ hasText: requestName }).locator('.close-icon')
closeTab: (requestName: string) => page.locator('.request-tab').filter({ hasText: requestName }).getByTestId('request-tab-close-icon')
},
folder: {
chevron: (folderName: string) => page.locator('.collection-item-name').filter({ hasText: folderName }).getByTestId('folder-chevron')