DrupalSelenium2Driver.php 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. <?php
  2. namespace Drupal\FunctionalJavascriptTests;
  3. use Behat\Mink\Driver\Selenium2Driver;
  4. use Behat\Mink\Exception\DriverException;
  5. use WebDriver\Exception\UnknownError;
  6. use WebDriver\ServiceFactory;
  7. /**
  8. * Provides a driver for Selenium testing.
  9. */
  10. class DrupalSelenium2Driver extends Selenium2Driver {
  11. /**
  12. * {@inheritdoc}
  13. */
  14. public function __construct($browserName = 'firefox', $desiredCapabilities = NULL, $wdHost = 'http://localhost:4444/wd/hub') {
  15. parent::__construct($browserName, $desiredCapabilities, $wdHost);
  16. ServiceFactory::getInstance()->setServiceClass('service.curl', WebDriverCurlService::class);
  17. }
  18. /**
  19. * {@inheritdoc}
  20. */
  21. public function setCookie($name, $value = NULL) {
  22. if ($value === NULL) {
  23. $this->getWebDriverSession()->deleteCookie($name);
  24. return;
  25. }
  26. $cookieArray = [
  27. 'name' => $name,
  28. 'value' => urlencode($value),
  29. 'secure' => FALSE,
  30. // Unlike \Behat\Mink\Driver\Selenium2Driver::setCookie we set a domain
  31. // and an expire date, as otherwise cookies leak from one test site into
  32. // another.
  33. 'domain' => parse_url($this->getWebDriverSession()->url(), PHP_URL_HOST),
  34. 'expires' => time() + 80000,
  35. ];
  36. $this->getWebDriverSession()->setCookie($cookieArray);
  37. }
  38. /**
  39. * Uploads a file to the Selenium instance and returns the remote path.
  40. *
  41. * \Behat\Mink\Driver\Selenium2Driver::uploadFile() is a private method so
  42. * that can't be used inside a test, but we need the remote path that is
  43. * generated when uploading to make sure the file reference exists on the
  44. * container running selenium.
  45. *
  46. * @param string $path
  47. * The path to the file to upload.
  48. *
  49. * @return string
  50. * The remote path.
  51. *
  52. * @throws \Behat\Mink\Exception\DriverException
  53. * When PHP is compiled without zip support, or the file doesn't exist.
  54. * @throws \WebDriver\Exception\UnknownError
  55. * When an unknown error occurred during file upload.
  56. * @throws \Exception
  57. * When a known error occurred during file upload.
  58. */
  59. public function uploadFileAndGetRemoteFilePath($path) {
  60. if (!is_file($path)) {
  61. throw new DriverException('File does not exist locally and cannot be uploaded to the remote instance.');
  62. }
  63. if (!class_exists('ZipArchive')) {
  64. throw new DriverException('Could not compress file, PHP is compiled without zip support.');
  65. }
  66. // Selenium only accepts uploads that are compressed as a Zip archive.
  67. $tempFilename = tempnam('', 'WebDriverZip');
  68. $archive = new \ZipArchive();
  69. $result = $archive->open($tempFilename, \ZipArchive::CREATE);
  70. if (!$result) {
  71. throw new DriverException('Zip archive could not be created. Error ' . $result);
  72. }
  73. $result = $archive->addFile($path, basename($path));
  74. if (!$result) {
  75. throw new DriverException('File could not be added to zip archive.');
  76. }
  77. $result = $archive->close();
  78. if (!$result) {
  79. throw new DriverException('Zip archive could not be closed.');
  80. }
  81. try {
  82. $remotePath = $this->getWebDriverSession()->file(['file' => base64_encode(file_get_contents($tempFilename))]);
  83. // If no path is returned the file upload failed silently.
  84. if (empty($remotePath)) {
  85. throw new UnknownError();
  86. }
  87. }
  88. catch (\Exception $e) {
  89. throw $e;
  90. }
  91. finally {
  92. unlink($tempFilename);
  93. }
  94. return $remotePath;
  95. }
  96. }