If you liked what you've learned so far, dive in!
Subscribe to get access to this tutorial plus
video, code and script downloads.
Open up authentication.feature
, because, you can't do much until you
login. Let's add a scenario:
... lines 1 - 5 | |
Scenario: Logging in | |
... lines 7 - 13 |
We remember from running behat -dl
:
./vendor/bin/behat -dl
That we have a lot of built in language already. Let's save some effort and describe the login process using these:
... lines 1 - 6 | |
Given I am on "/" | |
... lines 8 - 13 |
We want to start on the homepage. PhpStorm tries to help by auto-completing this
step, but when I hit tab, it prints it with extra stuff. When you use the -dl
option, the "Given I am on" ends with a bunch of crazy regex. Anytime you see
regex like this, it's just forming a wildcard: something where you can pass any
value, surrounded by quotes.
Oh, and one other thing: even though each line starts with Given
, When
and
Then
in the definition list, that first word doesn't matter. We could actually
say:
Then I am on "/"
It doesn't sound right in English, but technically, it would still run.
Alright! Given I am on "/". Next, I will click "Login". The built-in definition for that is "I follow". There's no built-in definition for "I click" but we'll add one later since that's how most people actually talk.
But for now let's add:
... lines 1 - 7 | |
When I follow "Login" | |
... lines 9 - 13 |
Remember, these all use the named selector, so we're using "Login" because that's the text of the link.
On the login page, we need to fill in these two fields. Again, because of the named selector, we'll target these by the labels "Username" and "Password". There are a few definitions for fields, byt the one I like is "When I fill in field with value". So:
... lines 1 - 8 | |
And I fill in "Username" with "admin" | |
And I fill in "Password" with "adminpass" | |
... lines 11 - 13 |
Yes I know, that isn't the right password - this won't work yet. It's cool though.
Finally, press the login button with:
... lines 1 - 10 | |
And I press "Login" | |
... lines 12 - 13 |
Notice that you follow a link but you press a button. Then we need to find something to assert - some sign that this worked. Login on the browser. Hmm, nothing says "Congratulations, you're in!"... but our login button did change to "Logout". Let's look for that with:
... lines 1 - 11 | |
Then I should see "Logout" |
Good work team. Let's run this!
./vendor/bin/behat features/web/authentication.feature
It runs... and fails:
The text "Logout" was not found anywhere in the text of the current page.
I happen to know this is because the password is wrong. But let's pretend that we didn't know that, and we're staring at this message wondering what the heck is going on.
Debugging tip number 1: right before the failing step, use a step definition called:
... lines 1 - 11 | |
Then print last response | |
... lines 13 - 14 |
Now run this again. It still fails, but first it prints out the entire page's code. Yes, this is ugly - I have another debugging tip later. There are two important things: first, we're still on the login page for some reason. And second, if you scan down, you'll see the error message: "invalid credentials".
Tip
You can also see the failed page by using Then show last response
:
... lines 1 - 5 | |
Scenario: Logging in | |
... lines 7 - 10 | |
And I press "Login" | |
Then show last response | |
... lines 13 - 14 |
You'll just need to configure the show_cmd
in behat.yml
. On OSX, I use show %s
,
but using firefox %s
is common on other systems:
default: | |
... lines 2 - 12 | |
extensions: | |
Behat\MinkExtension: | |
... lines 15 - 17 | |
show_cmd: 'open %s' |
You can even set the show_auto
setting to true
to automatically open a browser
on failures.
Let's remove our debug line and update this to the correct password which is "admin". And now let's rerun it:
./vendor/bin/behat features/web/authentication.feature
It's alive!
But we have a big problem: We're assuming that there will always be an admin
user in the database with password admin
. What if there isn't? What if the intern
deleted that or your dropped your database locally? Ah! Everything would start failing.
We can do better.
Hey Soltan!
I typically recommend to find things by CSS element instead of xpath... because xpath is hard :). But, you CAN find via xpath with:
$element = $this->getPage()->find('xpath', 'THEXPATH');
You can also use findAll() in the same way. See: http://mink.behat.org/en/latest/guides/traversing-pages.html#xpath-selector
Cheers!
// 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
}
}
Hi!
Which method can be used to find an element by xpath? How should be the sequence of script?
Thank you