在此应用程序上开发了这个新的导出功能,我尝试使用Behat / Mink进行测试。 这里的问题是,当我点击导出链接时,页面上的数据会导出为CSV并保存在/ Downloads下,但我没有在页面上看到任何响应代码或任何内容。
有没有办法可以导出CSV并导航到/ Downloads文件夹来验证文件?
答案 0 :(得分:3)
假设您使用的是Selenium驱动程序,您可以点击"在链接和$this->getSession()->wait(30)
上直到下载完成,然后检查下载文件夹中的文件。
这将是最简单的解决方案。或者,您可以使用代理(如BrowserMob)来监视所有请求,然后验证响应代码。但仅此一点,这将是一条非常痛苦的道路。
检查文件下载的最简单方法是使用基本断言定义另一个步骤。
/**
* @Then /^the file ".+" should be downloaded$/
*/
public function assertFileDownloaded($filename)
{
if (!file_exists('/download/dir/' . $filename)) {
throw new Exception();
}
}
当您下载具有相同名称的文件并且浏览器以不同的名称保存文件时,这可能会出现问题。作为解决方案,您可以添加@BeforeScenario
挂钩以清除已知文件的列表。
另一个问题是下载目录本身 - 对于其他用户/机器可能会有所不同。要解决此问题,您可以将behat.yml
中的下载目录作为参数传递给上下文构造函数,请阅读docs。
但最好的方法是将配置传递给Selenium,指定下载目录,以确保它始终清晰,并确切地知道搜索的位置。我不确定如何做到这一点,但从quick googling来看似乎是可能的。
答案 1 :(得分:2)
查看此博客:https://www.jverdeyen.be/php/behat-file-downloads/
基本思路是复制当前会话并使用Guzzle执行请求。之后,您可以按照自己喜欢的方式查看回复。
class FeatureContext extends \Behat\Behat\Context\BehatContext {
/**
* @When /^I try to download "([^"]*)"$/
*/
public function iTryToDownload($url)
{
$cookies = $this->getSession()->getDriver()->getWebDriverSession()->getCookie('PHPSESSID');
$cookie = new \Guzzle\Plugin\Cookie\Cookie();
$cookie->setName($cookies[0]['name']);
$cookie->setValue($cookies[0]['value']);
$cookie->setDomain($cookies[0]['domain']);
$jar = new \Guzzle\Plugin\Cookie\CookieJar\ArrayCookieJar();
$jar->add($cookie);
$client = new \Guzzle\Http\Client($this->getSession()->getCurrentUrl());
$client->addSubscriber(new \Guzzle\Plugin\Cookie\CookiePlugin($jar));
$request = $client->get($url);
$this->response = $request->send();
}
/**
* @Then /^I should see response status code "([^"]*)"$/
*/
public function iShouldSeeResponseStatusCode($statusCode)
{
$responseStatusCode = $this->response->getStatusCode();
if (!$responseStatusCode == intval($statusCode)) {
throw new \Exception(sprintf("Did not see response status code %s, but %s.", $statusCode, $responseStatusCode));
}
}
/**
* @Then /^I should see in the header "([^"]*)":"([^"]*)"$/
*/
public function iShouldSeeInTheHeader($header, $value)
{
$headers = $this->response->getHeaders();
if ($headers->get($header) != $value) {
throw new \Exception(sprintf("Did not see %s with value %s.", $header, $value));
}
}
}
答案 2 :(得分:0)
使用所有Cookie修改iTryToDownload()函数很少:
public function iTryToDownload($link) {
$elt = $this->getSession()->getPage()->findLink($link);
if($elt) {
$value = $elt->getAttribute('href');
$driver = $this->getSession()->getDriver();
if ($driver instanceof \Behat\Mink\Driver\Selenium2Driver) {
$ds = $driver->getWebDriverSession();
$cookies = $ds->getAllCookies();
} else {
throw new \InvalidArgumentException('Not Selenium2Driver');
}
$jar = new \Guzzle\Plugin\Cookie\CookieJar\ArrayCookieJar();
for ($i = 0; $i < count($cookies); $i++) {
$cookie = new \Guzzle\Plugin\Cookie\Cookie();
$cookie->setName($cookies[$i]['name']);
$cookie->setValue($cookies[$i]['value']);
$cookie->setDomain($cookies[$i]['domain']);
$jar->add($cookie);
}
$client = new \Guzzle\Http\Client($this->getSession()->getCurrentUrl());
$client->addSubscriber(new \Guzzle\Plugin\Cookie\CookiePlugin($jar));
$request = $client->get($value);
$this->response = $request->send();
} else {
throw new \InvalidArgumentException(sprintf('Could not evaluate: "%s"', $link));
}
}
答案 3 :(得分:0)
在项目中,我们遇到的问题是我们有两台服务器:一台带有网络驱动程序和浏览器,另一台带有selenium hub。因此,我们决定使用curl请求来获取标头。所以我写了一个在步骤定义中调用的函数。下面你可以找到一个使用标准php函数的函数:curl_init()
/**
* @param $request_url
* @param $userToken
* @return bool
* @throws Exception
*/
private function makeCurlRequestForDownloadCSV($request_url, $userToken)
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $request_url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$headers = [
'Content-Type: application/json',
"Authorization: Bearer {$userToken}"
];
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$output = curl_exec($ch);
$info = curl_getinfo($ch);
$output .= "\n" . curl_error($ch);
curl_close($ch);
if ($output === false || $info['http_code'] != 200 || $info['content_type'] != "text/csv; charset=UTF-8") {
$output = "No cURL data returned for $request_url [" . $info['http_code'] . "]";
throw new Exception($output);
} else {
return true;
}
}
如何看待我有令牌授权。如果您想了解应该使用哪些标题,则应下载文件手册并在浏览器的标签network