diff --git a/src/WebdriverClassicDriver.php b/src/WebdriverClassicDriver.php
index d072288..97976be 100644
--- a/src/WebdriverClassicDriver.php
+++ b/src/WebdriverClassicDriver.php
@@ -31,6 +31,9 @@
use Facebook\WebDriver\WebDriverSelect;
use JetBrains\PhpStorm\Language;
+/**
+ * @phpstan-type TWebDriverInstantiator callable(string $driverHost, DesiredCapabilities $capabilities): RemoteWebDriver
+ */
class WebdriverClassicDriver extends CoreDriver
{
public const DEFAULT_BROWSER = WebDriverBrowserType::CHROME;
@@ -81,19 +84,27 @@ class WebdriverClassicDriver extends CoreDriver
private string $webDriverHost;
+ /**
+ * @var TWebDriverInstantiator
+ */
+ private $webDriverInstantiator;
+
private ?string $initialWindowHandle = null;
/**
* @param string $browserName One of 'edge', 'firefox', 'chrome' or any one of {@see WebDriverBrowserType} constants.
+ * @param TWebDriverInstantiator|null $webDriverInstantiator
*/
public function __construct(
string $browserName = self::DEFAULT_BROWSER,
array $desiredCapabilities = [],
- string $webDriverHost = 'http://localhost:4444/wd/hub'
+ string $webDriverHost = 'http://localhost:4444/wd/hub',
+ ?callable $webDriverInstantiator = null
) {
$this->browserName = $browserName;
$this->desiredCapabilities = $this->initCapabilities($desiredCapabilities);
$this->webDriverHost = $webDriverHost;
+ $this->webDriverInstantiator = $webDriverInstantiator ?? [self::class, 'instantiateWebDriver'];
}
//
@@ -751,7 +762,7 @@ public function setTimeouts(array $timeouts): void
//
- //
+ //
/**
* @throws DriverException
@@ -762,7 +773,7 @@ protected function createWebDriver(): void
throw new DriverException('Base driver has already been created');
}
- $this->webDriver = RemoteWebDriver::create($this->webDriverHost, $this->getDesiredCapabilities());
+ $this->webDriver = ($this->webDriverInstantiator)($this->webDriverHost, $this->desiredCapabilities);
}
/**
@@ -777,9 +788,13 @@ protected function getWebDriver(): RemoteWebDriver
throw new DriverException('Base driver has not been created');
}
- protected function getDesiredCapabilities(): array
+ //
+
+ //
+
+ private static function instantiateWebDriver(string $driverHost, DesiredCapabilities $capabilities): RemoteWebDriver
{
- return $this->desiredCapabilities->toArray();
+ return RemoteWebDriver::create($driverHost, $capabilities);
}
private function getNormalisedBrowserName(): string
diff --git a/tests/Custom/CapabilityTest.php b/tests/Custom/CapabilityTest.php
index f3a3082..9abc275 100644
--- a/tests/Custom/CapabilityTest.php
+++ b/tests/Custom/CapabilityTest.php
@@ -2,10 +2,13 @@
namespace Mink\WebdriverClassicDriver\Tests\Custom;
+use Mink\WebdriverClassicDriver\Tests\WebDriverMockingTrait;
use Mink\WebdriverClassicDriver\WebdriverClassicDriver;
class CapabilityTest extends \PHPUnit\Framework\TestCase
{
+ use WebDriverMockingTrait;
+
/**
* @param array $desiredCapabilities
* @param array $expectedCapabilities
@@ -14,9 +17,22 @@ class CapabilityTest extends \PHPUnit\Framework\TestCase
*/
public function testThatCapabilitiesAreAsExpected(string $browserName, array $desiredCapabilities, array $expectedCapabilities): void
{
- $driver = $this->createDriverExposingCapabilities($browserName, $desiredCapabilities);
+ $mockWebDriver = $this->createMockWebDriver();
+
+ $actualCapabilities = null;
+ $driver = new WebdriverClassicDriver(
+ $browserName,
+ $desiredCapabilities,
+ 'example.com',
+ function ($host, $capabilities) use (&$actualCapabilities, $mockWebDriver) {
+ $actualCapabilities = $capabilities->toArray();
+ return $mockWebDriver;
+ }
+ );
+
+ $driver->start();
- $this->assertSame($expectedCapabilities, $driver->capabilities);
+ $this->assertSame($expectedCapabilities, $actualCapabilities);
}
public static function capabilitiesDataProvider(): iterable
@@ -78,26 +94,4 @@ public static function capabilitiesDataProvider(): iterable
],
];
}
-
- /**
- * @param string $browserName
- * @param array $desiredCapabilities
- * @return WebdriverClassicDriver&object{capabilities: array}
- */
- private function createDriverExposingCapabilities(string $browserName, array $desiredCapabilities = []): WebdriverClassicDriver
- {
- return new class($browserName, $desiredCapabilities) extends WebdriverClassicDriver {
- /**
- * @var array
- */
- public array $capabilities;
-
- public function __construct(string $browserName, array $desiredCapabilities)
- {
- parent::__construct($browserName, $desiredCapabilities);
-
- $this->capabilities = $this->getDesiredCapabilities();
- }
- };
- }
}
diff --git a/tests/Custom/WebDriverTest.php b/tests/Custom/WebDriverTest.php
index 1c4ff40..6a778d4 100644
--- a/tests/Custom/WebDriverTest.php
+++ b/tests/Custom/WebDriverTest.php
@@ -3,10 +3,13 @@
namespace Mink\WebdriverClassicDriver\Tests\Custom;
use Behat\Mink\Exception\DriverException;
+use Mink\WebdriverClassicDriver\Tests\WebDriverMockingTrait;
use Mink\WebdriverClassicDriver\WebdriverClassicDriver;
class WebDriverTest extends TestCase
{
+ use WebDriverMockingTrait;
+
public function testDriverMustBeStartedBeforeUse(): void
{
$this->expectException(DriverException::class);
@@ -35,11 +38,9 @@ public function testStartedDriverCannotBeSubsequentlyStarted(): void
public function testDriverCatchesUpstreamErrorsDuringStart(): void
{
- $driver = $this->createPartialMock(WebdriverClassicDriver::class, ['createWebDriver', 'getWebDriver']);
- $driver
- ->expects($this->once())
- ->method('createWebDriver')
- ->willThrowException(new \RuntimeException('An upstream error'));
+ $driver = new WebdriverClassicDriver('fake browser', [], 'example.com', function () {
+ throw new \RuntimeException('An upstream error');
+ });
$this->expectException(DriverException::class);
$this->expectExceptionMessage('Could not start driver: An upstream error');
@@ -49,15 +50,11 @@ public function testDriverCatchesUpstreamErrorsDuringStart(): void
public function testDriverCatchesUpstreamErrorsDuringStop(): void
{
- $driver = $this->createPartialMock(WebdriverClassicDriver::class, ['createWebDriver', 'isStarted', 'getWebDriver']);
- $driver
- ->expects($this->once())
- ->method('isStarted')
- ->willReturn(true);
- $driver
- ->expects($this->once())
- ->method('getWebDriver')
- ->willThrowException(new \RuntimeException('An upstream error'));
+ $mockWebDriver = $this->createMockWebDriver();
+ $mockWebDriver->method('quit')->willThrowException(new \RuntimeException('An upstream error'));
+ $driver = new WebdriverClassicDriver('fake browser', [], 'example.com', fn() => $mockWebDriver);
+
+ $driver->start();
$this->expectException(DriverException::class);
$this->expectExceptionMessage('Could not close connection: An upstream error');
diff --git a/tests/WebDriverMockingTrait.php b/tests/WebDriverMockingTrait.php
new file mode 100644
index 0000000..3bce02e
--- /dev/null
+++ b/tests/WebDriverMockingTrait.php
@@ -0,0 +1,34 @@
+ $class
+ * @return T&MockObject
+ */
+ abstract function createMock(string $class): object;
+
+ /**
+ * @return RemoteWebDriver&MockObject
+ */
+ private function createMockWebDriver(): RemoteWebDriver
+ {
+ $mockWebDriverTimeouts = $this->createMock(WebDriverTimeouts::class);
+
+ $mockWebDriverOptions = $this->createMock(WebDriverOptions::class);
+ $mockWebDriverOptions->method('timeouts')->willReturn($mockWebDriverTimeouts);
+
+ $mockWebDriver = $this->createMock(RemoteWebDriver::class);
+ $mockWebDriver->method('manage')->willReturn($mockWebDriverOptions);
+
+ return $mockWebDriver;
+ }
+}