Skip to content

Commit

Permalink
Inform developers about non-working "rightClick" on Selenium Server 3…
Browse files Browse the repository at this point in the history
….x (#407)

Inform developers about non-working "rightClick" on Selenium Server 3.x
  • Loading branch information
aik099 authored Jan 18, 2025
1 parent 906ea02 commit 4ad4a11
Show file tree
Hide file tree
Showing 5 changed files with 152 additions and 15 deletions.
3 changes: 3 additions & 0 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
33 changes: 29 additions & 4 deletions src/Selenium2Driver.php
Original file line number Diff line number Diff line change
Expand Up @@ -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(<<<TEXT
This driver requires Selenium version 3 or lower, but version {$seleniumVersion} was found.
Please use the "mink/webdriver-classic-driver" Mink driver or switch to Selenium Server 2.x/3.x.
TEXT
);
}

try {
$this->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;
Expand Down Expand Up @@ -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(<<<TEXT
Right-clicking via JsonWireProtocol is not possible on Selenium Server 3.x.
Please use the "mink/webdriver-classic-driver" Mink driver or switch to Selenium Server 2.x.
TEXT
);
}

$this->mouseOver($xpath);
$this->getWebDriverSession()->click(array('button' => 2));
}
Expand Down
41 changes: 41 additions & 0 deletions tests/Custom/SeleniumSupportTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<?php

namespace Behat\Mink\Tests\Driver\Custom;

use Behat\Mink\Exception\DriverException;
use Behat\Mink\Tests\Driver\Selenium2Config;
use Behat\Mink\Tests\Driver\TestCase;

final class SeleniumSupportTest extends TestCase
{
public function testDriverCannotBeUsedInUnsupportedSelenium(): void
{
if (Selenium2Config::getInstance()->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(<<<TEXT
Right-clicking via JsonWireProtocol is not possible on Selenium Server 3.x.
Please use the "mink/webdriver-classic-driver" Mink driver or switch to Selenium Server 2.x.
TEXT
);

$driver = $this->createDriver();
$driver->start();
$driver->rightClick('//');
}
}
19 changes: 19 additions & 0 deletions tests/Custom/WebDriverTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -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
{
Expand All @@ -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();
}
}
71 changes: 60 additions & 11 deletions tests/Selenium2Config.php
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand All @@ -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 <<<TEXT
WebDriver does not support setting value in color inputs.
See https://code.google.com/p/selenium/issues/detail?id=7650.
TEXT;
}

if (
'Behat\Mink\Tests\Driver\Js\WindowTest' === $testCase
if ('Behat\Mink\Tests\Driver\Js\WindowTest' === $testCase
&& (0 === strpos($test, 'testWindowMaximize'))
&& 'true' === getenv('GITHUB_ACTIONS')
) {
Expand All @@ -63,20 +80,52 @@ public function skipMessage($testCase, $test): ?string
return 'Checking status code is not supported.';
}

if (array(JavascriptTest::class, 'testDragDropOntoHiddenItself') === array($testCase, $test)) {
$seleniumVersion = $_SERVER['SELENIUM_VERSION'] ?? null;
if ([JavascriptTest::class, 'testDragDropOntoHiddenItself'] === $testCallback) {
$browser = $_SERVER['WEB_FIXTURES_BROWSER'] ?? null;

if ($seleniumVersion && version_compare($seleniumVersion, '3.0.0', '<') && $browser === 'firefox') {
return 'The Firefox browser compatible with Selenium Server 2.x doesn\'t fully implement drag-n-drop support.';
if ($browser === 'firefox' && $this->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 <<<TEXT
Selenium 3.x does not support right-clicking via JsonWireProtocol.
See https://github.com/SeleniumHQ/selenium/commit/085ceed1f55fbaaa1d419b19c73264415c394905.
TEXT;
}

// Skips all tests, except mentioned below, for an unsupported Selenium version.
if ([SeleniumSupportTest::class, 'testDriverCannotBeUsedInUnsupportedSelenium'] !== $testCallback
&& !$this->isSeleniumVersionSupported()
) {
return 'Does not apply to unsupported Selenium versions.';
}

return parent::skipMessage($testCase, $test);
}

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;
}
}

0 comments on commit 4ad4a11

Please sign in to comment.