|
5 | 5 | namespace DrevOps\BehatSteps; |
6 | 6 |
|
7 | 7 | use Behat\Step\When; |
| 8 | +use Behat\Mink\Driver\BrowserKitDriver; |
8 | 9 | use Behat\Mink\Driver\Selenium2Driver; |
9 | 10 | use Behat\Mink\Exception\ExpectationException; |
10 | 11 | use Behat\Mink\Exception\UnsupportedDriverActionException; |
@@ -92,8 +93,11 @@ public function keyboardPressKeysOnElement(string $keys, ?string $selector): voi |
92 | 93 | public function keyboardPressKeyOnElementSingle(string $char, ?string $selector): void { |
93 | 94 | $driver = $this->getSession()->getDriver(); |
94 | 95 |
|
95 | | - if (!$driver instanceof Selenium2Driver) { |
96 | | - throw new UnsupportedDriverActionException('Method can be used only with Selenium2 driver', $driver); |
| 96 | + // Keyboard interaction needs a JavaScript-capable driver: Selenium2 uses |
| 97 | + // the bundled Syn library, chrome-mink uses native DevTools key events. |
| 98 | + // BrowserKit-based (non-JavaScript) drivers cannot dispatch key events. |
| 99 | + if ($driver instanceof BrowserKitDriver) { |
| 100 | + throw new UnsupportedDriverActionException('Keyboard interaction is only supported by JavaScript drivers (Selenium2 or Chrome).', $driver); |
97 | 101 | } |
98 | 102 |
|
99 | 103 | $keys = [ |
@@ -227,22 +231,57 @@ function getPathTo(element) { |
227 | 231 | */ |
228 | 232 | protected function keyboardTriggerKey(string $xpath, string $key): void { |
229 | 233 | $driver = $this->getSession()->getDriver(); |
230 | | - // @codeCoverageIgnoreStart |
231 | | - if (!$driver instanceof Selenium2Driver) { |
232 | | - throw new UnsupportedDriverActionException('Method can be used only with Selenium2 driver', $driver); |
| 234 | + |
| 235 | + // Selenium2 driver: reuse the bundled Syn library via reflection to inject |
| 236 | + // synthetic events and execute JS on the element. |
| 237 | + if ($driver instanceof Selenium2Driver) { |
| 238 | + $reflector = new \ReflectionClass($driver); |
| 239 | + $with_syn_reflection = $reflector->getMethod('withSyn'); |
| 240 | + $execute_js_on_xpath_reflection = $reflector->getMethod('executeJsOnXpath'); |
| 241 | + $with_syn_result = $with_syn_reflection->invoke($driver); |
| 242 | + |
| 243 | + $execute_js_on_xpath_reflection->invokeArgs($with_syn_result, [ |
| 244 | + $xpath, |
| 245 | + sprintf("syn.key({{ELEMENT}}, '%s');", $key), |
| 246 | + ]); |
| 247 | + |
| 248 | + return; |
| 249 | + } |
| 250 | + |
| 251 | + // CDP-based drivers like the Chrome (chrome-mink) driver: dispatch native |
| 252 | + // DevTools key events. Special keys are sent as a keycode down/up pair so |
| 253 | + // their default action (focus move, submit, etc.) fires; printable |
| 254 | + // characters are sent as a single character so their text is inserted. |
| 255 | + $keycodes = [ |
| 256 | + "\b" => 8, |
| 257 | + "\t" => 9, |
| 258 | + "\r" => 13, |
| 259 | + 'shift' => 16, |
| 260 | + 'ctrl' => 17, |
| 261 | + 'alt' => 18, |
| 262 | + 'pause' => 19, |
| 263 | + 'break' => 19, |
| 264 | + 'caps' => 20, |
| 265 | + 'escape' => 27, |
| 266 | + 'page-up' => 33, |
| 267 | + 'page-down' => 34, |
| 268 | + 'end' => 35, |
| 269 | + 'home' => 36, |
| 270 | + 'left' => 37, |
| 271 | + 'up' => 38, |
| 272 | + 'right' => 39, |
| 273 | + 'down' => 40, |
| 274 | + 'insert' => 45, |
| 275 | + 'delete' => 46, |
| 276 | + ]; |
| 277 | + |
| 278 | + if (isset($keycodes[$key])) { |
| 279 | + $driver->keyDown($xpath, $keycodes[$key]); |
| 280 | + $driver->keyUp($xpath, $keycodes[$key]); |
| 281 | + } |
| 282 | + else { |
| 283 | + $driver->keyPress($xpath, $key); |
233 | 284 | } |
234 | | - // @codeCoverageIgnoreEnd |
235 | | - // Use reflection to re-use Syn library injection and execution of JS on |
236 | | - // element. |
237 | | - $reflector = new \ReflectionClass($driver); |
238 | | - $with_syn_reflection = $reflector->getMethod('withSyn'); |
239 | | - $execute_js_on_xpath_reflection = $reflector->getMethod('executeJsOnXpath'); |
240 | | - $with_syn_result = $with_syn_reflection->invoke($driver); |
241 | | - |
242 | | - $execute_js_on_xpath_reflection->invokeArgs($with_syn_result, [ |
243 | | - $xpath, |
244 | | - sprintf("syn.key({{ELEMENT}}, '%s');", $key), |
245 | | - ]); |
246 | 285 | } |
247 | 286 |
|
248 | 287 | } |
0 commit comments