2012-09-25 87 views
9

方案:修改並保存不完整修改了廣告系列如何讓Behat等待AJAX​​調用?

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 

的一點是,在最後的步驟中,該「錯誤氣球」是一個Ajax調用那麼這將帶來一個綠色或紅色的氣球根據成功操作。目前我所做的是在 之後「然後我按下Save ...」我會做一個睡眠(3),讓它有時間讓這個氣球出現。這似乎不是很聰明,因爲你在浪費時間,也因爲有時可能需要更多或更少的時間處理這個電話。

你們是怎麼讓你的behat測試等待Ajax做的,而不是讓這些野獸睡覺?

非常感謝您的任何反饋!

+0

顯示一些代碼? – StaticVariable

回答

26

這是通過等待您未完成的ajax調用達到0來完成的。jQuery.active將爲您檢查。

在你的FeatureContext.php中,你可以做類似的事情;

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

並確保您使用運行javascript和ajax的貂皮驅動程序(默認不)。

1

如果您正在使用Prototypejs(如Magento的),等效代碼:

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

哪裏是$持續時間變量來自? –

+0

http://mink.behat.org/api/behat/mink/session.html#wait() '公共無效等待(整數時間,字符串條件) 等待一段時間或直到JS條件變爲真。 – Steff

+0

只需更新該鏈接,儘管我已經使用了行號,它無疑會很快過時:https://github.com/Behat/Mink/blob/master/src/Behat/Mink/Session.php #L318-L329 – DanielM

2

我通過等待DOM改變作爲Ajax調用的結果做到這一點。我做了DocumentElement的子類,稱其AsyncDocumentElement並重寫的findAll方法:

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

然後在\貝哈特\水貂\會議,我改變了構造函數使用類。

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

一旦我這樣做了,我發現我的AngularJS測試正在工作。到目前爲止,我只在Firefox中測試過。