如何在 cypress.config.js 中的 cy.task() 函数(例如 validateZipFile 和 getZipFileSize)中添加等待

soc*_*way 3 javascript node.js cypress

如何在 cypress.config.js 文件中的cy.task() 函数(例如validateZipFile和)中添加等待?getZipFileSize

test.spec.js

cy.get('button[type="submit"]').contains("Download").click({force:true});
helperFunctions.validateZip("Booking Results Resource Pack - Task");
Run Code Online (Sandbox Code Playgroud)

// helperFunctions.js

validateZip (text) {
    const dfilename = text.replace(/-|_|\s/g,"");
    const downloadedFilename = dfilename+"ZipFile.zip";
   
    cy.task('getZipFileSize', downloadedFilename)
    .should('eq', 6149237)

    cy.task('validateZipFile', downloadedFilename)
    .should('deep.eq', [
      '__Booking-Resource__Question-Cards__Booking_BW.pdf', 
      '__Booking-Resource__Question-Cards__Booking-Colour.pdf'
    ]);
    
  }

  
Run Code Online (Sandbox Code Playgroud)

赛普拉斯.config.js

    const AdmZip = require("adm-zip");
    
    const { defineConfig } = require('cypress')
    
    module.exports = defineConfig({
       e2e: {
        setupNodeEvents(on, config) {
          .....
    
    
            on('task', {
            validateZipFile: filename => {
              const downloadsFolder = config.downloadsFolder
              return  validateZipFile(path.join(downloadsFolder, filename))
            },
            getZipFileSize: filename => {
              const downloadsFolder = config.downloadsFolder
              const stats = fs.statSync(path.join(downloadsFolder, filename))
              return stats.size
            }
          });
    
          return config;
        },
        baseUrl: "https://staging-qa.someurl.com/",
        specPattern: "cypress/e2e/**/*.spec.{js,jsx,ts,tsx}",
      },
    })

 function validateZipFile(filename) {
  const zip = new AdmZip(filename)
  const zipEntries = zip.getEntries()
  const names = zipEntries.map(entry => entry.entryName).sort()
  return names
}
Run Code Online (Sandbox Code Playgroud)

Fod*_*ody 6

假设网页上没有任何内容表明下载已完成:

来自赛普拉斯基辅的 Yevhen Laichenkov 撰写了这篇文章:How to verify that file is downloaded with cy-verify-downloads

他提到了大文件的内存问题cy.readFile(),并构建了一个库cy-verify-downloads

赛普拉斯.config.js

const { verifyDownloadTasks } = require('cy-verify-downloads');

module.exports = defineConfig({
  e2e: {
    setupNodeEvents(on, config) {
      on('task', verifyDownloadTasks);
    },
  },
})
Run Code Online (Sandbox Code Playgroud)

帮手

const { verifyDownloadTasks } = require('cy-verify-downloads');

module.exports = defineConfig({
  e2e: {
    setupNodeEvents(on, config) {
      on('task', verifyDownloadTasks);
    },
  },
})
Run Code Online (Sandbox Code Playgroud)

测试(无变化)

require('cy-verify-downloads').addCustomCommand()

validateZip (text) {
    const dfilename = text.replace(/-|_|\s/g,"");
    const downloadedFilename = dfilename+"ZipFile.zip";
   
    cy.verifyDownload(downloadedFilename );

    cy.task('getZipFileSize', downloadedFilename)
      .should('eq', 6149237)

    cy.task('validateZipFile', downloadedFilename)
      .should('deep.eq', [
        '__Booking-Resource__Question-Cards__Booking_BW.pdf', 
        '__Booking-Resource__Question-Cards__Booking-Colour.pdf'
      ]);
  }
Run Code Online (Sandbox Code Playgroud)

轮询下载

您可以基于poll nodejs 库构建任务。

这个方法可以让你

  • 配置测试超时
  • 从任务返回true/false并在“应该”中使用结果
const fs = require('fs')
const poll = require('poll')

module.exports = defineConfig({
  e2e: {
    setupNodeEvents(on, config) {
      on('task', {

        poll: async ({filename, timeout = 30_000}) => {
          const {poll} = await import('poll')

          const filepath = path.resolve(config.downloadsFolder, filename)
          let fileExists = false;
          let stopPolling = false
          setTimeout(() => stopPolling = true, timeout)

          return new Promise(resolve => {
            const shouldStopPolling = () => {
              if (stopPolling) resolve(false)
              return stopPolling || fileExists
            }
            poll(
              () => { 
                fileExists = fs.existsSync(filepath) 
                if (fileExists) resolve(true)
              }, 
              100,                                   // check every 100ms
              shouldStopPolling
            )
          })
        },
      });
    },
  },
})
Run Code Online (Sandbox Code Playgroud)

测试

cy.get('button[type="submit"]').contains("Download").click({force:true});
helperFunctions.validateZip("Booking Results Resource Pack - Task");
Run Code Online (Sandbox Code Playgroud)

测试轮询任务

为了检查上述任务,我test1.pdf在下载中添加了一个虚拟文件,然后运行一个测试来检查该文件以及不存在的文件test2.pdf

const fs = require('fs')
const poll = require('poll')

module.exports = defineConfig({
  e2e: {
    setupNodeEvents(on, config) {
      on('task', {

        poll: async ({filename, timeout = 30_000}) => {
          const {poll} = await import('poll')

          const filepath = path.resolve(config.downloadsFolder, filename)
          let fileExists = false;
          let stopPolling = false
          setTimeout(() => stopPolling = true, timeout)

          return new Promise(resolve => {
            const shouldStopPolling = () => {
              if (stopPolling) resolve(false)
              return stopPolling || fileExists
            }
            poll(
              () => { 
                fileExists = fs.existsSync(filepath) 
                if (fileExists) resolve(true)
              }, 
              100,                                   // check every 100ms
              shouldStopPolling
            )
          })
        },
      });
    },
  },
})
Run Code Online (Sandbox Code Playgroud)

等效的纯 JavaScript 任务

这是相同的任务,但使用纯 JavaScript

cy.get('button[type="submit"]').contains("Download").click({force:true});

cy.task('poll', {filename, timeout: 30_000})
  .should('eq' true)

helperFunctions.validateZip("Booking Results Resource Pack - Task");
Run Code Online (Sandbox Code Playgroud)