Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Verify the data of the downloaded file (PDF/Word/Excel) using cypress commands

I have one scenario where I have to verify the downloaded file's data using Cypress commands. FileType :- pdf, Word, Excel.

I have the URL of the Server API Action which gets called and In response, it returns the pdf file.

I need to implement using Cypress commands and Typescript (plugin and typings).

I am able to get the downloaded status and even the response.body has some text but it require some parser to parse the response body. Below is the code that I have tried.

const oReq = new XMLHttpRequest();
    oReq.open("GET", href as string, true);
    oReq.responseType = "arraybuffer";
    oReq.onload = () => {
        if (oReq.readyState === oReq.DONE) {
            if (oReq.status === 200) {
                // tried parsing the response. 
// looking for any parser which can parse the given reponse body into Text or json
            }
        }
    }


cy.request(href).then((response) => {
    expect(response.status).to.equal(200);
    expect(response.body).not.to.null;
    const headerValue = response.headers["content-disposition"];
    
    // expect(headerValue).to.equal("attachment; filename=ExperimentEntityList.<FileExtension-PDF | XLSX | DOCX>");
    
    /// have tried with YAML parser and the "FS" module that cypress and ends up in different console error
    // YAML parser causes console error about unidentified character "P".
    // FS module code is shown below
});     

import * as fs from "fs";

function GetPDFContent()
{
    // throws console that fs object doesn't have readFile and same with readFileSync method. 
    fs.readFile("url")..
    fs.readFileSync("url")..
}

Requirement:

  1. Read Content of PDF File
  2. Read Content of XLS(x) file
  3. Read content of doc(x) file.

Didn't get success in reading content of PDF and DOc(x) file in typescript for the cypress automation script. Gone through various blogs in the internet install pdfparser, pdfreader, yaml parser, filereader and couple of more. But, none of them works. I have used the above mentioned code to read the files. and Check the written comment for the respective command.

For the xlsx file I found the solution by using XSLX parser plugin that parse the Response.body which I can iterate and get the content. I am looking for the similar parser for PDF and Doc(x) file.

Anyone knows about this. Please share it!!!

NOTE: Brackets or syntax is not the problem. If found in above sample code then it would have missed during copy/paste.

EDIT:

I have found the solution to read and verify the PDF file content using Cypress commadns. Thanks to Richard Matsen, @Richard: But, the problem is when I have a full url of the PDF file. Like - http://domainname/upload/files/pdf/pdfname.pdf. Then I can read the content and verify it. But if My problem is I have a url like "http://domainname/controller/action?pdf=someid", which returns the pdf file response and the node command doesn't encode it properly and the pdf file is not parsed properly.

Small Question

Do anyone knows how to create a pdf file using node/cypress commands using the Response stream of the PDF data. I have tried the Axios plugin, http, xmlhttprequest plutins.

like image 256
Prashant Kankhara Avatar asked Dec 05 '18 07:12

Prashant Kankhara


People also ask

How do I verify downloaded files in Cypress?

To verify that the file has been downloaded we can install simple Cypress command, which will set up downloads directory, will wait and will verify that the file is downloaded.

How do I get data from Excel in Cypress?

But, we need to perform data driven testing. Therefore, we need to convert the excel file into json data and feed test data from json in the script. Install jsonpath (https://www.npmjs.com/package/jsonpath)as it is used in the test script to extract data from json file. In Cypress, we will see data.

How read data from external file in Cypress?

readFile() command look for the file to be present in default project root folder . Hence filepath should be specified relative to the root folder . For any files other than JSON format, this command yields the content of the file. For JSON files, the content is parsed into Javascript and returned.


1 Answers

You need a plugin to access libraries like pdf-parser which work in the NodeJs environment (i.e use Node commands like fs).

The best reference for this is Powerful cy.task

Here is an example of adapting this pattern to your scenario.

cypress/plugins/index.js

const fs = require('fs')
const path = require('path')
const pdf = require('pdf-parse');

const repoRoot = path.join(__dirname, '..', '..') // assumes pdf at project root

const parsePdf = async (pdfName) => {
  const pdfPathname = path.join(repoRoot, pdfName)
  let dataBuffer = fs.readFileSync(pdfPathname);
  return await pdf(dataBuffer)  // use async/await since pdf returns a promise 
}

module.exports = (on, config) => {
  on('task', {
    getPdfContent (pdfName) {
      return parsePdf(pdfName)
    }
  })
}

spec.js

it('tests a pdf', () => {
  cy.task('getPdfContent', 'mypdf.pdf').then(content => {
    // test you pdf content here, with expect(this and that)...
  })
})

I haven't tested this, so you may find some wrinkles to iron out.

The location of the pdf is repoRoot which I understand to mean the project root folder two levels above /cypress/plugins. You may need to adjust the path since downloading is involved. You have not given enough info to understand the full test logic, I leave it up to you to make the adjustments.

The form that the content comes back in depends on the pdf library used. It looks like pdf-parse gives a Json object which should be easy to test.
After cy.task('getPdfContent') is called you can choose various cy commands such as .should() and .contains() but I would use .then() and within the callback use expect() on the content.

like image 157
Richard Matsen Avatar answered Oct 13 '22 07:10

Richard Matsen