Shweta Sharma
Shweta Sharma

Reputation: 161

How to assert page/tab/window title in Behat + Mink

I need to assert a page title for my test, which is the tab/window title using Behat+Mink
I tried getWindowName() but realized that is not the function I am looking for.

Upvotes: 1

Views: 1407

Answers (4)

phpwebdev
phpwebdev

Reputation: 103

I can confirm that the following line will work in most versions of behat and mink.

$actTitle = $this->getSession()->getPage()->find('css','head title')->getText();

However, if you're using @javascript then you will need the following line. This is what we had to do after upgrading the entire testing suite to the newest versions.

$title = $this->getSession()->evaluateScript("return document.title");```

Upvotes: 0

miiimooo
miiimooo

Reputation: 131

This didn't work for me in cases where the title is manipulated using Javascript and history.pushState/replaceState

Here an implementation that works for Javascript:

  /**
   * @Then /^the title is "([^"]*)"$/
   */
  public function theTitleIs($arg1) {
    $title = $this->getSession()->evaluateScript("return document.title");
    if ($arg1 !== $title) {
      throw new \Exception("expected title '$arg1', got '$title'");
    }
  }

Upvotes: 1

lauda
lauda

Reputation: 4173

You should use a regular find by css for the title tag and use getText() to get the title.

The css should be: "head title"

Your solution is almost ok, you need to watch for possible exception, especially fatal ones that can stop your suite if encountered.

For example find() method will return an object or null, if null is returned and you are using getText() on it it will result in a fatal exception and your suite will stop.

Slightly improved method:

/**
 * @Given /^the page title should be "([^"]*)"$/
 */
public function thePageTitleShouldBe($expectedTitle)
{
    $titleElement = $this->getSession()->getPage()->find('css', 'head title');
    if ($titleElement === null) {
        throw new Exception('Page title element was not found!');
    } else {
        $title = $titleElement->getText();
        if ($expectedTitle !== $title) {
            throw new Exception("Incorrect title! Expected:$expectedTitle | Actual:$title ");
        }
    }
}

Improvements:

  • handled possible fatal exception
  • throw exception if element not found
  • throw exception with details if titles do not match

Note that you can also use other methods to check the title like: stripos, strpos or simply compare strings like i did. I prefer a simple compare if i need exact text or strpos/stripos method of php and I personally, avoid regular exceptions and associated methods like preg_match which are usually a bit slower.

One major improvement you could do is to have a method for waiting the element and handle the exception for you and use that instead of simple find, find you can use when you need to take decision based on the presence of the element like: if element exists do this else..

Upvotes: 4

Shweta Sharma
Shweta Sharma

Reputation: 161

Thanks Lauda. Yes, that indeed worked. Wrote the function below:

/**
     * @Given /^the page title should be "([^"]*)"$/
     */
    public function thePageTitleShouldBe($arg1)
    {
        $actTitle = $this->getSession()->getPage()->find('css','head title')->getText();
        if (!preg_match($arg1, $actTitle)) {
            throw new Exception ('Incorrect title');
        }
    }

Upvotes: 0

Related Questions