Behat Mink 文件上传在提交时找不到文件

Behat Mink file upload not finding file on submit

我正在尝试在 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 容器中的那个路径,但是当提交表单时,抛出这个错误:

没有有用的日志。

我试过在 behat.yml 中设置 files_path 参数,但在测试期间出现错误 运行:

unknown error: path is not absolute: 3.jpg

我错过了什么吗?该容器的文件路径不正确吗?

我已经尝试在我的机器上使用 abs 路径,但无济于事(尽管这种方法有严重的缺点,所以我很高兴这不是解决方案):

/Users/its.me/Sites/kbs/src/Resources/TestImages/1.jpg

本地 Users 目录也安装到我的 docker 机器中,因此 abs 路径在主机上有效。我认为这可能与权限有关,所以我将它们全部设置为 read/write/execute 但没有雪茄!相对路径不起作用。

我的图片在哪里?

将文件添加到您的 behat 目录并在 Behat\MinkExtension\Extension:

下设置 files_path

files_path 应该是这样的:files_path: %behat.paths.features%/bootstrap

基于issue posted by @lauda at GitHub, the MinkSeleniumDriver needs some file preparation to work properly. Namely, turning it into a zip file. 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;
  }

确保在 Behat.yml 文件的 MinkExtension 部分下包含 files_path,例如

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

行为特征示例:

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