【问题标题】:How to make Behat wait for Angular ajax calls?如何让 Behat 等待 Angular ajax 调用?
【发布时间】:2015-02-02 23:23:09
【问题描述】:

我有一个报告页面,它基本上是一个表格,您可以从中添加和删除列。当您添加一列时,该列的数据将通过 ajax 使用 angular 获取和加载。

考虑这个 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)');

我还没有找到类似的值来检查 angular。

【问题讨论】:

标签: ajax angularjs bdd behat


【解决方案1】:

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

/**
 * @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']
    );
}

然后在你的场景中使用:

然后我应该看到“页面上有东西”。如果我等待“5”

【讨论】:

    【解决方案2】:

    您可以使用 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');
        }  
    }
    

    【讨论】:

    • $this-&gt;evaluateScript() 应该是 $this-&gt;getSession()-&gt;evaluateScript()。当我们不知道是否也加载了 angular 时,为了使这项工作正常工作,我使用了这个:ideone.com/JYO7ug - 这也有我们的 jQuery 版本。
    • 这实际上在我的套件中导致了一个错误,我注意到当我的 URL 以 # 结尾时,当此行被执行时,页面重新加载而没有 # - 导致一个全新的页面加载。
    猜你喜欢
    • 1970-01-01
    • 2019-05-05
    • 1970-01-01
    • 2011-02-19
    • 2011-11-15
    • 1970-01-01
    • 2010-10-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多