Search code examples
validationtestingautomated-testszipcypress

Cypress: is it possible to extract zip-archive & validate content of files inside it?


Test-case is:

  1. Login
  2. Download the zip-archive
  3. Extract it (4 files)
  4. Validate fileContent inside them

My failed code is:


const decompress = require('decompress');

    decompress('C:/Users/Admin/QA/cypress/downloads/test.zip', 'C:/Users/Admin/QA/cypress/downloads');
    
    cy.readFile('C:/Users/Admin/QA/cypress/downloads/firstFile.c').then((fileContent) => {
      const expectedContent = `some code to validate`;
      expect(fileContent.trim()).to.equal(expectedContent.trim());

Faced with an error:


(uncaught exception)TypeError: fs$readFile is not a function
TypeError
The following error originated from your test code, not from Cypress. It was caused by an unhandled promise rejection.



  > fs$readFile is not a function



When Cypress detects uncaught errors originating from your test code it will automatically fail the current test.
node_modules/graceful-fs/graceful-fs.js:118:1

Where I did a mistake? Found the same idea of test https://github.com/MMCampos1703/unzipCypress but it also doesn't work

reinstalled cypress, updated dependencies, used ai to analyze code, searched the same errors


Solution

  • Of course, this should work, but please make sure that file path, and whether you use the function as Cypress task

    Otherwise what we followed is we use a plugin there and we can get these extracted zip/war files.

    dependency : extract-zip - https://www.npmjs.com/package/extract-zip So in our /cypress.config.js

    const extract = require("extract-zip");
    /**
     * Extract zip / war files using extract- zip npm dependency.
     * @param {*} source directory where zip/war file is located.
     * @param {*} target where to need extract the zipped / war file.
     */
    async function extractZip(source, target) {
        try {
            await extract(source, { dir: target });
        } catch (err) {
            console.log("Oops: extractZip failed.", err);
        }
    }
    
    const zippedFiles = [];
    
    const unzipFiles = async function (dirPath) {
        const files = fs.readdirSync(dirPath);
    
        await Promise.all(
            files.map(async (file) => {
                if (fs.statSync(dirPath + "/" + file).isDirectory()) {
                    await unzipFiles(dirPath + "/" + file);
                } else {
                    const fullFilePath = path.join(dirPath, "/", file);
                    const zipFolderName = file.replace(".zip", "");
                    const warFolderName = file.replace(".war", "");
                    if (file.endsWith(".zip")) {
                        zippedFiles.push(zipFolderName);
                        await extractZip(fullFilePath, path.join(dirPath, "/"));
                        await unzipFiles(path.join(dirPath, "/", zipFolderName));
                    }
                    if (file.endsWith(".war")) {
                        zippedFiles.push(warFolderName);
                        await extractZip(fullFilePath, path.join(dirPath, "/", warFolderName));
                        await unzipFiles(path.join(dirPath, "/", warFolderName));
                    }
                }
            })
        );
    };
    
    module.exports = defineConfig({
      e2e: {
        setupNodeEvents(on, config) {
          on('task', {
           /**
                     * This plugin is used to extract zipped files. 
                     * @param {*} dirPath The source, target directory where zipped files 
                     */
                    extractZipFiles(zippedFilePath) {
    
                        return new Promise((resolve, reject) => {
                            const OUTPUT_DIR = process.cwd() + zippedFilePath;
                            const source = process.cwd() + zippedFilePath;
                            const target = OUTPUT_DIR;
                            extractZip(source, target);
                            unzipFiles(target);
                            resolve(false);
                        });
                    },
          });
        },
        
      },
    });
    

    And how we use this, in the spec file this is how we use this

    cy.task('extractZipFiles, '<zipFileLocation>');