1

我遇到了一個問題,我創建了一個測試,我會隨機地得到這個問題,從我的理解是因爲有java腳本運行定期刷新元素。我不確定如何阻止這個錯誤發生,這裏是我的測試代碼;Watir「元素不再附加到DOM」錯誤

編輯:誠如我已經移除變量的元素,並直接調用它們,但錯誤依然存在,這是我更新的代碼和錯誤信息(包括行號)

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作爲我的列表,但是當我這樣做時,我會得到一個不同的錯誤,說'未定義的方法'爲'.as.each do | room |

回答

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? 

這是相當冗長和重複。如果你曾經去過水豚,那麼你可以嘗試蒔蘿寶石將這些元素包裹在小工具中,這就像特效。 https://github.com/mojotech/dill

+0

由於鋼所提供的答案,但是,即使元素被直接放入等待聲明我得到同樣的錯誤,還有什麼我可以嘗試解決問題? – Ethranes

+0

如果您使用了該代碼,我可以再看一次。在代碼中注意標記第63行,錯誤行?我還用一些更多的想法更新了我的答案,包括處理存儲參考的第二個變量,以及爲什麼這是一個不好的模式。 – steel

+0

感謝鋼鐵公司,我在主要文章中更新了我的代碼和錯誤 – Ethranes

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 
相關問題