diff --git a/docs/playwright-testing-guide.md b/docs/playwright-testing-guide.md index c0de8ad3d..5e1c3116f 100644 --- a/docs/playwright-testing-guide.md +++ b/docs/playwright-testing-guide.md @@ -324,7 +324,7 @@ test('should create and execute HTTP request', async ({ page, createTmpDir }) => await page.getByRole('button', { name: 'Create' }).click(); // Execute request - await page.locator('#send-request').getByRole('img').nth(2).click(); + await page.getByTestId('send-arrow-icon').click(); // Verify response await expect(page.getByRole('main')).toContainText('200 OK'); diff --git a/packages/bruno-app/src/components/RequestPane/QueryUrl/StyledWrapper.js b/packages/bruno-app/src/components/RequestPane/QueryUrl/StyledWrapper.js index e7a89d422..eeb31e538 100644 --- a/packages/bruno-app/src/components/RequestPane/QueryUrl/StyledWrapper.js +++ b/packages/bruno-app/src/components/RequestPane/QueryUrl/StyledWrapper.js @@ -2,9 +2,13 @@ import styled from 'styled-components'; const Wrapper = styled.div` height: 2.1rem; - border: ${(props) => props.theme.requestTabPanel.url.border}; - border-radius: ${(props) => props.theme.border.radius.base}; + .url-input-group { + border: ${(props) => props.theme.requestTabPanel.url.border}; + border-radius: ${(props) => props.theme.border.radius.base}; + flex: 1; + min-width: 0; + } .infotip { position: relative; @@ -49,6 +53,7 @@ const Wrapper = styled.div` .shortcut { font-size: 0.625rem; } + `; export default Wrapper; diff --git a/packages/bruno-app/src/components/RequestPane/QueryUrl/index.js b/packages/bruno-app/src/components/RequestPane/QueryUrl/index.js index 2d59cb5e7..53aab8a27 100644 --- a/packages/bruno-app/src/components/RequestPane/QueryUrl/index.js +++ b/packages/bruno-app/src/components/RequestPane/QueryUrl/index.js @@ -16,8 +16,9 @@ import { saveRequest, cancelRequest } from 'providers/ReduxStore/slices/collecti import { getRequestFromCurlCommand } from 'utils/curl'; import HttpMethodSelector from './HttpMethodSelector'; import { useTheme } from 'providers/Theme'; -import { IconDeviceFloppy, IconArrowRight, IconCode, IconSquareRoundedX } from '@tabler/icons'; +import { IconDeviceFloppy, IconCode } from '@tabler/icons'; import SingleLineEditor from 'components/SingleLineEditor'; +import SendButton from 'components/RequestPane/SendButton'; import { isMacOS } from 'utils/common/platform'; import { hasRequestChanges } from 'utils/collections'; import StyledWrapper from './StyledWrapper'; @@ -384,76 +385,67 @@ const QueryUrl = ({ item, collection, handleRun }) => { }; return ( -
- -
-
- onSave(finalValue)} - theme={storedTheme} - onChange={(newValue) => onUrlChange(newValue)} - onRun={handleRun} - onPaste={item.type === 'http-request' ? handleHttpPaste : item.type === 'graphql-request' ? handleGraphqlPaste : null} - collection={collection} - highlightPathParams={true} - item={item} - showNewlineArrow={true} - /> - -
-
-
{ - handleGenerateCode(e); - }} - > - - Generate Code +
+
+
{ - e.stopPropagation(); - if (!hasChanges) return; - onSave(); - }} + id="request-url" + className="h-full w-full flex flex-row items-center input-container overflow-auto" > - onSave(finalValue)} + theme={storedTheme} + onChange={(newValue) => onUrlChange(newValue)} + onRun={handleRun} + onPaste={item.type === 'http-request' ? handleHttpPaste : item.type === 'graphql-request' ? handleGraphqlPaste : null} + collection={collection} + highlightPathParams={true} + item={item} + showNewlineArrow={true} /> - - Save ({saveShortcut}) - +
+
{ + handleGenerateCode(e); + }} + > + + Generate Code +
+
{ + e.stopPropagation(); + if (!hasChanges) return; + onSave(); + }} + > + + + Save ({saveShortcut}) + +
+
- {isLoading || item.response?.stream?.running ? ( - - ) : ( - - )}
+ {generateCodeItemModalOpen && ( div { + display: flex; + flex: 1; + } + + button { + width: 100%; + height: 100%; + } +`; + +export default StyledWrapper; diff --git a/packages/bruno-app/src/components/RequestPane/SendButton/index.js b/packages/bruno-app/src/components/RequestPane/SendButton/index.js new file mode 100644 index 000000000..8b84dfaaa --- /dev/null +++ b/packages/bruno-app/src/components/RequestPane/SendButton/index.js @@ -0,0 +1,22 @@ +import React from 'react'; +import Button from 'ui/Button'; +import StyledWrapper from './StyledWrapper'; + +const SendButton = ({ isLoading = false, onSend, onCancel, testId = 'send-request-btn' }) => { + return ( + + + + ); +}; + +export default SendButton; diff --git a/packages/bruno-app/src/components/RequestPane/WsQueryUrl/StyledWrapper.js b/packages/bruno-app/src/components/RequestPane/WsQueryUrl/StyledWrapper.js index af596a1ef..9740818ca 100644 --- a/packages/bruno-app/src/components/RequestPane/WsQueryUrl/StyledWrapper.js +++ b/packages/bruno-app/src/components/RequestPane/WsQueryUrl/StyledWrapper.js @@ -3,12 +3,12 @@ import styled from 'styled-components'; const StyledWrapper = styled.div` height: 2.1rem; position: relative; - border: ${(props) => props.theme.requestTabPanel.url.border}; - border-radius: ${(props) => props.theme.border.radius.base}; .input-container { background-color: ${(props) => props.theme.requestTabPanel.url.bg}; + border: ${(props) => props.theme.requestTabPanel.url.border}; border-radius: ${(props) => props.theme.border.radius.base}; + position: relative; input { background-color: ${(props) => props.theme.requestTabPanel.url.bg}; @@ -99,6 +99,7 @@ const StyledWrapper = styled.div` } } } + `; export default StyledWrapper; diff --git a/packages/bruno-app/src/components/RequestPane/WsQueryUrl/index.js b/packages/bruno-app/src/components/RequestPane/WsQueryUrl/index.js index 3801501f8..23d0b2e91 100644 --- a/packages/bruno-app/src/components/RequestPane/WsQueryUrl/index.js +++ b/packages/bruno-app/src/components/RequestPane/WsQueryUrl/index.js @@ -1,4 +1,5 @@ -import { IconArrowRight, IconDeviceFloppy, IconPlugConnected, IconPlugConnectedX } from '@tabler/icons'; +import { IconDeviceFloppy, IconPlugConnected, IconPlugConnectedX } from '@tabler/icons'; +import SendButton from 'components/RequestPane/SendButton'; import classnames from 'classnames'; import SingleLineEditor from 'components/SingleLineEditor/index'; import { requestUrlChanged } from 'providers/ReduxStore/slices/collections'; @@ -123,7 +124,7 @@ const WsQueryUrl = ({ item, collection, handleRun }) => { return (
-
+
WS
@@ -187,15 +188,14 @@ const WsQueryUrl = ({ item, collection, handleRun }) => {
)} - -
- -
+ {connectionStatus === CONNECTION_STATUS.CONNECTED &&
}
+
- - {connectionStatus === CONNECTION_STATUS.CONNECTED &&
}
); }; diff --git a/tests/collection/create/create-collection.spec.ts b/tests/collection/create/create-collection.spec.ts index d929084e9..82a3d6a56 100644 --- a/tests/collection/create/create-collection.spec.ts +++ b/tests/collection/create/create-collection.spec.ts @@ -19,13 +19,13 @@ test.describe('Create collection', () => { // Set the URL await page.locator('#request-url .CodeMirror').click(); await page.locator('#request-url').locator('textarea').fill('http://localhost:8081'); - await page.locator('#send-request').getByTitle('Save Request').click(); + await page.locator('#request-actions').getByTitle('Save Request').click(); // Send a request await page.locator('#request-url .CodeMirror').click(); await page.locator('#request-url').locator('textarea').fill('/ping'); - await page.locator('#send-request').getByTitle('Save Request').click(); - await page.locator('#send-request').getByRole('img').nth(2).click(); + await page.locator('#request-actions').getByTitle('Save Request').click(); + await page.getByTestId('send-arrow-icon').click(); // Verify the response await expect(page.getByRole('main')).toContainText('200 OK'); diff --git a/tests/environments/multiline-variables/read-multiline-environment.spec.ts b/tests/environments/multiline-variables/read-multiline-environment.spec.ts index d9ec80636..ade71e84a 100644 --- a/tests/environments/multiline-variables/read-multiline-environment.spec.ts +++ b/tests/environments/multiline-variables/read-multiline-environment.spec.ts @@ -22,7 +22,7 @@ test.describe('Multiline Variables - Read Environment Test', () => { await expect(page.locator('.current-environment').filter({ hasText: /Test/ })).toBeVisible(); // send request - const sendButton = page.locator('#send-request').getByRole('img').nth(2); + const sendButton = page.getByTestId('send-arrow-icon'); await expect(sendButton).toBeVisible(); await sendButton.click(); await expect(page.locator('.response-status-code.text-ok')).toBeVisible(); diff --git a/tests/response-examples/create-example.spec.ts b/tests/response-examples/create-example.spec.ts index 5e889940f..4942e1cd6 100644 --- a/tests/response-examples/create-example.spec.ts +++ b/tests/response-examples/create-example.spec.ts @@ -77,7 +77,7 @@ test.describe.serial('Create and Delete Response Examples', () => { }); await test.step('Test form reset', async () => { - await page.locator('#send-request').getByRole('img').nth(2).click(); + await page.getByTestId('send-arrow-icon').click(); await clickResponseAction(page, 'response-bookmark-btn'); await page.getByTestId('create-example-name-input').fill('Test Name'); diff --git a/tests/utils/page/actions.ts b/tests/utils/page/actions.ts index cd212f0fc..6be8a8bdc 100644 --- a/tests/utils/page/actions.ts +++ b/tests/utils/page/actions.ts @@ -141,7 +141,7 @@ const createUntitledRequest = async ( if (url) { await page.locator('#request-url .CodeMirror').click(); await page.locator('#request-url textarea').fill(url); - await page.locator('#send-request').getByTitle('Save Request').click(); + await page.locator('#request-actions').getByTitle('Save Request').click(); await page.waitForTimeout(200); } diff --git a/tests/utils/page/locators.ts b/tests/utils/page/locators.ts index 211d0c947..30ae35da4 100644 --- a/tests/utils/page/locators.ts +++ b/tests/utils/page/locators.ts @@ -83,7 +83,7 @@ export const buildCommonLocators = (page: Page) => ({ newRequestUrl: () => page.locator('#new-request-url .CodeMirror'), requestNameInput: () => page.getByPlaceholder('Request Name'), requestTestId: () => page.getByTestId('request-name'), - generateCodeButton: () => page.locator('#send-request .infotip').first(), + generateCodeButton: () => page.locator('#request-actions .infotip').first(), bodyModeSelector: () => page.getByTestId('request-body-mode-selector'), bodyEditor: () => page.getByTestId('request-body-editor') },