Skip to content
Open
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
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ const MultipartFormParams = ({ item, collection }) => {
}, [dispatch, collection.uid, item.uid]);

const handleBrowseFiles = useCallback((row, onChange) => {
dispatch(browseFiles())
dispatch(browseFiles([], ['multiSelections']))
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

may need to do the same in ResponseExampleMultipartFormParams for consistency sake

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed - Added — updated ResponseExampleMultipartFormParams to use browseFiles([], ['multiSelections']) for consistency.

.then((filePaths) => {
const processedPaths = filePaths.map((filePath) => {
const collectionDir = collection.pathname;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ const ResponseExampleMultipartFormParams = ({ item, collection, exampleUid, edit
const handleBrowseFiles = useCallback((row, onChange) => {
if (!editMode) return;

dispatch(browseFiles())
dispatch(browseFiles([], ['multiSelections']))
.then((filePaths) => {
const processedPaths = filePaths.map((filePath) => {
const collectionDir = collection.pathname;
Expand Down Expand Up @@ -212,11 +212,11 @@ const ResponseExampleMultipartFormParams = ({ item, collection, exampleUid, edit
<div className="flex items-center value-cell">
<div className="flex-1">
<MultiLineEditor
onSave={() => {}}
onSave={() => { }}
theme={storedTheme}
value={value || ''}
onChange={(newValue) => handleValueChange(row, newValue, onChange)}
onRun={() => {}}
onRun={() => { }}
allowNewlines={true}
collection={collection}
item={item}
Expand All @@ -243,12 +243,12 @@ const ResponseExampleMultipartFormParams = ({ item, collection, exampleUid, edit
readOnly: !editMode,
render: ({ value, onChange }) => (
<SingleLineEditor
onSave={() => {}}
onSave={() => { }}
theme={storedTheme}
placeholder={!value ? 'Auto' : ''}
value={value || ''}
onChange={onChange}
onRun={() => {}}
onRun={() => { }}
collection={collection}
readOnly={!editMode}
/>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
import { test, expect } from '../../../playwright';
import {
closeAllCollections,
createCollection,
createRequest,
openCollection,
openRequest,
saveRequest,
selectRequestPaneTab
} from '../../utils/page';
import { buildCommonLocators } from '../../utils/page/locators';
import * as fs from 'fs';
import * as path from 'path';

test.describe.serial('Multipart Form - Multi-File Selection', () => {
let tmpDir: string;
let testFile1Path: string;
let testFile2Path: string;
let testFile3Path: string;

test.afterEach(async ({ electronApp }) => {
await electronApp.evaluate(({ dialog }) => {
if ((dialog as any).__originalShowOpenDialog) {
dialog.showOpenDialog = (dialog as any).__originalShowOpenDialog;
}
});
});
Comment thread
coderabbitai[bot] marked this conversation as resolved.

test.afterAll(async ({ page }) => {
await closeAllCollections(page);
});
Comment thread
coderabbitai[bot] marked this conversation as resolved.

test.beforeAll(async ({ page, electronApp, createTmpDir }) => {
tmpDir = await createTmpDir('multipart-multi-file-select');

testFile1Path = path.join(tmpDir, 'file1.txt');
testFile2Path = path.join(tmpDir, 'file2.txt');
testFile3Path = path.join(tmpDir, 'file3.pdf');

await fs.promises.writeFile(testFile1Path, '1');
await fs.promises.writeFile(testFile2Path, '2');
await fs.promises.writeFile(testFile3Path, '3');

await electronApp.evaluate(({ dialog }, filePaths: string[]) => {
(dialog as any).__originalShowOpenDialog = dialog.showOpenDialog;
dialog.showOpenDialog = async () => ({
canceled: false,
filePaths
});
}, [testFile1Path, testFile2Path, testFile3Path]);

await test.step('Create collection and request', async () => {
await createCollection(page, 'multipart-multi-file', tmpDir);
await createRequest(page, 'test-multi-file', 'multipart-multi-file', {
url: 'https://testbench-sanity.usebruno.com/api/echo/json',
method: 'POST',
inFolder: false
});
});

await test.step('Open request and set multipart', async () => {
await openCollection(page, 'multipart-multi-file');
await openRequest(page, 'multipart-multi-file', 'test-multi-file', { persist: true });

await selectRequestPaneTab(page, 'Body');
const locators = buildCommonLocators(page);
await locators.request.bodyModeSelector().click();
await page.locator('.dropdown-item').filter({ hasText: 'Multipart Form' }).click();
});
});

test('should select multiple files', async ({ page }) => {
const table = buildCommonLocators(page).table('editable-table');
const row = table.allRows().first();

await test.step('Enter key and upload', async () => {
await row.locator('td').nth(1).locator('input').fill('attachments');
await page.keyboard.press('Tab');

const uploadBtn = row.locator('.upload-btn');
await expect(uploadBtn).toBeVisible();
await uploadBtn.click();
});

await test.step('Verify file count', async () => {
const fileCell = row.locator('.file-value-cell');
await expect(fileCell).toContainText('3 file(s)');
});

await saveRequest(page);
});

test('should show filename for single file', async ({ page, electronApp }) => {
const table = buildCommonLocators(page).table('editable-table');
const row = table.allRows().last();

await electronApp.evaluate(({ dialog }, filePath: string) => {
if ((dialog as any).__originalShowOpenDialog === undefined) {
(dialog as any).__originalShowOpenDialog = dialog.showOpenDialog;
}
dialog.showOpenDialog = async () => ({
canceled: false,
filePaths: [filePath]
});
}, testFile1Path);

await test.step('Upload single file', async () => {
await row.locator('td').nth(1).locator('input').fill('single');
await page.keyboard.press('Tab');

await row.locator('.upload-btn').click();
});

await test.step('Verify filename', async () => {
const fileCell = row.locator('.file-value-cell');
await expect(fileCell).toContainText('file1.txt');
});

await saveRequest(page);
});

test('should clear files', async ({ page }) => {
const table = buildCommonLocators(page).table('editable-table');
const row = table.allRows().first();

await test.step('Clear files', async () => {
const clearBtn = row.locator('.clear-file-btn');
await expect(clearBtn).toBeVisible();
await clearBtn.click();
});

await test.step('Verify cleared', async () => {
await expect(row.locator('.upload-btn')).toBeVisible();
});

await saveRequest(page);
});
});
Loading