Dev Blog

There are cases, there User Interface state might depend on various factors. Or in our tests there might be case where button can be toggled or might get activated by remote action.

The first solution one might think of is to conditionally invoke action on element. Depending whether it is visible or not.

Using Facebook WebDriver to find element

Testing with $I->seeElement would result in test fail, not what we want. It turned out that RemoteWebDriver class is capable of finding element, however it will throw exception anyway if element is not found. The RemoteWebDriver method findElement takes as an argument WebDriverBy instance and returns RemoteWebElement if element is found. The  WebDriverBy class has static factory methods which will find element by selector, id, xpath etc.

Adding haveVisible method

The best way to implement visibility checking feature is to add it to AcceptanceTester class in tests/_support folder. For the sake of simplicity we will use finding by selector only, with WebDriverBy::cssSelector function.

The resulting code might be implemented as following:

  <?php
class AcceptanceTester extends Actor
{

use AcceptanceTesterActions; public function haveVisible($element) { $I = $this; $value = false; $I->executeInSelenium(function(RemoteWebDriver $webDriver)use($element, &$value) { try { $element = $webDriver->findElement(WebDriverBy::cssSelector($element)); $value = $element instanceof RemoteWebElement; } catch (Exception $e) { // Swallow exception silently } }); return $value; } }

Using in tests

The haveVisible method return boolean value, so should be used to conditionally call something:

  <?php
use AcceptanceTester;

class MyCest
{
public function tryToCreateNewPage(AcceptanceTester $I)
{
if(!$I->haveVisible('#editor'); { $I->click('Enable Editing');
$I->see('Edit Mode Enabled'); }
$I->click('Save'); // More commands...
}
}