Skip to content

fix: update action bar value after users click import from url #8643

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Apr 28, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
81 changes: 81 additions & 0 deletions packages/insomnia-smoke-test/fixtures/import-from-url.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
type: collection.insomnia.rest/5.0
name: simple
meta:
id: wrk_dc393cdd96524c44a632fdc3b09aa5c5
created: 1736279931529
modified: 1736279931529
collection:
- url: http://localhost:4010/echo?foo=bar&baz=qux
name: example http
meta:
id: req_49f06ac9024446728a9765162d56b95a
created: 1666867365377
modified: 1666867670885
isPrivate: false
method: GET
scripts:
preRequest: console.log('executing pre-request script');
settings:
renderRequestBody: true
encodeUrl: true
followRedirects: global
cookies:
send: true
store: true
rebuildPath: true
- url: ws://localhost:4010?foo=bar&baz=qux
name: example websocket
meta:
id: ws-req_9030f28cd1a64b44971cee35bbc09987
created: 1666867628351
modified: 1666867647526
settings:
encodeUrl: true
followRedirects: global
cookies:
send: true
store: true
cookieJar:
name: Default Jar
meta:
id: jar_5ac9997401a64a9ea81374670872319a
created: 1666867357074
modified: 1666868115288
cookies:
- id: bc6e6a71-1290-4334-8662-a49c1c58b037
key: foo
value: bar
domain: localhost
expires: 2038-01-19T03:14:07.000Z
path: /
secure: false
httpOnly: false
environments:
name: Base Environment
meta:
id: env_e86a031c9817439bb89991d31a46e50c
created: 1666867357072
modified: 1666867924188
isPrivate: false
data:
foo: bar
current-env: base
subEnvironments:
- name: production
meta:
id: env_f5742e2375e24f25b65c2ae97fbbda30
created: 1666867721814
modified: 1666867928920
isPrivate: false
data:
foo: bar
current-env: production
- name: staging
meta:
id: env_fdc1a90ec92c42899f599a4e8ab40a5f
created: 1666867735110
modified: 1666867933395
isPrivate: false
data:
foo: bar
current-env: staging
68 changes: 68 additions & 0 deletions packages/insomnia-smoke-test/tests/smoke/import-from-url.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import { expect } from '@playwright/test';

import { loadFixture } from '../../playwright/paths';
import { test } from '../../playwright/test';

test.describe('Import from URL', () => {
test.beforeEach(async ({ app, page }) => {
const text = await loadFixture('import-from-url.yaml');
await app.evaluate(async ({ clipboard }, text) => clipboard.writeText(text), text);
await page.getByLabel('Import').click();
await page.locator('[data-test-id="import-from-clipboard"]').click();
await page.getByRole('button', { name: 'Scan' }).click();
await page.getByRole('dialog').getByRole('button', { name: 'Import' }).click();
await page.getByLabel('simple').click();
});

test('Should work as expected in HTTP request', async ({ page }) => {
const requestUrl = 'http://localhost:4010/echo?foo=bar&baz=qux';
const codeMirror = page.getByTestId('OneLineEditor').first().locator('.CodeMirror');

await page.getByText('example http').click();

const importFromUrlButton = page.getByRole('button', { name: 'Import from URL' });
await importFromUrlButton.click();

await expect
.soft(codeMirror.locator('.CodeMirror-line').getByRole('presentation'))
.toHaveText('http://localhost:4010/echo');

// send
await page.getByTestId('request-pane').getByRole('button', { name: 'Send' }).click();

// verify response
const statusTag = page.locator('[data-testid="response-status-tag"]:visible');
await expect.soft(statusTag).toContainText('200 OK');

const responsePane = page.getByTestId('response-pane');
await page.getByRole('tab', { name: 'Console' }).click();

await expect.soft(responsePane).toContainText(requestUrl);
});

test('Should work as expected in Websocket request', async ({ page }) => {
const requestUrl = 'ws://localhost:4010?foo=bar&baz=qux';
const codeMirror = page.getByTestId('OneLineEditor').first().locator('.CodeMirror');

await page.getByText('example websocket').click();

const importFromUrlButton = page.getByRole('button', { name: 'Import from URL' });
await importFromUrlButton.click();

await expect
.soft(codeMirror.locator('.CodeMirror-line').getByRole('presentation'))
.toHaveText('ws://localhost:4010');

// connect
await page.getByTestId('request-pane').getByRole('button', { name: 'Connect' }).click();

// verify response
const statusTag = page.locator('[data-testid="response-status-tag"]:visible');
await expect.soft(statusTag).toContainText('101 Switching Protocols');

const responsePane = page.getByTestId('response-pane');
await page.getByRole('tab', { name: 'Console' }).click();

await expect.soft(responsePane).toContainText(requestUrl);
});
});
2 changes: 1 addition & 1 deletion packages/insomnia/src/common/database.ts
Original file line number Diff line number Diff line change
Expand Up @@ -857,7 +857,7 @@ async function _fixMultipleCookieJars(workspace: Workspace) {
console.log(`[fix] Merged ${cookieJars.length} cookie jars under ${workspace.name}`);
}

// Append .git to old git URIs to mimic previous isomorphic-git behaviour
// Append .git to old git URIs to mimic previous isomorphic-git behavior
async function _fixOldGitURIs(doc: GitRepository) {
if (!doc.uriNeedsMigration) {
return;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ export interface EditorEventListener<T extends keyof EditorEventMap> {
export interface OneLineEditorHandle {
selectAll: () => void;
focusEnd: () => void;
setValue: (value: string) => void;
}
export const OneLineEditor = forwardRef<OneLineEditorHandle, OneLineEditorProps>(
(
Expand Down Expand Up @@ -352,6 +353,13 @@ export const OneLineEditor = forwardRef<OneLineEditorHandle, OneLineEditorProps>
}
codeMirror.current?.getDoc()?.setCursor(codeMirror.current.getDoc().lineCount(), 0);
},
setValue: (value: string) => {
if (codeMirror.current) {
const cursor = codeMirror.current.getCursor();
codeMirror.current.setValue(value);
codeMirror.current.setCursor(cursor);
}
},
}),
[],
);
Expand Down
11 changes: 9 additions & 2 deletions packages/insomnia/src/ui/components/panes/request-pane.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { type FC, Fragment, useState } from 'react';
import React, { type FC, Fragment, useRef, useState } from 'react';
import { Button, Heading, Tab, TabList, TabPanel, Tabs, ToggleButton } from 'react-aria-components';
import { Panel, PanelGroup, PanelResizeHandle } from 'react-resizable-panels';
import { useParams, useRouteLoaderData } from 'react-router-dom';
Expand Down Expand Up @@ -26,7 +26,7 @@ import { Icon } from '../icon';
import { MarkdownEditor } from '../markdown-editor';
import { RequestSettingsModal } from '../modals/request-settings-modal';
import { RenderedQueryString } from '../rendered-query-string';
import { RequestUrlBar } from '../request-url-bar';
import { RequestUrlBar, type RequestUrlBarHandle } from '../request-url-bar';
import { Pane, PaneHeader } from './pane';
import { PlaceholderRequestPane } from './placeholder-request-pane';

Expand All @@ -44,6 +44,7 @@ export const RequestPane: FC<Props> = ({ environmentId, settings, onPaste }) =>
const [isRequestSettingsModalOpen, setIsRequestSettingsModalOpen] = useState(false);
const patchRequest = useRequestPatcher();

const requestUrlBarRef = useRef<RequestUrlBarHandle>(null);
const [dismissPathParameterTip, setDismissPathParameterTip] = useLocalStorage('dismissPathParameterTip', '');
const handleImportQueryFromUrl = () => {
let query;
Expand All @@ -62,6 +63,11 @@ export const RequestPane: FC<Props> = ({ environmentId, settings, onPaste }) =>
// Only update if url changed
if (url !== activeRequest.url) {
patchRequest(requestId, { url, parameters });
/**
* Currently the OneLineEditor is a uncontrolled component, and the value is asynchronously, if we change the component to controlled, users need to wait for the value to be updated when inputting, that's not a good experience.
* So as a workaround, we need to manually update the url bar value.
*/
requestUrlBarRef.current?.setUrl(url);
}
};
const gitVersion = useGitVCSVersion();
Expand Down Expand Up @@ -98,6 +104,7 @@ export const RequestPane: FC<Props> = ({ environmentId, settings, onPaste }) =>
handleAutocompleteUrls={() => queryAllWorkspaceUrls(workspaceId, models.request.type, requestId)}
nunjucksPowerUserMode={settings.nunjucksPowerUserMode}
onPaste={onPaste}
ref={requestUrlBarRef}
/>
</ErrorBoundary>
</PaneHeader>
Expand Down
12 changes: 11 additions & 1 deletion packages/insomnia/src/ui/components/request-url-bar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ interface Props {

export interface RequestUrlBarHandle {
focusInput: () => void;
setUrl: (url: string) => void;
}

export const RequestUrlBar = forwardRef<RequestUrlBarHandle, Props>(
Expand Down Expand Up @@ -94,7 +95,16 @@ export const RequestUrlBar = forwardRef<RequestUrlBarHandle, Props>(
}
}, [inputRef]);

useImperativeHandle(ref, () => ({ focusInput }), [focusInput]);
const setUrl = useCallback(
(url: string) => {
if (inputRef.current) {
inputRef.current.setValue(url);
}
},
[inputRef],
);

useImperativeHandle(ref, () => ({ focusInput, setUrl }), [focusInput, setUrl]);

const [currentInterval, setCurrentInterval] = useState<number | null>(null);
const [currentTimeout, setCurrentTimeout] = useState<number | undefined>(undefined);
Expand Down
Loading
Loading