2015-08-16 74 views
3

我使用的是Chrome瀏覽器驅動程序,因爲Firefox驅動程序似乎在Windows PC上有問題。之前,我前去度假Django:在瀏覽器上使用陳舊元素參考

我的Django的功能測試中工作得很好,但現在他們都扔各種錯誤。

有時,試圖找到一個頁面上的元素,當我得到:

selenium.common.exceptions.StaleElementReferenceException: Message: stale element reference: element is not attached to the page document

其他時間,以驗證該URL的嘗試失敗,因爲硒似乎是閱讀從以前的網頁的URL 。失敗點似乎從運行到運行都發生了變化,換句話說,測試的某些部分可以在執行之間在成功和失敗之間交替。但是,這個問題似乎總是在使用.click()後發生。

在觀看瀏覽器,硒似乎是成功的導航頁面,所以我想它只是在尋找項目太quickly-在瀏覽器中存在才。

添加implicitly.wait()我setUpClass似乎並沒有幫助,但我可能是用錯了。

我試過Harry Percival's site這個很有前途的想法(下面),但是Selenium在坐在被告知要等待的頁面上簡單地超時。

from contextlib import contextmanager 
from selenium.webdriver.support.ui import WebDriverWait 
from selenium.webdriver.support.expected_conditions import \ 
    staleness_of 
class MySeleniumTest(SomeFunctionalTestClass): 
    # assumes self.browser is a selenium webdriver 

    @contextmanager 
    def wait_for_page_load(self, timeout=30): 
     old_page = self.browser.find_element_by_tag_name('html') 
     yield 
     WebDriverWait(self.browser, timeout).until(
      staleness_of(old_page) 
     ) 

    def test_stuff(self): 
     # example use 
     with self.wait_for_page_load(timeout=10): 
      self.browser.find_element_by_link_text('a link') 
      # nice! 

還有其他人處理過嗎?我應該遵循這個問題的正確方法是什麼?

編輯: 張貼的解決方案工作出色,真正清理我的代碼,因爲我可以簡單地添加一個.click()到被調用的函數,就像描述的那樣。

下面是幫助我自定義此文檔:

Documentation for the syntax for By for modification purposes.

Documentation for Selenium's Expected Conditions

注:我用的術語「瀏覽器」的地方駕駛的,我認爲這是最初把我扔掉。

回答

2

是否wait_for_page_load必須是生成器?我認爲它會在不等待的情況下返回!這就是爲什麼你的測試是片狀的。有時元素在您調用find_element_by_link_text時有時不會加載。

我已經用這種方法成功:

from selenium.webdriver.support import expected_conditions as EC 

def wait_for_element(self, elm, by = 'id', timeout=10) : 
    wait = WebDriverWait(self.driver, timeout) 
    if by == 'id' : 
     element = wait.until(EC.element_to_be_clickable((By.ID,elm))) 
     return self.driver.find_element_by_id(elm) 
    elif by == 'link': 
     wait.until(EC.element_to_be_clickable((By.LINK_TEXT,elm))) 
     return self.driver.find_element_by_link_text(elm) 
    # by tag, by css etc etc goes here. 

我把這種方法與應顯示之前的頁面可以進行交互DOM元素的一個顯着標識。返回的元素可以直接與之交互。

+0

嗯,看起來我需要熟悉預期條件語法,以使其適用於我的情況。不知何故,Selenium在點擊之後但在加載下一個URL之前比較URL。我試圖搞砸這個,但它仍然超時,所以我不認爲我正在構建我的。 –

+0

如果您用wait_for_element將您的調用替換爲wait_for_page_load,我已經發布了它的工作。例如wait_for_element('鏈接','鏈接',30)應該這樣做。但30秒有點太長 – e4c5

+0

道歉,我不得不離開一段時間。我已經坐下來,並得到它的工作,我很高興我做到了!我非常感謝幫助。 –

相關問題