Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I send raw keyboard input using Mink and Selenium2?

I am using Behat and Mink with the Selenium2 driver, and I'm trying to type directly into a form field (simulating raw keyboard input), instead of using the fillField() function.

This is what I'm trying:

$element = $this->getSession()->getPage()->find('css', '#questionName');
$element->focus();

$element->keyPress('a');

// also tried this, with no success
// $element->keyDown('a');
// $element->keyUp('a');

There is an <input type="text" id="questionName"> element on the page. It correctly receives the focus, but does not respond to any of the simulated keyboard input.

Is it possible to simulate raw keyboard input like this?
What am I doing wrong?

like image 419
jcsanyi Avatar asked Jun 27 '13 02:06

jcsanyi


2 Answers

There seems to be a lot of posts complaining about keyPress not working as intended and some drivers don't support it at all. e.g.:

Goutte - Keyboard manipulations are not supported by Behat\Mink\Driver\GoutteDriver

The Selenium driver in particular uses a custom js library to run it's commands, however it doesn't seem to work. I've tried using both the $this->getSession()->getDriver()->keyPress() and the $element->getPress() without luck.

https://github.com/Behat/MinkSelenium2Driver/blob/master/src/Behat/Mink/Driver/Selenium2Driver.php#L815

https://github.com/Behat/MinkSelenium2Driver/blob/master/src/Behat/Mink/Driver/Selenium2/syn.js

What is interesting is that there are no unit tests for the keyPress event in the Selenium2 code base yet (so I assume it's currently in development).

So, for the moment, an adequate solution is to use the javascript emulation of key events from Is it possible to simulate key press events programmatically? (see this for an alternative if you're not using jQuery) and Behat Mink's evaluateScript function.

If you're using straight PHPUnit to test:

$key = 'a';
$script = "jQuery.event.trigger({ type : 'keypress', which : '" . $key . "' });";
$this->getSession()->evaluateScript($script);

Or if you're using Cucumber, add this to your FeatureContext.php file you can add this function:

/**
 * @Given /^(?:|I ) manually press "([^"]*)"$/
 */
public function manuallyPress($key)
{
    $script = "jQuery.event.trigger({ type : 'keypress', which : '" . $key . "' });";
    $this->getSession()->evaluateScript($script);
}

And use it in your feature file like this:

Given I manually press "a"

As for using the javascript as the solution, some of the drivers use javascript to perform the required keyPress. E.g.:

https://github.com/Behat/MinkZombieDriver/blob/master/src/Behat/Mink/Driver/ZombieDriver.php#L819

like image 134
Tom Avatar answered Oct 20 '22 10:10

Tom


I'm using Mink with Zombie.js and as it does not catching keyboard events natively, I both listen to focusout and keyup jQuery events.

$('form[name="order"]').find('input[id$="quantity"],input[id$="price"]').bind('keyup focusout', function(){
// [...] update order price
});

I has solved the problem for me but I didn't try it with Selenium2.

like image 45
Jeremy Jumeau Avatar answered Oct 20 '22 09:10

Jeremy Jumeau