mirror of
https://github.com/moodle/moodle.git
synced 2025-04-27 11:23:06 +02:00
Merge branch 'MDL-43837_master' of git://github.com/dmonllao/moodle
This commit is contained in:
commit
237243db02
@ -52,6 +52,15 @@ use Behat\Mink\Exception\ExpectationException as ExpectationException,
|
||||
*/
|
||||
class behat_base extends Behat\MinkExtension\Context\RawMinkContext {
|
||||
|
||||
/**
|
||||
* Small timeout.
|
||||
*
|
||||
* A reduced timeout for cases where self::TIMEOUT is too much
|
||||
* and a simple $this->getSession()->getPage()->find() could not
|
||||
* be enough.
|
||||
*/
|
||||
const REDUCED_TIMEOUT = 2;
|
||||
|
||||
/**
|
||||
* The timeout for each Behat step (load page, wait for an element to load...).
|
||||
*/
|
||||
@ -88,12 +97,13 @@ class behat_base extends Behat\MinkExtension\Context\RawMinkContext {
|
||||
* @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
|
||||
* @param NodeElement $node Spins around certain DOM node instead of the whole page
|
||||
* @param int $timeout Forces a specific time out (in seconds).
|
||||
* @return NodeElement
|
||||
*/
|
||||
protected function find($selector, $locator, $exception = false, $node = false) {
|
||||
protected function find($selector, $locator, $exception = false, $node = false, $timeout = false) {
|
||||
|
||||
// Returns the first match.
|
||||
$items = $this->find_all($selector, $locator, $exception, $node);
|
||||
$items = $this->find_all($selector, $locator, $exception, $node, $timeout);
|
||||
return count($items) ? reset($items) : null;
|
||||
}
|
||||
|
||||
@ -107,9 +117,10 @@ class behat_base extends Behat\MinkExtension\Context\RawMinkContext {
|
||||
* @param mixed $locator It depends on the $selector, can be the xpath, a name, a css locator...
|
||||
* @param Exception $exception Otherwise we throw expcetion with generic info
|
||||
* @param NodeElement $node Spins around certain DOM node instead of the whole page
|
||||
* @param int $timeout Forces a specific time out (in seconds). If 0 is provided the default timeout will be applied.
|
||||
* @return array NodeElements list
|
||||
*/
|
||||
protected function find_all($selector, $locator, $exception = false, $node = false) {
|
||||
protected function find_all($selector, $locator, $exception = false, $node = false, $timeout = false) {
|
||||
|
||||
// Generic info.
|
||||
if (!$exception) {
|
||||
@ -138,6 +149,17 @@ class behat_base extends Behat\MinkExtension\Context\RawMinkContext {
|
||||
$params['node'] = $node;
|
||||
}
|
||||
|
||||
// How much we will be waiting for the element to appear.
|
||||
if (!$timeout) {
|
||||
$timeout = self::TIMEOUT;
|
||||
$microsleep = false;
|
||||
} else {
|
||||
// Spinning each 0.1 seconds if the timeout was forced as we understand
|
||||
// that is a special case and is good to refine the performance as much
|
||||
// as possible.
|
||||
$microsleep = true;
|
||||
}
|
||||
|
||||
// Waits for the node to appear if it exists, otherwise will timeout and throw the provided exception.
|
||||
return $this->spin(
|
||||
function($context, $args) {
|
||||
@ -170,8 +192,9 @@ class behat_base extends Behat\MinkExtension\Context\RawMinkContext {
|
||||
return $context->getSession()->getDriver()->find(implode('|', $unions));
|
||||
},
|
||||
$params,
|
||||
self::TIMEOUT,
|
||||
$exception
|
||||
$timeout,
|
||||
$exception,
|
||||
$microsleep
|
||||
);
|
||||
}
|
||||
|
||||
@ -569,7 +592,7 @@ class behat_base extends Behat\MinkExtension\Context\RawMinkContext {
|
||||
|
||||
// If there are no editors we don't need to wait.
|
||||
try {
|
||||
$this->find('css', '.mceEditor');
|
||||
$this->find('css', '.mceEditor', false, false, self::REDUCED_TIMEOUT);
|
||||
} catch (ElementNotFoundException $e) {
|
||||
return;
|
||||
}
|
||||
|
@ -110,18 +110,20 @@ class behat_forms extends behat_base {
|
||||
// We ensure that all the editors are loaded and we can interact with them.
|
||||
$this->ensure_editors_are_loaded();
|
||||
|
||||
// behat_base::find() throws an exception if there are no elements, we should not fail a test because of this.
|
||||
// We already know that we waited for the DOM and the JS to be loaded, even the editor
|
||||
// so, we will use the reduced timeout as it is a common task and we should save time.
|
||||
try {
|
||||
|
||||
// Expand fieldsets link.
|
||||
$collapseexpandlink = $this->find('xpath', "//div[@class='collapsible-actions']" .
|
||||
$xpath = "//div[@class='collapsible-actions']" .
|
||||
"/descendant::a[contains(concat(' ', @class, ' '), ' collapseexpand ')]" .
|
||||
"[not(contains(concat(' ', @class, ' '), ' collapse-all '))]"
|
||||
);
|
||||
"[not(contains(concat(' ', @class, ' '), ' collapse-all '))]";
|
||||
$collapseexpandlink = $this->find('xpath', $xpath, false, false, self::REDUCED_TIMEOUT);
|
||||
$collapseexpandlink->click();
|
||||
|
||||
} catch (ElementNotFoundException $e) {
|
||||
// We continue if there are not expandable fields.
|
||||
// The behat_base::find() method throws an exception if there are no elements,
|
||||
// we should not fail a test because of this. We continue if there are not expandable fields.
|
||||
}
|
||||
|
||||
// Different try & catch as we can have expanded fieldsets with advanced fields on them.
|
||||
@ -132,7 +134,9 @@ class behat_forms extends behat_base {
|
||||
"[contains(concat(' ', normalize-space(@class), ' '), ' moreless-toggler')]";
|
||||
|
||||
// We don't wait here as we already waited when getting the expand fieldsets links.
|
||||
$showmores = $this->getSession()->getPage()->findAll('xpath', $showmorexpath);
|
||||
if (!$showmores = $this->getSession()->getPage()->findAll('xpath', $showmorexpath)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Funny thing about this, with findAll() we specify a pattern and each element matching the pattern is added to the array
|
||||
// with of xpaths with a [0], [1]... sufix, but when we click on an element it does not matches the specified xpath
|
||||
|
@ -346,10 +346,12 @@ class behat_general extends behat_base {
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks, that the specified element is not visible. Only available in tests using Javascript.
|
||||
* Checks, that the existing element is not visible. Only available in tests using Javascript.
|
||||
*
|
||||
* As a "not" method, it's performance is not specially good as we should ensure that the element
|
||||
* have time to appear.
|
||||
* As a "not" method, it's performance could not be good, but in this
|
||||
* case the performance is good because the element must exist,
|
||||
* otherwise there would be a ElementNotFoundException, also here we are
|
||||
* not spinning until the element is visible.
|
||||
*
|
||||
* @Then /^"(?P<element_string>(?:[^"]|\\")*)" "(?P<selector_string>(?:[^"]|\\")*)" should not be visible$/
|
||||
* @throws ElementNotFoundException
|
||||
@ -396,7 +398,12 @@ class behat_general extends behat_base {
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks, that the specified element is not visible inside the specified container. Only available in tests using Javascript.
|
||||
* Checks, that the existing element is not visible inside the existing container. Only available in tests using Javascript.
|
||||
*
|
||||
* As a "not" method, it's performance could not be good, but in this
|
||||
* case the performance is good because the element must exist,
|
||||
* otherwise there would be a ElementNotFoundException, also here we are
|
||||
* not spinning until the element is visible.
|
||||
*
|
||||
* @Then /^"(?P<element_string>(?:[^"]|\\")*)" "(?P<selector_string>[^"]*)" in the "(?P<element_container_string>(?:[^"]|\\")*)" "(?P<text_selector_string>[^"]*)" should not be visible$/
|
||||
* @throws ElementNotFoundException
|
||||
@ -447,7 +454,8 @@ class behat_general extends behat_base {
|
||||
}
|
||||
|
||||
// We spin as we don't have enough checking that the element is there, we
|
||||
// should also ensure that the element is visible.
|
||||
// should also ensure that the element is visible. Using microsleep as this
|
||||
// is a repeated step and global performance is important.
|
||||
$this->spin(
|
||||
function($context, $args) {
|
||||
|
||||
@ -460,7 +468,10 @@ class behat_general extends behat_base {
|
||||
// If non of the nodes is visible we loop again.
|
||||
throw new ExpectationException('"' . $args['text'] . '" text was found but was not visible', $context->getSession());
|
||||
},
|
||||
array('nodes' => $nodes, 'text' => $text)
|
||||
array('nodes' => $nodes, 'text' => $text),
|
||||
false,
|
||||
false,
|
||||
true
|
||||
);
|
||||
|
||||
}
|
||||
@ -481,9 +492,10 @@ class behat_general extends behat_base {
|
||||
"[count(descendant::*[contains(., $xpathliteral)]) = 0]";
|
||||
|
||||
// We should wait a while to ensure that the page is not still loading elements.
|
||||
// Giving preference to the reliability of the results rather than to the performance.
|
||||
// Waiting less than self::TIMEOUT as we already waited for the DOM to be ready and
|
||||
// all JS to be executed.
|
||||
try {
|
||||
$nodes = $this->find_all('xpath', $xpath);
|
||||
$nodes = $this->find_all('xpath', $xpath, false, false, self::REDUCED_TIMEOUT);
|
||||
} catch (ElementNotFoundException $e) {
|
||||
// All ok.
|
||||
return;
|
||||
@ -508,7 +520,10 @@ class behat_general extends behat_base {
|
||||
// If non of the found nodes is visible we consider that the text is not visible.
|
||||
return true;
|
||||
},
|
||||
array('nodes' => $nodes, 'text' => $text)
|
||||
array('nodes' => $nodes, 'text' => $text),
|
||||
self::REDUCED_TIMEOUT,
|
||||
false,
|
||||
true
|
||||
);
|
||||
|
||||
}
|
||||
@ -547,7 +562,8 @@ class behat_general extends behat_base {
|
||||
return;
|
||||
}
|
||||
|
||||
// We also check the element visibility when running JS tests.
|
||||
// We also check the element visibility when running JS tests. Using microsleep as this
|
||||
// is a repeated step and global performance is important.
|
||||
$this->spin(
|
||||
function($context, $args) {
|
||||
|
||||
@ -559,7 +575,10 @@ class behat_general extends behat_base {
|
||||
|
||||
throw new ExpectationException('"' . $args['text'] . '" text was found in the "' . $args['element'] . '" element but was not visible', $context->getSession());
|
||||
},
|
||||
array('nodes' => $nodes, 'text' => $text, 'element' => $element)
|
||||
array('nodes' => $nodes, 'text' => $text, 'element' => $element),
|
||||
false,
|
||||
false,
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
@ -587,7 +606,7 @@ class behat_general extends behat_base {
|
||||
// We should wait a while to ensure that the page is not still loading elements.
|
||||
// Giving preference to the reliability of the results rather than to the performance.
|
||||
try {
|
||||
$nodes = $this->find_all('xpath', $xpath, false, $container);
|
||||
$nodes = $this->find_all('xpath', $xpath, false, $container, self::REDUCED_TIMEOUT);
|
||||
} catch (ElementNotFoundException $e) {
|
||||
// All ok.
|
||||
return;
|
||||
@ -612,7 +631,10 @@ class behat_general extends behat_base {
|
||||
// If all the found nodes are hidden we are happy.
|
||||
return true;
|
||||
},
|
||||
array('nodes' => $nodes, 'text' => $text, 'element' => $element)
|
||||
array('nodes' => $nodes, 'text' => $text, 'element' => $element),
|
||||
self::REDUCED_TIMEOUT,
|
||||
false,
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
@ -771,8 +793,28 @@ class behat_general extends behat_base {
|
||||
*/
|
||||
public function should_not_exists($element, $selectortype) {
|
||||
|
||||
// Getting Mink selector and locator.
|
||||
list($selector, $locator) = $this->transform_selector($selectortype, $element);
|
||||
|
||||
try {
|
||||
$this->should_exists($element, $selectortype);
|
||||
|
||||
// Using directly the spin method as we want a reduced timeout but there is no
|
||||
// need for a 0.1 seconds interval because in the optimistic case we will timeout.
|
||||
$params = array('selector' => $selector, 'locator' => $locator);
|
||||
// The exception does not really matter as we will catch it and will never "explode".
|
||||
$exception = new ElementNotFoundException($this->getSession(), $selectortype, null, $element);
|
||||
|
||||
// If all goes good it will throw an ElementNotFoundExceptionn that we will catch.
|
||||
$this->spin(
|
||||
function($context, $args) {
|
||||
return $context->getSession()->getPage()->findAll($args['selector'], $args['locator']);
|
||||
},
|
||||
$params,
|
||||
false,
|
||||
$exception,
|
||||
self::REDUCED_TIMEOUT
|
||||
);
|
||||
|
||||
throw new ExpectationException('The "' . $element . '" "' . $selectortype . '" exists in the current page', $this->getSession());
|
||||
} catch (ElementNotFoundException $e) {
|
||||
// It passes.
|
||||
@ -828,8 +870,20 @@ class behat_general extends behat_base {
|
||||
* @param string $containerselectortype The container locator
|
||||
*/
|
||||
public function should_not_exist_in_the($element, $selectortype, $containerelement, $containerselectortype) {
|
||||
|
||||
// Get the container node; here we throw an exception
|
||||
// if the container node does not exist.
|
||||
$containernode = $this->get_selected_node($containerselectortype, $containerelement);
|
||||
|
||||
list($selector, $locator) = $this->transform_selector($selectortype, $element);
|
||||
|
||||
// Will throw an ElementNotFoundException if it does not exist, but, actually
|
||||
// it should not exists, so we try & catch it.
|
||||
try {
|
||||
$this->should_exist_in_the($element, $selectortype, $containerelement, $containerselectortype);
|
||||
// Would be better to use a 1 second sleep because the element should not be there,
|
||||
// but we would need to duplicate the whole find_all() logic to do it, the benefit of
|
||||
// changing to 1 second sleep is not significant.
|
||||
$this->find($selector, $locator, false, $containernode, self::REDUCED_TIMEOUT);
|
||||
throw new ExpectationException('The "' . $element . '" "' . $selectortype . '" exists in the "' .
|
||||
$containerelement . '" "' . $containerselectortype . '"', $this->getSession());
|
||||
} catch (ElementNotFoundException $e) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user