Closed paradox37 closed 1 year ago
Looks like you are using unsupported options due to your fixtures not being typed. Look at the following file which has your fixtures in a typed manner:
import { test as base, APIRequestContext, request, expect } from '@playwright/test';
const snakecaseKeys = input => input;
const camelcaseKeys = input => input;
export const test = base.extend<{
apiRequest: APIRequestContext;
post: (options: { url: string; options?: Parameters<APIRequestContext['post']>[1] }) => Promise<any>;
submitFile: (data: { orderId: string }, token: string) => Promise<any>;
}, {
apiBaseURL: string;
}>({
apiBaseURL: [process.env.REACT_APP_API_URL!, { scope: 'worker', option: true }],
apiRequest: async ({ apiBaseURL }, use) => {
const apiRequestContext = await request.newContext({
baseURL: process.env.REACT_APP_API_URL
})
await use(apiRequestContext);
await apiRequestContext.dispose();
},
post: async ({ apiRequest }, use) => {
await use(async ({ url, options, context }) => {
if (options && options.data) {
options.data = snakecaseKeys(options.data, { exclude: options.exclude || [] });
}
if (options && options.multipart) {
options.multipart = snakecaseKeys(options.multipart, { exclude: options.exclude || [] });
}
const response = await apiRequest.post(url, options);
return camelcaseKeys(await response.json(), { deep: true });
});
},
submitFile: async ({ post }, use) => {
await use(async (data, token) => {
const { orderId } = data;
const file = {
name: 'file.pdf',
mimeType: 'application/pdf',
buffer: Buffer.from('file content'),
};
const payload = snakecaseKeys({
orderId
});
return post(
{
url: '/api/v1/orders/submit-file',
options: {
multipart: {
...payload,
file,
},
headers: {
'api-token': token,
},
exclude: ['mimeType']
},
}
);
});
},
});
test('test', async ({ submitFile }) => {
const response = await submitFile({ orderId: '1' }, 'token');
expect(response).toEqual({ orderId: '1' });
})
With this setup you immediately spot, that you are e.g. using an unsupported option key here:
For your specific error, looks like that file.buffer
wasn't a Buffer
instance, I recommend to add some console logs there to find out what it actually was. (Also use TypeScript if your are not yet).
I wasn't able to replicate your specific error, because this above is not a full reproducible so I had to adjust some things here and there.
I am actually using typed fixtures, just didn't put it here, I was taking pieces from the project just to make an example.
How can it not be a buffer instance when I used?:
const file = {
name: 'file.pdf',
mimeType: 'application/pdf',
buffer: Buffer.from('file content'),
};
Are you able to provide a full reproduction? A full repro with actual/expected outcome would help a ton here to find out why. Without we are unfortunately not able to act on it. Thanks for your understanding.
Hm, not sure how to achieve it, I need response from server. Any suggestions for this ?
I now remembered one thing. If server responds with success, this error occurs, but if server responds with validation error, buffer error does not occur. But, everything works fine if newContext() is not used.
The error you shared does not rely on a server response or http endpoint, because it throws already before from here. Would be good to know what you pass to the apiRequestContext.post() function to understand if this is a bug on our side or on your end.
I recommend to put e.g. a try/catch there and log the multipart payload or attach a JavaScript debugger when the exception occurs so you understand wich function passed what.
Thanks for pointing me in the right direction. snake-case keys library is causing the issue. It modifies the buffer when using deep conversion. I reported the issue in that library.
System info
Source code
When I use newContext() and post() api to send multipart form which includes a file, I get the error
apiRequestContext.post: Unexpected buffer type of 'data.file'
.I have this fixture:
Also, second fixture which uses
post
that relies onnewContext()
(this is not working, getting error from the title):The same fixture is working if I use
context
to callpost
(I would prefer to usenewContext()
since I don't have to repeat baseUrl every time):So, it seems newContext() have some issues with multipart form and Buffer.
Expected
Expected multipart form data to be submitted when using
newContext()
Actual
Getting the error
Error: apiRequestContext.post: Unexpected buffer type of 'data.file'
on the line which points topost
method in my first fixture.