2013-06-27 5 views
9

Ich benutze Behat und Mink mit dem Selenium2-Treiber, und ich versuche, direkt in ein Formularfeld einzugeben (Simulation der unformatierten Tastatureingabe), anstatt die fillField()-Funktion zu verwenden. DieseKann ich rohe Tastatureingabe mit Mink und Selenium2 senden?

ist, was ich versuche:

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

$element->keyPress('a'); 

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

Es ist ein <input type="text" id="questionName"> Element auf der Seite. Es empfängt den Fokus korrekt, reagiert jedoch nicht auf die simulierte Tastatureingabe.

Ist es möglich, rohe Tastatureingaben so zu simulieren?
Was mache ich falsch?

Antwort

12

Es scheint eine Menge Beiträge zu geben, die sich darüber beschweren, dass keyPress nicht wie vorgesehen funktioniert und einige Treiber überhaupt nicht unterstützen. z.B .:

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

Der Selen-Treiber insbesondere verwendet eine benutzerdefinierte js Bibliothek ist es, Befehle auszuführen, es ist jedoch nicht zu funktionieren scheint. Ich habe versucht, die $this->getSession()->getDriver()->keyPress() und die $element->getPress() ohne Glück zu verwenden.

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

Was interessant ist, ist, dass es keine Unit-Tests für die keyPress Veranstaltung sind in der Selenium2 Code-Basis noch (so gehe ich davon aus, es ist derzeit in der Entwicklung).

Für den Augenblick ist eine adäquate Lösung, die Javascript-Emulation von Schlüsselereignissen von Is it possible to simulate key press events programmatically? zu verwenden (sehen Sie dies für eine Alternative, wenn Sie jQuery nicht verwenden) und behat Minks evaluateScript-Funktion.

Wenn Sie gerade PHPUnit Test verwenden:

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

Oder wenn Sie mit Gurke, fügen Sie diese zu Ihrer FeatureContext.php Datei, die Sie diese Funktion hinzufügen:

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

Und verwenden Sie es in Ihrer Feature-Datei wie folgt:

Given I manually press "a" 

Wie für die Verwendung des Javascript als Lösung, einige der Fahrer verwenden Javascript, um die erforderliche keyPress durchzuführen. Z.B .:

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

0

Die einfachste Antwort, die ich gefunden habe, ist das Schlüsselereignis in Javascript auszulösen und einen spezifischen Behat Schritt die js an den Browser zu senden und lösen sie schreiben.

Wir haben YUI verwendet, also verwenden wir das YUI-Ereignis simulieren, aber jquery oder native js behandelt es. Das Konzept ist was zählt. Es ist die beste Lösung, die ich gefunden habe, bis der native Behat-Support da ist.

hoffe das hilft.

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

Ich benutze Mink mit Zombie.js und da es Tastaturereignisse nativ nicht abfängt, höre ich beide focusout und keyup jQuery-Ereignisse.

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

Ich habe das Problem für mich gelöst, aber ich habe es nicht mit Selenium2 versucht.