如何让Behat等待Angular ajax调用?

时间:2014-03-03 20:41:32

标签: ajax angularjs bdd behat

我有一个报告页面,基本上是一个表格,您可以添加和删除列。添加列时,将使用angular。

获取该列的数据并使用ajax加载

考虑这个Behat场景:

Given I have a user named "Dillinger Four"
And I am on "/reports"
When I add the "User's Name" column
Then I should see "Dillinger Four"

如何让Behat等到angular的ajax调用完成?我想避免使用睡眠,因为睡眠会增加不必要的延迟,如果通话时间太长,则会失败。

我使用以下内容来等待jquery代码:

$this->getSession()->wait($duration, '(0 === jQuery.active)');

我没有找到类似的值来检查角度。

2 个答案:

答案 0 :(得分:3)

上面的链接很有用,只是为了扩展它并节省其他人一点时间。

/**
 * @Then /^I should see "([^"]*)" if I wait "([^"]*)"$/
 */
public function iShouldSeeIfIWait($text, $time)
{
    $this->spin(function($context) use ($text) {
        $this->assertPageContainsText($text);
        return true;
    }, intval($time) );
}


/**
 * Special function to wait until angular has rendered the page fully, it will keep trying until either
 * the condition is meet or the time runs out.
 * 
 * @param  function  $lambda A anonymous function
 * @param  integer $wait   Wait this length of time
 */
public function spin ($lambda, $wait = 60)
{
    for ($i = 0; $i < $wait; $i++)
    {
        try {
            if ($lambda($this)) {
                return true;
            }
        } catch (Exception $e) {
            // do nothing
        }

        sleep(1);
    }

    $backtrace = debug_backtrace();

    throw new Exception(
        "Timeout thrown by " . $backtrace[1]['class'] . "::" . $backtrace[1]['function'] . "()\n" .
        $backtrace[1]['file'] . ", line " . $backtrace[1]['line']
    );
}

然后在您的场景中使用:

然后我应该看到&#34;页面上的东西。&#34;如果我等待&#34; 5&#34;

答案 1 :(得分:1)

您可以使用Angular的Protractor库中的代码来等待加载。在这里你可以找到一个函数waitForAngular()。它只是等待具有相同名称的client-side function 这是有效的PHP代码。

class WebContext implements Context
{
    /**
     * @Then the list of products should be:
     */
    public function theListOfProductsShouldBe(TableNode $table)
    {
        $this->waitForAngular();
        // ...
    }

    private function waitForAngular()
    {
        // Wait for angular to load
        $this->getSession()->wait(1000, "typeof angular != 'undefined'");
        // Wait for angular to be testable
        $this->getPage()->evaluateScript(
            'angular.getTestability(document.body).whenStable(function() {
                window.__testable = true;
            })'
        );
        $this->getSession()->wait(1000, 'window.__testable == true');
    }  
}