2012-09-25 10 views
9

Szenario: Ändern und eine unvollständige Änderung an eine Kampagne speichernWie kann Behath auf einen AJAX-Anruf warten?

Given I click on the Campaign section folder 
And I press Save in the selected Campaign 
Then I should see an error balloon informing the changes cannot be saved 

Punkt ist, dass dieser ‚Fehler Ballon‘ im letzten Schritt einen Ajax-Aufruf ist, die dann einen grünen oder roten Ballon nach dem für den Erfolg bringen die Operation. Momentan was ich tue, ist nach 'Und ich drücke Speichern ...' Ich werde einen Schlaf (3) tun, um es Zeit für diesen Ballon zu geben. Das scheint nicht sehr schlau zu sein, weil Sie Zeit verschwenden und weil es manchmal einige Zeit dauern kann, bis dieser Anruf bearbeitet wird.

Wie machen Sie Ihre Behat-Tests warten auf Ajax getan werden, anstatt nur die Tiere schlafen zu legen?

Vielen Dank für Feedback!

+0

Code anzeigen? – StaticVariable

Antwort

26

Dies geschieht, indem Sie darauf warten, dass Ihre ausstehenden Ajax-Aufrufe den Wert 0 erreichen. JQuery.active prüft genau das für Sie.

In Ihrer FeatureContext.php können Sie etwas wie tun;

public function iShouldSeeAnErrorBalloon($title) 
{ 
    $time = 5000; // time should be in milliseconds 
    $this->getSession()->wait($time, '(0 === jQuery.active)'); 
    // asserts below 
} 

Und stellen Sie sicher, verwenden Sie einen Nerz-Treiber, der Javascript und Ajax läuft (der Standard nicht).

1

Falls Sie PrototypeJS (z Magento), der entsprechende Code verwenden, ist:

public function iShouldSeeAnErrorBalloon($title) 
{ 
    $this->getSession()->wait($duration, '(0 === Ajax.activeRequestCount)'); 
    // asserts below 
} 
+1

Woher kommt die Variable $ duration? –

+0

http://mink.behat.org/api/behat/mink/session.html#wait() 'öffentliche void warten (ganzzahlige Zeit, String-Bedingung) Wartet einige Zeit oder bis JS-Bedingung wahr wird – Steff

+0

Ich aktualisiere nur diesen Link, obwohl ich Zeilennummern verwendet habe, wird es in Kürze nicht mehr aktuell sein: https://github.com/Behat/Mink/blob/master/src/Behat/Mink/Session.php # L318-L329 – DanielM

2

ich es wartet darauf, von für das DOM als Ergebnis der Ajax-Aufruf zu ändern. Ich habe eine Unterklasse von Document, es AsyncDocumentElement Aufruf und das Überschreiben der findAll Methode:

public function findAll($selector, $locator, $waitms=5000) 
{ 
    $xpath = $this->getSession()->getSelectorsHandler()->selectorToXpath($selector, $locator); 

    // add parent xpath before element selector 
    if (0 === strpos($xpath, '/')) { 
     $xpath = $this->getXpath().$xpath; 
    } else { 
     $xpath = $this->getXpath().'/'.$xpath; 
    } 

    $page = $this->getSession()->getPage(); 

    // my code to wait until the xpath expression provides an element 
    if ($waitms && !($this->getSession()->getDriver() instanceof \Behat\Symfony2Extension\Driver\KernelDriver)) { 
     $templ = 'document.evaluate("%s", document, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null).snapshotLength > 0;'; 

     $waitJs = sprintf($templ, $xpath); 

     $this->getSession()->wait($waitms, $waitJs); 
    } 

    return $this->getSession()->getDriver()->find($xpath); 
} 

dann in \ Behat \ Mink \ Session ich den Konstruktor geändert diese Klasse zu verwenden.

public function __construct(DriverInterface $driver, SelectorsHandler $selectorsHandler = null) 
{ 
    $driver->setSession($this); 

    if (null === $selectorsHandler) { 
     $selectorsHandler = new SelectorsHandler(); 
    } 

    $this->driver   = $driver; 
    $this->page    = new AsyncDocumentElement($this); 
    $this->selectorsHandler = $selectorsHandler; 
} 

Sobald ich dies getan habe, fand ich meine AngularJS Tests funktionierten. Bisher habe ich nur in Firefox getestet.