Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/master' into bugfix/fix-dnd-on-s…
Browse files Browse the repository at this point in the history
…elenium3
  • Loading branch information
uuf6429 committed Jan 18, 2025
2 parents da03000 + 4ad4a11 commit 319602d
Show file tree
Hide file tree
Showing 6 changed files with 185 additions and 19 deletions.
20 changes: 16 additions & 4 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ jobs:

tests:
name: "Tests (PHP ${{ matrix.php }}, Selenium ${{ matrix.selenium_version }})${{ matrix.with_coverage == true && ' with coverage' || ''}}"
runs-on: ubuntu-20.04
runs-on: ubuntu-latest
strategy:
matrix:
selenium_version: [ '2.53.1' ]
Expand All @@ -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 All @@ -74,24 +77,27 @@ jobs:
composer update --no-interaction --prefer-dist
- name: Setup Mink test server
env:
MINK_HOST: 0.0.0.0:8002
run: |
mkdir ./logs
./vendor/bin/mink-test-server &> ./logs/mink-test-server.log &
- name: Start Selenium
run: |
docker run --net host --name selenium --volume /dev/shm:/dev/shm --volume ./vendor/mink/driver-testsuite/web-fixtures:/fixtures --shm-size 2g selenium/standalone-firefox:${{ matrix.selenium_version }} &> ./logs/selenium.log &
SELENIUM_IMAGE=selenium/standalone-firefox:${{ matrix.selenium_version }} docker compose up --wait
- name: Wait for browser & PHP to start
run: |
while ! nc -z localhost 4444 </dev/null; do echo Waiting for remote driver to start...; sleep 1; done
while ! nc -z localhost 8002 </dev/null; do echo Waiting for PHP server to start...; sleep 1; done
curl --retry 5 --retry-all-errors --retry-delay 1 --max-time 10 --head -X GET http://localhost:4444/wd/hub/status
curl --retry 5 --retry-all-errors --retry-delay 1 --max-time 10 --head -X GET http://localhost:8002/index.html
- name: Run tests with Coverage
if: "${{ matrix.with_coverage == true }}"
env:
SELENIUM_VERSION: ${{ matrix.selenium_version }}
DRIVER_URL: http://localhost:4444/wd/hub
WEB_FIXTURES_HOST: http://host.docker.internal:8002
WEB_FIXTURES_BROWSER: firefox
DRIVER_MACHINE_BASE_PATH: /fixtures/
run: |
Expand All @@ -102,6 +108,7 @@ jobs:
env:
SELENIUM_VERSION: ${{ matrix.selenium_version }}
DRIVER_URL: http://localhost:4444/wd/hub
WEB_FIXTURES_HOST: http://host.docker.internal:8002
WEB_FIXTURES_BROWSER: firefox
DRIVER_MACHINE_BASE_PATH: /fixtures/
run: |
Expand All @@ -120,6 +127,11 @@ jobs:
with:
token: ${{ secrets.CODECOV_TOKEN }}

- name: Extract docker logs
if: ${{ failure() }}
run: |
docker compose logs --no-color &> ./logs/selenium.log
- name: Archive logs artifacts
if: ${{ failure() }}
uses: actions/upload-artifact@v4
Expand Down
20 changes: 20 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
services:
selenium:
image: ${SELENIUM_IMAGE:-selenium/standalone-chrome:4}
hostname: selenium
shm_size: 2g
environment:
VNC_NO_PASSWORD: 1
SCREEN_WIDTH: 1024
SCREEN_HEIGHT: 768
volumes:
- /dev/shm:/dev/shm
- ./vendor/mink/driver-testsuite/web-fixtures:/fixtures
ports:
- "4444:4444"
# VNC Web Viewer port (new images)
- "7900:7900"
# VNC Server port (old "-debug" images)
- "5900:5900"
extra_hosts:
- host.docker.internal:host-gateway
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 319602d

Please sign in to comment.