2012-09-25 49 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中测试过。