2012-07-24 25 views
0

我只是檢查元素的頁面上的存在形式:的Watir StaleElementReferenceError在框架

sleep 5 # for the page load 
form.wait_until_present 
next if form.span(:class => "SSSMSGWARNINGTEXT").exists? 

form來自這兩條線:

browser.goto browser.frame(:name => "TargetContent").src 
form = browser.form(:name => "win1") 

無論是以前和目前的頁面上有form,所以我添加了一個睡眠以確保它有新的頁面。然而,我的程序仍與錯誤崩潰:

[remote server] resource://fxdriver/modules/web_element_cache.js:5665:in `unknown': Element not found in the cache - perhaps the page has changed since it was looked up (Selenium::WebDriver::Error::StaleElementReferenceError) 
from [remote server] file:///var/folders/80/_bwll9x91h7d6c5dp2d3fbb00000gr/T/webdriver-profile20120724-63693-194o52g/extensions/[email protected]/components/driver_component.js:5354:in `unknown' 
from [remote server] file:///var/folders/80/_bwll9x91h7d6c5dp2d3fbb00000gr/T/webdriver-profile20120724-63693-194o52g/extensions/[email protected]/components/driver_component.js:6597:in `unknown' 
from [remote server] file:///var/folders/80/_bwll9x91h7d6c5dp2d3fbb00000gr/T/webdriver-profile20120724-63693-194o52g/extensions/[email protected]/components/driver_component.js:471:in `unknown' 
from /Users/amosng/.rvm/gems/ruby-1.8.7-p370/gems/selenium-webdriver-2.25.0/lib/selenium/webdriver/remote/response.rb:52:in `assert_ok' 
from /Users/amosng/.rvm/gems/ruby-1.8.7-p370/gems/selenium-webdriver-2.25.0/lib/selenium/webdriver/remote/response.rb:15:in `initialize' 
from /Users/amosng/.rvm/gems/ruby-1.8.7-p370/gems/selenium-webdriver-2.25.0/lib/selenium/webdriver/remote/http/common.rb:59:in `new' 
from /Users/amosng/.rvm/gems/ruby-1.8.7-p370/gems/selenium-webdriver-2.25.0/lib/selenium/webdriver/remote/http/common.rb:59:in `create_response' 
from /Users/amosng/.rvm/gems/ruby-1.8.7-p370/gems/selenium-webdriver-2.25.0/lib/selenium/webdriver/remote/http/default.rb:65:in `request' 
from /Users/amosng/.rvm/gems/ruby-1.8.7-p370/gems/selenium-webdriver-2.25.0/lib/selenium/webdriver/remote/http/common.rb:40:in `call' 
from /Users/amosng/.rvm/gems/ruby-1.8.7-p370/gems/selenium-webdriver-2.25.0/lib/selenium/webdriver/remote/bridge.rb:598:in `raw_execute' 
from /Users/amosng/.rvm/gems/ruby-1.8.7-p370/gems/selenium-webdriver-2.25.0/lib/selenium/webdriver/remote/bridge.rb:576:in `execute' 
from /Users/amosng/.rvm/gems/ruby-1.8.7-p370/gems/selenium-webdriver-2.25.0/lib/selenium/webdriver/remote/bridge.rb:542:in `find_element_by' 
from /Users/amosng/.rvm/gems/ruby-1.8.7-p370/gems/selenium-webdriver-2.25.0/lib/selenium/webdriver/common/search_context.rb:42:in `find_element' 
from /Users/amosng/.rvm/gems/ruby-1.8.7-p370/gems/watir-webdriver-0.6.1/lib/watir-webdriver/locators/element_locator.rb:85:in `find_first_by_multiple' 
from /Users/amosng/.rvm/gems/ruby-1.8.7-p370/gems/watir-webdriver-0.6.1/lib/watir-webdriver/locators/element_locator.rb:32:in `locate' 
from /Users/amosng/.rvm/gems/ruby-1.8.7-p370/gems/watir-webdriver-0.6.1/lib/watir-webdriver/elements/element.rb:384:in `locate' 
from /Users/amosng/.rvm/gems/ruby-1.8.7-p370/gems/watir-webdriver-0.6.1/lib/watir-webdriver/elements/element.rb:362:in `assert_exists' 
from /Users/amosng/.rvm/gems/ruby-1.8.7-p370/gems/watir-webdriver-0.6.1/lib/watir-webdriver/elements/element.rb:37:in `exists?' 
from ./my-script.rb:123:in `foo' 

什麼都不可能讓它拋出一個錯誤,當我知道一個特定的元素是否存在僅僅是興趣?

編輯:所以看起來像延長等待時間到10秒可以解決問題。由於該頁面上有一堆Javascript,因此我認爲當執行form.wait_until_present時頁面可能沒有開始重新加載,並且執行next if form.span(:class => "SSSMSGWARNINGTEXT").exists?時,表單在加載頁面之間不再存在。至少這是我能想到的這個崩潰的唯一原因...

但問題是,我有幾個地方的頁面重新加載像這樣。每個地方增加10秒鐘的睡眠都會讓它變得難以忍受。如何讓程序檢測頁面何時完全重新加載?

編輯2:嘗試設置form每次重新加載頁面:

... 
    form = browser.form(:name => "win1") 
    form.wait_until_present 
    form.a(:id => "CLASS_SRCH_WRK2_SSR_PB_CLASS_SRCH").click 
    form = browser.form(:name => "win1") 
    form.wait_until_present 
    form.input(:id => "#ICSave").click if form.input(:id => "#ICSave").exists? 
    form = browser.form(:name => "win1") 
    form.wait_until_present 
    ... 

還有一個類似的錯誤:

[remote server] resource://fxdriver/modules/web_element_cache.js:5665:in `unknown': Element not found in the cache - perhaps the page has changed since it was looked up (Selenium::WebDriver::Error::StaleElementReferenceError) 
    from [remote server] file:///var/folders/80/_bwll9x91h7d6c5dp2d3fbb00000gr/T/webdriver-profile20120725-47093-y3nzl8/extensions/[email protected]/components/driver_component.js:5354:in `unknown' 
    from [remote server] file:///var/folders/80/_bwll9x91h7d6c5dp2d3fbb00000gr/T/webdriver-profile20120725-47093-y3nzl8/extensions/[email protected]/components/driver_component.js:6597:in `unknown' 
    from [remote server] file:///var/folders/80/_bwll9x91h7d6c5dp2d3fbb00000gr/T/webdriver-profile20120725-47093-y3nzl8/extensions/[email protected]/components/driver_component.js:471:in `unknown' 
    from /Users/amosng/.rvm/gems/ruby-1.9.3-p194/gems/selenium-webdriver-2.25.0/lib/selenium/webdriver/remote/response.rb:52:in `assert_ok' 
    from /Users/amosng/.rvm/gems/ruby-1.9.3-p194/gems/selenium-webdriver-2.25.0/lib/selenium/webdriver/remote/response.rb:15:in `initialize' 
    from /Users/amosng/.rvm/gems/ruby-1.9.3-p194/gems/selenium-webdriver-2.25.0/lib/selenium/webdriver/remote/http/common.rb:59:in `new' 
    from /Users/amosng/.rvm/gems/ruby-1.9.3-p194/gems/selenium-webdriver-2.25.0/lib/selenium/webdriver/remote/http/common.rb:59:in `create_response' 
    from /Users/amosng/.rvm/gems/ruby-1.9.3-p194/gems/selenium-webdriver-2.25.0/lib/selenium/webdriver/remote/http/default.rb:65:in `request' 
    from /Users/amosng/.rvm/gems/ruby-1.9.3-p194/gems/selenium-webdriver-2.25.0/lib/selenium/webdriver/remote/http/common.rb:40:in `call' 
    from /Users/amosng/.rvm/gems/ruby-1.9.3-p194/gems/selenium-webdriver-2.25.0/lib/selenium/webdriver/remote/bridge.rb:598:in `raw_execute' 
    from /Users/amosng/.rvm/gems/ruby-1.9.3-p194/gems/selenium-webdriver-2.25.0/lib/selenium/webdriver/remote/bridge.rb:576:in `execute' 
    from /Users/amosng/.rvm/gems/ruby-1.9.3-p194/gems/selenium-webdriver-2.25.0/lib/selenium/webdriver/remote/bridge.rb:542:in `find_element_by' 
    from /Users/amosng/.rvm/gems/ruby-1.9.3-p194/gems/selenium-webdriver-2.25.0/lib/selenium/webdriver/common/search_context.rb:42:in `find_element' 
    from /Users/amosng/.rvm/gems/ruby-1.9.3-p194/gems/watir-webdriver-0.6.1/lib/watir-webdriver/locators/element_locator.rb:247:in `by_id' 
    from /Users/amosng/.rvm/gems/ruby-1.9.3-p194/gems/watir-webdriver-0.6.1/lib/watir-webdriver/locators/element_locator.rb:26:in `locate' 
    from /Users/amosng/.rvm/gems/ruby-1.9.3-p194/gems/watir-webdriver-0.6.1/lib/watir-webdriver/elements/element.rb:384:in `locate' 
    from /Users/amosng/.rvm/gems/ruby-1.9.3-p194/gems/watir-webdriver-0.6.1/lib/watir-webdriver/elements/element.rb:362:in `assert_exists' 
    from /Users/amosng/.rvm/gems/ruby-1.9.3-p194/gems/watir-webdriver-0.6.1/lib/watir-webdriver/elements/element.rb:95:in `click' 
    from my-script.rb:471:in `block (2 levels) in foo' 
    ... 

編輯3:這裏是完整的測試腳本:

require 'watir-webdriver' 

def foo 
    browser = Watir::Browser.new 
    browser.driver.manage.timeouts.implicit_wait = 3 
    browser.goto "http://schedule.arizona.edu" 
    browser.form(:name => "win1").select_list(:name => "CLASS_SRCH_WRK2_STRM$54$").option(:index => 2).select 
    browser.goto browser.frame(:name => "TargetContent").src 
    form = browser.form(:name => "win1") 
    term_select_list = form.select_list(:name => "CLASS_SRCH_WRK2_STRM$54$") 
    (1..browser.form(:name => "win1").select_list(:name => "CLASS_SRCH_WRK2_STRM$54$").options.count - 1).each do |term_index| 
    (1..term_select_list.options.count - 1).each do |subj_index| 
     term_select_list.option(:index => term_index).select 
     sleep 1 
     form.select_list(:name => "CLASS_SRCH_WRK2_SUBJECT$67$").option(:index => subj_index).select 
     sleep 1 
     form.checkbox(:id => "CLASS_SRCH_WRK2_SSR_OPEN_ONLY").click 
     sleep 1 
     form.a(:id => "CLASS_SRCH_WRK2_SSR_PB_CLASS_SRCH").click 
     sleep 1 
     form.input(:id => "#ICSave").click if form.input(:id => "#ICSave").exists? 
     sleep 10 
     form.wait_until_present 
     next if form.span(:class => "SSSMSGWARNINGTEXT").exists? 
     puts "got the form I want!!! do something with it: #{form.html[0..10]}" 
     form.a(:id => "CLASS_SRCH_WRK2_SSR_PB_NEW_SEARCH").click 
     sleep 1 
     form.wait_until_present 
    end 
    end 
    browser.close 
    GC.start 
end 

foo 

直到ACCT崩潰需要等待,但是當它到達ACCT時,它會可靠地崩潰(對我而言),儘管這可能僅僅是因爲1秒鐘的睡眠時間不夠長。

form.wait_until_present而不是任意的睡覺的腳本:

require 'watir-webdriver' 

def foo 
    browser = Watir::Browser.new 
    browser.driver.manage.timeouts.implicit_wait = 3 
    browser.goto "http://schedule.arizona.edu" 
    browser.form(:name => "win1").select_list(:name => "CLASS_SRCH_WRK2_STRM$54$").option(:index => 2).select 
    browser.goto browser.frame(:name => "TargetContent").src 
    form = browser.form(:name => "win1") 
    term_select_list = form.select_list(:name => "CLASS_SRCH_WRK2_STRM$54$") 
    (1..browser.form(:name => "win1").select_list(:name => "CLASS_SRCH_WRK2_STRM$54$").options.count - 1).each do |term_index| 
    (1..term_select_list.options.count - 1).each do |subj_index| 
     term_select_list.option(:index => term_index).select 
     form = browser.form(:name => "win1") 
     form.wait_until_present 
     form.select_list(:name => "CLASS_SRCH_WRK2_SUBJECT$67$").option(:index => subj_index).select 
     form = browser.form(:name => "win1") 
     form.wait_until_present 
     form.checkbox(:id => "CLASS_SRCH_WRK2_SSR_OPEN_ONLY").click 
     form = browser.form(:name => "win1") 
     form.wait_until_present 
     form.a(:id => "CLASS_SRCH_WRK2_SSR_PB_CLASS_SRCH").click 
     form = browser.form(:name => "win1") 
     form.wait_until_present 
     form.input(:id => "#ICSave").click if form.input(:id => "#ICSave").exists? 
     form = browser.form(:name => "win1") 
     form.wait_until_present 
     next if form.span(:class => "SSSMSGWARNINGTEXT").exists? 
     puts "got the form I want!!! do something with it: #{form.html[0..10]}" 
     form.a(:id => "CLASS_SRCH_WRK2_SSR_PB_NEW_SEARCH").click 
     form = browser.form(:name => "win1") 
     form.wait_until_present 
    end 
    end 
    browser.close 
    GC.start 
end 

foo 

甚至還讓安倍晉三之前崩潰。

+0

由於您使用'next',這是否意味着這個代碼是一個循環內?該循環中是否存在導致頁面或元素重新加載的操作? – 2012-07-24 20:33:06

+0

@JustinKo是的,它是在一個循環中,是的,有很多操作導致框架重新加載。這是我的問題 - 我想等待幀完成重新加載。 – wrongusername 2012-07-24 23:53:21

+0

每次重新加載框架時,你是否重新聲明'form = browser.form(:name =>「win1」)?我通常在存儲元素時看到過時的引用,然後在頁面重新加載後嘗試使用它們而不重新聲明。 – 2012-07-25 00:20:45

回答

3

有時最好等待某些東西消失,而不是出現某些東西。在這種情況下,當進行ajax調用時,會得到一個表示正在加載頁面的方便徽標。用以下內容替換所有sleep 1使腳本無錯地完成。

browser.image(:id, 'processing').wait_while_present 

結果似乎有點奇怪,但下面的腳本不再運行到你都拿到例外。希望這可以幫助你至少起牀。

require 'watir-webdriver' 

def foo 
    browser = Watir::Browser.new 
    browser.driver.manage.timeouts.implicit_wait = 3 
    browser.goto "http://schedule.arizona.edu" 
    browser.form(:name => "win1").select_list(:name => "CLASS_SRCH_WRK2_STRM$54$").option(:index => 2).select 
    browser.goto browser.frame(:name => "TargetContent").src 
    form = browser.form(:name => "win1") 
    term_select_list = form.select_list(:name => "CLASS_SRCH_WRK2_STRM$54$") 
    (1..browser.form(:name => "win1").select_list(:name => "CLASS_SRCH_WRK2_STRM$54$").options.count - 1).each do |term_index| 
    (1..term_select_list.options.count - 1).each do |subj_index| 
     term_select_list.option(:index => term_index).select 
     browser.image(:id, 'processing').wait_while_present 
     form.select_list(:name => "CLASS_SRCH_WRK2_SUBJECT$67$").option(:index => subj_index).select 
     browser.image(:id, 'processing').wait_while_present 
     form.checkbox(:id => "CLASS_SRCH_WRK2_SSR_OPEN_ONLY").click 
     browser.image(:id, 'processing').wait_while_present 
     form.a(:id => "CLASS_SRCH_WRK2_SSR_PB_CLASS_SRCH").click 
     browser.image(:id, 'processing').wait_while_present 
     form.input(:id => "#ICSave").click if form.input(:id => "#ICSave").exists? 
     browser.image(:id, 'processing').wait_while_present 
     form.wait_until_present 
     next if form.span(:class => "SSSMSGWARNINGTEXT").exists? 
     puts "got the form I want!!! do something with it: #{form.html[0..10]}" 
     form.a(:id => "CLASS_SRCH_WRK2_SSR_PB_NEW_SEARCH").click 
     browser.image(:id, 'processing').wait_while_present 
     form.wait_until_present 
    end 
    end 
    browser.close 
    GC.start 
end 

foo 
+0

令人驚歎。完美的作品。非常感謝你的幫助! – wrongusername 2012-07-27 17:20:01