【问题标题】:Can I send raw keyboard input using Mink and Selenium2?我可以使用 Mink 和 Selenium2 发送原始键盘输入吗?
【发布时间】:2016-05-04 18:57:19
【问题描述】:

我将 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"> 元素。它正确接收焦点,但不响应任何模拟键盘输入。

是否可以像这样模拟原始键盘输入?
我做错了什么?

【问题讨论】:

    标签: php selenium-webdriver behat mink


    【解决方案1】:

    似乎有很多帖子抱怨 keyPress 无法按预期工作,并且一些驱动程序根本不支持它。例如:

    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/Selenium2Driver.php#L815

    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 来执行所需的按键。例如:

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

    【讨论】:

      【解决方案2】:

      我将 Mink 与 Zombie.js 一起使用,由于它本身不捕捉键盘事件,我都听 focusoutkeyup jQuery 事件。

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

      我已经为我解决了这个问题,但我没有尝试使用 Selenium2。

      【讨论】:

        【解决方案3】:

        我找到的最简单的答案是在javascript中触发关键事件并编写一个特定的behat步骤将js发送到浏览器并触发它。

        我们一直在使用 YUI,所以我们使用 YUI 事件模拟,但 jquery 或原生 js 处理它。概念才是最重要的。在原生 behat 支持出现之前,这是我找到的最佳解决方案。

        希望这会有所帮助。

        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);
            }
        

        【讨论】:

          猜你喜欢
          • 2022-11-25
          • 1970-01-01
          • 1970-01-01
          • 2011-01-05
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多