我试图在Symfony应用程序中使用Selenium / Mink和Behat测试图像上传。该应用程序在Docker容器中运行。
我将文件直接附加到输入的NodeElement
而不是$driver->attachFileToField('#id-of-input', $filePath)
,因为我们在上下文中处理了大量输入并且已经输入在被调用的方法中:
$input->attachFile($this->filesPath . '1.jpg');
结果路径是:
/var/www/html/src/Resources/TestImages/1.jpg
此文件当然存在于docker容器中的该路径中,但是在提交表单时,会抛出此错误:
没有有用的日志。
我已尝试在files_path
中设置behat.yml
参数,但在测试运行期间出现错误:
unknown error: path is not absolute: 3.jpg
我错过了什么吗?该容器的文件路径是否不正确?
我尝试在我的机器上使用abs路径无济于事(虽然这种方法有严重的缺点,所以我很高兴它不是解决方案):
/Users/its.me/Sites/kbs/src/Resources/TestImages/1.jpg
本地Users
目录也安装在我的docker-machine中,以便abs路径在主机上运行。我认为它可能是权限相关所以我将它们全部设置为读/写/执行但没有雪茄!相对路径不起作用。
我的图片在哪里?
答案 0 :(得分:2)
基于issue posted by @lauda at GitHub,MinkSeleniumDriver需要一些文件准备才能正常工作。即,将其变成zip文件。 This comment帮助:
$localFile = $this->filesPath . '01.jpg';
$tempZip = tempnam('', 'WebDriverZip');
$zip = new \ZipArchive();
$zip->open($tempZip, \ZipArchive::CREATE);
$zip->addFile($localFile, basename($localFile));
$zip->close();
$remotePath = $this->getSession()->getDriver()->getWebDriverSession()->file([
'file' => base64_encode(file_get_contents($tempZip))
]);
$input->attachFile($remotePath);
unlink($tempZip);
上述代码基于facebook/php-webdriver
中的upload()
方法:
/**
* Upload a local file to the server
*
* @param string $local_file
*
* @throws WebDriverException
* @return string The remote path of the file.
*/
private function upload($local_file) {
if (!is_file($local_file)) {
throw new WebDriverException("You may only upload files: " . $local_file);
}
// Create a temporary file in the system temp directory.
$temp_zip = tempnam('', 'WebDriverZip');
$zip = new ZipArchive();
if ($zip->open($temp_zip, ZipArchive::CREATE) !== true) {
return false;
}
$info = pathinfo($local_file);
$file_name = $info['basename'];
$zip->addFile($local_file, $file_name);
$zip->close();
$params = array(
'file' => base64_encode(file_get_contents($temp_zip)),
);
$remote_path = $this->executor->execute(
DriverCommand::UPLOAD_FILE,
$params
);
unlink($temp_zip);
return $remote_path;
}
答案 1 :(得分:1)
在behat目录中添加该文件,并在files_path
Behat\MinkExtension\Extension:
files_path
应该是:files_path: %behat.paths.features%/bootstrap
答案 2 :(得分:1)
请务必在files_path
部分的Behat.yml
部分中加入MinkExtension
,例如
default:
extensions:
Behat\MinkExtension\Extension:
files_path: %behat.paths.base%/build/dummy/
还要确保您拥有正确的文件夹结构,例如
# Your application
football
build
dummy
document
hello.doc
world.xls
image
test.jpg
示例Behat功能:
Feature: Example feature
Scenario: I can upload image
Given I am on "/"
When I attach the file "image/test.jpg" to "league_flag"
And I press "Submit"
Then I should see "Succeeded."
这是实际的MinkExtension构建方法:
/**
* Attaches file to field with specified id|name|label|value
* Example: When I attach "bwayne_profile.png" to "profileImageUpload"
* Example: And I attach "bwayne_profile.png" to "profileImageUpload"
*
* @When /^(?:|I )attach the file "(?P<path>[^"]*)" to "(?P<field>(?:[^"]|\\")*)"$/
*/
public function attachFileToField($field, $path)
{
$field = $this->fixStepArgument($field);
if ($this->getMinkParameter('files_path')) {
$fullPath = rtrim(realpath($this->getMinkParameter('files_path')), DIRECTORY_SEPARATOR).DIRECTORY_SEPARATOR.$path;
if (is_file($fullPath)) {
$path = $fullPath;
}
}
$this->getSession()->getPage()->attachFileToField($field, $path);
}