10

シナリオ:キャンペーンへの不完全な変更を変更して保存します

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呼び出しであるということです。現在、私が行っているのは「そして保存を押します...」の後で、このバルーンが表示されるまでの時間を与えるためにsleep(3)を実行します。これは、時間を無駄にしているとは思えません。また、この呼び出しの処理に多少時間がかかる場合もあるためです。

獣をただ眠らせるのではなく、どうやってあなたのbehatテストをAjaxが行われるのを待たせるのですか?

フィードバックありがとうございます!

4

3 に答える 3

27

これは、未処理の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を実行するMinkドライバーを使用していることを確認してください(デフォルトでは実行されません)。

于 2012-09-25T10:40:54.067 に答える
2

私は、Ajax呼び出しの結果としてDOMが変更されるのを待つことによってそれを行います。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);
}

次に、\ Behat \ Mink \ Sessionで、そのクラスを使用するようにコンストラクターを変更しました。

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でのみテストしました。

于 2014-10-28T04:36:14.983 に答える
1

Prototypejs(Magentoなど)を使用している場合、同等のコードは次のとおりです。

public function iShouldSeeAnErrorBalloon($title)
{
    $this->getSession()->wait($duration, '(0 === Ajax.activeRequestCount)');
    // asserts below
}
于 2013-11-12T12:18:00.647 に答える