When I tried to use cy.request() API to get content of PDF file, I end up with broken file content.
Example of spec file:
/// <reference types="Cypress" />
context('Download Pdf', () => {
it('Download Pdf', () => {
const pdfUrl = 'http://www.pdf995.com/samples/pdf.pdf';
cy.request({ url: pdfUrl, gzip: false})
.then((response) => {
const fileName = 'test';
const filePath = 'temp/' + fileName + '.pdf';
cy.writeFile(filePath, response.body, 'binary');
});
});
});
As a result, I have got PDF file with blank pages:
Which is not really what I try to download:
http://www.pdf995.com/samples/pdf.pdf
I want to get exactly the same file that I would get if use browser to download it.
examplescypress/integration/sample/download-pdf.spec.js file and put there a snippet from Current behavior section.temp directory in the root directory of the projectdownload-pdf.spec.js in GUItemp/test.pdf file with source one: http://www.pdf995.com/samples/pdf.pdfThis same on Windows
Yeah, this is reproducible from the code given above.
Hi
Same here. Is there any updates on this issue?
I'm checking #2029, i hope that workaround works:S
I need to save the pdf file, no further steps.
Thanks,
Turul
If anyone step into this river, the workaround in #2029 works (pdf).
Hi there,
You could try to set header of the response to 'Content-Type' : 'application/pdf' probably. This is for example possible with cy.route where you can provide 'headers: { 'Content-Type': 'application/pdf' } as an Object. This helped me with incorrect display of pdf as sometimes by default type is 'text/plain'
I'm facing the same issue as well… any updates?
I'm currently working on a fix proposal for this problem. The changes to cypress core would be:
Support of boolean option encodeBodyToBase64 to cy.request() options argument which would mean that the body of the response will be encoded to base64 at the stage of being a buffer/Uint8Array through buffer.toString('base64').
This will ensure safe buffer transformation to base64, which can be quite useful for non-text responses. For example: in case response is an image, it can be directly used for data urls: data:text/plain;base64,IMAGE_RESPONSE_BODY_AS_BASE64.
Support of boolean option decodeContentFromBase64 to cy.writeFile() options argument which would mean that the content value passed should be treated as base64-encoded value, i.e: should be decoded throught buffer.from(base64Data, 'base64') before writing to file.
This will be useful as data in cypress is are safer to transfer as strings from client to cypress server. So user can safely write binary content to file through cy.writeFile().
I finished the implementation of the fix itself and ensured that it is working locally. Even though, I still need to write tests before creating 2 proposal PRs to cypress-io/cypress and cypress-io/request repositories.
After the fix proposal, a working example would be:
/// <reference types="Cypress" />
context('Download Pdf', () => {
it('Download Pdf', () => {
const pdfUrl = 'http://www.pdf995.com/samples/pdf.pdf';
// ADDED: "encodeBodyToBase64: true"
cy.request({ url: pdfUrl, gzip: false, encodeBodyToBase64: true }).then(
(response) => {
const fileName = 'test';
const filePath = 'temp/' + fileName + '.pdf';
cy.writeFile(filePath, response.body, {
encoding: 'binary',
decodeContentFromBase64: true, // ADDED
});
}
);
});
});
I.e: setting the flag encodeBodyToBase64: true in cy.request() and decodeContentFromBase64: true in cy.writeFile()
The code for this is done in cypress-io/cypress#7382, but has yet to be released.
We'll update this issue and reference the changelog when it's released.
Released in 4.7.0.
This comment thread has been locked. If you are still experiencing this issue after upgrading to
Cypress v4.7.0, please open a new issue.
Most helpful comment
Yeah, this is reproducible from the code given above.