如何在Laravel Dusk中测试文件下载功能?
Laravel Dusk 断言JS触发的PDF下载正常启动的方案
步骤1:配置Chrome驱动允许自动下载
首先需要修改Dusk的Chrome启动参数,指定固定的下载目录,并且关闭下载前的确认弹窗,避免下载被拦截。
打开tests/DuskTestCase.php文件,修改driver()方法中Chrome的配置部分:
protected function driver() { $options = (new \Facebook\WebDriver\Chrome\ChromeOptions())->addArguments([ '--disable-gpu', '--headless', // 无头模式下也需要配置该参数 '--no-sandbox', '--window-size=1920,1080', ]); // 配置下载规则 $options->setExperimentalOption('prefs', [ 'download.default_directory' => storage_path('temp/dusk-downloads'), 'download.prompt_for_download' => false, 'download.directory_upgrade' => true, 'safebrowsing.enabled' => false, // 关闭安全扫描拦截PDF下载 'plugins.always_open_pdf_externally' => true, // 禁止Chrome内置打开PDF,强制触发下载 ]); return \Facebook\WebDriver\Remote\RemoteWebDriver::create( 'http://localhost:9515', \Facebook\WebDriver\Chrome\ChromeOptions::capabilities($options) ); }
注意:提前手动创建storage/temp/dusk-downloads目录,并且给足读写权限,避免文件写入失败。
步骤2:编写测试逻辑
测试流程按照「清理历史文件 -> 触发下载 -> 等待下载完成 -> 断言文件存在」的顺序编写:
public function test_pdf_download_triggered_correctly() { // 先清理目录下的旧PDF文件,避免历史数据干扰 $downloadDir = storage_path('temp/dusk-downloads'); $targetFileName = '导出的报表.pdf'; // 替换为你实际的PDF文件名 $targetFilePath = $downloadDir . '/' . $targetFileName; if (file_exists($targetFilePath)) { unlink($targetFilePath); } $this->browse(function ($browser) use ($targetFilePath) { $browser->visit('/your-page-url') ->press('#download-pdf-btn') // 替换为你实际的按钮选择器 ->waitFor(5); // 等待5秒,可根据文件大小调整时长,也可用轮询逻辑代替固定等待 // 断言文件存在 $this->assertFileExists($targetFilePath); // 可选:断言文件大小大于0,排除下载空文件的情况 $this->assertGreaterThan(0, filesize($targetFilePath)); }); }
特殊场景处理
- 如果你的PDF文件名是动态生成的(比如带订单号、时间戳),可以在点击下载前先获取页面上对应的动态标识,拼接成最终的文件名再做断言;也可以在等待后扫描下载目录下最新生成的
.pdf后缀文件,判断生成时间是否在点击时间之后即可。 - 如果下载耗时不稳定,可以把固定等待改成轮询检查,最多等待10秒,每秒检查一次文件是否存在,避免固定等待太长或太短。
内容的提问来源于stack exchange,提问作者Magmatic
相关产品推荐
相关产品推荐

