Skip to content

Commit bc2aa5d

Browse files
refactor: update UI interactions and improve test stability
1 parent 3fe5299 commit bc2aa5d

File tree

21 files changed

+171
-211
lines changed

21 files changed

+171
-211
lines changed

packages/bruno-app/src/components/SingleLineEditor/index.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,11 @@ class SingleLineEditor extends Component {
205205
render() {
206206
return (
207207
<div className={`flex flex-row justify-between w-full overflow-x-auto ${this.props.className}`}>
208-
<StyledWrapper ref={this.editorRef} className={`single-line-editor grow ${this.props.readOnly ? 'read-only' : ''}`} />
208+
<StyledWrapper
209+
ref={this.editorRef}
210+
className={`single-line-editor grow ${this.props.readOnly ? 'read-only' : ''}`}
211+
{...(this.props['data-testid'] ? { 'data-testid': this.props['data-testid'] } : {})}
212+
/>
209213
{this.secretEye(this.props.isSecret)}
210214
</div>
211215
);

packages/bruno-app/src/components/TagList/StyledWrapper.js

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,18 @@ const StyledWrapper = styled.div`
2323
max-width: 200px;
2424
transition: all 0.2s ease;
2525
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
26+
cursor: default;
2627
27-
&:hover {
28+
&:has(.tag-remove:hover) {
2829
background-color: ${(props) => props.theme.requestTabs.active.bg};
2930
border-color: ${(props) => props.theme.requestTabs.active.border || props.theme.requestTabs.bottomBorder};
3031
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
3132
transform: translateY(-1px);
3233
}
34+
35+
.tag-remove {
36+
cursor: pointer;
37+
}
3338
}
3439
3540
.tag-icon {

packages/bruno-app/src/components/TagList/index.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ const TagList = ({ tagsHintList = [], handleAddTag, tags, handleRemoveTag, onSav
4949
onChange={handleInputChange}
5050
onRun={handleKeyDown}
5151
onSave={onSave}
52+
data-testid="tag-input"
5253
/>
5354
{error && <span className='text-xs text-red-500'>{error}</span>}
5455
<ul className="flex flex-wrap gap-1">
@@ -57,14 +58,15 @@ const TagList = ({ tagsHintList = [], handleAddTag, tags, handleRemoveTag, onSav
5758
<li key={_tag}>
5859
<button
5960
className="tag-item"
60-
onClick={() => handleRemoveTag(_tag)}
6161
type="button"
6262
>
6363
<IconTag size={12} className="tag-icon" aria-hidden="true" />
6464
<span className="tag-text" title={_tag}>
6565
{_tag}
6666
</span>
67-
<IconX size={12} strokeWidth={2} aria-hidden="true" />
67+
<span className="tag-remove" title="Remove tag" onClick={() => handleRemoveTag(_tag)}>
68+
<IconX size={12} strokeWidth={2} aria-hidden="true" />
69+
</span>
6870
</button>
6971
</li>
7072
))

tests/collection/create-requests/graphql-requests.spec.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,14 @@ test.describe('Create GraphQL Requests', () => {
1111

1212
test.afterAll(async ({ pageWithUserData: page }) => {
1313
// Clean up Root GraphQL Request
14-
await locators.sidebar.request('Root GraphQL Request').click({ button: 'right' });
14+
await locators.sidebar.request('Root GraphQL Request').hover();
15+
await locators.actions.collectionItemActions('Root GraphQL Request').click();
1516
await locators.dropdown.item('Delete').click();
1617
await locators.modal.button('Delete').click();
1718

1819
// Clean up Folder GraphQL Request
19-
await locators.sidebar.request('Folder GraphQL Request').click({ button: 'right' });
20+
await locators.sidebar.request('Folder GraphQL Request').hover();
21+
await locators.actions.collectionItemActions('Folder GraphQL Request').click();
2022
await locators.dropdown.item('Delete').click();
2123
await locators.modal.button('Delete').click();
2224

@@ -58,8 +60,8 @@ test.describe('Create GraphQL Requests', () => {
5860
});
5961

6062
await test.step('Create GraphQL request via folder1 three dots menu', async () => {
61-
const folderItem = locators.sidebar.folder('folder1');
62-
await folderItem.click({ button: 'right' });
63+
await locators.sidebar.folder('folder1').hover();
64+
await locators.actions.collectionItemActions('folder1').click();
6365
await locators.dropdown.item('New Request').click();
6466

6567
await page.getByTestId('graphql-request').click();

tests/collection/create-requests/grpc-requests.spec.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,14 @@ test.describe('Create gRPC Requests', () => {
1313
const locators = buildCommonLocators(page);
1414

1515
// Clean up Root gRPC Request
16-
await locators.sidebar.request('Root gRPC Request').click({ button: 'right' });
16+
await locators.sidebar.request('Root gRPC Request').hover();
17+
await locators.actions.collectionItemActions('Root gRPC Request').click();
1718
await locators.dropdown.item('Delete').click();
1819
await locators.modal.button('Delete').click();
1920

2021
// Clean up Folder gRPC Request
21-
await locators.sidebar.request('Folder gRPC Request').click({ button: 'right' });
22+
await locators.sidebar.request('Folder gRPC Request').hover();
23+
await locators.actions.collectionItemActions('Folder gRPC Request').click();
2224
await locators.dropdown.item('Delete').click();
2325
await locators.modal.button('Delete').click();
2426

@@ -60,8 +62,8 @@ test.describe('Create gRPC Requests', () => {
6062
});
6163

6264
await test.step('Create gRPC request via folder1 three dots menu', async () => {
63-
const folderItem = locators.sidebar.folder('folder1');
64-
await folderItem.click({ button: 'right' });
65+
await locators.sidebar.folder('folder1').hover();
66+
await locators.actions.collectionItemActions('folder1').click();
6567
await locators.dropdown.item('New Request').click();
6668

6769
await page.getByTestId('grpc-request').click();

tests/collection/create-requests/http-requests.spec.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,14 @@ test.describe('Create HTTP Requests', () => {
1313
const locators = buildCommonLocators(page);
1414

1515
// Clean up Root HTTP Request
16-
await locators.sidebar.request('Root HTTP Request').click({ button: 'right' });
16+
await locators.sidebar.request('Root HTTP Request').hover();
17+
await locators.actions.collectionItemActions('Root HTTP Request').click();
1718
await locators.dropdown.item('Delete').click();
1819
await locators.modal.button('Delete').click();
1920

2021
// Clean up Folder HTTP Request
21-
await locators.sidebar.request('Folder HTTP Request').click({ button: 'right' });
22+
await locators.sidebar.request('Folder HTTP Request').hover();
23+
await locators.actions.collectionItemActions('Folder HTTP Request').click();
2224
await locators.dropdown.item('Delete').click();
2325
await locators.modal.button('Delete').click();
2426

@@ -59,8 +61,8 @@ test.describe('Create HTTP Requests', () => {
5961
});
6062

6163
await test.step('Create HTTP request via folder1 three dots menu', async () => {
62-
const folderItem = locators.sidebar.folder('folder1');
63-
await folderItem.click({ button: 'right' });
64+
await locators.sidebar.folder('folder1').hover();
65+
await locators.actions.collectionItemActions('folder1').click();
6466
await locators.dropdown.item('New Request').click();
6567

6668
await page.getByTestId('request-name').fill('Folder HTTP Request');

tests/collection/create-requests/ws-requests.spec.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,14 @@ test.describe('Create WebSocket Requests', () => {
1313
const locators = buildCommonLocators(page);
1414

1515
// Clean up Folder WebSocket Request
16-
await locators.sidebar.request('Folder WebSocket Request').click({ button: 'right' });
16+
await locators.sidebar.request('Folder WebSocket Request').hover();
17+
await locators.actions.collectionItemActions('Folder WebSocket Request').click();
1718
await locators.dropdown.item('Delete').click();
1819
await locators.modal.button('Delete').click();
1920

2021
// Clean up Root WebSocket Request
21-
await locators.sidebar.request('Root WebSocket Request').click({ button: 'right' });
22+
await locators.sidebar.request('Root WebSocket Request').hover();
23+
await locators.actions.collectionItemActions('Root WebSocket Request').click();
2224
await locators.dropdown.item('Delete').click();
2325
await locators.modal.button('Delete').click();
2426

@@ -60,8 +62,8 @@ test.describe('Create WebSocket Requests', () => {
6062
});
6163

6264
await test.step('Create WebSocket request via folder1 three dots menu', async () => {
63-
const folderItem = locators.sidebar.folder('folder1');
64-
await folderItem.click({ button: 'right' });
65+
await locators.sidebar.folder('folder1').hover();
66+
await locators.actions.collectionItemActions('folder1').click();
6567
await locators.dropdown.item('New Request').click();
6668

6769
await page.getByTestId('ws-request').click();

tests/collection/moving-requests/cross-collection-drag-drop-folder.spec.ts

Lines changed: 17 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { test, expect } from '../../../playwright';
2-
import { closeAllCollections } from '../../utils/page';
2+
import { closeAllCollections, createCollection } from '../../utils/page';
33

44
test.describe('Cross-Collection Drag and Drop for folder', () => {
55
test.afterEach(async ({ page }) => {
@@ -8,18 +8,8 @@ test.describe('Cross-Collection Drag and Drop for folder', () => {
88
});
99

1010
test('Verify cross-collection folder drag and drop', async ({ page, createTmpDir }) => {
11-
// Create first collection - click dropdown menu first
12-
await page.locator('.dropdown-icon').click();
13-
await page.locator('.dropdown-item').filter({ hasText: 'Create Collection' }).click();
14-
await page.getByLabel('Name').fill('source-collection');
15-
await page.getByLabel('Location').fill(await createTmpDir('source-collection'));
16-
await page.getByRole('button', { name: 'Create', exact: true }).click();
17-
18-
// Wait for collection to appear and click on it
19-
await expect(page.locator('#sidebar-collection-name').filter({ hasText: 'source-collection' })).toBeVisible();
20-
await page.locator('#sidebar-collection-name').filter({ hasText: 'source-collection' }).click();
21-
await page.getByLabel('Safe Mode').check();
22-
await page.getByRole('button', { name: 'Save' }).click();
11+
// Create first collection - open with sandbox mode
12+
await createCollection(page, 'source-collection', await createTmpDir('source-collection'), { openWithSandboxMode: 'safe' });
2313

2414
// Create a folder in the first collection
2515
// Look for the collection menu button for the source collection specifically
@@ -34,37 +24,28 @@ test.describe('Cross-Collection Drag and Drop for folder', () => {
3424
await page.getByRole('button', { name: 'Create' }).click();
3525

3626
// Wait for the folder to be created and appear in the sidebar
37-
await page.waitForTimeout(2000);
27+
await page.waitForTimeout(200);
3828
await expect(page.locator('.collection-item-name').filter({ hasText: 'test-folder' })).toBeVisible();
3929

4030
// Add a request to the folder to make it more realistic
41-
await page.locator('.collection-item-name').filter({ hasText: 'test-folder' }).click({ button: 'right' });
31+
await page.locator('.collection-item-name').filter({ hasText: 'test-folder' }).hover();
32+
await page.locator('.collection-item-name').filter({ hasText: 'test-folder' }).locator('.menu-icon').click();
4233
await page.locator('.dropdown-item').filter({ hasText: 'New Request' }).click();
4334
await page.getByPlaceholder('Request Name').fill('test-request-in-folder');
4435
await page.locator('#new-request-url .CodeMirror').click();
4536
await page.locator('textarea').fill('https://echo.usebruno.com');
4637
await page.getByRole('button', { name: 'Create' }).click();
4738

4839
// Wait for the request to be created
49-
await page.waitForTimeout(1000);
40+
await page.waitForTimeout(200);
5041

5142
// Expand the folder to see the request inside
5243
await page.locator('.collection-item-name').filter({ hasText: 'test-folder' }).click();
53-
await page.waitForTimeout(500);
44+
await page.waitForTimeout(200);
5445
await expect(page.locator('.collection-item-name').filter({ hasText: 'test-request-in-folder' })).toBeVisible();
5546

56-
// Create second collection - click dropdown menu first
57-
await page.locator('.dropdown-icon').click();
58-
await page.locator('.dropdown-item').filter({ hasText: 'Create Collection' }).click();
59-
await page.getByLabel('Name').fill('target-collection');
60-
await page.getByLabel('Location').fill(await createTmpDir('target-collection'));
61-
await page.getByRole('button', { name: 'Create', exact: true }).click();
62-
63-
// Wait for second collection to appear and click on it
64-
await expect(page.locator('#sidebar-collection-name').filter({ hasText: 'target-collection' })).toBeVisible();
65-
await page.locator('#sidebar-collection-name').filter({ hasText: 'target-collection' }).click();
66-
await page.getByLabel('Safe Mode').check();
67-
await page.getByRole('button', { name: 'Save' }).click();
47+
// Create second collection - open with sandbox mode
48+
await createCollection(page, 'target-collection', await createTmpDir('target-collection'), { openWithSandboxMode: 'safe' });
6849

6950
// Wait for both collections to be visible in sidebar
7051
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', () => {
8263
await sourceFolder.dragTo(targetCollection);
8364

8465
// Wait for the operation to complete
85-
await page.waitForTimeout(3000);
66+
await page.waitForTimeout(200);
8667

8768
// Verify the folder has been moved to the target collection
8869
// Click on target collection to expand it if needed
8970
await page.locator('#sidebar-collection-name').filter({ hasText: 'target-collection' }).click();
90-
await page.waitForTimeout(1000);
71+
await page.waitForTimeout(200);
9172

9273
// Check that the folder now appears under target collection
9374
const targetCollectionContainer = page
@@ -100,7 +81,7 @@ test.describe('Cross-Collection Drag and Drop for folder', () => {
10081

10182
// Expand the moved folder to verify the request inside is also moved
10283
await targetCollectionContainer.locator('.collection-item-name').filter({ hasText: 'test-folder' }).click();
103-
await page.waitForTimeout(500);
84+
await page.waitForTimeout(200);
10485
await expect(
10586
targetCollectionContainer.locator('.collection-item-name').filter({ hasText: 'test-request-in-folder' })
10687
).toBeVisible();
@@ -125,17 +106,7 @@ test.describe('Cross-Collection Drag and Drop for folder', () => {
125106
createTmpDir
126107
}) => {
127108
// Create first collection (source) - use unique names for this test
128-
await page.locator('.dropdown-icon').click();
129-
await page.locator('.dropdown-item').filter({ hasText: 'Create Collection' }).click();
130-
await page.getByLabel('Name').fill('source-collection');
131-
await page.getByLabel('Location').fill(await createTmpDir('source-collection'));
132-
await page.getByRole('button', { name: 'Create', exact: true }).click();
133-
134-
// Wait for collection to appear and click on it
135-
await expect(page.locator('#sidebar-collection-name').filter({ hasText: 'source-collection' })).toBeVisible();
136-
await page.locator('#sidebar-collection-name').filter({ hasText: 'source-collection' }).click();
137-
await page.getByLabel('Safe Mode').check();
138-
await page.getByRole('button', { name: 'Save' }).click();
109+
await createCollection(page, 'source-collection', await createTmpDir('source-collection'), { openWithSandboxMode: 'safe' });
139110

140111
// Create a folder in the first collection
141112
await page
@@ -158,7 +129,8 @@ test.describe('Cross-Collection Drag and Drop for folder', () => {
158129
await expect(page.locator('.collection-item-name').filter({ hasText: 'folder-1' })).toBeVisible();
159130

160131
// Add a request to the folder to make it more realistic
161-
await page.locator('.collection-item-name').filter({ hasText: 'folder-1' }).click({ button: 'right' });
132+
await page.locator('.collection-item-name').filter({ hasText: 'folder-1' }).hover();
133+
await page.locator('.collection-item-name').filter({ hasText: 'folder-1' }).locator('.menu-icon').click();
162134
await page.locator('.dropdown-item').filter({ hasText: 'New Request' }).click();
163135
await page.getByPlaceholder('Request Name').fill('http-request');
164136
await page.locator('#new-request-url .CodeMirror').click();
@@ -169,17 +141,7 @@ test.describe('Cross-Collection Drag and Drop for folder', () => {
169141
await expect(page.locator('.collection-item-name').filter({ hasText: 'http-request' })).toBeVisible();
170142

171143
// Create second collection (target)
172-
await page.locator('.dropdown-icon').click();
173-
await page.locator('.dropdown-item').filter({ hasText: 'Create Collection' }).click();
174-
await page.getByLabel('Name').fill('target-collection');
175-
await page.getByLabel('Location').fill(await createTmpDir('target-collection'));
176-
await page.getByRole('button', { name: 'Create', exact: true }).click();
177-
178-
// Wait for second collection to appear and click on it
179-
await expect(page.locator('#sidebar-collection-name').filter({ hasText: 'target-collection' })).toBeVisible();
180-
await page.locator('#sidebar-collection-name').filter({ hasText: 'target-collection' }).click();
181-
await page.getByLabel('Safe Mode').check();
182-
await page.getByRole('button', { name: 'Save' }).click();
144+
await createCollection(page, 'target-collection', await createTmpDir('target-collection'), { openWithSandboxMode: 'safe' });
183145

184146
// Create a folder with the same name in the target collection
185147
await page

0 commit comments

Comments
 (0)