Joeri Verdeyen bio photo

Joeri Verdeyen

Web-engineer, cyclist, Nespresso lover, Strava pusher.

Twitter LinkedIn Instagram Github Stackoverflow Last.fm Strava

How to test file downloads with Behat

Behat

Behat logo

Definitions

Add the following definitions in your Context class. These definitions allow you to download a file from a specific path, even when you are logged in. The same PHPSESSID cookie is used as in the current running Scenario. If you don’t need to keep the session cookie, you can delete these cookie related lines.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
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));
        }
    }
}

Features

This is how you can use the new definitions in you features.

1
2
3
4
5
Scenario: Download a file as a logged in user
    Given I am logged in as "admin" with password "admin"
    When I try to download "downloads/pdf/generated.pdf"
    Then I should see response status code "200"
    Then I should see in the header "content-type":"application/pdf"

Guzzle

I used Guzzle in the download definition. Guzzle is a PHP HTTP client and framework for building RESTful web service clients. It’s a nice wrapper for PHP cURL, which is a PHP library that allows you to connect and communicate to many different types of servers with many different types of protocols

Thanks for reading

Feel free to leave a comment if you have remarks or like this post