diff --git a/packages/bruno-app/src/components/SingleLineEditor/index.js b/packages/bruno-app/src/components/SingleLineEditor/index.js
index 0bbb0bbde..87c47f3b0 100644
--- a/packages/bruno-app/src/components/SingleLineEditor/index.js
+++ b/packages/bruno-app/src/components/SingleLineEditor/index.js
@@ -205,7 +205,11 @@ class SingleLineEditor extends Component {
render() {
return (
-
+
{this.secretEye(this.props.isSecret)}
);
diff --git a/packages/bruno-app/src/components/TagList/StyledWrapper.js b/packages/bruno-app/src/components/TagList/StyledWrapper.js
index c81897a27..97fbdf920 100644
--- a/packages/bruno-app/src/components/TagList/StyledWrapper.js
+++ b/packages/bruno-app/src/components/TagList/StyledWrapper.js
@@ -23,13 +23,18 @@ const StyledWrapper = styled.div`
max-width: 200px;
transition: all 0.2s ease;
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
+ cursor: default;
- &:hover {
+ &:has(.tag-remove:hover) {
background-color: ${(props) => props.theme.requestTabs.active.bg};
border-color: ${(props) => props.theme.requestTabs.active.border || props.theme.requestTabs.bottomBorder};
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
transform: translateY(-1px);
}
+
+ .tag-remove {
+ cursor: pointer;
+ }
}
.tag-icon {
diff --git a/packages/bruno-app/src/components/TagList/index.js b/packages/bruno-app/src/components/TagList/index.js
index e683a0a41..1b800a6a0 100644
--- a/packages/bruno-app/src/components/TagList/index.js
+++ b/packages/bruno-app/src/components/TagList/index.js
@@ -49,6 +49,7 @@ const TagList = ({ tagsHintList = [], handleAddTag, tags, handleRemoveTag, onSav
onChange={handleInputChange}
onRun={handleKeyDown}
onSave={onSave}
+ data-testid="tag-input"
/>
{error && {error}}
@@ -57,14 +58,15 @@ const TagList = ({ tagsHintList = [], handleAddTag, tags, handleRemoveTag, onSav
-
))
diff --git a/tests/collection/create-requests/graphql-requests.spec.ts b/tests/collection/create-requests/graphql-requests.spec.ts
index b54118a2b..49f9915ae 100644
--- a/tests/collection/create-requests/graphql-requests.spec.ts
+++ b/tests/collection/create-requests/graphql-requests.spec.ts
@@ -11,12 +11,14 @@ test.describe('Create GraphQL Requests', () => {
test.afterAll(async ({ pageWithUserData: page }) => {
// Clean up Root GraphQL Request
- await locators.sidebar.request('Root GraphQL Request').click({ button: 'right' });
+ await locators.sidebar.request('Root GraphQL Request').hover();
+ await locators.actions.collectionItemActions('Root GraphQL Request').click();
await locators.dropdown.item('Delete').click();
await locators.modal.button('Delete').click();
// Clean up Folder GraphQL Request
- await locators.sidebar.request('Folder GraphQL Request').click({ button: 'right' });
+ await locators.sidebar.request('Folder GraphQL Request').hover();
+ await locators.actions.collectionItemActions('Folder GraphQL Request').click();
await locators.dropdown.item('Delete').click();
await locators.modal.button('Delete').click();
@@ -58,8 +60,8 @@ test.describe('Create GraphQL Requests', () => {
});
await test.step('Create GraphQL request via folder1 three dots menu', async () => {
- const folderItem = locators.sidebar.folder('folder1');
- await folderItem.click({ button: 'right' });
+ await locators.sidebar.folder('folder1').hover();
+ await locators.actions.collectionItemActions('folder1').click();
await locators.dropdown.item('New Request').click();
await page.getByTestId('graphql-request').click();
diff --git a/tests/collection/create-requests/grpc-requests.spec.ts b/tests/collection/create-requests/grpc-requests.spec.ts
index 8b67914cf..b3df569d9 100644
--- a/tests/collection/create-requests/grpc-requests.spec.ts
+++ b/tests/collection/create-requests/grpc-requests.spec.ts
@@ -13,12 +13,14 @@ test.describe('Create gRPC Requests', () => {
const locators = buildCommonLocators(page);
// Clean up Root gRPC Request
- await locators.sidebar.request('Root gRPC Request').click({ button: 'right' });
+ await locators.sidebar.request('Root gRPC Request').hover();
+ await locators.actions.collectionItemActions('Root gRPC Request').click();
await locators.dropdown.item('Delete').click();
await locators.modal.button('Delete').click();
// Clean up Folder gRPC Request
- await locators.sidebar.request('Folder gRPC Request').click({ button: 'right' });
+ await locators.sidebar.request('Folder gRPC Request').hover();
+ await locators.actions.collectionItemActions('Folder gRPC Request').click();
await locators.dropdown.item('Delete').click();
await locators.modal.button('Delete').click();
@@ -60,8 +62,8 @@ test.describe('Create gRPC Requests', () => {
});
await test.step('Create gRPC request via folder1 three dots menu', async () => {
- const folderItem = locators.sidebar.folder('folder1');
- await folderItem.click({ button: 'right' });
+ await locators.sidebar.folder('folder1').hover();
+ await locators.actions.collectionItemActions('folder1').click();
await locators.dropdown.item('New Request').click();
await page.getByTestId('grpc-request').click();
diff --git a/tests/collection/create-requests/http-requests.spec.ts b/tests/collection/create-requests/http-requests.spec.ts
index 6c53e4bcc..64c05f4d9 100644
--- a/tests/collection/create-requests/http-requests.spec.ts
+++ b/tests/collection/create-requests/http-requests.spec.ts
@@ -13,12 +13,14 @@ test.describe('Create HTTP Requests', () => {
const locators = buildCommonLocators(page);
// Clean up Root HTTP Request
- await locators.sidebar.request('Root HTTP Request').click({ button: 'right' });
+ await locators.sidebar.request('Root HTTP Request').hover();
+ await locators.actions.collectionItemActions('Root HTTP Request').click();
await locators.dropdown.item('Delete').click();
await locators.modal.button('Delete').click();
// Clean up Folder HTTP Request
- await locators.sidebar.request('Folder HTTP Request').click({ button: 'right' });
+ await locators.sidebar.request('Folder HTTP Request').hover();
+ await locators.actions.collectionItemActions('Folder HTTP Request').click();
await locators.dropdown.item('Delete').click();
await locators.modal.button('Delete').click();
@@ -59,8 +61,8 @@ test.describe('Create HTTP Requests', () => {
});
await test.step('Create HTTP request via folder1 three dots menu', async () => {
- const folderItem = locators.sidebar.folder('folder1');
- await folderItem.click({ button: 'right' });
+ await locators.sidebar.folder('folder1').hover();
+ await locators.actions.collectionItemActions('folder1').click();
await locators.dropdown.item('New Request').click();
await page.getByTestId('request-name').fill('Folder HTTP Request');
diff --git a/tests/collection/create-requests/ws-requests.spec.ts b/tests/collection/create-requests/ws-requests.spec.ts
index 7c0ab53c1..cdd2cc377 100644
--- a/tests/collection/create-requests/ws-requests.spec.ts
+++ b/tests/collection/create-requests/ws-requests.spec.ts
@@ -13,12 +13,14 @@ test.describe('Create WebSocket Requests', () => {
const locators = buildCommonLocators(page);
// Clean up Folder WebSocket Request
- await locators.sidebar.request('Folder WebSocket Request').click({ button: 'right' });
+ await locators.sidebar.request('Folder WebSocket Request').hover();
+ await locators.actions.collectionItemActions('Folder WebSocket Request').click();
await locators.dropdown.item('Delete').click();
await locators.modal.button('Delete').click();
// Clean up Root WebSocket Request
- await locators.sidebar.request('Root WebSocket Request').click({ button: 'right' });
+ await locators.sidebar.request('Root WebSocket Request').hover();
+ await locators.actions.collectionItemActions('Root WebSocket Request').click();
await locators.dropdown.item('Delete').click();
await locators.modal.button('Delete').click();
@@ -60,8 +62,8 @@ test.describe('Create WebSocket Requests', () => {
});
await test.step('Create WebSocket request via folder1 three dots menu', async () => {
- const folderItem = locators.sidebar.folder('folder1');
- await folderItem.click({ button: 'right' });
+ await locators.sidebar.folder('folder1').hover();
+ await locators.actions.collectionItemActions('folder1').click();
await locators.dropdown.item('New Request').click();
await page.getByTestId('ws-request').click();
diff --git a/tests/collection/moving-requests/cross-collection-drag-drop-folder.spec.ts b/tests/collection/moving-requests/cross-collection-drag-drop-folder.spec.ts
index 30d384d15..fdee42d29 100644
--- a/tests/collection/moving-requests/cross-collection-drag-drop-folder.spec.ts
+++ b/tests/collection/moving-requests/cross-collection-drag-drop-folder.spec.ts
@@ -1,5 +1,5 @@
import { test, expect } from '../../../playwright';
-import { closeAllCollections } from '../../utils/page';
+import { closeAllCollections, createCollection } from '../../utils/page';
test.describe('Cross-Collection Drag and Drop for folder', () => {
test.afterEach(async ({ page }) => {
@@ -8,18 +8,8 @@ test.describe('Cross-Collection Drag and Drop for folder', () => {
});
test('Verify cross-collection folder drag and drop', async ({ page, createTmpDir }) => {
- // Create first collection - click dropdown menu first
- await page.locator('.dropdown-icon').click();
- await page.locator('.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();
-
- // Wait for collection to appear and click on it
- 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();
- await page.getByRole('button', { name: 'Save' }).click();
+ // Create first collection - open with sandbox mode
+ await createCollection(page, 'source-collection', await createTmpDir('source-collection'), { openWithSandboxMode: 'safe' });
// Create a folder in the first collection
// Look for the collection menu button for the source collection specifically
@@ -34,11 +24,12 @@ test.describe('Cross-Collection Drag and Drop for folder', () => {
await page.getByRole('button', { name: 'Create' }).click();
// Wait for the folder to be created and appear in the sidebar
- await page.waitForTimeout(2000);
+ await page.waitForTimeout(200);
await expect(page.locator('.collection-item-name').filter({ hasText: 'test-folder' })).toBeVisible();
// Add a request to the folder to make it more realistic
- await page.locator('.collection-item-name').filter({ hasText: 'test-folder' }).click({ button: 'right' });
+ await page.locator('.collection-item-name').filter({ hasText: 'test-folder' }).hover();
+ await page.locator('.collection-item-name').filter({ hasText: 'test-folder' }).locator('.menu-icon').click();
await page.locator('.dropdown-item').filter({ hasText: 'New Request' }).click();
await page.getByPlaceholder('Request Name').fill('test-request-in-folder');
await page.locator('#new-request-url .CodeMirror').click();
@@ -46,25 +37,15 @@ test.describe('Cross-Collection Drag and Drop for folder', () => {
await page.getByRole('button', { name: 'Create' }).click();
// Wait for the request to be created
- await page.waitForTimeout(1000);
+ await page.waitForTimeout(200);
// Expand the folder to see the request inside
await page.locator('.collection-item-name').filter({ hasText: 'test-folder' }).click();
- await page.waitForTimeout(500);
+ await page.waitForTimeout(200);
await expect(page.locator('.collection-item-name').filter({ hasText: 'test-request-in-folder' })).toBeVisible();
- // Create second collection - click dropdown menu first
- await page.locator('.dropdown-icon').click();
- await page.locator('.dropdown-item').filter({ hasText: 'Create Collection' }).click();
- await page.getByLabel('Name').fill('target-collection');
- await page.getByLabel('Location').fill(await createTmpDir('target-collection'));
- await page.getByRole('button', { name: 'Create', exact: true }).click();
-
- // Wait for second collection to appear and click on it
- await expect(page.locator('#sidebar-collection-name').filter({ hasText: 'target-collection' })).toBeVisible();
- await page.locator('#sidebar-collection-name').filter({ hasText: 'target-collection' }).click();
- await page.getByLabel('Safe Mode').check();
- await page.getByRole('button', { name: 'Save' }).click();
+ // Create second collection - open with sandbox mode
+ await createCollection(page, 'target-collection', await createTmpDir('target-collection'), { openWithSandboxMode: 'safe' });
// Wait for both collections to be visible in sidebar
await expect(page.locator('#sidebar-collection-name').filter({ hasText: 'source-collection' })).toBeVisible();
@@ -82,12 +63,12 @@ test.describe('Cross-Collection Drag and Drop for folder', () => {
await sourceFolder.dragTo(targetCollection);
// Wait for the operation to complete
- await page.waitForTimeout(3000);
+ await page.waitForTimeout(200);
// Verify the folder has been moved to the target collection
// Click on target collection to expand it if needed
await page.locator('#sidebar-collection-name').filter({ hasText: 'target-collection' }).click();
- await page.waitForTimeout(1000);
+ await page.waitForTimeout(200);
// Check that the folder now appears under target collection
const targetCollectionContainer = page
@@ -100,7 +81,7 @@ test.describe('Cross-Collection Drag and Drop for folder', () => {
// Expand the moved folder to verify the request inside is also moved
await targetCollectionContainer.locator('.collection-item-name').filter({ hasText: 'test-folder' }).click();
- await page.waitForTimeout(500);
+ await page.waitForTimeout(200);
await expect(
targetCollectionContainer.locator('.collection-item-name').filter({ hasText: 'test-request-in-folder' })
).toBeVisible();
@@ -125,17 +106,7 @@ test.describe('Cross-Collection Drag and Drop for folder', () => {
createTmpDir
}) => {
// Create first collection (source) - use unique names for this test
- await page.locator('.dropdown-icon').click();
- await page.locator('.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();
-
- // Wait for collection to appear and click on it
- 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();
- await page.getByRole('button', { name: 'Save' }).click();
+ await createCollection(page, 'source-collection', await createTmpDir('source-collection'), { openWithSandboxMode: 'safe' });
// Create a folder in the first collection
await page
@@ -158,7 +129,8 @@ test.describe('Cross-Collection Drag and Drop for folder', () => {
await expect(page.locator('.collection-item-name').filter({ hasText: 'folder-1' })).toBeVisible();
// Add a request to the folder to make it more realistic
- await page.locator('.collection-item-name').filter({ hasText: 'folder-1' }).click({ button: 'right' });
+ await page.locator('.collection-item-name').filter({ hasText: 'folder-1' }).hover();
+ await page.locator('.collection-item-name').filter({ hasText: 'folder-1' }).locator('.menu-icon').click();
await page.locator('.dropdown-item').filter({ hasText: 'New Request' }).click();
await page.getByPlaceholder('Request Name').fill('http-request');
await page.locator('#new-request-url .CodeMirror').click();
@@ -169,17 +141,7 @@ test.describe('Cross-Collection Drag and Drop for folder', () => {
await expect(page.locator('.collection-item-name').filter({ hasText: 'http-request' })).toBeVisible();
// Create second collection (target)
- await page.locator('.dropdown-icon').click();
- await page.locator('.dropdown-item').filter({ hasText: 'Create Collection' }).click();
- await page.getByLabel('Name').fill('target-collection');
- await page.getByLabel('Location').fill(await createTmpDir('target-collection'));
- await page.getByRole('button', { name: 'Create', exact: true }).click();
-
- // Wait for second collection to appear and click on it
- await expect(page.locator('#sidebar-collection-name').filter({ hasText: 'target-collection' })).toBeVisible();
- await page.locator('#sidebar-collection-name').filter({ hasText: 'target-collection' }).click();
- await page.getByLabel('Safe Mode').check();
- await page.getByRole('button', { name: 'Save' }).click();
+ await createCollection(page, 'target-collection', await createTmpDir('target-collection'), { openWithSandboxMode: 'safe' });
// Create a folder with the same name in the target collection
await page
diff --git a/tests/collection/moving-requests/cross-collection-drag-drop-request.spec.ts b/tests/collection/moving-requests/cross-collection-drag-drop-request.spec.ts
index 390a17fc0..7c6e2438c 100644
--- a/tests/collection/moving-requests/cross-collection-drag-drop-request.spec.ts
+++ b/tests/collection/moving-requests/cross-collection-drag-drop-request.spec.ts
@@ -1,5 +1,5 @@
import { test, expect } from '../../../playwright';
-import { closeAllCollections } from '../../utils/page';
+import { closeAllCollections, createCollection } from '../../utils/page';
test.describe('Cross-Collection Drag and Drop', () => {
test.afterEach(async ({ page }) => {
@@ -8,17 +8,8 @@ test.describe('Cross-Collection Drag and Drop', () => {
});
test('Verify request drag and drop', async ({ page, createTmpDir }) => {
- // Create first collection - click dropdown menu first
- await page.locator('.dropdown-icon').click();
- await page.locator('.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();
-
- 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();
- await page.getByRole('button', { name: 'Save' }).click();
+ // Create first collection - open with sandbox mode
+ await createCollection(page, 'source-collection', await createTmpDir('source-collection'), { openWithSandboxMode: 'safe' });
// Create a request in the first collection
await page.locator('#create-new-tab').getByRole('img').click();
@@ -29,17 +20,8 @@ test.describe('Cross-Collection Drag and Drop', () => {
await expect(page.locator('.collection-item-name').filter({ hasText: 'test-request' })).toBeVisible();
- // Create second collection - click dropdown menu first
- await page.locator('.dropdown-icon').click();
- await page.locator('.dropdown-item').filter({ hasText: 'Create Collection' }).click();
- await page.getByLabel('Name').fill('target-collection');
- await page.getByLabel('Location').fill(await createTmpDir('target-collection'));
- await page.getByRole('button', { name: 'Create', exact: true }).click();
-
- await expect(page.locator('#sidebar-collection-name').filter({ hasText: 'target-collection' })).toBeVisible();
- await page.locator('#sidebar-collection-name').filter({ hasText: 'target-collection' }).click();
- await page.getByLabel('Safe Mode').check();
- await page.getByRole('button', { name: 'Save' }).click();
+ // Create second collection - open with sandbox mode
+ await createCollection(page, 'target-collection', await createTmpDir('target-collection'), { openWithSandboxMode: 'safe' });
await expect(page.locator('#sidebar-collection-name').filter({ hasText: 'source-collection' })).toBeVisible();
await expect(page.locator('#sidebar-collection-name').filter({ hasText: 'target-collection' })).toBeVisible();
@@ -83,17 +65,7 @@ test.describe('Cross-Collection Drag and Drop', () => {
createTmpDir
}) => {
// Create first collection (source-collection)
- await page.locator('.dropdown-icon').click();
- await page.locator('.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();
-
- // Open collection
- 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();
- await page.getByRole('button', { name: 'Save' }).click();
+ await createCollection(page, 'source-collection', await createTmpDir('source-collection'), { openWithSandboxMode: 'safe' });
// Create a request in the first collection (request-1)
await page.locator('#create-new-tab').getByRole('img').click();
@@ -106,17 +78,7 @@ test.describe('Cross-Collection Drag and Drop', () => {
await expect(page.locator('.collection-item-name').filter({ hasText: 'request-1' })).toBeVisible();
// Create second collection (target-collection)
- await page.locator('.dropdown-icon').click();
- await page.locator('.dropdown-item').filter({ hasText: 'Create Collection' }).click();
- await page.getByLabel('Name').fill('target-collection');
- await page.getByLabel('Location').fill(await createTmpDir('target-collection'));
- await page.getByRole('button', { name: 'Create', exact: true }).click();
-
- // Open collection
- await expect(page.locator('#sidebar-collection-name').filter({ hasText: 'target-collection' })).toBeVisible();
- await page.locator('#sidebar-collection-name').filter({ hasText: 'target-collection' }).click();
- await page.getByLabel('Safe Mode').check();
- await page.getByRole('button', { name: 'Save' }).click();
+ await createCollection(page, 'target-collection', await createTmpDir('target-collection'), { openWithSandboxMode: 'safe' });
// Create a request in the target collection with the same name (request-1)
await page.locator('#create-new-tab').getByRole('img').click();
diff --git a/tests/collection/moving-requests/tag-persistence.spec.ts b/tests/collection/moving-requests/tag-persistence.spec.ts
index 49f1e7b18..78681d6b9 100644
--- a/tests/collection/moving-requests/tag-persistence.spec.ts
+++ b/tests/collection/moving-requests/tag-persistence.spec.ts
@@ -19,19 +19,19 @@ test.describe('Tag persistence', () => {
// Create a new request
await page.locator('#create-new-tab').getByRole('img').click();
- await page.getByRole('textbox', { name: 'Request Name' }).fill('r1');
+ await page.getByRole('textbox', { name: 'Request Name' }).fill('request-1');
await page.locator('#new-request-url textarea').fill('https://httpfaker.org/api/echo');
await page.getByRole('button', { name: 'Create' }).click();
// create another request
await page.locator('#create-new-tab').getByRole('img').click();
- await page.getByRole('textbox', { name: 'Request Name' }).fill('r2');
+ await page.getByRole('textbox', { name: 'Request Name' }).fill('request-2');
await page.locator('#new-request-url textarea').fill('https://httpfaker.org/api/echo');
await page.getByRole('button', { name: 'Create' }).click();
// create another request
await page.locator('#create-new-tab').getByRole('img').click();
- await page.getByRole('textbox', { name: 'Request Name' }).fill('r3');
+ await page.getByRole('textbox', { name: 'Request Name' }).fill('request-3');
await page.locator('#new-request-url textarea').fill('https://httpfaker.org/api/echo');
await page.getByRole('button', { name: 'Create' }).click();
@@ -39,37 +39,38 @@ test.describe('Tag persistence', () => {
// Add a tag to the request
await page.getByRole('tab', { name: 'Settings' }).click();
- await page.getByText('Tagse.g., smoke, regression').click();
- await page.getByRole('textbox').nth(2).fill('smoke');
- await page.getByRole('textbox').nth(2).press('Enter');
-
+ await page.waitForTimeout(200);
+ const tagInput = await page.getByTestId('tag-input').getByRole('textbox');
+ await tagInput.fill('smoke');
+ await tagInput.press('Enter');
+ await page.waitForTimeout(200);
// Verify the tag was added
- await expect(page.getByRole('button', { name: 'smoke' })).toBeVisible();
+ await expect(page.locator('.tag-item', { hasText: 'smoke' })).toBeVisible();
await page.keyboard.press('Meta+s');
- // Move the r2 request to just above r1 within the same collection
- const r3Request = page.locator('.collection-item-name').filter({ hasText: 'r3' });
- const r1Request = page.locator('.collection-item-name').filter({ hasText: 'r1' });
+ // Move the request-3 request to just above request-1 within the same collection
+ const r3Request = page.locator('.collection-item-name').filter({ hasText: 'request-3' });
+ const r1Request = page.locator('.collection-item-name').filter({ hasText: 'request-1' });
await expect(r3Request).toBeVisible();
await expect(r1Request).toBeVisible();
- // Perform drag and drop operation to move r3 below r1 using source position
+ // Perform drag and drop operation to move request-3 below request-1 using source position
await r3Request.dragTo(r1Request, {
targetPosition: { x: 0, y: 1 }
});
- // Verify the requests are still in the collection and r3 is now above r1
- await expect(page.locator('.collection-item-name').filter({ hasText: 'r3' })).toBeVisible();
- await expect(page.locator('.collection-item-name').filter({ hasText: 'r1' })).toBeVisible();
+ // Verify the requests are still in the collection and request-3 is now above request-1
+ await expect(page.locator('.collection-item-name').filter({ hasText: 'request-3' })).toBeVisible();
+ await expect(page.locator('.collection-item-name').filter({ hasText: 'request-1' })).toBeVisible();
- // Click on r3 to verify the tag persisted after the move
- await page.locator('.collection-item-name').filter({ hasText: 'r3' }).click();
- await page.locator('.request-tab.active', { hasText: 'r3' }).waitFor({ state: 'visible' });
+ // Click on request-3 to verify the tag persisted after the move
+ await page.locator('.collection-item-name').filter({ hasText: 'request-3' }).click();
+ await page.locator('.request-tab.active').filter({ hasText: 'request-3' }).waitFor({ state: 'visible' });
await page.getByRole('tab', { name: 'Settings' }).click();
-
+ await page.waitForTimeout(200);
// Verify the tag is still present after the move
- await expect(page.getByRole('button', { name: 'smoke' })).toBeVisible();
+ await expect(page.locator('.tag-item', { hasText: 'smoke' })).toBeVisible();
});
test('verify tag persistence while moving requests between folders', async ({ page, createTmpDir }) => {
@@ -83,75 +84,82 @@ test.describe('Tag persistence', () => {
await page.getByRole('button', { name: 'Save' }).click();
// Create a new folder
- await page.getByTitle('test-collection').click({
- button: 'right'
- });
- await page.waitForTimeout(200);
+ await page.locator('.collection-name')
+ .filter({ hasText: 'test-collection' }).hover();
+ await page.locator('.collection-name')
+ .filter({ hasText: 'test-collection' }).locator('.collection-actions .icon').click();
+ await page.waitForTimeout(1);
await page.getByText('New Folder').click();
- await page.locator('#folder-name').fill('f1');
+ await page.locator('#folder-name').fill('folder-1');
await page.getByRole('button', { name: 'Create' }).click();
+ await page.waitForTimeout(100);
+
+ // Create a new request within folder-1 folder
+ await page.getByText('folder-1').click();
await page.waitForTimeout(200);
- // Create a new request within f1 folder
- await page.getByText('f1').click();
- await page.waitForTimeout(200);
- await page.getByTitle('f1', { exact: true }).click({
- button: 'right'
- });
+ await page.locator('.collection-item-name').filter({ hasText: 'folder-1' }).hover();
+ await page.locator('.collection-item-name').filter({ hasText: 'folder-1' }).locator('.menu-icon').click();
await page.locator('.dropdown-item').getByText('New Request').click()
- await page.getByRole('textbox', { name: 'Request Name' }).fill('r1');
+ await page.getByRole('textbox', { name: 'Request Name' }).fill('request-1');
await page.locator('#new-request-url textarea').fill('https://httpfaker.org/api/echo');
await page.getByRole('button', { name: 'Create' }).click();
- // create another request within f1 folder
- await page.getByTitle('f1', { exact: true }).click({
- button: 'right'
- });
+ // create another request within folder-1 folder
+ await page.locator('.collection-item-name')
+ .filter({ hasText: 'folder-1' }).hover();
+ await page.locator('.collection-item-name')
+ .filter({ hasText: 'folder-1' }).locator('.menu-icon').click();
await page.locator('.dropdown-item').getByText('New Request').click()
- await page.getByRole('textbox', { name: 'Request Name' }).fill('r2');
+ await page.getByRole('textbox', { name: 'Request Name' }).fill('request-2');
await page.locator('#new-request-url textarea').fill('https://httpfaker.org/api/echo');
await page.getByRole('button', { name: 'Create' }).click();
await page.waitForTimeout(200);
// Add a tag to the request
await page.getByRole('tab', { name: 'Settings' }).click();
- await page.getByText('Tagse.g., smoke, regression').click();
- await page.getByRole('textbox').nth(2).fill('smoke');
- await page.getByRole('textbox').nth(2).press('Enter');
- await expect(page.getByRole('button', { name: 'smoke' })).toBeVisible();
+ await page.waitForTimeout(200);
+ const tagInput = await page.getByTestId('tag-input').getByRole('textbox');
+ await tagInput.fill('smoke');
+ await tagInput.press('Enter');
+ await page.waitForTimeout(200);
+ await expect(page.locator('.tag-item', { hasText: 'smoke' })).toBeVisible();
await page.keyboard.press('Meta+s');
// Create another folder
- await page.getByTitle('test-collection').click({
- button: 'right'
- });
+ await page.locator('.collection-name')
+ .filter({ hasText: 'test-collection' }).hover();
+ await page.locator('.collection-name')
+ .filter({ hasText: 'test-collection' }).locator('.collection-actions .icon').click();
await page.locator('.dropdown-item').getByText('New Folder').click();
- await page.locator('#folder-name').fill('f2');
+ await page.locator('#folder-name').fill('folder-2');
await page.getByRole('button', { name: 'Create' }).click();
- // open f2 folder
- await page.getByText('f2').click();
- await page.getByTitle('f2', { exact: true }).click({
- button: 'right'
- });
+ // open folder-2 folder
+ await page.getByText('folder-2').click();
+ await page.locator('.collection-item-name')
+ .filter({ hasText: 'folder-2' }).hover();
+ await page.locator('.collection-item-name')
+ .filter({ hasText: 'folder-2' }).locator('.menu-icon').click();
await page.locator('.dropdown-item').getByText('New Request').click();
- await page.getByRole('textbox', { name: 'Request Name' }).fill('r3');
+ await page.getByRole('textbox', { name: 'Request Name' }).fill('request-3');
await page.locator('#new-request-url textarea').fill('https://httpfaker.org/api/echo');
await page.getByRole('button', { name: 'Create' }).click();
- // Drag and drop r2 request to f2 folder
- const r2Request = page.locator('.collection-item-name').filter({ hasText: 'r2' });
- const f2Folder = page.locator('.collection-item-name').filter({ hasText: 'f2' });
+ // Drag and drop request-2 request to folder-2 folder
+ const r2Request = page.locator('.collection-item-name').filter({ hasText: 'request-2' });
+ const f2Folder = page.locator('.collection-item-name').filter({ hasText: 'folder-2' });
await r2Request.dragTo(f2Folder);
- // Verify the requests are still in the collection and r2 is now in f2 folder
- await expect(page.locator('.collection-item-name').filter({ hasText: 'r2' })).toBeVisible();
- await expect(page.locator('.collection-item-name').filter({ hasText: 'f2' })).toBeVisible();
+ // Verify the requests are still in the collection and request-2 is now in folder-2 folder
+ await expect(page.locator('.collection-item-name').filter({ hasText: 'request-2' })).toBeVisible();
+ await expect(page.locator('.collection-item-name').filter({ hasText: 'folder-2' })).toBeVisible();
- // Click on r2 to verify the tag persisted after the move
- await page.locator('.collection-item-name').filter({ hasText: 'r2' }).click();
- await page.locator('.request-tab.active', { hasText: 'r2' }).waitFor({ state: 'visible' });
+ // Click on request-2 to verify the tag persisted after the move
+ await page.locator('.collection-item-name').filter({ hasText: 'request-2' }).click();
+ await page.locator('.request-tab.active').filter({ hasText: 'request-2' }).waitFor({ state: 'visible' });
await page.getByRole('tab', { name: 'Settings' }).click();
- await expect(page.getByRole('button', { name: 'smoke' })).toBeVisible();
+ await page.waitForTimeout(200);
+ await expect(page.locator('.tag-item', { hasText: 'smoke' })).toBeVisible();
});
});
diff --git a/tests/environments/api-setEnvVar/multiple-persist-vars.spec.ts b/tests/environments/api-setEnvVar/multiple-persist-vars.spec.ts
index 3da10e997..083b08fc2 100644
--- a/tests/environments/api-setEnvVar/multiple-persist-vars.spec.ts
+++ b/tests/environments/api-setEnvVar/multiple-persist-vars.spec.ts
@@ -10,7 +10,9 @@ test.describe.serial('bru.setEnvVar multiple persistent variables', () => {
if (page && !page.isClosed()) {
await page.locator('#sidebar-collection-name').click();
await page.getByTestId('environment-selector-trigger').click();
+ await page.waitForTimeout(200);
await page.locator('#configure-env').click();
+ await page.waitForTimeout(200);
// Remove the test environment variables
const key1Row = page.getByRole('row', { name: 'multiple-persist-vars-key1' });
@@ -40,6 +42,7 @@ test.describe.serial('bru.setEnvVar multiple persistent variables', () => {
await test.step('Select stage environment', async () => {
await page.getByTestId('environment-selector-trigger').click();
+ await page.waitForTimeout(200);
await expect(page.locator('.environment-list .dropdown-item', { hasText: 'Stage' })).toBeVisible();
await page.locator('.environment-list .dropdown-item', { hasText: 'Stage' }).click();
await expect(page.locator('.current-environment', { hasText: 'Stage' })).toBeVisible();
@@ -49,8 +52,9 @@ test.describe.serial('bru.setEnvVar multiple persistent variables', () => {
// Ensure we're in the correct collection context before selecting the folder
await expect(page.locator('#sidebar-collection-name', { hasText: 'collection' })).toBeVisible();
- // Right-click on the folder to open context menu
- await page.getByText('multiple-persist-vars-folder', { exact: true }).click({ button: 'right' });
+ // Hover on the folder and open context menu
+ await page.getByText('multiple-persist-vars-folder', { exact: true }).hover();
+ await page.locator('.collection-item-name').filter({ hasText: 'multiple-persist-vars-folder' }).locator('.menu-icon').click();
// Click on Run option
await page.getByText('Run', { exact: true }).click();
@@ -67,7 +71,9 @@ test.describe.serial('bru.setEnvVar multiple persistent variables', () => {
await expect(page.locator('#sidebar-collection-name', { hasText: 'collection' })).toBeVisible();
await page.getByTestId('environment-selector-trigger').click();
+ await page.waitForTimeout(200);
await page.locator('#configure-env').click();
+ await page.waitForTimeout(200);
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();
diff --git a/tests/environments/export-environment/global-env-export/global-env-export.spec.ts b/tests/environments/export-environment/global-env-export/global-env-export.spec.ts
index ec0eab2bd..50f853936 100644
--- a/tests/environments/export-environment/global-env-export/global-env-export.spec.ts
+++ b/tests/environments/export-environment/global-env-export/global-env-export.spec.ts
@@ -249,7 +249,7 @@ test.describe.serial('Global Environment Export Tests', () => {
await page.getByRole('button', { name: 'Export 1 Environment' }).click();
// Verify success message
- await expect(page.getByText('Environment(s) exported successfully', { exact: false })).toBeVisible();
+ await expect(page.getByText('Environment(s) exported successfully', { exact: false }).first()).toBeVisible();
await page.getByTestId('modal-close-button').click();
});
@@ -296,9 +296,9 @@ test.describe.serial('Global Environment Export Tests', () => {
await test.step('Execute export and verify success', async () => {
// Export the environments
await page.getByRole('button', { name: 'Export 2 Environments' }).click();
-
+ await page.waitForTimeout(200);
// Verify success message
- await expect(page.getByText('Environment(s) exported successfully', { exact: false })).toBeVisible();
+ await expect(page.getByText('Environment(s) exported successfully', { exact: false }).first()).toBeVisible();
await page.getByTestId('modal-close-button').click();
});
diff --git a/tests/environments/import-environment/collection-env-import.spec.ts b/tests/environments/import-environment/collection-env-import.spec.ts
index 0569f55e0..0e5097f54 100644
--- a/tests/environments/import-environment/collection-env-import.spec.ts
+++ b/tests/environments/import-environment/collection-env-import.spec.ts
@@ -83,17 +83,5 @@ test.describe('Collection Environment Import Tests', () => {
await page.locator('[data-testid="send-arrow-icon"]').click();
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();
- // Wait for the close collection modal to be hidden
- await page.locator('.dropdown-item').filter({ hasText: 'Close' }).click();
- await page.locator('.dropdown-item').filter({ hasText: 'Close' }).waitFor({ state: 'detached' });
- await page.getByRole('button', { name: 'Close' }).click();
});
});
diff --git a/tests/onboarding/sample-collection.spec.ts b/tests/onboarding/sample-collection.spec.ts
index a229676a4..78d89a38b 100644
--- a/tests/onboarding/sample-collection.spec.ts
+++ b/tests/onboarding/sample-collection.spec.ts
@@ -87,11 +87,13 @@ test.describe('Onboarding', () => {
const page = await app.firstWindow();
// First launch - sample collection should be created
- const sampleCollection = page.locator('#sidebar-collection-name').getByText('Sample API Collection');
+ const sampleCollection = page.locator('.collection-name').filter({ hasText: 'Sample API Collection' });
await expect(sampleCollection).toBeVisible();
- // User closes the sample collection (right-click to open context menu)
- await sampleCollection.click({ button: 'right' });
+ // User closes the sample collection (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');
diff --git a/tests/preferences/default-collection-location/default-collection-location.spec.js b/tests/preferences/default-collection-location/default-collection-location.spec.js
index 8194d854c..3eeda754f 100644
--- a/tests/preferences/default-collection-location/default-collection-location.spec.js
+++ b/tests/preferences/default-collection-location/default-collection-location.spec.js
@@ -28,7 +28,7 @@ test.describe('Default Collection Location Feature', () => {
await page.getByRole('button', { name: 'Save' }).click();
// verify success message
- await expect(page.locator('text=Preferences saved successfully')).toBeVisible();
+ await expect(page.locator('text=Preferences saved successfully').first()).toBeVisible();
// wait for 2 seconds
await page.waitForTimeout(2000);
@@ -48,7 +48,7 @@ test.describe('Default Collection Location Feature', () => {
await page.getByRole('button', { name: 'Save' }).click();
// verify success message
- await expect(page.locator('text=Preferences saved successfully')).toBeVisible();
+ await expect(page.locator('text=Preferences saved successfully').first()).toBeVisible();
// wait for 2 seconds
await page.waitForTimeout(2000);
diff --git a/tests/protobuf/manage-protofile.spec.ts b/tests/protobuf/manage-protofile.spec.ts
index b8c6418cb..787448d65 100644
--- a/tests/protobuf/manage-protofile.spec.ts
+++ b/tests/protobuf/manage-protofile.spec.ts
@@ -1,9 +1,13 @@
+import { execSync } from 'child_process';
import { test, expect } from '../../playwright';
import { closeAllCollections } from '../utils/page';
+import path from 'path';
test.describe('manage protofile', () => {
test.afterAll(async ({ pageWithUserData: page }) => {
await closeAllCollections(page);
+ // Reset the collection request file to the original state
+ execSync(`git checkout -- ${path.join(__dirname, 'collection', 'bruno.json')}`);
});
test('protofiles, import paths from bruno.json are visible in the protobuf settings', async ({ pageWithUserData: page }) => {
diff --git a/tests/request/copy-request/copy-request.spec.ts b/tests/request/copy-request/copy-request.spec.ts
index f6d2e5713..1646a4969 100644
--- a/tests/request/copy-request/copy-request.spec.ts
+++ b/tests/request/copy-request/copy-request.spec.ts
@@ -27,7 +27,8 @@ test.describe('Copy and Paste Requests', () => {
await page.locator('.dropdown-item').filter({ hasText: 'Copy' }).click();
// Paste into the collection root
- await collection.click({ button: 'right' });
+ await collection.hover();
+ await collection.locator('.collection-actions .icon').click();
await page.locator('.dropdown-item').filter({ hasText: 'Paste' }).click();
// Verify the pasted request appears with the same name
@@ -45,7 +46,8 @@ test.describe('Copy and Paste Requests', () => {
// Paste into the folder
const folder = page.locator('.collection-item-name').filter({ hasText: 'test-folder' });
await folder.click();
- await folder.click({ button: 'right' });
+ await folder.hover();
+ await folder.locator('.menu-icon').click();
await page.locator('.dropdown-item').filter({ hasText: 'Paste' }).click();
await page.waitForTimeout(2000);
@@ -57,7 +59,8 @@ test.describe('Copy and Paste Requests', () => {
const collection = page.locator('.collection-name').filter({ hasText: 'test-collection-2' });
// Paste into the collection root
- await collection.click({ button: 'right' });
+ await collection.hover();
+ await collection.locator('.collection-actions .icon').click();
await page.locator('.dropdown-item').filter({ hasText: 'Paste' }).click();
// Verify the pasted request appears with the same name
diff --git a/tests/response-examples/create-example.spec.ts b/tests/response-examples/create-example.spec.ts
index 55f619971..54b996b3e 100644
--- a/tests/response-examples/create-example.spec.ts
+++ b/tests/response-examples/create-example.spec.ts
@@ -10,8 +10,8 @@ test.describe.serial('Create and Delete Response Examples', () => {
test('should create a response example from response bookmark', async ({ pageWithUserData: page }) => {
await test.step('Open collection and request', async () => {
- await page.locator('#sidebar-collection-name').getByText('collection').click();
- await page.locator('.collection-item-name').getByText('create-example').click();
+ await page.locator('#sidebar-collection-name').filter({ hasText: 'collection' }).click();
+ await page.locator('.collection-item-name').filter({ hasText: 'create-example' }).click();
});
await test.step('Send request and validate example creation', async () => {
diff --git a/tests/response-examples/edit-example.spec.ts b/tests/response-examples/edit-example.spec.ts
index a781045a2..8abf742c1 100644
--- a/tests/response-examples/edit-example.spec.ts
+++ b/tests/response-examples/edit-example.spec.ts
@@ -27,7 +27,7 @@ test.describe.serial('Edit Response Examples', () => {
await test.step('Open existing example', async () => {
await page.locator('.collection-item-name', { hasText: 'edit-example' }).getByTestId('request-item-chevron').click();
- const exampleItem = page.locator('.collection-item-name').getByText('Test Example', { exact: true });
+ const exampleItem = page.locator('.collection-item-name').filter({ hasText: 'Test Example' });
await expect(exampleItem).toBeVisible();
await exampleItem.click();
});
diff --git a/tests/response-examples/menu-operations.spec.ts b/tests/response-examples/menu-operations.spec.ts
index 74b62a376..8dc7f6662 100644
--- a/tests/response-examples/menu-operations.spec.ts
+++ b/tests/response-examples/menu-operations.spec.ts
@@ -3,6 +3,7 @@ import { execSync } from 'child_process';
import path from 'path';
test.describe.serial('Response Example Menu Operations', () => {
+ test.setTimeout(1 * 60 * 1000); // 1 minute for all tests in this describe block, default is 30 seconds.
test.afterAll(async () => {
// Reset the collection request file to the original state
execSync(`git checkout -- ${path.join(__dirname, 'fixtures', 'collection', 'menu-operations.bru')}`);
@@ -15,7 +16,7 @@ test.describe.serial('Response Example Menu Operations', () => {
});
await test.step('Create example', async () => {
- await page.locator('#send-request').getByRole('img').nth(2).click();
+ await page.getByTestId('send-arrow-icon').click();
await page.getByTestId('response-bookmark-btn').click();
await page.getByTestId('create-example-name-input').clear();
await page.getByTestId('create-example-name-input').fill('Example to Clone');
diff --git a/tests/utils/page/locators.ts b/tests/utils/page/locators.ts
index b6c6eedb1..cf9d200ca 100644
--- a/tests/utils/page/locators.ts
+++ b/tests/utils/page/locators.ts
@@ -21,7 +21,12 @@ export const buildCommonLocators = (page: Page) => ({
collectionActions: (collectionName: string) =>
page.locator('.collection-name')
.filter({ hasText: collectionName })
- .locator('.collection-actions .icon')
+ .locator('.collection-actions .icon'),
+ collectionItemActions: (itemName: string) =>
+ page.locator('.collection-item-name')
+ .filter({ hasText: itemName })
+ .locator('.menu-icon')
+
},
dropdown: {
item: (text: string) => page.locator('.dropdown-item').filter({ hasText: text })