Flag of Ukraine
SymfonyCasts stands united with the people of Ukraine

Mink

Keep on Learning!

If you liked what you've learned so far, dive in!
Subscribe to get access to this tutorial plus
video, code and script downloads.

Start your All-Access Pass
Buy just this tutorial for $12.00

With a Subscription, click any sentence in the script to jump to that part of the video!

Login Subscribe

Forget about Behat for a few minutes - I want to talk about a totally different library. Imagine if there were a simple PHP library that let you take command of a browser: surf to pages, find links with CSS, click those links, fill out forms and anything else you can dream up. It exists! And it's called Mink.

This is such a cool library that it deserves some direct attention. Start by creating a mink.php file right at the root of your project. And require composer's autoload file:

5 lines mink.php
... lines 1 - 2
require __DIR__.'/vendor/autoload.php';
... lines 4 - 5

We'll use Mink all by itself, outside of Symfony, Behat and everything else so we can focus on just how it works.

Important Object 1: The Driver

As awesome as Mink is, it only has four important objects. The first is the driver. Create a new $driver variable and set it to new GoutteDriver():

9 lines mink.php
... lines 1 - 4
use Behat\Mink\Driver\GoutteDriver;
... line 7
$driver = new GoutteDriver();

Now, ignore it: I'll come back and explain important object number 1 in a little while.

Important Object 2: The Session

Let's move on to important object #2, and the first that we really care about: the session. Add $session = new Session() and pass it the $driver as an argument:

19 lines mink.php
... lines 1 - 5
use Behat\Mink\Session;
... lines 8 - 11
$session = new Session($driver);
... lines 13 - 19

Think of the session like a browser tab: anything you can do in a tab, you can do in a session. And actually, that isn't very much. You can visit URLs, refresh, go backwards, go forwards and that's about it. Let's use it to visit a very awesome and absurdly-designed site "jurassicpark.wikia.com".

Tip

After vocal protests from the dinosaurs, jurassicpark.wikia.com was redesigned! That means its HTML/CSS was updated after we recorded this screencast. Don't worry: we've updated the code in the code blocks on this page to work for the new design. Use them instead of the CSS selectors used in the video.

After that we'll just print out a few things about the page like the status code, and the current URL:

19 lines mink.php
... lines 1 - 14
$session->visit('http://jurassicpark.wikia.com');
echo "Status code: ". $session->getStatusCode() . "\n";
echo "Current URL: ". $session->getCurrentUrl() . "\n";

To execute this, head over to the terminal and run:

php mink.php

Look at that: it's printing out 200 and a slightly different URL than we put in our code. That makes sense: when you go to the site in a browser, it redirects to the URL we see in our terminal. Mink is emulating a real browser by following redirects. But in reality, so far, it's making invisible cURL requests: it's not using a real browser.

Important Object 3: The Page (DocumentElement)

The third important object is called the page. Grab it by saying $page = $session->getPage():

24 lines mink.php
... lines 1 - 20
$page = $session->getPage();
... lines 22 - 24

I want you to think of this as the JQuery object or the DOM. Anything you can do with JQuery - like select elements, click links and fill out fields - you can do with the page. Less impressively, it also knows the HTML of whatever page we're currently on.

Tip

If you like to dig into the source code, the page is an instance of DocumentElement.

Let's use it to print out this first bit of text on the page with var_dump(substr($page->getText()), 0, 75);:

24 lines mink.php
... lines 1 - 22
echo "First 75 chars: ".substr($page->getText() , 0, 75) . "\n";

Run that again in the terminal.

php mink.php

Now we see the thrilling text of: "Park Pedia - Jurassic Park, Dinosaurs, Stephen Spielberg...". There's some weird a:lang code stuff on the end. Open up the source on the page.

The getText() method returns anything other than the HTML tags themselves. The first part comes from the title tag and then it grabs some other stuff from the style tag, which is technically text.

But what we really want to do is find individual elements so we can click links and fill out fields. Let's talk about that next.

Leave a comment!

4
Login or Register to join the conversation
Default user avatar

I don't see Autocomplete in sublime. Don't get correct suggestions while typing How can i enable that?

Reply

Hey Sumeet,

We don't use Sublime - it's just an advanced text editor but IDE. In our screencasts we use PhpStorm IDE. I found a Sublime text 2 plugin for Behat syntax highlighting on GitHub - looks like something you interested in: https://github.com/omissis/...

Cheers!

1 Reply
Default user avatar

Thanks for replying Victor.

Syntax color highlighting looks good. But i meant autocompleting class methods and being able to use external classes like we could do in eclipse for Java with cmd shift O shortcut. Can it be done with sublime 3? Else, could you recommend an IDE not too costly. Is eclipse / Netbeans a better choice than sublime for PHP ?

Regards

Reply

Ah, sorry, my fault. This looks work for Behat autocompletion in Sublime, but I have not used it at all yet.: https://packagecontrol.io/p...

What about other IDEs - difficult to say, I don't use other IDEs besides PhpStorm a long time. But you can check out PhpStorm early access program - https://confluence.jetbrain... , it's a beta version, but free, just don't forget to upgrade it.

Cheers!

1 Reply
Cat in space

"Houston: no signs of life"
Start the conversation!

This tutorial uses a very old version of Symfony. The fundamentals of Behat are still valid, but integration with Symfony will be different.

What PHP libraries does this tutorial use?

// composer.json
{
    "require": {
        "php": ">=5.4.0, <7.3.0",
        "symfony/symfony": "^2.7", // v2.7.4
        "twig/twig": "^1.22", // v1.22.1
        "sensio/framework-extra-bundle": "^3.0", // v3.0.16
        "doctrine/doctrine-bundle": "^1.5", // v1.5.1
        "doctrine/orm": "^2.5", // v2.5.1
        "doctrine/doctrine-fixtures-bundle": "^2.2", // v2.2.1
        "behat/symfony2-extension": "^2.0" // v2.0.0
    },
    "require-dev": {
        "behat/mink-extension": "^2.0", // v2.0.1
        "behat/mink-goutte-driver": "^1.1", // v1.1.0
        "behat/mink-selenium2-driver": "^1.2", // v1.2.0
        "phpunit/phpunit": "^4.8" // 4.8.18
    }
}
userVoice