Skip to content

Commit 00b5f88

Browse files
authored
Implement driver initializer (#56)
1 parent 5206bb4 commit 00b5f88

4 files changed

Lines changed: 83 additions & 43 deletions

File tree

src/WebdriverClassicDriver.php

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,9 @@
3131
use Facebook\WebDriver\WebDriverSelect;
3232
use JetBrains\PhpStorm\Language;
3333

34+
/**
35+
* @phpstan-type TWebDriverInstantiator callable(string $driverHost, DesiredCapabilities $capabilities): RemoteWebDriver
36+
*/
3437
class WebdriverClassicDriver extends CoreDriver
3538
{
3639
public const DEFAULT_BROWSER = WebDriverBrowserType::CHROME;
@@ -81,19 +84,27 @@ class WebdriverClassicDriver extends CoreDriver
8184

8285
private string $webDriverHost;
8386

87+
/**
88+
* @var TWebDriverInstantiator
89+
*/
90+
private $webDriverInstantiator;
91+
8492
private ?string $initialWindowHandle = null;
8593

8694
/**
8795
* @param string $browserName One of 'edge', 'firefox', 'chrome' or any one of {@see WebDriverBrowserType} constants.
96+
* @param TWebDriverInstantiator|null $webDriverInstantiator
8897
*/
8998
public function __construct(
9099
string $browserName = self::DEFAULT_BROWSER,
91100
array $desiredCapabilities = [],
92-
string $webDriverHost = 'http://localhost:4444/wd/hub'
101+
string $webDriverHost = 'http://localhost:4444/wd/hub',
102+
?callable $webDriverInstantiator = null
93103
) {
94104
$this->browserName = $browserName;
95105
$this->desiredCapabilities = $this->initCapabilities($desiredCapabilities);
96106
$this->webDriverHost = $webDriverHost;
107+
$this->webDriverInstantiator = $webDriverInstantiator ?? [self::class, 'instantiateWebDriver'];
97108
}
98109

99110
// <editor-fold desc="Implementation">
@@ -751,7 +762,7 @@ public function setTimeouts(array $timeouts): void
751762

752763
// </editor-fold>
753764

754-
// <editor-fold desc="Private Utilities">
765+
// <editor-fold desc="Extension Points">
755766

756767
/**
757768
* @throws DriverException
@@ -762,7 +773,7 @@ protected function createWebDriver(): void
762773
throw new DriverException('Base driver has already been created');
763774
}
764775

765-
$this->webDriver = RemoteWebDriver::create($this->webDriverHost, $this->getDesiredCapabilities());
776+
$this->webDriver = ($this->webDriverInstantiator)($this->webDriverHost, $this->desiredCapabilities);
766777
}
767778

768779
/**
@@ -777,9 +788,13 @@ protected function getWebDriver(): RemoteWebDriver
777788
throw new DriverException('Base driver has not been created');
778789
}
779790

780-
protected function getDesiredCapabilities(): array
791+
// </editor-fold>
792+
793+
// <editor-fold desc="Private Utilities">
794+
795+
private static function instantiateWebDriver(string $driverHost, DesiredCapabilities $capabilities): RemoteWebDriver
781796
{
782-
return $this->desiredCapabilities->toArray();
797+
return RemoteWebDriver::create($driverHost, $capabilities);
783798
}
784799

785800
private function getNormalisedBrowserName(): string

tests/Custom/CapabilityTest.php

Lines changed: 18 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,13 @@
22

33
namespace Mink\WebdriverClassicDriver\Tests\Custom;
44

5+
use Mink\WebdriverClassicDriver\Tests\WebDriverMockingTrait;
56
use Mink\WebdriverClassicDriver\WebdriverClassicDriver;
67

78
class CapabilityTest extends \PHPUnit\Framework\TestCase
89
{
10+
use WebDriverMockingTrait;
11+
912
/**
1013
* @param array<string, mixed> $desiredCapabilities
1114
* @param array<string, mixed> $expectedCapabilities
@@ -14,9 +17,22 @@ class CapabilityTest extends \PHPUnit\Framework\TestCase
1417
*/
1518
public function testThatCapabilitiesAreAsExpected(string $browserName, array $desiredCapabilities, array $expectedCapabilities): void
1619
{
17-
$driver = $this->createDriverExposingCapabilities($browserName, $desiredCapabilities);
20+
$mockWebDriver = $this->createMockWebDriver();
21+
22+
$actualCapabilities = null;
23+
$driver = new WebdriverClassicDriver(
24+
$browserName,
25+
$desiredCapabilities,
26+
'example.com',
27+
function ($host, $capabilities) use (&$actualCapabilities, $mockWebDriver) {
28+
$actualCapabilities = $capabilities->toArray();
29+
return $mockWebDriver;
30+
}
31+
);
32+
33+
$driver->start();
1834

19-
$this->assertSame($expectedCapabilities, $driver->capabilities);
35+
$this->assertSame($expectedCapabilities, $actualCapabilities);
2036
}
2137

2238
public static function capabilitiesDataProvider(): iterable
@@ -78,26 +94,4 @@ public static function capabilitiesDataProvider(): iterable
7894
],
7995
];
8096
}
81-
82-
/**
83-
* @param string $browserName
84-
* @param array<string, mixed> $desiredCapabilities
85-
* @return WebdriverClassicDriver&object{capabilities: array<string, mixed>}
86-
*/
87-
private function createDriverExposingCapabilities(string $browserName, array $desiredCapabilities = []): WebdriverClassicDriver
88-
{
89-
return new class($browserName, $desiredCapabilities) extends WebdriverClassicDriver {
90-
/**
91-
* @var array<string, mixed>
92-
*/
93-
public array $capabilities;
94-
95-
public function __construct(string $browserName, array $desiredCapabilities)
96-
{
97-
parent::__construct($browserName, $desiredCapabilities);
98-
99-
$this->capabilities = $this->getDesiredCapabilities();
100-
}
101-
};
102-
}
10397
}

tests/Custom/WebDriverTest.php

Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,13 @@
33
namespace Mink\WebdriverClassicDriver\Tests\Custom;
44

55
use Behat\Mink\Exception\DriverException;
6+
use Mink\WebdriverClassicDriver\Tests\WebDriverMockingTrait;
67
use Mink\WebdriverClassicDriver\WebdriverClassicDriver;
78

89
class WebDriverTest extends TestCase
910
{
11+
use WebDriverMockingTrait;
12+
1013
public function testDriverMustBeStartedBeforeUse(): void
1114
{
1215
$this->expectException(DriverException::class);
@@ -35,11 +38,9 @@ public function testStartedDriverCannotBeSubsequentlyStarted(): void
3538

3639
public function testDriverCatchesUpstreamErrorsDuringStart(): void
3740
{
38-
$driver = $this->createPartialMock(WebdriverClassicDriver::class, ['createWebDriver', 'getWebDriver']);
39-
$driver
40-
->expects($this->once())
41-
->method('createWebDriver')
42-
->willThrowException(new \RuntimeException('An upstream error'));
41+
$driver = new WebdriverClassicDriver('fake browser', [], 'example.com', function () {
42+
throw new \RuntimeException('An upstream error');
43+
});
4344

4445
$this->expectException(DriverException::class);
4546
$this->expectExceptionMessage('Could not start driver: An upstream error');
@@ -49,15 +50,11 @@ public function testDriverCatchesUpstreamErrorsDuringStart(): void
4950

5051
public function testDriverCatchesUpstreamErrorsDuringStop(): void
5152
{
52-
$driver = $this->createPartialMock(WebdriverClassicDriver::class, ['createWebDriver', 'isStarted', 'getWebDriver']);
53-
$driver
54-
->expects($this->once())
55-
->method('isStarted')
56-
->willReturn(true);
57-
$driver
58-
->expects($this->once())
59-
->method('getWebDriver')
60-
->willThrowException(new \RuntimeException('An upstream error'));
53+
$mockWebDriver = $this->createMockWebDriver();
54+
$mockWebDriver->method('quit')->willThrowException(new \RuntimeException('An upstream error'));
55+
$driver = new WebdriverClassicDriver('fake browser', [], 'example.com', fn() => $mockWebDriver);
56+
57+
$driver->start();
6158

6259
$this->expectException(DriverException::class);
6360
$this->expectExceptionMessage('Could not close connection: An upstream error');

tests/WebDriverMockingTrait.php

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
<?php
2+
3+
namespace Mink\WebdriverClassicDriver\Tests;
4+
5+
use Facebook\WebDriver\Remote\RemoteWebDriver;
6+
use Facebook\WebDriver\WebDriverOptions;
7+
use Facebook\WebDriver\WebDriverTimeouts;
8+
use PHPUnit\Framework\MockObject\MockObject;
9+
10+
trait WebDriverMockingTrait
11+
{
12+
/**
13+
* @template T
14+
* @param class-string<T> $class
15+
* @return T&MockObject
16+
*/
17+
abstract function createMock(string $class): object;
18+
19+
/**
20+
* @return RemoteWebDriver&MockObject
21+
*/
22+
private function createMockWebDriver(): RemoteWebDriver
23+
{
24+
$mockWebDriverTimeouts = $this->createMock(WebDriverTimeouts::class);
25+
26+
$mockWebDriverOptions = $this->createMock(WebDriverOptions::class);
27+
$mockWebDriverOptions->method('timeouts')->willReturn($mockWebDriverTimeouts);
28+
29+
$mockWebDriver = $this->createMock(RemoteWebDriver::class);
30+
$mockWebDriver->method('manage')->willReturn($mockWebDriverOptions);
31+
32+
return $mockWebDriver;
33+
}
34+
}

0 commit comments

Comments
 (0)