mirror of
https://github.com/usebruno/bruno.git
synced 2026-06-23 04:35:40 +00:00
* feat: add variable interpolation support for WebSocket requests
- Add WebSocket body interpolation in interpolateVars function
- Interpolate URL, headers, and all messages in request.body.ws array with full variable context
- Refactor sendWsRequest to use main process preparation (removes duplication)
- Add mode property to wsRequest object for proper request type detection
- Ensure consistent variable precedence matching HTTP/gRPC requests
- Centralize all interpolation logic in main process via prepareWsRequest
* Add Playwright tests for WebSocket variable interpolation
- Add tests for URL interpolation (wss://echo.{{url}}.org)
- Add tests for message content interpolation ({"test": "{{data}}"})
- Update test fixtures to use wss://echo.websocket.org echo server
- Add WEBSOCKET_FLOWS.md documentation
- Refactor queueWsMessage to handle variable interpolation in main process
* removed ws flow documentation
* chore: updated the network/index.js file to reduce merge conflicts by moving around code
* fix: added collection and item to WsQueryUrl Editor to fix available variable highlight
* chore: remove unnecessary whitespace in WebSocket event handlers
* feat: add automatic WebSocket reconnection on URL variable changes
- Detect changes to interpolated URL (including variable changes)
- Automatically disconnect and reconnect when interpolated URL changes
- Add debouncing (400ms) to prevent excessive reconnections
- Track previous interpolated URL to avoid unnecessary reconnects
- Store interpolated URL when connection becomes active
- Improve error handling and cleanup
* chore: removing diff
* Add WebSocket connection status IPC method
- Add connectionStatus() method to WsClient that returns detailed status
('disconnected', 'connecting', 'connected') instead of boolean
- Add renderer:ws:connection-status IPC handler in electron layer
- Add getWsConnectionStatus() utility function in network utils
- Provides more granular connection state information for UI components
* refactor: improve WebSocket connection status tracking in WsQueryUrl
- Replace boolean isConnectionActive with connectionStatus state ('disconnected', 'connecting', 'connected')
- Add useWsConnectionStatus hook to poll connection status every 2 seconds
- Refactor connection handlers: handleConnect, handleDisconnect, handleReconnect
- Update to use getWsConnectionStatus instead of isWsConnectionActive for more granular status
- Improve reconnect logic to handle URL variable interpolation changes
- Add proper connection status indicators in UI (connecting state with pulse animation)
* fix: improve WebSocket URL handling and request initialization
- Fix WebSocket URL state management by reading directly from item instead of local state
- Add handleUrlChange function to properly dispatch URL changes
- Fix interpolated URL change detection logic in useEffect
- Initialize params array for new WebSocket requests to prevent undefined errors
- Ensure params array is initialized when URL changes in draft/request
- Remove console.log statements and unused imports
- Update persistence test replacement URL to avoid port conflicts
These changes ensure WebSocket requests properly handle URL changes and
maintain consistent state between draft and saved requests.
* feat: refactor WebSocket connection status handling
---------
Co-authored-by: Sid <siddharth@usebruno.com>
69 lines
2.4 KiB
TypeScript
69 lines
2.4 KiB
TypeScript
import { expect, Locator, test } from '../../playwright';
|
|
import { buildWebsocketCommonLocators } from '../utils/page/locators';
|
|
import { readFile, writeFile } from 'fs/promises';
|
|
import { join } from 'path';
|
|
import { waitForPredicate } from '../utils/wait';
|
|
|
|
const BRU_REQ_NAME = /^base$/;
|
|
|
|
// TODO: reaper move to someplace common
|
|
const isRequestSaved = async (saveButton: Locator) => {
|
|
const savedColor = '#9f9f9f';
|
|
return (await saveButton.evaluate((d) => d.querySelector('svg')?.getAttribute('stroke') ?? '#invalid')) === savedColor;
|
|
};
|
|
|
|
test.describe.serial('persistence', () => {
|
|
let originalUrl = '';
|
|
let originalContext = {
|
|
path: join(__dirname, 'fixtures/collection/base.bru'),
|
|
data: ''
|
|
};
|
|
|
|
test.beforeAll(async () => {
|
|
// Store original request data to simplify test consistency
|
|
originalContext.data = await readFile(originalContext.path, 'utf8');
|
|
const originalUrlMatch = originalContext.data.match(`(url)\s*\:\s*(.+)`);
|
|
if (!originalUrlMatch) {
|
|
throw new Error('url not found in bru file for websocket');
|
|
}
|
|
originalUrl = originalUrlMatch[0].replace(/url\:/, '');
|
|
});
|
|
|
|
test.afterAll(async () => {
|
|
// Write back the original request information
|
|
await writeFile(originalContext.path, originalContext.data, 'utf8');
|
|
});
|
|
|
|
test('save new websocket url', async ({ pageWithUserData: page }) => {
|
|
const replacementUrl = 'ws://localhost:8083';
|
|
const locators = buildWebsocketCommonLocators(page);
|
|
|
|
const clearText = async (text: string) => {
|
|
for (let i = text.length; i > 0; i--) {
|
|
await page.keyboard.press('Backspace');
|
|
}
|
|
};
|
|
|
|
await page.locator('#sidebar-collection-name').click();
|
|
await page.getByTitle(BRU_REQ_NAME).click();
|
|
|
|
// remove the original url from the request
|
|
await page.locator('.input-container').filter({ hasText: originalUrl }).first().click();
|
|
await clearText(originalUrl);
|
|
|
|
// replace it with an arbritrary url
|
|
await page.keyboard.insertText(replacementUrl);
|
|
|
|
// check if the request is now unsaved
|
|
expect(await isRequestSaved(locators.saveButton())).toBe(false);
|
|
|
|
await locators.saveButton().click();
|
|
|
|
const result = await waitForPredicate(() => isRequestSaved(locators.saveButton()));
|
|
expect(result).toBe(true);
|
|
|
|
// check if the replacementUrl is now visually available
|
|
expect(page.locator('.input-container').filter({ hasText: replacementUrl }).first()).toBeAttached();
|
|
});
|
|
});
|