如何处理Behat/Mink中的竞态条件



所以我有以下,非常简单的测试在Behat/Mink。当按下按钮时,会显示一个元素,然后我用一些文本填充该元素。这个测试有时有效,有时无效。基本结构如下:

file.blade.php

<button id="show-inputs">Show</button>
<div id="inputs" class="hidden">
<span>Input</span>
<input type="text" id="test-input"/>
</div>

script.js

jQuery(function($){
$('#show-inputs').on('click', function() {
$('#inputs').removeClass('hidden');
});
});

TestingFeature.feature

@javascript
Scenario: Testing Input Show/Fill
Given I am on "/"
Then I press "show-inputs"
And I wait for javascript to finish loading
Then I fill in "test-input" with "This is a Test"
...

FeatureContext.php

public function iWaitForJavascriptToFinishLoading() {
$this->getSession()->wait(10000, '$.active === 0');
}

可以看到,这是一个简单的测试;导航到/后,触发#show-inputs的点击,等待JS完成(即给#inputsdiv显示时间),然后用一个简单的测试填充#test-input

运行这些测试,有时有效,有时无效。下面是behat的输出:

...
Then I press "show-inputs"                        # FeatureContext::pressButton()
And I wait for javascript to finish loading       # FeatureContext::iWaitForJavascriptToFinishLoading()
Then I fill in "test-input" with "This is a Test" # FeatureContext::fillField()
Element is not visible and can not be focused

错误Element is not visible and can not be focused只是偶尔出现,暗示在Show Element>填充元素,以不正确的顺序发生。我认为And I wait for javascript to finish loading,直到$.active0才会处理这个问题,但显然它没有。我想知道它是否与使用类hidden(display:none)与简单的$('{$selector}').show()有关,但我不确定。

我可以为And I wait for "inputs" to be "visible"添加一个新的检查,直到$('{$selector}').is(':visible') === true,但这感觉不对。

以前有人遇到过这个问题吗?

我最终选择了我认为我必须使用的方式,使用And I wait for "test-input" to be "visible",在FeatureContext.php中使用自定义定义:

/**
* @Then I wait for :elementId to be :visibility
*/
public function iWaitForElementToBe($elementId, $visibility) {
if ($visibility != 'visible' && $visibility != 'hidden') {
throw new Exception("Invalid visibility pseudo `{$visibility}` supplied: Must be one of `visible`, `hidden`");
}
$this->getSession()->wait(1000, "$('#{$elementId}').is(':{$visibility}') === true");
}

TestingFeature.feature:

@javascript
Scenario: Testing Input Show/Fill
Given I am on "/"
Then I press "show-inputs"
And I wait for "test-input" to be "visible"
Then I fill in "test-input" with "This is a Test"
唯一需要注意的是,如果同时显示多个元素,则需要为每个元素重复显示And I wait for ... to be ...,即使它们在同一行代码中被切换为可见/隐藏(例如$('#id, #id2').removeClass('hidden'))。

最新更新