Testcafe 断言文件下载的示例

问题描述 投票:0回答:5

我想编写一个装置来模拟导出文件并确保从浏览器操作下载文件。 有什么例子吗?

不适用

javascript testing automated-tests e2e-testing testcafe
5个回答
7
投票

没有一种奇特的方法来检查下载是否完成,TestCafe 在控制浏览器下载能力方面受到一定限制。

import fs from 'fs';

const fileName = 'junk.txt';
const downloadLocation = 'C:\\Wherever\\Downloads\\';
const fileDLUrlBase = 'https://example.com/downloads/';
fixture('download test fixture');
test('download test', async t => {
  await t.navigateTo(fileDLUrlBase + fileName);
  await t.wait(30000);
  // Wait 30 seconds
  await t.expect(fs.fileExistsSync(downloadLocation + fileName));
});

如果需要,您可以将其转换为循环,例如每 5 秒检查一次,持续 60 秒。


4
投票
  // Wait 15*1000 ms or less
  async function waitForFile (path) {
     for (let i = 0; i < 15; i++) {
        if (fs.existsSync(path))
           return true;
  
        await t.wait(1000);
     }
  
     return fs.existsSync(path);
  }
  
  await t.expect(await waitForFile(/*path*/)).ok();

另请参阅:检查下载的文件名和内容


1
投票

由于问题很模糊我们知道OP的导出文件是否是:

  • 来自远程 URL,或者
  • data
    URI

我正在添加对后者的回答,因为我最近有一个类似的问题。我想测试下载

data
URI,而不是远程 URL 下载,但我找不到答案,因此我发布了我的答案,以防有人有相同的问题。

这是带有

data
URI 的下载按钮:

<a
  download="file.txt"
  target="_black"
  href="data:text/plain;,generated text data that will force download on click"
  id="btn-download">
  Download
</a>

以及我的测试片段(使用 TypeScript):

  const DownloadButton = Selector("#btn-download");

  // Simulate a file download
  const fileName = await DownloadLink.getAttribute("download");
  const filePath = `${downloadsFolder()}\\${fileName}`; // Used the downloads-folder package
  await t.click(DownloadButton);
  // Using Vladimir's answer to check for file download every x seconds
  await t.expect(await waitForFile(filePath)).eql(true);

  // We expect the contents of the input to match the downloaded file
  await t.expect(JSON.parse(readFileSync(filePath, "utf8"))).eql(TestDocument2);

  // Clean up
  await unlinkSync(filePath); // Or you can use the afterEach hook to do cleanups

重点是,如果您下载的文件是通过锚点

href
,出于安全原因
,您将无法使用上面发布的
navigateTo解决方案,并且您将收到不允许将顶部框架导航到数据URL错误。

过去几个月,Google Chrome 发布了新的安全更新,实际上消除了直接使用 JavaScript 在浏览器中打开 base64 URI 的可能性。


0
投票

这对我有用

await t 
    .click(this.downloadPdfImage) // selector -- downloadPdfImage file name that get downloaded
    .wait(1000)
await t.expect(fs.existsSync(this.downloadLocation + this.fileNamePdf)).ok(); //assertion to verify

0
投票

这是一种最新的方法,可以更好地控制 TestCafe 中的下载文件,而不会混淆下载目录:

  1. 首先,确保您使用 TestCafe 3.6.0 或更高版本。旧版本不公开
    t.getCurrentCDPSession
    方法。
  2. 为了方便起见,请安装“chrome-remote-interface”和“@types/chrome-remote-interface”。这与 TestCafe 内部使用的库相同,但它将客户端公开为
    unknown
    ,依赖项用于恢复已删除的类型。
  3. 在下载文件之前,进行 CDP 调用以设置下载目录。我更喜欢将其靠近固定装置,就像我对测试附件所做的那样。
    export const setDownloadsDir = async (dirName: string = 'downloads') => {
      const client = await t.getCurrentCDPSession() as remoteChrome.Client;
      const downloadPath = path.resolve(__dirname, dirName);
      await client.send('Page.setDownloadBehavior', { behavior: 'allow', downloadPath });
      return downloadPath
    };
    const downloadsPah = await setDownloadsDir();
    
  4. 使用返回的路径检查文件内容或您有什么:
      await t
        .expect(fs.readFileSync(path.resolve(downloadsPah, 'file.txt')))
        .eql(fs.readFileSync('file-reference.txt'))
    
© www.soinside.com 2019 - 2024. All rights reserved.