通过轮询检查 Capybara 中是否存在 html 标签的特定属性

Check the specific attribute of a html tag exists in Capybara with polling

我有这个简单的HTML。按钮的那些属性(例如 "AAAAA")将根据外部事件进行传递。实时更新由 AJAX 池执行。

<div class="parent">
<div class="group"><button title="AAAAA"/></div>
<div class="group"><button title="BBBBB"/></div>
<div class="group"><button title="CCCCC"/></div>
</div>
<div class="parent">
...
</div>

我们假设 "AAAAA" 将在 XXX 事件后过渡到 "DDDDD"。测试脚本就像...

scenario 'test' do
    # Before change
    page.within(first('.parent')) do
        page.within(all('.group')[0]) do
            expect(page.find('button')[:title]).to include('AAAAA')
        end
        page.within(all('.group')[1]) do
            expect(page.find('button')[:title]).to include('BBBBB')
        end
        page.within(all('.group')[2]) do
            expect(page.find('button')[:title]).to include('CCCCC')
        end
    end

    XXX

    # After change (AJAX polling)
    page.within(first('.parent')) do
        page.within(all('.group')[0]) do
            expect(page.find('button')[:title]).to include('DDDDD')
        end
    end 
end

但是,这不起作用。因为 expect(page.find('button')[:title]).to include('DDDDD') 不会等到 AJAX 轮询执行。如果我把 sleep(20) 放在 XXX 之后,这个测试就成功了,但是,我猜这不是水豚的方式。

我想知道正确处理这种情况的聪明方法。

感谢您的帮助。

您需要使用 Capybara 提供的匹配器,它具有 waiting/retrying 行为 built-in,而不是 RSpec 提供的include

expect(page).to have_css("button[title='DDDDDD']")

如果你想让它测试标题中的子字符串,而不是相等,你可以使用 *= 而不是 =,等等

您还应该尽可能选择唯一的 css 选择器,例如 find('.group:nth-of-type(1)') 而不是 all('.group')[0] (这两个表达式的含义略有不同,因此有时可能无法实现)因为从 all/first 返回的元素是 non-reloadable