我有一个iframe,它是表单的目标:
<form target="preview">
<textarea name="content"></textarea>
</form>
<iframe name="preview"></iframe>
表单是在用户在文本区域中键入时提交的(为了简洁起见,我省略了debouncing代码):
$('textarea').keyup(function() {
// debouncer ensures this happens at *most* every two seconds
$('form').submit();
});
我有一个脚本,可以根据内容调整iframe的高度:
$('iframe').load(function() {
var height = $('body', $(this).contents()).height();
$(this).height(height);
});
现在,我正在编写一个特性规范,以断言实际发生了高度调整。我已经确定我需要使用evaluate_script
来获得iframe的高度。所以,理论上,我的规范应该看起来像:
def preview_iframe_height
page.evaluate_script('$("iframe").height()')
end
scenario 'preview grows to content', js: true do
initial_height = preview_iframe_height
fill_in('Content', with: 'some content')
expect(preview_iframe_height).to be > initial_height
end
然而,这段代码并不等待请求重新填充iframe,并且总是失败。我知道Capybara非常擅长使用have_content
等匹配器等待内容出现,但我不知道如何等待高度的变化。有什么想法吗?
我的测试套件:
- RSpec
- 水豚
- 恐怖分子
感谢@taryn east在上面的评论,我已经成功地将其改编自Thoughtbot的博客:
def preview_iframe_height
page.evaluate_script('$("iframe").height()')
end
scenario 'preview grows to content', js: true do
page.execute_script(%{
iframe_loaded = false;
$('iframe').load(function() {
iframe_loaded = true;
});
});
initial_height = preview_iframe_height
content = "linenn" * 30
fill_in('Content', with: content)
Timeout.timeout(Capybara.default_wait_time) do
loop until page.evaluate_script('iframe_loaded')
end
expect(preview_iframe_height).to be > initial_height
end
这定义了一个变量iframe_loaded
,并在iframe完成加载时将其设置为true
。规范等待iframe_loaded
变成true
,然后再继续它的期望。
这可以抽象为一个helper方法,以便更通用。
请投票支持@taryn east对这个问题非常有用的评论!