SW Designs

Technology and Photography

Multiple Sessions With Behat, Mink and Selenium2

At work, we have a few scenarios where acceptance tests require two or more users to interact with each other on a website. An example of this is multiple users joining a poker table and playing against each other.

Mink doesn’t fully support this out-of-the-box, but with a bit of effort multi-session scenarios can be achieved, albeit with a few gotchas. For the purposes of this blog, I’ve created a sample scenario based around a Web Sockets demo app at html5labs.cloudapp.net.

Lets start with some suitable Gherkin. Note the step reuse for the ‘Given’ sections and that the user profile will be passed to the step as an argument.

Scenario: Simple 1-way chat
 Given "User1" enters the chat room
 And "User2" enters the chat room
 When "User1" posts a message
 Then "User2" should see that message

And now for some code. There’s a lot going on below, first we retrieve the default Mink session (as configured in behat.yml) and clone it. At this point we have two session objects linked to the same Selenium2 session. To correct this and provide session isolation, we instantiate and set a fresh WebDriver object before finally registering the new session with Mink and restarting. Okay, this is a bit hacky, but stay with me.

Now we have multiple sessions registered with Mink and subsequent steps will be passed the appropriate session name as defined in the Gherkin. These steps can simply reference the required session with $this->getSession($user).

I mentioned some gotchas previously. They are,

  • This code is Selenium2/Web Driver specific, however, broadly speaking the same approach should work with other drivers too.
  • Mink auto-starts the default session when you first call getSession(). This means a total of 3 browser instances are used for this test.
  • I’ve duplicated some Selenium2 config in behat.yml for ease. I couldn’t figure how-to ‘ask’ Mink for another Selenium2 driver instance
  • The standard MinkContext steps can’t be used as they only work with the default Mink session. UPDATE: Switching the default session name within a step with $this->getMink()–>setDefaultSessionName($name) means the MinkContext continue to work. I’ve updated the code on GitHub to reflect this.
  • Probably more

Clearly this isn’t the cleanest implementation of multiple sessions, however it does prove the concept works while retaining the focus on describing behaviour in the Gherkin. I suspect the limitations of MinkContext and custom sessions can be resolved with a simple patch which I hope to raise over the next few days.

The full source code is available on GitHub. Any ideas/suggestions/improvements are welcome!