Behat Mink文件上传未提交文件

时间:2017-02-08 13:07:30

标签: php symfony selenium docker behat

我试图在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容器中的该路径中,但是在提交表单时,会抛出此错误:

Your file was not found

没有有用的日志。

我已尝试在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路径在主机上运行。我认为它可能是权限相关所以我将它们全部设置为读/写/执行但没有雪茄!相对路径不起作用。

我的图片在哪里?

3 个答案:

答案 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);
}

请参阅:File uploading with Behat