JavascriptTestBase.php 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. <?php
  2. namespace Drupal\FunctionalJavascriptTests;
  3. use Drupal\Tests\BrowserTestBase;
  4. use Zumba\GastonJS\Exception\DeadClient;
  5. use Zumba\Mink\Driver\PhantomJSDriver;
  6. /**
  7. * Runs a browser test using PhantomJS.
  8. *
  9. * Base class for testing browser interaction implemented in JavaScript.
  10. */
  11. abstract class JavascriptTestBase extends BrowserTestBase {
  12. /**
  13. * {@inheritdoc}
  14. */
  15. protected $minkDefaultDriverClass = PhantomJSDriver::class;
  16. /**
  17. * {@inheritdoc}
  18. */
  19. protected function initMink() {
  20. // Set up the template cache used by the PhantomJS mink driver.
  21. $path = $this->tempFilesDirectory . DIRECTORY_SEPARATOR . 'browsertestbase-templatecache';
  22. $this->minkDefaultDriverArgs = [
  23. 'http://127.0.0.1:8510',
  24. $path,
  25. ];
  26. if (!file_exists($path)) {
  27. mkdir($path);
  28. }
  29. try {
  30. return parent::initMink();
  31. }
  32. catch (DeadClient $e) {
  33. $this->markTestSkipped('PhantomJS is either not installed or not running. Start it via phantomjs --ssl-protocol=any --ignore-ssl-errors=true vendor/jcalderonzumba/gastonjs/src/Client/main.js 8510 1024 768&');
  34. }
  35. catch (Exception $e) {
  36. $this->markTestSkipped('An unexpected error occurred while starting Mink: ' . $e->getMessage());
  37. }
  38. }
  39. /**
  40. * {@inheritdoc}
  41. */
  42. protected function tearDown() {
  43. // Wait for all requests to finish. It is possible that an AJAX request is
  44. // still on-going.
  45. $result = $this->getSession()->wait(5000, '(typeof(jQuery)=="undefined" || (0 === jQuery.active && 0 === jQuery(\':animated\').length))');
  46. if (!$result) {
  47. // If the wait is unsuccessful, there may still be an AJAX request in
  48. // progress. If we tear down now, then this AJAX request may fail with
  49. // missing database tables, because tear down will have removed them. Rather
  50. // than allow it to fail, throw an explicit exception now explaining what
  51. // the problem is.
  52. throw new \RuntimeException('Unfinished AJAX requests whilst tearing down a test');
  53. }
  54. parent::tearDown();
  55. }
  56. /**
  57. * Asserts that the element with the given CSS selector is visible.
  58. *
  59. * @param string $css_selector
  60. * The CSS selector identifying the element to check.
  61. * @param string $message
  62. * Optional message to show alongside the assertion.
  63. *
  64. * @deprecated in Drupal 8.1.x, will be removed before Drupal 8.3.x. Use
  65. * \Behat\Mink\Element\NodeElement::isVisible() instead.
  66. */
  67. protected function assertElementVisible($css_selector, $message = '') {
  68. $this->assertTrue($this->getSession()->getDriver()->isVisible($this->cssSelectToXpath($css_selector)), $message);
  69. }
  70. /**
  71. * Asserts that the element with the given CSS selector is not visible.
  72. *
  73. * @param string $css_selector
  74. * The CSS selector identifying the element to check.
  75. * @param string $message
  76. * Optional message to show alongside the assertion.
  77. *
  78. * @deprecated in Drupal 8.1.x, will be removed before Drupal 8.3.x. Use
  79. * \Behat\Mink\Element\NodeElement::isVisible() instead.
  80. */
  81. protected function assertElementNotVisible($css_selector, $message = '') {
  82. $this->assertFalse($this->getSession()->getDriver()->isVisible($this->cssSelectToXpath($css_selector)), $message);
  83. }
  84. /**
  85. * Waits for the given time or until the given JS condition becomes TRUE.
  86. *
  87. * @param string $condition
  88. * JS condition to wait until it becomes TRUE.
  89. * @param int $timeout
  90. * (Optional) Timeout in milliseconds, defaults to 1000.
  91. * @param string $message
  92. * (optional) A message to display with the assertion. If left blank, a
  93. * default message will be displayed.
  94. *
  95. * @throws \PHPUnit_Framework_AssertionFailedError
  96. *
  97. * @see \Behat\Mink\Driver\DriverInterface::evaluateScript()
  98. */
  99. protected function assertJsCondition($condition, $timeout = 1000, $message = '') {
  100. $message = $message ?: "Javascript condition met:\n" . $condition;
  101. $result = $this->getSession()->getDriver()->wait($timeout, $condition);
  102. $this->assertTrue($result, $message);
  103. }
  104. /**
  105. * Creates a screenshot.
  106. *
  107. * @param string $filename
  108. * The file name of the resulting screenshot. If using the default phantomjs
  109. * driver then this should be a JPG filename.
  110. * @param bool $set_background_color
  111. * (optional) By default this method will set the background color to white.
  112. * Set to FALSE to override this behaviour.
  113. *
  114. * @throws \Behat\Mink\Exception\UnsupportedDriverActionException
  115. * When operation not supported by the driver.
  116. * @throws \Behat\Mink\Exception\DriverException
  117. * When the operation cannot be done.
  118. */
  119. protected function createScreenshot($filename, $set_background_color = TRUE) {
  120. $session = $this->getSession();
  121. if ($set_background_color) {
  122. $session->executeScript("document.body.style.backgroundColor = 'white';");
  123. }
  124. $image = $session->getScreenshot();
  125. file_put_contents($filename, $image);
  126. }
  127. /**
  128. * {@inheritdoc}
  129. */
  130. public function assertSession($name = NULL) {
  131. return new JSWebAssert($this->getSession($name), $this->baseUrl);
  132. }
  133. }