MDL-38025 behat: Adding generic manipulation methods

Also required modifications in the affected
steps definitions
This commit is contained in:
David Monllao
2013-03-01 16:06:15 +08:00
parent 5f470b28bf
commit 4092397794
4 changed files with 153 additions and 33 deletions
+2
View File
@@ -86,6 +86,8 @@ class tool_behat_renderer extends plugin_renderer_base {
$stepsdefinitions = get_string('nostepsdefinitions', 'tool_behat');
} else {
$stepsdefinitions = implode('', $stepsdefinitions);
// Replace text selector type arguments with a user-friendly select.
$stepsdefinitions = preg_replace_callback('/(TEXT_SELECTOR_STRING)/',
function ($matches) {
+54 -2
View File
@@ -59,7 +59,7 @@ class behat_base extends Behat\MinkExtension\Context\RawMinkContext {
* @param string $path
* @return string
*/
protected function locatePath($path) {
protected function locate_path($path) {
$startUrl = rtrim($this->getMinkParameter('base_url'), '/') . '/';
return 0 !== strpos($path, 'http') ? $startUrl . ltrim($path, '/') : $path;
}
@@ -68,9 +68,9 @@ class behat_base extends Behat\MinkExtension\Context\RawMinkContext {
* Adapter to Behat\Mink\Element\Element::find() using the spin() method.
*
* @link http://mink.behat.org/#traverse-the-page-selectors
* @param Exception $exception Otherwise we throw expcetion with generic info
* @param string $selector The selector type (css, xpath, named...)
* @param mixed $locator It depends on the $selector, can be the xpath, a name, a css locator...
* @param Exception $exception Otherwise we throw exception with generic info
* @return NodeElement
*/
protected function find($selector, $locator, $exception = false) {
@@ -216,4 +216,56 @@ class behat_base extends Behat\MinkExtension\Context\RawMinkContext {
throw $exception;
}
/**
* Gets a NodeElement based on the locator and selector type received as argument from steps definitions.
*
* @throws ElementNotFoundException Thrown by behat_base::find
* @param string $selectortype
* @param string $element
* @return NodeElement
*/
protected function get_selected_node($selectortype, $element) {
// Getting Mink selector and locator.
list($selector, $locator) = $this->transform_selector($selectortype, $element);
// Returns the NodeElement.
return $this->find($selector, $locator);
}
/**
* Transforms from step definition's argument style to Mink format.
*
* Mink has 3 different selectors css, xpath and named, where named
* selectors includes link, button, field... to simplify and group multiple
* steps in one we use the same interface, considering all link, buttons...
* at the same level as css selectors and xpath; this method makes the
* conversion from the arguments received by the steps to the selectors and locators
* required to interact with Mink.
*
* @throws ExpectationException
* @param string $selectortype It can be css, xpath or any of the named selectors.
* @param string $element The locator (or string) we are looking for.
* @return array Contains the selector and the locator expected by Mink.
*/
protected function transform_selector($selectortype, $element) {
// Here we don't know if a $allowedtextselector is used.
if (!isset(behat_command::$allowedselectors[$selectortype])) {
throw new ExpectationException('The "' . $selectortype . '" selector type does not exist', $this->getSession());
}
// CSS and XPath selectors locator is one single argument.
if ($selectortype == 'css_element' || $selectortype == 'xpath_element') {
$selector = str_replace('_element', '', $selectortype);
$locator = $element;
} else {
// Named selectors uses arrays as locators including the type of named selector.
$locator = array($selectortype, $this->getSession()->getSelectorsHandler()->xpathLiteral($element));
$selector = 'named';
}
return array($selector, $locator);
}
}
+28
View File
@@ -42,6 +42,34 @@ class behat_command {
*/
const DOCS_URL = 'http://docs.moodle.org/dev/Acceptance_testing';
/**
* @var Allowed types when using text selectors arguments.
*/
public static $allowedtextselectors = array(
'css_element' => 'css_element',
'xpath_element' => 'xpath_element'
);
/**
* @var Allowed types when using selector arguments.
*/
public static $allowedselectors = array(
'link' => 'link',
'button' => 'button',
'link_or_button' => 'link_or_button',
'select' => 'select',
'checkbox' => 'checkbox',
'radio' => 'radio',
'file' => 'file',
'optgroup' => 'optgroup',
'option' => 'option',
'table' => 'table',
'field' => 'field',
'fieldset' => 'fieldset',
'css_element' => 'css_element',
'xpath_element' => 'xpath_element'
);
/**
* Ensures the behat dir exists in moodledata
* @return string Full path
+69 -31
View File
@@ -50,7 +50,7 @@ class behat_general extends behat_base {
* @Given /^I am on homepage$/
*/
public function i_am_on_homepage() {
$this->getSession()->visit($this->locatePath('/'));
$this->getSession()->visit($this->locate_path('/'));
}
/**
@@ -58,6 +58,7 @@ class behat_general extends behat_base {
*
* @When /^I follow "(?P<link_string>(?:[^"]|\\")*)"$/
* @throws ElementNotFoundException Thrown by behat_base::find
* @param string $link
*/
public function click_link($link) {
@@ -85,27 +86,39 @@ class behat_general extends behat_base {
}
/**
* Mouse over a CSS element.
* Generic mouse over action. Mouse over a element of the specified type.
*
* @When /^I hover "(?P<element_string>(?:[^"]|\\")*)"$/
* @throws ExpectationException Thrown by behat_base::find
* @param string $element
* @When /^I hover "(?P<element_string>(?:[^"]|\\")*)" "(?P<selector_string>[^"]*)"$/
* @param string $element Element we look for
* @param string $selectortype The type of what we look for
*/
public function i_hover($element) {
public function i_hover($element, $selectortype) {
$exception = new ExpectationException(
'The hovered element "' . $element . '" was not found anywhere in the page', $this->getSession()
);
$node = $this->find('css', $element, $exception);
// Gets the node based on the requested selector type and locator.
$node = $this->get_selected_node($selectortype, $element);
$node->mouseOver();
}
/**
* Generic click action. Click on the element of the specified type.
*
* @When /^I click on "(?P<element_string>(?:[^"]|\\")*)" "(?P<selector_string>[^"]*)"$/
* @param string $element Element we look for
* @param string $selectortype The type of what we look for
*/
public function i_click_on($element, $selectortype) {
// Gets the node based on the requested selector type and locator.
$node = $this->get_selected_node($selectortype, $element);
$node->click();
}
/**
* Checks, that page contains specified text.
*
* @see Behat\MinkExtension\Context\MinkContext
* @Then /^I should see "(?P<text_string>(?:[^"]|\\")*)"$/
* @param string $text
*/
public function assert_page_contains_text($text) {
$this->assertSession()->pageTextContains($text);
@@ -116,40 +129,64 @@ class behat_general extends behat_base {
*
* @see Behat\MinkExtension\Context\MinkContext
* @Then /^I should not see "(?P<text_string>(?:[^"]|\\")*)"$/
* @param string $text
*/
public function assert_page_not_contains_text($text) {
$this->assertSession()->pageTextNotContains($text);
}
/**
* Checks, that element with specified CSS contains specified text.
* Checks, that element with specified CSS selector or XPath contains specified text.
*
* @Then /^I should see "(?P<text_string>(?:[^"]|\\")*)" in the "(?P<element_string>(?:[^"]|\\")*)" element$/
* @Then /^I should see "(?P<text_string>(?:[^"]|\\")*)" in the "(?P<element_string>(?:[^"]|\\")*)" "(?P<text_selector_string>[^"]*)"$/
* @param string $text
* @param string $element Element we look in.
* @param string $selectortype The type of element where we are looking in.
*/
public function assert_element_contains_text($text, $element) {
$this->assertSession()->elementTextContains('css', $element, $text);
public function assert_element_contains_text($text, $element, $selectortype) {
// Transforming from steps definitions selector/locator format to Mink format.
list($selector, $locator) = $this->transform_selector($selectortype, $element);
if ($selector != 'css' && $selector != 'xpath') {
throw new ExpectationException('The "' . $selectortype . '" selector can not be used to select text nodes', $this->getSession());
}
$this->assertSession()->elementTextContains($selector, $locator, $text);
}
/**
* Checks, that element with specified CSS doesn't contain specified text.
* Checks, that element with specified CSS selector or XPath doesn't contain specified text.
*
* @Then /^I should not see "(?P<text_string>(?:[^"]|\\")*)" in the "(?P<element_string>(?:[^"]|\\")*)" element$/
* @Then /^I should not see "(?P<text_string>(?:[^"]|\\")*)" in the "(?P<element_string>(?:[^"]|\\")*)" "(?P<text_selector_string>[^"]*)"$/
* @param string $text
* @param string $element Element we look in.
* @param string $selectortype The type of element where we are looking in.
*/
public function assert_element_not_contains_text($text, $element) {
$this->assertSession()->elementTextNotContains('css', $element, $text);
public function assert_element_not_contains_text($text, $element, $selectortype) {
// Transforming from steps definitions selector/locator format to mink format.
list($selector, $locator) = $this->transform_selector($selectortype, $element);
if ($selector != 'css' && $selector != 'xpath') {
throw new ExpectationException('The "' . $selectortype . '" selector can not be used to select text nodes', $this->getSession());
}
$this->assertSession()->elementTextNotContains($selector, $locator, $text);
}
/**
* Checks, that element with given CSS is disabled.
* Checks, that element of specified type is disabled.
*
* @Then /^the element "(?P<element_string>(?:[^"]|\\")*)" should be disabled$/
* @Then /^the "(?P<element_string>(?:[^"]|\\")*)" "(?P<selector_string>[^"]*)" should be disabled$/
* @throws ExpectationException Thrown by behat_base::find
* @param string $element
* @param string $element Element we look in
* @param string $selectortype The type of element where we are looking in.
*/
public function the_element_should_be_disabled($element) {
public function the_element_should_be_disabled($element, $selectortype) {
$exception = new ExpectationException('There is no "' . $element . '" element', $this->getSession());
$node = $this->find('css', $element, $exception);
// Transforming from steps definitions selector/locator format to Mink format and getting the NodeElement.
$node = $this->get_selected_node($selectortype, $element);
if (!$node->hasAttribute('disabled')) {
throw new ExpectationException('The element "' . $element . '" is not disabled', $this->getSession());
@@ -157,16 +194,17 @@ class behat_general extends behat_base {
}
/**
* Checks, that element with given CSS is enabled.
* Checks, that element of specified type is enabled.
*
* @Then /^the element "(?P<element_string>(?:[^"]|\\")*)" should be enabled$/
* @Then /^the "(?P<element_string>(?:[^"]|\\")*)" "(?P<selector_string>[^"]*)" should be enabled$/
* @throws ExpectationException Thrown by behat_base::find
* @param string $element
* @param string $element Element we look on
* @param string $selectortype The type of where we look
*/
public function the_element_should_be_enabled($element) {
public function the_element_should_be_enabled($element, $selectortype) {
$exception = new ExpectationException('There is no "' . $element . '" element', $this->getSession());
$node = $this->find('css', $element, $exception);
// Transforming from steps definitions selector/locator format to mink format and getting the NodeElement.
$node = $this->get_selected_node($selectortype, $element);
if ($node->hasAttribute('disabled')) {
throw new ExpectationException('The element "' . $element . '" is not enabled', $this->getSession());