MDL-38025 behat: Adding generic manipulation methods
Also required modifications in the affected steps definitions
This commit is contained in:
@@ -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) {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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());
|
||||
|
||||
Reference in New Issue
Block a user