title: Watir StaleElementReferenceError in form in frame
body: <p>I am merely checking for the existing of an element on the page:</p>
  
  <pre><code>sleep 5 # for the page load
  form.wait_until_present
  next if form.span(:class =&gt; "SSSMSGWARNINGTEXT").exists?
  </code></pre>
  
  <p><code>form</code> comes from these two lines:</p>
  
  <pre><code>browser.goto browser.frame(:name =&gt; "TargetContent").src
  form = browser.form(:name =&gt; "win1")
  </code></pre>
  
  <p>Both the previous and the current page have <code>form</code> present, so I added a sleep to make sure that it had the new page. However, my program still crashes with the error:</p>
  
  <pre><code>[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/fxdriver@googlecode.com/components/driver_component.js:5354:in `unknown'
  from [remote server] file:///var/folders/80/_bwll9x91h7d6c5dp2d3fbb00000gr/T/webdriver-profile20120724-63693-194o52g/extensions/fxdriver@googlecode.com/components/driver_component.js:6597:in `unknown'
  from [remote server] file:///var/folders/80/_bwll9x91h7d6c5dp2d3fbb00000gr/T/webdriver-profile20120724-63693-194o52g/extensions/fxdriver@googlecode.com/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'
  </code></pre>
  
  <p>What can possibly make it throw an error when I'm merely interested in knowing whether or not a certain element exists?</p>
  
  <p><strong>EDIT</strong>: So it seems like extending the wait time to 10 seconds fixes the problem. Since there is a bunch of Javascript on that page, I suppose the page might not have started reloading when <code>form.wait_until_present</code> is executed, and when <code>next if form.span(:class =&gt; "SSSMSGWARNINGTEXT").exists?</code> is executed, the form is no longer there in between loading pages. At least that is the only reason I can think of for this crash...</p>
  
  <p>But the problem is, I have several places where the page reloads like this. Adding 10 second sleeps everywhere would slow it down to an unbearable crawl. How can I get the program to detect when a page has fully reloaded?</p>
  
  <p><strong>EDIT 2</strong>: Tried setting <code>form</code> every time page reloads:</p>
  
  <pre><code>    ...
      form = browser.form(:name =&gt; "win1")
      form.wait_until_present
      form.a(:id =&gt; "CLASS_SRCH_WRK2_SSR_PB_CLASS_SRCH").click
      form = browser.form(:name =&gt; "win1")
      form.wait_until_present
      form.input(:id =&gt; "#ICSave").click if form.input(:id =&gt; "#ICSave").exists?
      form = browser.form(:name =&gt; "win1")
      form.wait_until_present
      ...
  </code></pre>
  
  <p>Still a similar error:</p>
  
  <pre><code>[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/fxdriver@googlecode.com/components/driver_component.js:5354:in `unknown'
      from [remote server] file:///var/folders/80/_bwll9x91h7d6c5dp2d3fbb00000gr/T/webdriver-profile20120725-47093-y3nzl8/extensions/fxdriver@googlecode.com/components/driver_component.js:6597:in `unknown'
      from [remote server] file:///var/folders/80/_bwll9x91h7d6c5dp2d3fbb00000gr/T/webdriver-profile20120725-47093-y3nzl8/extensions/fxdriver@googlecode.com/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'
      ...
  </code></pre>
  
  <p><strong>EDIT 3</strong>: Here's the test script in its entirety:</p>
  
  <pre><code>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 =&gt; "win1").select_list(:name =&gt; "CLASS_SRCH_WRK2_STRM$54$").option(:index =&gt; 2).select
    browser.goto browser.frame(:name =&gt; "TargetContent").src
    form = browser.form(:name =&gt; "win1")
    term_select_list = form.select_list(:name =&gt; "CLASS_SRCH_WRK2_STRM$54$")
    (1..browser.form(:name =&gt; "win1").select_list(:name =&gt; "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 =&gt; term_index).select
        sleep 1
        form.select_list(:name =&gt; "CLASS_SRCH_WRK2_SUBJECT$67$").option(:index =&gt; subj_index).select
        sleep 1
        form.checkbox(:id =&gt; "CLASS_SRCH_WRK2_SSR_OPEN_ONLY").click
        sleep 1
        form.a(:id =&gt; "CLASS_SRCH_WRK2_SSR_PB_CLASS_SRCH").click
        sleep 1
        form.input(:id =&gt; "#ICSave").click if form.input(:id =&gt; "#ICSave").exists?
        sleep 10
        form.wait_until_present
        next if form.span(:class =&gt; "SSSMSGWARNINGTEXT").exists?
        puts "got the form I want!!! do something with it: #{form.html[0..10]}"
        form.a(:id =&gt; "CLASS_SRCH_WRK2_SSR_PB_NEW_SEARCH").click
        sleep 1
        form.wait_until_present
      end
    end
    browser.close
    GC.start
  end
  
  foo
  </code></pre>
  
  <p>It takes until reaching ACCT to crash, but when it reaches ACCT, it crashes reliably (for me), though that is probably just because the 1 second sleep wasn't long enough.</p>
  
  <p>The script with <code>form.wait_until_present</code> instead of arbitrary sleeps:</p>
  
  <pre><code>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 =&gt; "win1").select_list(:name =&gt; "CLASS_SRCH_WRK2_STRM$54$").option(:index =&gt; 2).select
    browser.goto browser.frame(:name =&gt; "TargetContent").src
    form = browser.form(:name =&gt; "win1")
    term_select_list = form.select_list(:name =&gt; "CLASS_SRCH_WRK2_STRM$54$")
    (1..browser.form(:name =&gt; "win1").select_list(:name =&gt; "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 =&gt; term_index).select
        form = browser.form(:name =&gt; "win1")
        form.wait_until_present
        form.select_list(:name =&gt; "CLASS_SRCH_WRK2_SUBJECT$67$").option(:index =&gt; subj_index).select
        form = browser.form(:name =&gt; "win1")
        form.wait_until_present
        form.checkbox(:id =&gt; "CLASS_SRCH_WRK2_SSR_OPEN_ONLY").click
        form = browser.form(:name =&gt; "win1")
        form.wait_until_present
        form.a(:id =&gt; "CLASS_SRCH_WRK2_SSR_PB_CLASS_SRCH").click
        form = browser.form(:name =&gt; "win1")
        form.wait_until_present
        form.input(:id =&gt; "#ICSave").click if form.input(:id =&gt; "#ICSave").exists?
        form = browser.form(:name =&gt; "win1")
        form.wait_until_present
        next if form.span(:class =&gt; "SSSMSGWARNINGTEXT").exists?
        puts "got the form I want!!! do something with it: #{form.html[0..10]}"
        form.a(:id =&gt; "CLASS_SRCH_WRK2_SSR_PB_NEW_SEARCH").click
        form = browser.form(:name =&gt; "win1")
        form.wait_until_present
      end
    end
    browser.close
    GC.start
  end
  
  foo
  </code></pre>
  
  <p>Crashes before even getting to ABE.</p>