PHP-WebDriver and By

The folks at Mozilla came up with a really elegant way of encapsulating their locators in Python which makes use varargs syntax to unpack (not the right word, I know) the tuple at runtime into the two arguments that find_element wants.

locators = {
   "username": (By.ID, "username"),
   "errors": (By.CSS_SELECTOR, ".errors")
}

username = driver.find_element(*locators[username])

With the PHP-WebDriver binding I maintain I have been struggling to find a syntax as nice as that. (Yes, it is PHP, so good luck!) By default this is the syntax for finding the username element shown above.

$username = $this->session->element("id", "username");

Which isn’t too horrible, but starts to get yucky once page objects get introduced and your locators are collected up in arrays.

private $locators = array(
  "username" => array("id", "username"),
  "errors" => array("css selector", ".errors")
);

$username = $this->session->element($locators["username"][0], $locators["username"][0]);

Not horrible I suppose, but still a ways to go. Unfortunately PHP does not have something varargs-like. The closest thing I can find is the list function.

list($type, $value) = $locators["username"];
$username = $this->session->element($type, $value);

This is two lines, but is starting to look a little nicer. But even still, that you have to type in the type by hand as a magic string introduces all sorts of possibilities for pain when it comes to fat fingers. Because of this I have lifted the concept of a By class like the other drivers have so that rather than having a raw string you have a constant — that will fail at compile time rather than at runtime.

What is exposed by it is exactly as the other drivers.

  • ID
  • XPATH
  • LINK_TEXT
  • PARTIAL_LINK_TEXT
  • NAME
  • TAG_NAME
  • CLASS_NAME
  • CSS_SELECTOR

Here again is the username snippet with all the moving parts.

require_once('PHPWebDriver/WebDriverBy.php');

private $locators = array(
  "username" => array(PHPWebDriver_WebDriverBy::ID, "username"),
  "errors" => array(PHPWebDriver_WebDriverBy::CSS_SELECTOR, ".errors")
);

list($type, $value) = $locators["username"];
$username = $this->session->element($type, $value);

Oh, and for this to work you need to have at least PHP-WebDriver 1.1.0 (which I released yesterday).

Post a Comment

Your email is never published nor shared. Required fields are marked *