From b3a563e7f02fe47350b1a8ab936d623f79b788df Mon Sep 17 00:00:00 2001 From: Alex Date: Wed, 10 Apr 2024 10:43:17 +0300 Subject: [PATCH 1/4] The "getWindowNames" and "getWindowName" methods return window names now, instead of window handles --- src/Selenium2Driver.php | 64 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 61 insertions(+), 3 deletions(-) diff --git a/src/Selenium2Driver.php b/src/Selenium2Driver.php index 3f2d1c39..29d81aac 100755 --- a/src/Selenium2Driver.php +++ b/src/Selenium2Driver.php @@ -31,6 +31,8 @@ */ class Selenium2Driver extends CoreDriver { + private const W3C_WINDOW_HANDLE_PREFIX = 'w3cwh:'; + /** * Whether the browser has been started * @var bool @@ -65,6 +67,11 @@ class Selenium2Driver extends CoreDriver */ private $timeouts = array(); + /** + * @var string|null + */ + private $initialWindowHandle = null; + /** * @var Escaper */ @@ -343,6 +350,7 @@ public function start() $this->started = true; $this->applyTimeouts(); + $this->initialWindowHandle = $this->getWebDriverSession()->window_handle(); } /** @@ -432,7 +440,40 @@ public function back() public function switchToWindow(?string $name = null) { - $this->getWebDriverSession()->focusWindow($name ?: ''); + $name = $name === null + ? $this->initialWindowHandle + : $this->getWindowHandleFromName($name); + + $this->getWebDriverSession()->focusWindow($name); + } + + /** + * @throws DriverException + */ + private function getWindowHandleFromName(string $name): string + { + // if name is actually prefixed window handle, just remove the prefix + if (strpos($name, self::W3C_WINDOW_HANDLE_PREFIX) === 0) { + return substr($name, strlen(self::W3C_WINDOW_HANDLE_PREFIX)); + } + + // ..otherwise check if any existing window has the specified name + + $origWindowHandle = $this->getWebDriverSession()->window_handle(); + + try { + foreach ($this->getWebDriverSession()->window_handles() as $handle) { + $this->getWebDriverSession()->focusWindow($handle); + + if ($this->evaluateScript('window.name') === $name) { + return $handle; + } + } + + throw new DriverException("Could not find handle of window named \"$name\""); + } finally { + $this->getWebDriverSession()->focusWindow($origWindowHandle); + } } public function switchToIFrame(?string $name = null) @@ -499,12 +540,29 @@ public function getScreenshot() public function getWindowNames() { - return $this->getWebDriverSession()->window_handles(); + $origWindow = $this->getWebDriverSession()->window_handle(); + + try { + $result = array(); + foreach ($this->getWebDriverSession()->window_handles() as $tempWindow) { + $this->getWebDriverSession()->focusWindow($tempWindow); + $result[] = $this->getWindowName(); + } + return $result; + } finally { + $this->getWebDriverSession()->focusWindow($origWindow); + } } public function getWindowName() { - return $this->getWebDriverSession()->window_handle(); + $name = (string) $this->evaluateScript('window.name'); + + if ($name === '') { + $name = self::W3C_WINDOW_HANDLE_PREFIX . $this->getWebDriverSession()->window_handle(); + } + + return $name; } /** From 256f9741748c01ef611f206b931b5543c125dd34 Mon Sep 17 00:00:00 2001 From: Alex Date: Wed, 10 Apr 2024 10:43:36 +0300 Subject: [PATCH 2/4] Close all, but main window during session reset --- src/Selenium2Driver.php | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/Selenium2Driver.php b/src/Selenium2Driver.php index 29d81aac..6303b51e 100755 --- a/src/Selenium2Driver.php +++ b/src/Selenium2Driver.php @@ -410,7 +410,20 @@ public function stop() public function reset() { - $this->getWebDriverSession()->deleteAllCookies(); + $webDriverSession = $this->getWebDriverSession(); + + // Close all windows except the initial one. + foreach ($webDriverSession->window_handles() as $windowHandle) { + if ($windowHandle === $this->initialWindowHandle) { + continue; + } + + $webDriverSession->focusWindow($windowHandle); + $webDriverSession->deleteWindow(); + } + + $this->switchToWindow(); + $webDriverSession->deleteAllCookies(); } public function visit(string $url) From 5ee4ad75c30744e9c4efbe8db0e9b1a822cbd522 Mon Sep 17 00:00:00 2001 From: Alex Date: Wed, 10 Apr 2024 10:43:55 +0300 Subject: [PATCH 3/4] Repair of the "$name" parameter for "resizeWindow" and "maximizeWindow" methods --- src/Selenium2Driver.php | 43 +++++++++++++++++++++++++++++++++-------- 1 file changed, 35 insertions(+), 8 deletions(-) diff --git a/src/Selenium2Driver.php b/src/Selenium2Driver.php index 6303b51e..0795103d 100755 --- a/src/Selenium2Driver.php +++ b/src/Selenium2Driver.php @@ -999,11 +999,13 @@ public function wait(int $timeout, string $condition) public function resizeWindow(int $width, int $height, ?string $name = null) { - $window = $this->getWebDriverSession()->window($name ?: 'current'); - \assert($window instanceof Window); - $window->postSize( - array('width' => $width, 'height' => $height) - ); + $this->withWindow($name, function () use ($width, $height) { + $window = $this->getWebDriverSession()->window('current'); + \assert($window instanceof Window); + $window->postSize( + array('width' => $width, 'height' => $height) + ); + }); } public function submitForm(string $xpath) @@ -1013,9 +1015,34 @@ public function submitForm(string $xpath) public function maximizeWindow(?string $name = null) { - $window = $this->getWebDriverSession()->window($name ?: 'current'); - \assert($window instanceof Window); - $window->maximize(); + $this->withWindow($name, function () { + $window = $this->getWebDriverSession()->window('current'); + \assert($window instanceof Window); + $window->maximize(); + }); + } + + private function withWindow(?string $name, callable $callback): void + { + if ($name === null) { + $callback(); + + return; + } + + $origName = $this->getWindowName(); + + try { + if ($origName !== $name) { + $this->switchToWindow($name); + } + + $callback(); + } finally { + if ($origName !== $name) { + $this->switchToWindow($origName); + } + } } /** From c9a24f83010461dbd9fa6396c98b1acd84c434e0 Mon Sep 17 00:00:00 2001 From: Alex Date: Fri, 28 Jun 2024 12:38:29 +0300 Subject: [PATCH 4/4] Renamed variables in the "switchToWindow" method to better explain code logic --- src/Selenium2Driver.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Selenium2Driver.php b/src/Selenium2Driver.php index 0795103d..987b5f54 100755 --- a/src/Selenium2Driver.php +++ b/src/Selenium2Driver.php @@ -453,11 +453,11 @@ public function back() public function switchToWindow(?string $name = null) { - $name = $name === null + $handle = $name === null ? $this->initialWindowHandle : $this->getWindowHandleFromName($name); - $this->getWebDriverSession()->focusWindow($name); + $this->getWebDriverSession()->focusWindow($handle); } /**