我正在使用Behat和Mink与Selenium2驱动程序,我正在尝试直接键入表单字段(模拟原始键盘输入),而不是使用fillField()
函数。
这就是我正在尝试的:
$element = $this->getSession()->getPage()->find('css', '#questionName');
$element->focus();
$element->keyPress('a');
// also tried this, with no success
// $element->keyDown('a');
// $element->keyUp('a');
页面上有一个<input type="text" id="questionName">
元素。它正确接收焦点,但不响应任何模拟键盘输入。
是否可以像这样模拟原始键盘输入?
我做错了什么?
答案 0 :(得分:13)
似乎有很多帖子抱怨keyPress无法正常工作,而且有些驱动程序根本不支持它。 e.g:
Goutte - Keyboard manipulations are not supported by Behat\Mink\Driver\GoutteDriver
Selenium驱动程序特别使用自定义js库来运行它的命令,但它似乎不起作用。我已经尝试过使用$this->getSession()->getDriver()->keyPress()
和$element->getPress()
而没有运气。
https://github.com/Behat/MinkSelenium2Driver/blob/master/src/Behat/Mink/Driver/Selenium2/syn.js
有趣的是,Selenium2代码库中没有针对keyPress事件的单元测试(因此我假设它目前正在开发中)。
所以,目前,一个适当的解决方案是使用来自Is it possible to simulate key press events programmatically?的关键事件的javascript仿真(如果您不使用jQuery,请参阅此替代方案)和Behat Mink的evaluateScript函数。
如果您使用直接的PHPUnit进行测试:
$key = 'a';
$script = "jQuery.event.trigger({ type : 'keypress', which : '" . $key . "' });";
$this->getSession()->evaluateScript($script);
或者,如果您使用的是Cucumber,请将此添加到您的FeatureContext.php文件中,您可以添加此功能:
/**
* @Given /^(?:|I ) manually press "([^"]*)"$/
*/
public function manuallyPress($key)
{
$script = "jQuery.event.trigger({ type : 'keypress', which : '" . $key . "' });";
$this->getSession()->evaluateScript($script);
}
并在您的功能文件中使用它:
Given I manually press "a"
至于使用javascript作为解决方案,一些驱动程序使用javascript来执行所需的keyPress。 E.g:
https://github.com/Behat/MinkZombieDriver/blob/master/src/Behat/Mink/Driver/ZombieDriver.php#L819
答案 1 :(得分:1)
我正在使用Mink和Zombie.js,因为它本身没有捕捉键盘事件,所以我都会听focusout
和keyup
jQuery事件。
$('form[name="order"]').find('input[id$="quantity"],input[id$="price"]').bind('keyup focusout', function(){
// [...] update order price
});
我已经为我解决了这个问题,但我没有尝试过Selenium2。
答案 2 :(得分:0)
我找到的最简单的答案是在javascript中触发键事件并编写一个特定的behat步骤将js发送到浏览器并触发它。
我们一直在使用YUI,因此我们使用YUI事件模拟,但jquery或本机js处理它。这个概念至关重要。这是我发现的最佳解决方案,直到本机支持为止。
希望这会有所帮助。public function press_key_in_the_ousupsub_editor($keys, $fieldlocator) {
// NodeElement.keyPress simply doesn't work.
if (!$this->running_javascript()) {
throw new coding_exception('Selecting text requires javascript.');
}
// We delegate to behat_form_field class, it will
// guess the type properly.
$field = behat_field_manager::get_form_field_from_label($fieldlocator, $this);
if (!method_exists($field, 'get_value')) {
throw new coding_exception('Field does not support the get_value function.');
}
$editorid = $this->find_field($fieldlocator)->getAttribute('id');
// Get query values for the range.
$js = '
function TriggerKeyPressBehat() {
// http://www.wfimc.org/public/js/yui/3.4.1/docs/event/simulate.html
YUI().use(\'node-event-simulate\', function(Y) {
var id = "'.$editorid.'";
var node = Y.one("#" + id + "editable");
node.focus();
var keyEvent = "keypress";
if (Y.UA.webkit || Y.UA.ie) {
keyEvent = "keydown";
}
// Key code (up arrow) for the keyboard shortcut which triggers this button:
var keys = ['.$keys.'];
for(var i=0; i<keys.length;i++) {
node.simulate(keyEvent, { charCode: keys[i] });
}
});
}
TriggerKeyPressBehat();';
$this->getSession()->executeScript($js);
}