我遇到了一个问题,我已经创建了一个问题,我会随机地解决这个问题,因为有一些java脚本在运行,它会定期刷新元素。我不确定如何阻止此错误发生,这是我的测试代码;
编辑:正如我所知,我已从变量中删除了元素并直接调用它们,但错误仍然存在,这是我更新的代码和错误消息(包括行号)
47 When(/^I click the create room button$/) do
49 Watir::Wait.for_condition(10, 2, "Waiting for room data to load") {
50 @browser.iframe(:id, 'iconsole-plugin-session_iframe__').div(:id, 'lobby_rooms').div(:id, 'room_list').present?
51 }
53 rooms = []
55 @browser.iframe(:id, 'iconsole-plugin-session_iframe__').div(:id, 'lobby_rooms').div(:id, 'room_list').as.each do |room |
56 rooms << room.attribute_value('data-room-id')
57 end
59 puts roomvalue = rooms.size.to_i
61 @current_rooms = rooms
63 roomvalue
65 Watir::Wait.for_condition(10, 2, "Waiting for button to be present") {
66 @browser.iframe(:id, 'iconsole-plugin-session_iframe__').button(:id, 'create_room_form_button').present?
67 }
68 @browser.iframe(:id, 'iconsole-plugin-session_iframe__').button(:id, 'create_room_form_button').click
69 end
我得到的错误是;
Element is no longer attached to the DOM - {:element=>#<Selenium::WebDriver::Element:0x68d78665e583d27c id="{80a6296c-fc63-4d63-917c-9a2bf35bb429}">} (Watir::Exception::UnknownObjectException)
./features/step_definitions/multiplayer_fe_steps.rb:56:in `block (2 levels) in <top (required)>'
./features/step_definitions/multiplayer_fe_steps.rb:55:in `/^I click the create room button$/'
features/multiplayer_fe.feature:21:in `When I click the create room button'
感谢钢铁提供的答案,但是即使将元素直接放入等待语句中我也会遇到同样的错误,还有什么我可以尝试解决这个问题吗?
编辑:我已尝试将lamda用于我的列表,但是,当我这样做时,我会得到一个不同的错误,说明未定义的方法&#39; as&#39;在我的.as.each做|房间|
答案 0 :(得分:0)
我不太了解Watir,但我怀疑问题在于您将引用存储在变量中。也许试试这个:
Watir::Wait.for_condition(10, 2, "Waiting for room data to load") {
@browser.iframe(:id, 'iconsole-plugin-session_iframe__').div(:id, 'lobby_rooms').present?
}
还
Watir::Wait.for_condition(10, 2, "Waiting for button to be present") {
@browser.iframe(:id, 'iconsole-plugin-session_iframe__').button(:id, 'create_room_form_button').present?
}
@browser.iframe(:id, 'iconsole-plugin-session_iframe__').button(:id, 'create_room_form_button').click
问题在于每次调用@ browser.find_element时......你都在重新审视DOM。存储变量时,您没有存储要查找的过程,而是存储实际的元素,是否存在。当您尝试调用不再存在的找到的元素变量时,您将获得此Selenium StaleObjectError。
在这里走出另一个边缘,但你也可能尝试在Proc或Lambda中包装那些调用,而不是变量。
createpress = -> { @browser.iframe(:id, 'iconsole-plugin-session_iframe__').button(:id, 'create_room_form_button') }
然后,当您想要触发它时,请将其命名为:
create_press.call.present?
这非常冗长和重复。如果你曾经去过Capybara,你可以尝试使用Dill gem将这些元素包装在小部件中,就像触发器一样。 https://github.com/mojotech/dill
答案 1 :(得分:0)
您的代码......
@browser.iframe(:id, 'iconsole-plugin-session_iframe__').div(:id, 'lobby_rooms').div(:id, 'room_list').as
....,在您声明它的那一刻,是一个包含链接元素列表的静态数组。
如果在迭代该元素列表时,DOM会更新,那么这些元素就会变得陈旧。这就是你得到这个错误的原因。
至于如何解决迭代更新链接元素列表的潜在问题......
您可能做的一件事是获取列表的大小,然后直接引用链接:
count = @browser.iframe(:id, 'iconsole-plugin-session_iframe__').div(:id, 'lobby_rooms').div(:id, 'room_list').as
count.times do |x|
rooms << @browser.iframe(:id, 'iconsole-plugin-session_iframe__').div(:id, 'lobby_rooms').div(:id, 'room_list').a(index: x-1).attribute_value('data-room-id')
end