diff --git a/composer.json b/composer.json index 41801fec..a26a3f15 100644 --- a/composer.json +++ b/composer.json @@ -27,7 +27,7 @@ "php": ">=8.0", "ext-dom": "*", "ext-libxml": "*", - "php-webdriver/webdriver": "^1.8.2", + "php-webdriver/webdriver": "^1.14.0", "symfony/browser-kit": "^5.4 || ^6.4 || ^7.0", "symfony/dependency-injection": "^5.4 || ^6.4 || ^7.0", "symfony/deprecation-contracts": "^2.4 || ^3", diff --git a/src/Client.php b/src/Client.php index a1c53e51..062ce62d 100644 --- a/src/Client.php +++ b/src/Client.php @@ -14,8 +14,8 @@ namespace Symfony\Component\Panther; use Facebook\WebDriver\Exception\NoSuchElementException; +use Facebook\WebDriver\Exception\PhpWebDriverExceptionInterface; use Facebook\WebDriver\Exception\TimeoutException; -use Facebook\WebDriver\Exception\WebDriverException; use Facebook\WebDriver\JavaScriptExecutor; use Facebook\WebDriver\Remote\RemoteWebDriver; use Facebook\WebDriver\WebDriver; @@ -108,11 +108,7 @@ public function __wakeup(): void public function __destruct() { - try { - $this->quit(); - } catch (WebDriverException) { - // ignore - } + $this->quit(); } public function start(): void @@ -602,8 +598,12 @@ public function getWindowHandles(): array public function quit(bool $quitBrowserManager = true): void { if (null !== $this->webDriver) { - $this->webDriver->quit(); - $this->webDriver = null; + try { + $this->webDriver->quit(); + $this->webDriver = null; + } catch (PhpWebDriverExceptionInterface) { + // ignore + } } if ($quitBrowserManager) { diff --git a/tests/ClientTest.php b/tests/ClientTest.php index edda41dd..4db1ab93 100644 --- a/tests/ClientTest.php +++ b/tests/ClientTest.php @@ -14,9 +14,11 @@ namespace Symfony\Component\Panther\Tests; use Facebook\WebDriver\Exception\ElementClickInterceptedException; +use Facebook\WebDriver\Exception\Internal\UnexpectedResponseException; use Facebook\WebDriver\Exception\InvalidSelectorException; use Facebook\WebDriver\Exception\StaleElementReferenceException; use Facebook\WebDriver\Exception\TimeoutException; +use Facebook\WebDriver\Exception\WebDriverException; use Facebook\WebDriver\JavaScriptExecutor; use Facebook\WebDriver\WebDriver; use Facebook\WebDriver\WebDriverExpectedCondition; @@ -30,6 +32,7 @@ use Symfony\Component\Panther\DomCrawler\Crawler; use Symfony\Component\Panther\Exception\LogicException; use Symfony\Component\Panther\PantherTestCase; +use Symfony\Component\Panther\ProcessManager\BrowserManagerInterface; use Symfony\Component\Panther\ProcessManager\ChromeManager; use Symfony\Contracts\HttpClient\HttpClientInterface; @@ -627,4 +630,37 @@ public static function providePrefersReducedMotion(): iterable yield 'Chrome' => [PantherTestCase::CHROME]; yield 'Firefox' => [PantherTestCase::FIREFOX]; } + + /** + * In order to test if destructing is fine, even when WebDriver throws exceptions, we test Client directly and use + * mocks to simulate wrong webdriver behaviour. + * + * @dataProvider provideSupportedWebDriverExceptions + */ + public function testQuitBrowserManagerDuringDeconstructionEvenIfWebDriverThrowsExceptions(\Throwable $exception): void + { + $webDriverMock = $this->createMock(WebDriver::class); + $browserManagerMock = $this->createMock(BrowserManagerInterface::class); + + $browserManagerMock->expects(self::once()) + ->method('start') + ->willReturn($webDriverMock); + $browserManagerMock->expects(self::once()) + ->method('quit'); + + $webDriverMock->expects(self::once()) + ->method('quit') + ->willThrowException($exception); + + $client = new Client($browserManagerMock); + $client->start(); + + unset($client); + } + + public static function provideSupportedWebDriverExceptions(): iterable + { + yield 'WebDriverException' => [new WebDriverException('something went wrong')]; + yield 'UnexpectedResponseException' => [UnexpectedResponseException::forError('something went wrong')]; + } }