From ed548e8d0f87f18780c16be88a78efbc9112af16 Mon Sep 17 00:00:00 2001 From: Oleg Andreyev Date: Thu, 29 Aug 2024 23:38:16 +0300 Subject: [PATCH 01/14] Update ci.yml Execute CI on 1.3.x --- .github/workflows/ci.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 87ee2b5..7f9a385 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -2,9 +2,11 @@ on: push: branches: - master + - 1.3 pull_request: branches: - master + - 1.3 env: DRIVER_URL: "http://localhost:4444" From 8acd60a70d51b7d47da95e0bfd66571792f1ebe4 Mon Sep 17 00:00:00 2001 From: Oleg Andreyev Date: Wed, 13 Nov 2024 10:15:45 +0200 Subject: [PATCH 02/14] phpcs --- src/WebDriver.php | 58 +++++++++++++++++++++++------------------------ 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/src/WebDriver.php b/src/WebDriver.php index ab26009..913fb77 100755 --- a/src/WebDriver.php +++ b/src/WebDriver.php @@ -215,7 +215,7 @@ private function executeJsOnXpath( string $xpath, #[Language('javascript')] string $script, - bool $sync = true + bool $sync = true, ): mixed { $element = $this->findElement($xpath); @@ -496,7 +496,7 @@ public function getWindowName() public function findElementXpaths( #[Language('xpath')] - $xpath + $xpath, ) { $nodes = $this->webDriver->findElements(WebDriverBy::xpath($xpath)); @@ -510,7 +510,7 @@ public function findElementXpaths( public function getTagName( #[Language('xpath')] - $xpath + $xpath, ) { $element = $this->findElement($xpath); @@ -519,7 +519,7 @@ public function getTagName( public function getText( #[Language('xpath')] - $xpath + $xpath, ) { $element = $this->findElement($xpath); $text = $element->getText(); @@ -534,7 +534,7 @@ public function getText( */ public function getHtml( #[Language('xpath')] - $xpath + $xpath, ) { return $this->executeJsOnXpath($xpath, 'return {{ELEMENT}}.innerHTML;'); } @@ -544,7 +544,7 @@ public function getHtml( */ public function getOuterHtml( #[Language('xpath')] - $xpath + $xpath, ) { return $this->executeJsOnXpath($xpath, 'return {{ELEMENT}}.outerHTML;'); } @@ -558,7 +558,7 @@ public function getOuterHtml( public function getAttribute( #[Language('xpath')] $xpath, - $name + $name, ) { $element = $this->findElement($xpath); @@ -599,7 +599,7 @@ private function hasAttribute(WebDriverElement $element, $name) */ public function getValue( #[Language('xpath')] - $xpath + $xpath, ) { $element = $this->findElement($xpath); $elementName = strtolower($element->getTagName()); @@ -665,7 +665,7 @@ public function getValue( public function setValue( #[Language('xpath')] $xpath, - $value + $value, ) { $element = $this->findElement($xpath); $elementName = strtolower($element->getTagName()); @@ -765,7 +765,7 @@ public function setValue( */ public function check( #[Language('xpath')] - $xpath + $xpath, ) { $element = $this->findElement($xpath); $this->ensureInputType($element, $xpath, 'checkbox', 'check'); @@ -787,7 +787,7 @@ public function check( */ public function uncheck( #[Language('xpath')] - $xpath + $xpath, ) { $element = $this->findElement($xpath); $this->ensureInputType($element, $xpath, 'checkbox', 'uncheck'); @@ -806,7 +806,7 @@ public function uncheck( */ public function isChecked( #[Language('xpath')] - $xpath + $xpath, ) { return $this->isSelected($xpath); } @@ -828,7 +828,7 @@ public function selectOption( #[Language('xpath')] $xpath, $value, - $multiple = false + $multiple = false, ) { $element = $this->findElement($xpath); $tagName = strtolower($element->getTagName()); @@ -866,7 +866,7 @@ public function selectOption( */ public function isSelected( #[Language('xpath')] - $xpath + $xpath, ) { $element = $this->findElement($xpath); @@ -880,7 +880,7 @@ public function isSelected( */ public function click( #[Language('xpath')] - $xpath + $xpath, ) { $element = $this->findElement($xpath); $this->clickOnElement($element); @@ -952,7 +952,7 @@ private function clickOnElement(WebDriverElement $element) */ public function doubleClick( #[Language('xpath')] - $xpath + $xpath, ) { $element = $this->findElement($xpath); $this->webDriver->action()->doubleClick($element)->perform(); @@ -965,7 +965,7 @@ public function doubleClick( */ public function rightClick( #[Language('xpath')] - $xpath + $xpath, ) { $element = $this->findElement($xpath); $this->webDriver->action()->contextClick($element)->perform(); @@ -982,7 +982,7 @@ public function rightClick( public function attachFile( #[Language('xpath')] $xpath, - $path + $path, ) { $element = $this->findElement($xpath); $this->ensureInputType($element, $xpath, 'file', 'attach a file on'); @@ -994,7 +994,7 @@ public function attachFile( public function isVisible( #[Language('xpath')] - $xpath + $xpath, ) { $element = $this->findElement($xpath); @@ -1008,7 +1008,7 @@ public function isVisible( */ public function mouseOver( #[Language('xpath')] - $xpath + $xpath, ) { $element = $this->findElement($xpath); $this->webDriver->action()->moveToElement($element)->perform(); @@ -1029,7 +1029,7 @@ private function mouseOverElement(WebDriverElement $element) */ public function focus( #[Language('xpath')] - $xpath + $xpath, ) { $element = $this->findElement($xpath); $action = $this->webDriver->action(); @@ -1047,7 +1047,7 @@ public function focus( */ public function blur( #[Language('xpath')] - $xpath + $xpath, ) { $element = $this->findElement($xpath); @@ -1067,7 +1067,7 @@ public function keyPress( $xpath, $char, - $modifier = null + $modifier = null, ) { $this->sendKey($xpath, $char, $modifier); } @@ -1092,7 +1092,7 @@ public function keyDown( #[Language('xpath')] $xpath, $char, - $modifier = null + $modifier = null, ) { // Own implementation of https://github.com/php-webdriver/php-webdriver/pull/803 $element = $this->findElement($xpath); @@ -1125,7 +1125,7 @@ public function keyUp( #[Language('xpath')] $xpath, $char, - $modifier = null + $modifier = null, ) { // Own implementation of https://github.com/php-webdriver/php-webdriver/pull/803 $element = $this->findElement($xpath); @@ -1245,7 +1245,7 @@ public function resizeWindow($width, $height, $name = null) */ public function submitForm( #[Language('xpath')] - $xpath + $xpath, ) { $element = $this->findElement($xpath); $element->submit(); @@ -1286,7 +1286,7 @@ public function getWebDriverSessionId() */ private function findElement( #[Language('xpath')] - $xpath + $xpath, ) { return $this->webDriver->findElement(WebDriverBy::xpath($xpath)); } @@ -1307,7 +1307,7 @@ private function ensureInputType( #[Language('xpath')] $xpath, $type, - $action + $action, ) { if ('input' !== strtolower($element->getTagName()) || $type !== strtolower($element->getAttribute('type') ?: 'text')) { $message = 'Impossible to %s the element with XPath "%s" as it is not a %s input'; @@ -1373,7 +1373,7 @@ private function sendKey( #[Language('xpath')] $xpath, $char, - $modifier + $modifier, ) { $element = $this->findElement($xpath); $char = $this->decodeChar($char); From 7c0101328deb62f91a254d21abd4736e6d328388 Mon Sep 17 00:00:00 2001 From: Oleg Andreyev Date: Wed, 13 Nov 2024 12:33:04 +0200 Subject: [PATCH 03/14] - updated chrome.sh/firefox.sh to download driver using bdi - fixing firefox options - update shell scripts --- .gitignore | 3 ++- bin/browser/chrome.sh | 19 +-------------- bin/browser/firefox.sh | 27 +-------------------- bin/start_driver.sh | 2 +- bin/start_webserver.sh | 22 +++++++++++++++-- composer.json | 3 ++- phpunit.xml.dist | 51 ++++++++++++++++++--------------------- tests/WebDriverConfig.php | 23 +++++++++++++----- 8 files changed, 68 insertions(+), 82 deletions(-) diff --git a/.gitignore b/.gitignore index 62abc64..4f435f9 100644 --- a/.gitignore +++ b/.gitignore @@ -9,9 +9,10 @@ logs/ vendor-bin/**/vendor/ bin/ vendor/ -composer.lock !bin/browser !bin/start_driver.sh !bin/start_webserver.sh .phpunit.result.cache .php-cs-fixer.cache +driver.zip +driver.tar.gz diff --git a/bin/browser/chrome.sh b/bin/browser/chrome.sh index 953c3c7..9ddcddf 100755 --- a/bin/browser/chrome.sh +++ b/bin/browser/chrome.sh @@ -5,25 +5,8 @@ set -ex MACHINE_FAMILY=$1 DRIVER_VERSION=$2 -if [[ "$DRIVER_VERSION" == "latest" ]]; then - DRIVER_VERSION=$(curl -sS https://chromedriver.storage.googleapis.com/LATEST_RELEASE) -fi - mkdir -p chromedriver -if [[ $MACHINE_FAMILY == "windows" ]]; then - PLATFORM="win32" -fi - -if [[ $MACHINE_FAMILY == "linux" ]]; then - PLATFORM="linux64" -fi - -if [[ $MACHINE_FAMILY == "mac" ]]; then - PLATFORM="mac64" -fi - -wget -q -t 3 "https://chromedriver.storage.googleapis.com/${DRIVER_VERSION}/chromedriver_${PLATFORM}.zip" -O driver.zip -unzip -qo driver.zip -d chromedriver/ +./bin/bdi -vvv driver:chromedriver --driver-version=$DRIVER_VERSION --os=$MACHINE_FAMILY ./chromedriver ./chromedriver/chromedriver --port=4444 --verbose --enable-chrome-logs --whitelisted-ips= diff --git a/bin/browser/firefox.sh b/bin/browser/firefox.sh index 90f04b3..9953914 100755 --- a/bin/browser/firefox.sh +++ b/bin/browser/firefox.sh @@ -5,33 +5,8 @@ set -ex MACHINE_FAMILY=$1 DRIVER_VERSION=$2 -if [[ "$DRIVER_VERSION" == "latest" ]]; then - DRIVER_VERSION=$(curl -sS https://api.github.com/repos/mozilla/geckodriver/releases/latest | grep -E -o 'tag_name([^,]+)' | tr -d \" | tr -d " " | cut -d':' -f2) -fi - mkdir -p geckodriver -EXTENSION="tar.gz" - -if [[ $MACHINE_FAMILY == "windows" ]]; then - PLATFORM="win64" - EXTENSION="zip" -fi - -if [[ $MACHINE_FAMILY == "linux" ]]; then - PLATFORM="linux64" -fi - -if [[ $MACHINE_FAMILY == "mac" ]]; then - PLATFORM="macos" -fi - -wget -q -t 3 "https://github.com/mozilla/geckodriver/releases/download/${DRIVER_VERSION}/geckodriver-$DRIVER_VERSION-${PLATFORM}.${EXTENSION}" -O "driver.${EXTENSION}" - -if [[ "$EXTENSION" == "tar.gz" ]]; then - tar -xf driver.tar.gz -C ./geckodriver/; -else - unzip -qo driver.zip -d geckodriver/ -fi; +./bin/bdi -vvv driver:geckodriver --driver-version=$DRIVER_VERSION --os=$MACHINE_FAMILY ./geckodriver ./geckodriver/geckodriver --host 127.0.0.1 -vv --port 4444 diff --git a/bin/start_driver.sh b/bin/start_driver.sh index 8049a8a..0abf5b3 100755 --- a/bin/start_driver.sh +++ b/bin/start_driver.sh @@ -29,7 +29,7 @@ UNAME=$(uname -s) case "$UNAME" in *NT*) MACHINE_FAMILY=windows ;; Linux*) MACHINE_FAMILY=linux ;; -Darwin*) MACHINE_FAMILY=mac ;; +Darwin*) MACHINE_FAMILY=macos ;; esac if [ -z "$BROWSER_NAME" ]; then diff --git a/bin/start_webserver.sh b/bin/start_webserver.sh index c61d1b8..7860faa 100755 --- a/bin/start_webserver.sh +++ b/bin/start_webserver.sh @@ -2,12 +2,25 @@ set -ex +WEBSERVER_PID=0 + +function stop() { + echo "Stopping PHP server" + kill -9 $WEBSERVER_PID +} + +trap stop INT +trap stop ERR +trap stop EXIT + +echo "Starting PHP server on port 8002" # see https://github.com/minkphp/driver-testsuite/pull/28 export USE_ZEND_ALLOC=0 -php -S localhost:8002 -t ./vendor/mink/driver-testsuite/web-fixtures - +php -S localhost:8002 -t ./vendor/mink/driver-testsuite/web-fixtures & WEBSERVER_PID=$! +echo "Started PHP server on port 8002, pid $WEBSERVER_PID" +echo "Waiting for PHP server to be ready..." ATTEMPT=0 until $(echo | nc localhost 8002); do if [ $ATTEMPT -gt 5 ]; then @@ -19,4 +32,9 @@ until $(echo | nc localhost 8002); do echo waiting for PHP server on port 8002...; ATTEMPT=$((ATTEMPT + 1)) done; + echo "PHP server started" +while true; do + echo "PHP server is running" + sleep 1 +done diff --git a/composer.json b/composer.json index 67d2398..bad014c 100644 --- a/composer.json +++ b/composer.json @@ -37,7 +37,8 @@ "mink/driver-testsuite": "dev-integration-branch", "behat/mink-extension": "^2.3", "bamarni/composer-bin-plugin": "^1.8", - "jetbrains/phpstorm-attributes": "^1.0" + "jetbrains/phpstorm-attributes": "^1.0", + "dbrekelmans/bdi": "^1.3" }, "scripts": { "bin": "echo 'bin not installed'", diff --git a/phpunit.xml.dist b/phpunit.xml.dist index c152bf7..b11ca13 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -1,48 +1,45 @@ - + + + ./src + + tests vendor/mink/driver-testsuite/tests - - - - - - - - - - - - - - - - - + + + + + - + - + + + + + + + + + + + + - - - - ./src - - diff --git a/tests/WebDriverConfig.php b/tests/WebDriverConfig.php index 50d590a..7a0536b 100644 --- a/tests/WebDriverConfig.php +++ b/tests/WebDriverConfig.php @@ -5,6 +5,7 @@ use Behat\Mink\Tests\Driver\AbstractConfig; use Facebook\WebDriver\Chrome\ChromeOptions; use Facebook\WebDriver\Firefox\FirefoxDriver; +use Facebook\WebDriver\Firefox\FirefoxOptions; use Facebook\WebDriver\Firefox\FirefoxProfile; use Facebook\WebDriver\Remote\DesiredCapabilities; use OAndreyev\Mink\Driver\WebDriver; @@ -122,29 +123,39 @@ private function buildChromeOptions(DesiredCapabilities $desiredCapabilities, Ch */ private function buildFirefoxProfile(DesiredCapabilities $desiredCapabilities, FirefoxProfile $optionsOrProfile, array $driverOptions): FirefoxProfile { + /** @var FirefoxOptions|array $firefoxOptions */ if (isset($driverOptions['binary'])) { - $firefoxOptions = $desiredCapabilities->getCapability('moz:firefoxOptions'); + $firefoxOptions = $desiredCapabilities->getCapability(FirefoxOptions::CAPABILITY); if (empty($firefoxOptions)) { $firefoxOptions = []; } + if ($firefoxOptions instanceof FirefoxOptions) { + $firefoxOptions = $firefoxOptions->toArray(); + } $firefoxOptions = array_merge($firefoxOptions, ['binary' => $driverOptions['binary']]); - $desiredCapabilities->setCapability('moz:firefoxOptions', $firefoxOptions); + $desiredCapabilities->setCapability(FirefoxOptions::CAPABILITY, $firefoxOptions); } if (isset($driverOptions['log'])) { - $firefoxOptions = $desiredCapabilities->getCapability('moz:firefoxOptions'); + $firefoxOptions = $desiredCapabilities->getCapability(FirefoxOptions::CAPABILITY); if (empty($firefoxOptions)) { $firefoxOptions = []; } + if ($firefoxOptions instanceof FirefoxOptions) { + $firefoxOptions = $firefoxOptions->toArray(); + } $firefoxOptions = array_merge($firefoxOptions, ['log' => $driverOptions['log']]); - $desiredCapabilities->setCapability('moz:firefoxOptions', $firefoxOptions); + $desiredCapabilities->setCapability(FirefoxOptions::CAPABILITY, $firefoxOptions); } if (isset($driverOptions['args'])) { - $firefoxOptions = $desiredCapabilities->getCapability('moz:firefoxOptions'); + $firefoxOptions = $desiredCapabilities->getCapability(FirefoxOptions::CAPABILITY); if (empty($firefoxOptions)) { $firefoxOptions = []; } + if ($firefoxOptions instanceof FirefoxOptions) { + $firefoxOptions = $firefoxOptions->toArray(); + } $firefoxOptions = array_merge($firefoxOptions, ['args' => $driverOptions['args']]); - $desiredCapabilities->setCapability('moz:firefoxOptions', $firefoxOptions); + $desiredCapabilities->setCapability(FirefoxOptions::CAPABILITY, $firefoxOptions); } $preferences = isset($driverOptions['preference']) ? $driverOptions['preference'] : []; foreach ($preferences as $key => $preference) { From d7e5bd0a8597a1e68d84e72ef1467c4743f741eb Mon Sep 17 00:00:00 2001 From: Oleg Andreyev Date: Wed, 13 Nov 2024 12:48:02 +0200 Subject: [PATCH 04/14] phpcs --- tests/WebDriverConfig.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/WebDriverConfig.php b/tests/WebDriverConfig.php index 7a0536b..68ef737 100644 --- a/tests/WebDriverConfig.php +++ b/tests/WebDriverConfig.php @@ -123,7 +123,7 @@ private function buildChromeOptions(DesiredCapabilities $desiredCapabilities, Ch */ private function buildFirefoxProfile(DesiredCapabilities $desiredCapabilities, FirefoxProfile $optionsOrProfile, array $driverOptions): FirefoxProfile { - /** @var FirefoxOptions|array $firefoxOptions */ + /* @var FirefoxOptions|array $firefoxOptions */ if (isset($driverOptions['binary'])) { $firefoxOptions = $desiredCapabilities->getCapability(FirefoxOptions::CAPABILITY); if (empty($firefoxOptions)) { From cded01a6552f046a5449071eea2a6f5c880d6b5d Mon Sep 17 00:00:00 2001 From: Oleg Andreyev Date: Wed, 13 Nov 2024 12:49:34 +0200 Subject: [PATCH 05/14] moved 8.3 into stable and 8.4 into experimental --- .github/workflows/ci.yml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7f9a385..616ef36 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,12 +1,12 @@ on: push: branches: - - master - - 1.3 + - "master" + - "1.3" pull_request: branches: - - master - - 1.3 + - "master" + - "1.3" env: DRIVER_URL: "http://localhost:4444" @@ -22,7 +22,7 @@ jobs: strategy: fail-fast: false matrix: - php: [ 8.2 ] + php: [ 8.3 ] steps: - uses: actions/checkout@v4 - uses: shivammathur/setup-php@v2 @@ -50,11 +50,11 @@ jobs: strategy: fail-fast: false matrix: - php: [ 8.0, 8.1, 8.2 ] + php: [ 8.0, 8.1, 8.2, 8.3 ] browser: [ chrome, firefox ] experimental: [false] include: - - php: 8.3 + - php: 8.4 experimental: true browser: chrome continue-on-error: ${{ matrix.experimental }} From df45e1e9dcc1c0ae286c82307e3c5cbe03e22926 Mon Sep 17 00:00:00 2001 From: Oleg Andreyev Date: Wed, 13 Nov 2024 12:50:30 +0200 Subject: [PATCH 06/14] removed 8.0 EOL --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 616ef36..5085ad5 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -50,7 +50,7 @@ jobs: strategy: fail-fast: false matrix: - php: [ 8.0, 8.1, 8.2, 8.3 ] + php: [ 8.1, 8.2, 8.3 ] browser: [ chrome, firefox ] experimental: [false] include: From ed7165fc619bd528ebb6a1296047082fffa57f73 Mon Sep 17 00:00:00 2001 From: Oleg Andreyev Date: Wed, 13 Nov 2024 12:53:26 +0200 Subject: [PATCH 07/14] added phpstan-baseline.neon --- phpstan-baseline.neon | 6 ++++++ phpstan.neon | 3 +++ 2 files changed, 9 insertions(+) create mode 100644 phpstan-baseline.neon diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon new file mode 100644 index 0000000..31e10f9 --- /dev/null +++ b/phpstan-baseline.neon @@ -0,0 +1,6 @@ +parameters: + ignoreErrors: + - + message: "#^Parameter \\#1 \\$timeout_in_second of method Facebook\\\\WebDriver\\\\Remote\\\\RemoteWebDriver\\:\\:wait\\(\\) expects int, float given\\.$#" + count: 1 + path: src/WebDriver.php diff --git a/phpstan.neon b/phpstan.neon index 2c1fc66..ab13118 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -1,3 +1,6 @@ +includes: + - phpstan-baseline.neon + parameters: level: 6 paths: From a580a77e8cb88681ac05cf7b8a20b153b9f66734 Mon Sep 17 00:00:00 2001 From: Oleg Andreyev Date: Wed, 13 Nov 2024 16:00:05 +0200 Subject: [PATCH 08/14] fix tests --- composer.json | 2 +- src/WebDriver.php | 54 +++++++++++++++++++++++++++++++++++++++-------- 2 files changed, 46 insertions(+), 10 deletions(-) diff --git a/composer.json b/composer.json index bad014c..383202e 100644 --- a/composer.json +++ b/composer.json @@ -34,7 +34,7 @@ "require-dev": { "ext-json": "*", "roave/security-advisories": "dev-master", - "mink/driver-testsuite": "dev-integration-branch", + "mink/driver-testsuite": "dev-integration-branch-v2", "behat/mink-extension": "^2.3", "bamarni/composer-bin-plugin": "^1.8", "jetbrains/phpstorm-attributes": "^1.0", diff --git a/src/WebDriver.php b/src/WebDriver.php index 913fb77..bddc40f 100755 --- a/src/WebDriver.php +++ b/src/WebDriver.php @@ -302,8 +302,18 @@ public function stop() * * @throws UnsupportedDriverActionException */ - public function reset() + public function reset(): void { + $currentWindowName = $this->getWindowName(); + foreach ($this->getWindowNames() as $windowName) { + if ($windowName === $currentWindowName) { + continue; + } + + $this->switchToWindow($windowName); + $this->webDriver->close(); + } + $this->switchToWindow($currentWindowName); $this->webDriver->manage()->deleteAllCookies(); // TODO: resizeWindow does not accept NULL $this->maximizeWindow(); @@ -417,13 +427,16 @@ public function switchToWindow($name = null) /** * @param string $name - * - * @return void */ - public function switchToIFrame($name = null) + public function switchToIFrame($name = null): void { if ($name) { - $element = $this->webDriver->findElement(WebDriverBy::name($name)); + try { + $element = $this->webDriver->findElement(WebDriverBy::name($name)); + } catch (NoSuchElementException) { + $element = $this->webDriver->findElement(WebDriverBy::id($name)); + } + $this->webDriver->switchTo()->frame($element); } else { $this->webDriver->switchTo()->defaultContent(); @@ -653,8 +666,6 @@ public function getValue( * @param string $xpath * @param string|string[] $value * - * @return void - * * @throws DriverException * @throws ElementNotInteractableException * @throws NoSuchElementException @@ -664,13 +675,17 @@ public function getValue( */ public function setValue( #[Language('xpath')] - $xpath, + string $xpath, $value, - ) { + ): void { $element = $this->findElement($xpath); $elementName = strtolower($element->getTagName()); if ('select' === $elementName) { + if (is_bool($value)) { + throw new DriverException(sprintf('Impossible to set %s value an element with XPath "%s" as it is a select input', gettype($value), $xpath)); + } + $select = new WebDriverSelect($element); if (is_array($value)) { @@ -703,6 +718,10 @@ public function setValue( } if ('radio' === $elementType) { + if (is_bool($value) || is_array($value)) { + throw new DriverException(sprintf('Impossible to set %s value an element with XPath "%s" as it is a radio input', gettype($value), $xpath)); + } + $radios = new WebDriverRadios($element); $radios->selectByValue($value); @@ -710,6 +729,10 @@ public function setValue( } if ('file' === $elementType) { + if (is_array($value) || is_bool($value)) { + throw new DriverException(sprintf('Impossible to set %s value an element with XPath "%s" as it is a file input', gettype($value), $xpath)); + } + $this->attachFile($xpath, $value); return; @@ -719,6 +742,10 @@ public function setValue( // Each OS will show native color picker // See https://code.google.com/p/selenium/issues/detail?id=7650 if ('color' === $elementType) { + if (is_array($value) || is_bool($value)) { + throw new DriverException(sprintf('Impossible to set %s value an element with XPath "%s" as it is a color input', gettype($value), $xpath)); + } + $this->executeJsOnElement($element, sprintf('return {{ELEMENT}}.value = "%s"', $value)); return; @@ -726,6 +753,10 @@ public function setValue( // See https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement if ('date' === $elementType || 'time' === $elementType) { + if (is_array($value) || is_bool($value)) { + throw new DriverException(sprintf('Impossible to set %s value an element with XPath "%s" as it is a color input', gettype($value), $xpath)); + } + $date = date(DATE_ATOM, strtotime($value)); $this->executeJsOnElement($element, sprintf('return {{ELEMENT}}.valueAsDate = new Date("%s")', $date)); @@ -733,6 +764,11 @@ public function setValue( } } + if (in_array($elementName, ['input', 'textarea'])) { + if (is_array($value) || is_bool($value)) { + throw new DriverException(sprintf('Impossible to set %s value an element with XPath "%s" as it is a text input', gettype($value), $xpath)); + } + } $value = (string) $value; if (in_array($elementName, ['input', 'textarea'])) { From 1b2474121f8a412f27a0a5eeea000ce6909541bb Mon Sep 17 00:00:00 2001 From: Oleg Andreyev Date: Wed, 13 Nov 2024 16:04:32 +0200 Subject: [PATCH 09/14] update ci.yaml --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5085ad5..953cfab 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -32,7 +32,7 @@ jobs: extensions: zip, :xdebug tools: composer - id: composer-cache - run: echo "::set-output name=directory::$(composer config cache-dir)" + run: echo "directory=$(composer config cache-dir)" >> $GITHUB_OUTPUT - uses: actions/cache@v4 with: path: ${{ steps.composer-cache.outputs.directory }} @@ -73,7 +73,7 @@ jobs: - name: Determine composer cache directory id: composer-cache - run: echo "::set-output name=directory::$(composer config cache-dir)" + run: echo "directory=$(composer config cache-dir)" >> $GITHUB_OUTPUT - name: Cache composer dependencies uses: actions/cache@v4 From 02cfb10b2ca639c61643a7297d2f394986a3411b Mon Sep 17 00:00:00 2001 From: Oleg Andreyev Date: Wed, 13 Nov 2024 16:10:44 +0200 Subject: [PATCH 10/14] trigger --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index ab00342..8b36780 100644 --- a/README.md +++ b/README.md @@ -42,4 +42,4 @@ Follow https://github.com/shivammathur/setup-php#local-testing-setup ## Copyright -Copyright (c) 2023 Oleg Andreyev +Copyright (c) 2024 Oleg Andreyev From c144f639ae7c958e23183230a3e58e17ba43df48 Mon Sep 17 00:00:00 2001 From: Oleg Andreyev Date: Wed, 13 Nov 2024 16:12:43 +0200 Subject: [PATCH 11/14] phpcs --- src/WebDriver.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/WebDriver.php b/src/WebDriver.php index bddc40f..25d833c 100755 --- a/src/WebDriver.php +++ b/src/WebDriver.php @@ -298,8 +298,6 @@ public function stop() } /** - * @return void - * * @throws UnsupportedDriverActionException */ public function reset(): void From ead03e1735d004758edce9cb44fe9a35d1e16df4 Mon Sep 17 00:00:00 2001 From: Oleg Andreyev Date: Wed, 13 Nov 2024 16:15:13 +0200 Subject: [PATCH 12/14] phpstan --- phpstan-baseline.neon | 5 +++++ src/WebDriver.php | 5 ++--- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index 31e10f9..dca0746 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -1,5 +1,10 @@ parameters: ignoreErrors: + - + message: "#^Method OAndreyev\\\\Mink\\\\Driver\\\\WebDriver\\:\\:setValue\\(\\) has parameter \\$value with no value type specified in iterable type array\\.$#" + count: 1 + path: src/WebDriver.php + - message: "#^Parameter \\#1 \\$timeout_in_second of method Facebook\\\\WebDriver\\\\Remote\\\\RemoteWebDriver\\:\\:wait\\(\\) expects int, float given\\.$#" count: 1 diff --git a/src/WebDriver.php b/src/WebDriver.php index 25d833c..5a0988b 100755 --- a/src/WebDriver.php +++ b/src/WebDriver.php @@ -661,8 +661,7 @@ public function getValue( } /** - * @param string $xpath - * @param string|string[] $value + * @param string $xpath * * @throws DriverException * @throws ElementNotInteractableException @@ -674,7 +673,7 @@ public function getValue( public function setValue( #[Language('xpath')] string $xpath, - $value, + mixed $value, ): void { $element = $this->findElement($xpath); $elementName = strtolower($element->getTagName()); From b9ac75e9f96eaf05b74f33db99e87a7a9c3048e5 Mon Sep 17 00:00:00 2001 From: Oleg Andreyev Date: Wed, 13 Nov 2024 16:18:55 +0200 Subject: [PATCH 13/14] phpcs --- .php-cs-fixer.dist.php | 1 + src/WebDriver.php | 24 ++++++++++++------------ tests/WebDriverConfig.php | 2 +- 3 files changed, 14 insertions(+), 13 deletions(-) diff --git a/.php-cs-fixer.dist.php b/.php-cs-fixer.dist.php index e9a857c..f32a9c7 100644 --- a/.php-cs-fixer.dist.php +++ b/.php-cs-fixer.dist.php @@ -10,6 +10,7 @@ return (new PhpCsFixer\Config()) ->setRiskyAllowed(true) ->setRules([ + '@PHP81Migration' => true, '@Symfony' => true, ]) ->setFinder($finder); diff --git a/src/WebDriver.php b/src/WebDriver.php index 5a0988b..5e919e7 100755 --- a/src/WebDriver.php +++ b/src/WebDriver.php @@ -779,11 +779,11 @@ public function setValue( // Trigger a change event. $script = <<executeJsOnXpath($xpath, $script); } @@ -925,15 +925,15 @@ public function click( private function scrollElementIntoViewIfRequired(WebDriverElement $element) { $js = <<executeJsOnElement($element, $js); } diff --git a/tests/WebDriverConfig.php b/tests/WebDriverConfig.php index 68ef737..5aad152 100644 --- a/tests/WebDriverConfig.php +++ b/tests/WebDriverConfig.php @@ -157,7 +157,7 @@ private function buildFirefoxProfile(DesiredCapabilities $desiredCapabilities, F $firefoxOptions = array_merge($firefoxOptions, ['args' => $driverOptions['args']]); $desiredCapabilities->setCapability(FirefoxOptions::CAPABILITY, $firefoxOptions); } - $preferences = isset($driverOptions['preference']) ? $driverOptions['preference'] : []; + $preferences = $driverOptions['preference'] ?? []; foreach ($preferences as $key => $preference) { $optionsOrProfile->setPreference($key, $preference); // TODO From 667e09dc21fe369ba7cd81205dfcd0a27c18e792 Mon Sep 17 00:00:00 2001 From: Oleg Andreyev Date: Wed, 13 Nov 2024 16:24:31 +0200 Subject: [PATCH 14/14] phpcs --- .php-cs-fixer.dist.php | 1 + vendor-bin/phpstan/composer.json | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/.php-cs-fixer.dist.php b/.php-cs-fixer.dist.php index f32a9c7..976956f 100644 --- a/.php-cs-fixer.dist.php +++ b/.php-cs-fixer.dist.php @@ -11,6 +11,7 @@ ->setRiskyAllowed(true) ->setRules([ '@PHP81Migration' => true, + '@PHPUnit91Migration:risky' => true, '@Symfony' => true, ]) ->setFinder($finder); diff --git a/vendor-bin/phpstan/composer.json b/vendor-bin/phpstan/composer.json index f153e5f..34dfa7a 100644 --- a/vendor-bin/phpstan/composer.json +++ b/vendor-bin/phpstan/composer.json @@ -2,7 +2,8 @@ "require-dev": { "phpstan/phpstan": "^1.9", "phpstan/phpstan-phpunit": "^1.3", - "phpstan/extension-installer": "^1.2" + "phpstan/extension-installer": "^1.2", + "phpstan/phpstan-symfony": "^1.4" }, "config": { "allow-plugins": {