问题描述
所以我有以下内容,非常简单地在 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完成(即给时间显示#inputs
div),然后用一个简单的测试填写#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 > Fill Element 存在竞争条件,发生顺序不正确。我以为 And I wait for javascript to finish loading
会一直等到 $.active
变为 0
才能处理这个问题,但显然没有。我想知道这是否与使用类 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 ...
,即使它们在同一行代码中切换为可见/隐藏(例如 { {1}})。