minkphp/MinkGoutteDriver

Custom port configuration issue

debo opened this issue · 7 comments

debo commented

I'm desperatly trying to have behat to run headless tests using mink and goutte on top of the PHP built-in webserver runnin on a custom port but I'm probably missing or overlooking something.

Following is the configuration I'm currently using:
https://gist.github.com/debo/2ed20f22685b816bfb9d

I also tried to add the port to the base_url but it doesn't work either. A quick initial investigation suggests that the problem is here:

https://github.com/symfony/browser-kit/blob/master/Client.php#L534

No matter what the port seems to get stripped off. Any idea about how to make this work properly?

stof commented

Well, you need to put it in the base_url, not as a curl option. And then, it should work

debo commented

As I said, even passed in the base_url doesn't work. That was the very first thing I tried even before getting dirty with the curl options. I ended up using the curl options because the guzzle throws the exception but I think that's just a mere consequence.

stof commented

well, MinkGoutteDriver itself works with custom ports: this is exactly our setup on Travis, where we run the builtin webserver on port 8000 for the fixtures website.

So I see a few possible reasons:

  • you are not using the latest versions of Goutte (there was a bug in the past with custom ports) or of another package involved (Mink, MinkGoutteDriver, BrowserKit, etc...)
  • your website is broken and returns links containing absolute urls built without including the port number (in which case it is a good news that your tests are failing as it allows to discover the bug)
  • the bug is coming from the Behat layer built on top of Mink (which would have to be debugged)
debo commented

I'm putting together some testing code so you can maybe have a look too, if you have time of course; in the meantime I'll have a look at your travis configuration as well. As per the versions, it's a brand new project so composer requires all the latest I would assume:

{
  "autoload": {
    "psr-4": {
      "Framework\\": "app"
    }
  },
  "config": {
    "bin-dir": "bin"
  },
  "require": {
    "symfony/http-foundation": "^2.7",
    "symfony/routing": "^2.7",
    "symfony/http-kernel": "^2.7",
    "symfony/event-dispatcher": "^2.7",
    "symfony/dependency-injection": "^2.7",
    "twig/twig": "^1.23"
  },
  "require-dev": {
    "phpspec/phpspec": "^2.3",
    "behat/behat": "^3.0",
    "behat/mink-extension": "^2.1",
    "behat/mink-goutte-driver": "^1.2"
  }
}
debo commented

@stof I gave you access to some sample code you shoud be familiar with; I'm starting the project with:

~ php -S localhost:5555 -t web web/rewrite.php

and then simply run bin/behat and get the following:

Feature: Site navigation
  In order to enjoy the website experience
  As a visitor
  I want to be able to navigate through the website

  Scenario: View Homepage                      # features/core.feature:6
    Given visit the website for the first time # FeatureContext::visitTheWebsiteForTheFirstTime()
    When I am on page "/"                      # FeatureContext::iAmOnPage()
      cURL error 7: Failed to connect to localhost port 80: Connection refused (see http://curl.haxx.se/libcurl/c/libcurl-errors.html) (GuzzleHttp\Exception\ConnectException)
    Then I should see "Welcome to Stardust!"
      Ambiguous match of "I should see "Welcome to Stardust!"":
      to `I should see :arg1` from FeatureContext::iShouldSee()
      to `/^(?:|I )should see "(?P<text>(?:[^"]|\\")*)"$/` from FeatureContext::assertPageContainsText()

--- Failed scenarios:

    features/core.feature:6

1 scenario (1 failed)
3 steps (1 passed, 2 failed)
0m0.08s (14.82Mb)

Thanks a lot for your help.

stof commented

@debo there was a bug in your context. You were bypassing the RawMinkContext logic to apply the base URL. And BrowserKit indeed uses http://localhost as base url when you give it a non-absolute URL (you were passing / here) and there is no browsing history. See the PR I sent you on the code you shared with me

debo commented

To add further details to for posterity reading, based on the following basic feature file:

Feature: Site navigation
  In order to enjoy the website experience
  As a visitor
  I want to be able to navigate through the website

  Scenario: View Homepage
    Given visit the website for the first time
    When I am on page "/"
    Then I should see "Welcome guest!"

I did try to implement my context in the following way:

class FeatureContext extends MinkContext implements Context, SnippetAcceptingContext
{
    // ...
    public function visitTheWebsiteForTheFirstTime()
    {
        $this->session = $this->getSession();
    }
    // ...
    public function iAmOnPage($page)
    {
        $this->session->visit($page);
    }
    // ...
}

When the right and recommended way in this case is to do the following instead:

class FeatureContext extends RawMinkContext implements Context, SnippetAcceptingContext
{
    // ...
    public function visitTheWebsiteForTheFirstTime()
    {
    }
    // ...
    public function iAmOnPage($page)
    {
        $this->visitPath($page);
    }
    // ...
}

This is also means that anything that you might find on google which suggest to set guzzle parameters are beyond unnecessary.

@stof thanks again for your help, very appreciated.