Move into nested docroot
This commit is contained in:
parent
83a0d3a149
commit
c8b70abde9
13405 changed files with 0 additions and 0 deletions
369
web/core/tests/Drupal/FunctionalJavascriptTests/JSWebAssert.php
Normal file
369
web/core/tests/Drupal/FunctionalJavascriptTests/JSWebAssert.php
Normal file
|
|
@ -0,0 +1,369 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\FunctionalJavascriptTests;
|
||||
|
||||
use Behat\Mink\Element\NodeElement;
|
||||
use Behat\Mink\Exception\ElementHtmlException;
|
||||
use Behat\Mink\Exception\ElementNotFoundException;
|
||||
use Behat\Mink\Exception\UnsupportedDriverActionException;
|
||||
use Drupal\Tests\WebAssert;
|
||||
|
||||
/**
|
||||
* Defines a class with methods for asserting presence of elements during tests.
|
||||
*/
|
||||
class JSWebAssert extends WebAssert {
|
||||
|
||||
/**
|
||||
* Waits for AJAX request to be completed.
|
||||
*
|
||||
* @param int $timeout
|
||||
* (Optional) Timeout in milliseconds, defaults to 10000.
|
||||
* @param string $message
|
||||
* (optional) A message for exception.
|
||||
*
|
||||
* @throws \RuntimeException
|
||||
* When the request is not completed. If left blank, a default message will
|
||||
* be displayed.
|
||||
*/
|
||||
public function assertWaitOnAjaxRequest($timeout = 10000, $message = 'Unable to complete AJAX request.') {
|
||||
$condition = <<<JS
|
||||
(function() {
|
||||
function isAjaxing(instance) {
|
||||
return instance && instance.ajaxing === true;
|
||||
}
|
||||
return (
|
||||
// Assert no AJAX request is running (via jQuery or Drupal) and no
|
||||
// animation is running.
|
||||
(typeof jQuery === 'undefined' || (jQuery.active === 0 && jQuery(':animated').length === 0)) &&
|
||||
(typeof Drupal === 'undefined' || typeof Drupal.ajax === 'undefined' || !Drupal.ajax.instances.some(isAjaxing))
|
||||
);
|
||||
}());
|
||||
JS;
|
||||
$result = $this->session->wait($timeout, $condition);
|
||||
if (!$result) {
|
||||
throw new \RuntimeException($message);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Waits for the specified selector and returns it when available.
|
||||
*
|
||||
* @param string $selector
|
||||
* The selector engine name. See ElementInterface::findAll() for the
|
||||
* supported selectors.
|
||||
* @param string|array $locator
|
||||
* The selector locator.
|
||||
* @param int $timeout
|
||||
* (Optional) Timeout in milliseconds, defaults to 10000.
|
||||
*
|
||||
* @return \Behat\Mink\Element\NodeElement|null
|
||||
* The page element node if found, NULL if not.
|
||||
*
|
||||
* @see \Behat\Mink\Element\ElementInterface::findAll()
|
||||
*/
|
||||
public function waitForElement($selector, $locator, $timeout = 10000) {
|
||||
$page = $this->session->getPage();
|
||||
|
||||
$result = $page->waitFor($timeout / 1000, function() use ($page, $selector, $locator) {
|
||||
return $page->find($selector, $locator);
|
||||
});
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Waits for the specified selector and returns it when available and visible.
|
||||
*
|
||||
* @param string $selector
|
||||
* The selector engine name. See ElementInterface::findAll() for the
|
||||
* supported selectors.
|
||||
* @param string|array $locator
|
||||
* The selector locator.
|
||||
* @param int $timeout
|
||||
* (Optional) Timeout in milliseconds, defaults to 10000.
|
||||
*
|
||||
* @return \Behat\Mink\Element\NodeElement|null
|
||||
* The page element node if found and visible, NULL if not.
|
||||
*
|
||||
* @see \Behat\Mink\Element\ElementInterface::findAll()
|
||||
*/
|
||||
public function waitForElementVisible($selector, $locator, $timeout = 10000) {
|
||||
$page = $this->session->getPage();
|
||||
|
||||
$result = $page->waitFor($timeout / 1000, function() use ($page, $selector, $locator) {
|
||||
$element = $page->find($selector, $locator);
|
||||
if (!empty($element) && $element->isVisible()) {
|
||||
return $element;
|
||||
}
|
||||
return NULL;
|
||||
});
|
||||
|
||||
return $result;
|
||||
}
|
||||
/**
|
||||
* Waits for a button (input[type=submit|image|button|reset], button) with
|
||||
* specified locator and returns it.
|
||||
*
|
||||
* @param string $locator
|
||||
* The button ID, value or alt string.
|
||||
* @param int $timeout
|
||||
* (Optional) Timeout in milliseconds, defaults to 10000.
|
||||
*
|
||||
* @return \Behat\Mink\Element\NodeElement|null
|
||||
* The page element node if found, NULL if not.
|
||||
*/
|
||||
public function waitForButton($locator, $timeout = 10000) {
|
||||
return $this->waitForElement('named', array('button', $locator), $timeout);
|
||||
}
|
||||
|
||||
/**
|
||||
* Waits for a link with specified locator and returns it when available.
|
||||
*
|
||||
* @param string $locator
|
||||
* The link ID, title, text or image alt.
|
||||
* @param int $timeout
|
||||
* (Optional) Timeout in milliseconds, defaults to 10000.
|
||||
*
|
||||
* @return \Behat\Mink\Element\NodeElement|null
|
||||
* The page element node if found, NULL if not.
|
||||
*/
|
||||
public function waitForLink($locator, $timeout = 10000) {
|
||||
return $this->waitForElement('named', array('link', $locator), $timeout);
|
||||
}
|
||||
|
||||
/**
|
||||
* Waits for a field with specified locator and returns it when available.
|
||||
*
|
||||
* @param string $locator
|
||||
* The input ID, name or label for the field (input, textarea, select).
|
||||
* @param int $timeout
|
||||
* (Optional) Timeout in milliseconds, defaults to 10000.
|
||||
*
|
||||
* @return \Behat\Mink\Element\NodeElement|null
|
||||
* The page element node if found, NULL if not.
|
||||
*/
|
||||
public function waitForField($locator, $timeout = 10000) {
|
||||
return $this->waitForElement('named', array('field', $locator), $timeout);
|
||||
}
|
||||
|
||||
/**
|
||||
* Waits for an element by its id and returns it when available.
|
||||
*
|
||||
* @param string $id
|
||||
* The element ID.
|
||||
* @param int $timeout
|
||||
* (Optional) Timeout in milliseconds, defaults to 10000.
|
||||
*
|
||||
* @return \Behat\Mink\Element\NodeElement|null
|
||||
* The page element node if found, NULL if not.
|
||||
*/
|
||||
public function waitForId($id, $timeout = 10000) {
|
||||
return $this->waitForElement('named', array('id', $id), $timeout);
|
||||
}
|
||||
|
||||
/**
|
||||
* Waits for the jQuery autocomplete delay duration.
|
||||
*
|
||||
* @see https://api.jqueryui.com/autocomplete/#option-delay
|
||||
*/
|
||||
public function waitOnAutocomplete() {
|
||||
// Wait for the autocomplete to be visible.
|
||||
return $this->waitForElementVisible('css', '.ui-autocomplete li');
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that a node, or it's specific corner, is visible in the viewport.
|
||||
*
|
||||
* Note: Always set the viewport size. This can be done with a PhantomJS
|
||||
* startup parameter or in your test with \Behat\Mink\Session->resizeWindow().
|
||||
* Drupal CI Javascript tests by default use a viewport of 1024x768px.
|
||||
*
|
||||
* @param string $selector_type
|
||||
* The element selector type (CSS, XPath).
|
||||
* @param string|array $selector
|
||||
* The element selector. Note: the first found element is used.
|
||||
* @param bool|string $corner
|
||||
* (Optional) The corner to test:
|
||||
* topLeft, topRight, bottomRight, bottomLeft.
|
||||
* Or FALSE to check the complete element (default).
|
||||
* @param string $message
|
||||
* (optional) A message for the exception.
|
||||
*
|
||||
* @throws \Behat\Mink\Exception\ElementHtmlException
|
||||
* When the element doesn't exist.
|
||||
* @throws \Behat\Mink\Exception\ElementNotFoundException
|
||||
* When the element is not visible in the viewport.
|
||||
*/
|
||||
public function assertVisibleInViewport($selector_type, $selector, $corner = FALSE, $message = 'Element is not visible in the viewport.') {
|
||||
$node = $this->session->getPage()->find($selector_type, $selector);
|
||||
if ($node === NULL) {
|
||||
if (is_array($selector)) {
|
||||
$selector = implode(' ', $selector);
|
||||
}
|
||||
throw new ElementNotFoundException($this->session->getDriver(), 'element', $selector_type, $selector);
|
||||
}
|
||||
|
||||
// Check if the node is visible on the page, which is a prerequisite of
|
||||
// being visible in the viewport.
|
||||
if (!$node->isVisible()) {
|
||||
throw new ElementHtmlException($message, $this->session->getDriver(), $node);
|
||||
}
|
||||
|
||||
$result = $this->checkNodeVisibilityInViewport($node, $corner);
|
||||
|
||||
if (!$result) {
|
||||
throw new ElementHtmlException($message, $this->session->getDriver(), $node);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that a node, or its specific corner, is not visible in the viewport.
|
||||
*
|
||||
* Note: the node should exist in the page, otherwise this assertion fails.
|
||||
*
|
||||
* @param string $selector_type
|
||||
* The element selector type (CSS, XPath).
|
||||
* @param string|array $selector
|
||||
* The element selector. Note: the first found element is used.
|
||||
* @param bool|string $corner
|
||||
* (Optional) Corner to test: topLeft, topRight, bottomRight, bottomLeft.
|
||||
* Or FALSE to check the complete element (default).
|
||||
* @param string $message
|
||||
* (optional) A message for the exception.
|
||||
*
|
||||
* @throws \Behat\Mink\Exception\ElementHtmlException
|
||||
* When the element doesn't exist.
|
||||
* @throws \Behat\Mink\Exception\ElementNotFoundException
|
||||
* When the element is not visible in the viewport.
|
||||
*
|
||||
* @see \Drupal\FunctionalJavascriptTests\JSWebAssert::assertVisibleInViewport()
|
||||
*/
|
||||
public function assertNotVisibleInViewport($selector_type, $selector, $corner = FALSE, $message = 'Element is visible in the viewport.') {
|
||||
$node = $this->session->getPage()->find($selector_type, $selector);
|
||||
if ($node === NULL) {
|
||||
if (is_array($selector)) {
|
||||
$selector = implode(' ', $selector);
|
||||
}
|
||||
throw new ElementNotFoundException($this->session->getDriver(), 'element', $selector_type, $selector);
|
||||
}
|
||||
|
||||
$result = $this->checkNodeVisibilityInViewport($node, $corner);
|
||||
|
||||
if ($result) {
|
||||
throw new ElementHtmlException($message, $this->session->getDriver(), $node);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check the visibility of a node, or it's specific corner.
|
||||
*
|
||||
* @param \Behat\Mink\Element\NodeElement $node
|
||||
* A valid node.
|
||||
* @param bool|string $corner
|
||||
* (Optional) Corner to test: topLeft, topRight, bottomRight, bottomLeft.
|
||||
* Or FALSE to check the complete element (default).
|
||||
*
|
||||
* @return bool
|
||||
* Returns TRUE if the node is visible in the viewport, FALSE otherwise.
|
||||
*
|
||||
* @throws \Behat\Mink\Exception\UnsupportedDriverActionException
|
||||
* When an invalid corner specification is given.
|
||||
*/
|
||||
private function checkNodeVisibilityInViewport(NodeElement $node, $corner = FALSE) {
|
||||
$xpath = $node->getXpath();
|
||||
|
||||
// Build the Javascript to test if the complete element or a specific corner
|
||||
// is in the viewport.
|
||||
switch ($corner) {
|
||||
case 'topLeft':
|
||||
$test_javascript_function = <<<JS
|
||||
function t(r, lx, ly) {
|
||||
return (
|
||||
r.top >= 0 &&
|
||||
r.top <= ly &&
|
||||
r.left >= 0 &&
|
||||
r.left <= lx
|
||||
)
|
||||
}
|
||||
JS;
|
||||
break;
|
||||
|
||||
case 'topRight':
|
||||
$test_javascript_function = <<<JS
|
||||
function t(r, lx, ly) {
|
||||
return (
|
||||
r.top >= 0 &&
|
||||
r.top <= ly &&
|
||||
r.right >= 0 &&
|
||||
r.right <= lx
|
||||
);
|
||||
}
|
||||
JS;
|
||||
break;
|
||||
|
||||
case 'bottomRight':
|
||||
$test_javascript_function = <<<JS
|
||||
function t(r, lx, ly) {
|
||||
return (
|
||||
r.bottom >= 0 &&
|
||||
r.bottom <= ly &&
|
||||
r.right >= 0 &&
|
||||
r.right <= lx
|
||||
);
|
||||
}
|
||||
JS;
|
||||
break;
|
||||
|
||||
case 'bottomLeft':
|
||||
$test_javascript_function = <<<JS
|
||||
function t(r, lx, ly) {
|
||||
return (
|
||||
r.bottom >= 0 &&
|
||||
r.bottom <= ly &&
|
||||
r.left >= 0 &&
|
||||
r.left <= lx
|
||||
);
|
||||
}
|
||||
JS;
|
||||
break;
|
||||
|
||||
case FALSE:
|
||||
$test_javascript_function = <<<JS
|
||||
function t(r, lx, ly) {
|
||||
return (
|
||||
r.top >= 0 &&
|
||||
r.left >= 0 &&
|
||||
r.bottom <= ly &&
|
||||
r.right <= lx
|
||||
);
|
||||
}
|
||||
JS;
|
||||
break;
|
||||
|
||||
// Throw an exception if an invalid corner parameter is given.
|
||||
default:
|
||||
throw new UnsupportedDriverActionException($corner, $this->session->getDriver());
|
||||
}
|
||||
|
||||
// Build the full Javascript test. The shared logic gets the corner
|
||||
// specific test logic injected.
|
||||
$full_javascript_visibility_test = <<<JS
|
||||
(function(t){
|
||||
var w = window,
|
||||
d = document,
|
||||
e = d.documentElement,
|
||||
n = d.evaluate("$xpath", d, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue,
|
||||
r = n.getBoundingClientRect(),
|
||||
lx = (w.innerWidth || e.clientWidth),
|
||||
ly = (w.innerHeight || e.clientHeight);
|
||||
|
||||
return t(r, lx, ly);
|
||||
}($test_javascript_function));
|
||||
JS;
|
||||
|
||||
// Check the visibility by injecting and executing the full Javascript test
|
||||
// script in the page.
|
||||
return $this->session->evaluateScript($full_javascript_visibility_test);
|
||||
}
|
||||
|
||||
}
|
||||
Reference in a new issue