Skip to content

Commit 61c495c

Browse files
authored
fix(ws): remove default '{}' message body and make all message headers sticky (usebruno#8565)
1 parent 5346a72 commit 61c495c

6 files changed

Lines changed: 72 additions & 24 deletions

File tree

packages/bruno-app/src/components/RequestPane/WsBody/SingleWSMessage/StyledWrapper.js

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,14 +23,11 @@ const StyledWrapper = styled.div`
2323
}
2424
}
2525
26-
&:not(.disabled) .accordion-header {
26+
.accordion-header {
2727
position: sticky;
2828
top: 0;
2929
z-index: 1;
3030
background: ${(props) => props.theme.bg};
31-
}
32-
33-
.accordion-header {
3431
display: flex;
3532
align-items: center;
3633
justify-content: space-between;

packages/bruno-lang/v2/src/jsonToBru.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -660,7 +660,7 @@ ${indentString(body.sparql)}
660660
}
661661

662662
// Convert content to JSON string if it's an object
663-
let contentValue = typeof content === 'object' ? JSON.stringify(content, null, 2) : content || '{}';
663+
let contentValue = typeof content === 'object' ? JSON.stringify(content, null, 2) : content || '';
664664

665665
// Wrap content with triple quotes for multiline support, without extra indentation
666666
bru += `${indentString(`content: '''\n${indentString(contentValue)}\n'''`)}\n`;

packages/bruno-lang/v2/tests/jsonToBru.spec.js

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,26 @@ describe('jsonToBru stringify', () => {
5252
expect(output).toMatch(new RegExp(`keepAliveInterval: ${input.settings.keepAliveInterval}`));
5353
expect(output).toMatch(new RegExp(`timeout: ${input.settings.timeout}`));
5454
});
55+
56+
it('serializes falsy content to an empty content block', () => {
57+
const input = {
58+
body: {
59+
mode: 'ws',
60+
ws: [
61+
{
62+
content: '',
63+
name: 'message 1'
64+
}
65+
]
66+
}
67+
};
68+
69+
const output = stringify(input);
70+
71+
// Content block is emitted but empty (no '{}' fallback).
72+
expect(output).toMatch(/content: '''\s*'''/);
73+
expect(output).not.toContain('{}');
74+
});
5575
});
5676

5777
describe('body:multipart-form file values', () => {

tests/utils/page/actions.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1658,6 +1658,12 @@ const closeAllTabs = async (page: Page) => {
16581658
if (await discardAllButton.isVisible({ timeout: 1000 }).catch(() => false)) {
16591659
await discardAllButton.click();
16601660
}
1661+
1662+
const saveTransientModal = page.getByTestId('save-transient-request-modal');
1663+
if (await saveTransientModal.isVisible({ timeout: 1000 }).catch(() => false)) {
1664+
await saveTransientModal.getByRole('button', { name: 'Cancel' }).click();
1665+
await expect(saveTransientModal).toBeHidden();
1666+
}
16611667
});
16621668
};
16631669

tests/utils/page/locators.ts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -351,9 +351,20 @@ export const buildWebsocketCommonLocators = (page: Page) => ({
351351
},
352352
messages: () => page.locator('.ws-message'),
353353
message: {
354+
container: () => page.getByTestId('ws-messages-container'),
355+
addButton: () => page.getByTestId('ws-add-message'),
356+
headers: () => page.getByTestId(/^ws-message-header-/),
357+
header: (index: number) => page.getByTestId(`ws-message-header-${index}`),
358+
body: (index: number) => page.getByTestId(`ws-message-body-${index}`),
359+
editor: (index: number) => page.getByTestId(`ws-message-body-${index}`).locator('.CodeMirror'),
360+
editorPlaceholder: (index: number) =>
361+
page.getByTestId(`ws-message-body-${index}`).locator('.CodeMirror-placeholder'),
362+
editorCode: (index: number) => page.getByTestId(`ws-message-body-${index}`).locator('.CodeMirror-code'),
354363
label: (index: number) => page.getByTestId(`ws-message-label-${index}`),
355364
nameInput: (index: number) => page.getByTestId(`ws-message-name-input-${index}`),
356-
nameTooltip: () => page.getByTestId('ws-message-name-tooltip')
365+
nameTooltip: () => page.getByTestId('ws-message-name-tooltip'),
366+
sendButton: (index: number) => page.getByTestId(`ws-send-msg-${index}`),
367+
deleteButton: (index: number) => page.getByTestId(`ws-delete-msg-${index}`)
357368
},
358369
toolbar: {
359370
latestFirst: () => page.getByRole('button', { name: 'Latest First' }),
Lines changed: 32 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,48 @@
11
import { expect, test } from '../../playwright';
2-
import { closeAllCollections } from '../utils/page/actions';
3-
4-
const REQ_NAME = /^ws-default-body-request$/;
2+
import { closeAllTabs, createTransientRequest, selectRequestPaneTab } from '../utils/page/actions';
3+
import { buildWebsocketCommonLocators } from '../utils/page/locators';
54

65
test.describe('websocket message default body', () => {
7-
test.afterAll(async ({ pageWithUserData: page }) => {
8-
await closeAllCollections(page);
6+
test.afterEach(async ({ page }) => {
7+
await closeAllTabs(page);
98
});
109

1110
test('a newly added message defaults to an empty body showing the placeholder', async ({
12-
pageWithUserData: page
11+
page
1312
}) => {
14-
// Open the preloaded websocket request
15-
await page.getByTestId('sidebar-collection-row').click();
16-
await page.getByTitle(REQ_NAME).click();
13+
const ws = buildWebsocketCommonLocators(page);
14+
15+
await createTransientRequest(page, { requestType: 'WebSocket' });
16+
await selectRequestPaneTab(page, 'Message');
1717

18-
const headers = page.getByTestId(/^ws-message-header-/);
19-
const beforeCount = await headers.count();
18+
const beforeCount = await ws.message.headers().count();
2019

21-
await page.getByTestId('ws-add-message').click();
22-
await expect(headers).toHaveCount(beforeCount + 1);
20+
await ws.message.addButton().click();
21+
await expect(ws.message.headers()).toHaveCount(beforeCount + 1);
2322

2423
// The newly added message is the last one and auto-expands.
25-
const newBody = page.getByTestId(`ws-message-body-${beforeCount}`);
26-
await expect(newBody).toBeVisible();
24+
await expect(ws.message.body(beforeCount)).toBeVisible();
2725

28-
const editor = newBody.locator('.CodeMirror');
2926
// Body should be empty (previously defaulted to '{}'); the editor should
3027
// surface the '...' placeholder instead of any '{}' content.
31-
await expect(editor.locator('.CodeMirror-placeholder')).toHaveText('...');
32-
await expect(editor.locator('.CodeMirror-code')).not.toContainText('{}');
28+
await expect(ws.message.editorPlaceholder(beforeCount)).toHaveText('...');
29+
await expect(ws.message.editorCode(beforeCount)).not.toContainText('{}');
30+
});
31+
32+
test('the default first message of a newly created websocket request has an empty body', async ({
33+
page
34+
}) => {
35+
const ws = buildWebsocketCommonLocators(page);
36+
37+
await createTransientRequest(page, { requestType: 'WebSocket' });
38+
await selectRequestPaneTab(page, 'Message');
39+
40+
// The default first message auto-expands.
41+
await expect(ws.message.body(0)).toBeVisible();
42+
43+
// Body must be empty (previously defaulted to '{}'); the editor should surface
44+
// the '...' placeholder rather than any '{}' content.
45+
await expect(ws.message.editorPlaceholder(0)).toHaveText('...');
46+
await expect(ws.message.editorCode(0)).not.toContainText('{}');
3347
});
3448
});

0 commit comments

Comments
 (0)