| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369 | 
							- <?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', ['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', ['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', ['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', ['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 its 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 its 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);
 
-   }
 
- }
 
 
  |