From 4ad4a11b3fa80fd464bc6b062588684230fd8970 Mon Sep 17 00:00:00 2001 From: Alex Date: Sat, 18 Jan 2025 21:57:12 +0200 Subject: [PATCH] Inform developers about non-working "rightClick" on Selenium Server 3.x (#407) Inform developers about non-working "rightClick" on Selenium Server 3.x --- .github/workflows/tests.yml | 3 ++ src/Selenium2Driver.php | 33 +++++++++++-- tests/Custom/SeleniumSupportTest.php | 41 ++++++++++++++++ tests/Custom/WebDriverTest.php | 19 ++++++++ tests/Selenium2Config.php | 71 +++++++++++++++++++++++----- 5 files changed, 152 insertions(+), 15 deletions(-) create mode 100644 tests/Custom/SeleniumSupportTest.php diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 1c9a7eba..ce8a0b40 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -52,6 +52,9 @@ jobs: - selenium_version: '3.141.59' php: '8.3' with_coverage: true + - selenium_version: '4' + php: '8.3' + with_coverage: true fail-fast: false steps: diff --git a/src/Selenium2Driver.php b/src/Selenium2Driver.php index fe8b1650..01e86c27 100755 --- a/src/Selenium2Driver.php +++ b/src/Selenium2Driver.php @@ -349,15 +349,30 @@ private function executeJsOnElement(Element $element, string $script, bool $sync public function start() { try { - $this->wdSession = $this->webDriver->session($this->browserName, $this->desiredCapabilities); - $status = $this->webDriver->status(); - $this->isW3C = version_compare($status['build']['version'], '3.0.0', '>='); + $seleniumVersion = $status['build']['version'] ?? $status['nodes'][0]['version'] ?? 'unknown'; + $seleniumMajorVersion = (int) explode('.', $seleniumVersion)[0]; + } catch (\Throwable $ex) { + throw new DriverException("Selenium Server version could not be detected: {$ex->getMessage()}", 0, $ex); + } + + if ($seleniumMajorVersion > 3) { + throw new DriverException(<<isW3C = $seleniumMajorVersion === 3; + $this->wdSession = $this->webDriver->session($this->browserName, $this->desiredCapabilities); $this->applyTimeouts(); $this->initialWindowHandle = $this->getWebDriverSession()->window_handle(); } catch (\Exception $e) { - throw new DriverException('Could not open connection: '.$e->getMessage(), 0, $e); + throw new DriverException('Could not open connection: ' . $e->getMessage(), 0, $e); } $this->started = true; @@ -936,6 +951,16 @@ public function doubleClick(string $xpath) public function rightClick(string $xpath) { + if ($this->isW3C) { + // See: https://github.com/SeleniumHQ/selenium/commit/085ceed1f55fbaaa1d419b19c73264415c394905. + throw new DriverException(<<mouseOver($xpath); $this->getWebDriverSession()->click(array('button' => 2)); } diff --git a/tests/Custom/SeleniumSupportTest.php b/tests/Custom/SeleniumSupportTest.php new file mode 100644 index 00000000..f2cbb355 --- /dev/null +++ b/tests/Custom/SeleniumSupportTest.php @@ -0,0 +1,41 @@ +isSeleniumVersionSupported()) { + $this->markTestSkipped('This test applies to unsupported Selenium versions only.'); + } + + $this->expectException(DriverException::class); + $this->expectExceptionMessage('This driver requires Selenium version 3 or lower'); + + $this->createDriver()->start(); + } + + public function testThatRightClickingCannotBeUsedInUnsupportedSelenium(): void + { + if (Selenium2Config::getInstance()->isRightClickingInSeleniumSupported()) { + $this->markTestSkipped('This test applies to Selenium 3 only.'); + } + + $this->expectException(DriverException::class); + $this->expectExceptionMessage(<<createDriver(); + $driver->start(); + $driver->rightClick('//'); + } +} diff --git a/tests/Custom/WebDriverTest.php b/tests/Custom/WebDriverTest.php index a6f71e6d..3863f4d2 100644 --- a/tests/Custom/WebDriverTest.php +++ b/tests/Custom/WebDriverTest.php @@ -3,7 +3,9 @@ namespace Behat\Mink\Tests\Driver\Custom; use Behat\Mink\Driver\Selenium2Driver; +use Behat\Mink\Exception\DriverException; use Behat\Mink\Tests\Driver\TestCase; +use WebDriver\WebDriver; class WebDriverTest extends TestCase { @@ -18,4 +20,21 @@ public function testGetWebDriverSessionId() $driver = new Selenium2Driver(); $this->assertNull($driver->getWebDriverSessionId(), 'Not started session don\'t have an ID'); } + + public function testUnsupportedStatusResponseHandling(): void + { + $mockWebDriver = $this->createMock(WebDriver::class); + $mockWebDriver->expects($this->once()) + ->method('__call') + ->with($this->equalTo('status')) + ->willThrowException(new \RuntimeException('some internal error')); + + $driver = new Selenium2Driver(); + $driver->setWebDriver($mockWebDriver); + + $this->expectException(DriverException::class); + $this->expectExceptionMessage('Selenium Server version could not be detected: some internal error'); + + $driver->start(); + } } diff --git a/tests/Selenium2Config.php b/tests/Selenium2Config.php index cc2d8347..38b7f1bc 100644 --- a/tests/Selenium2Config.php +++ b/tests/Selenium2Config.php @@ -7,10 +7,25 @@ use Behat\Mink\Tests\Driver\Basic\BasicAuthTest; use Behat\Mink\Tests\Driver\Basic\HeaderTest; use Behat\Mink\Tests\Driver\Basic\StatusCodeTest; +use Behat\Mink\Tests\Driver\Css\HoverTest; +use Behat\Mink\Tests\Driver\Custom\SeleniumSupportTest; +use Behat\Mink\Tests\Driver\Form\Html5Test; +use Behat\Mink\Tests\Driver\Js\EventsTest; use Behat\Mink\Tests\Driver\Js\JavascriptTest; class Selenium2Config extends AbstractConfig { + + /** + * @var integer + */ + protected $seleniumMajorVersion; + + public function __construct() + { + $this->seleniumMajorVersion = (int) explode('.', $_SERVER['SELENIUM_VERSION'] ?? '')[0]; + } + public static function getInstance(): self { return new self(); @@ -36,15 +51,17 @@ public function mapRemoteFilePath($file): string public function skipMessage($testCase, $test): ?string { - if ( - 'Behat\Mink\Tests\Driver\Form\Html5Test' === $testCase - && 'testHtml5Types' === $test - ) { - return 'WebDriver does not support setting value in color inputs. See https://code.google.com/p/selenium/issues/detail?id=7650'; + $testCallback = [$testCase, $test]; + + if ([Html5Test::class, 'testHtml5Types'] === $testCallback) { + return <<getSeleniumMajorVersion() === 2) { + return 'The Firefox browser compatible with Selenium 2.x does not fully implement drag-n-drop support.'; } } + // Skip right-clicking tests, when an unsupported Selenium version detected. + if (([HoverTest::class, 'testRightClickHover'] === $testCallback || [EventsTest::class, 'testRightClick'] === $testCallback) + && !$this->isRightClickingInSeleniumSupported() + ) { + return <<isSeleniumVersionSupported() + ) { + return 'Does not apply to unsupported Selenium versions.'; + } + return parent::skipMessage($testCase, $test); } @@ -79,4 +113,19 @@ protected function supportsCss(): bool { return true; } + + public function isRightClickingInSeleniumSupported(): bool + { + return $this->getSeleniumMajorVersion() < 3; + } + + public function isSeleniumVersionSupported(): bool + { + return $this->getSeleniumMajorVersion() < 4; + } + + protected function getSeleniumMajorVersion(): int + { + return $this->seleniumMajorVersion; + } }