Search code examples
javascriptautomated-testscypresscypress-file-upload

How can I check if uploaded and downloaded file have same content with cypress?


I wanted to test if the content of the uploaded file and the downloaded file are the same. So, following is what I tried through cypress:

it.only(cfg.testname, () => {

    // 1. Login to website, navigate to desired webapge
    // 2. Upload the file
    // 3. Download the file

    // cy.wait(5000)
    
    // 4. Read the uploaded file:
    const fileContent = cy.fixture(_filePath)
    console.log('fixture file path', '======>', _filePath)
    console.log('fixture file content', '=====>', fileContent)
    
    // 5. Read the downloaded file:
    const downloadsFolder = Cypress.config("downloadsFolder")
    const downloadedFileContent = cy.readFile(path.join(downloadsFolder, _fileName))
    console.log('downloaded file path', '======>', path.join(downloadsFolder, fileName))
    console.log('downloaded file content','====>', downloadedFileContent)
    
    // 6. Check if they are equal:
    expect(downloadedFileContent).equals(fileContent)            
}) 

However, when I run this test, it does not even complete login step and immediately give asserition error one step 6, that is on expect()...:

AssertionError: expected { Object (userInvocationStack, specWindow, ...) } to equal { 
Object (userInvocationStack, specWindow, ...) }
    at Context.eval (VM753 tests:224)

When I comment step 6 expect()..., it correctly logins, uploads file and downloads file. So, I felt somehow I should make the process wait till download is complete before expect().... So I tried uncommenting cy.wait(5000), but no help. It still gives me above error (with of course expect()... uncommented).

Q1. Why this behavior?
Q2. How should I fix this?

PS: I am getting bunch of errors in the console which I am unable to understand. This is the screenshot of console:

enter image description here


Solution

  • The fixture read is async, so you need to use .then(), same with cy.readFile()

    The use of path.join(downloadsFolder, _fileName) probably will not work as it's a Node command, substitute a string template instead

    If you have a complicated file in JSON format, also try .to.deep.eq

    cy.fixture(_filePath).then(fileContent => {
      const downloadsFolder = Cypress.config("downloadsFolder")
      const downloadPath = `${downloadsFolder}/${_fileName}`
      cy.readFile(downloadPath).then(downloadedFileContent => { 
        expect(downloadedFileContent).equals(fileContent)   
        // or may need deep
        // expect(downloadedFileContent).to.deep.eq(fileContent)   
      })
    })