Selenium无法访问死对象/元素引用是陈旧的

时间:2016-12-17 21:25:06

标签: python django selenium selenium-webdriver geckodriver

我正在跟随guide学习使用python的TDD。在some point,在进行迁移之后,命令python3 functional_tests.py的输出应该是(根据书中):

self.fail('Finish the test!')
AssertionError: Finish the test!

但我收到错误:

selenium.common.exceptions.InvalidSelectorException: Message: Given css selector expression "tr" is invalid: TypeError: can't access dead object

在尝试第二次(以及更多)时间之后:

selenium.common.exceptions.StaleElementReferenceException: Message: The element reference is stale. Either the element is no longer attached to the DOM or the page has been refreshed.

我一直在Google上搜索并搜索类似的问题,但找不到可以帮我解决问题的问题。
我正在使用geckodriver,并将其路径添加到PATH

Django==1.8.7
selenium==3.0.2
Mozilla Firefox 50.0.2
(X)Ubuntu 16.04

我应该切换到Chrome吗?这不是微不足道的,它需要我一些时间,但它可以工作吗?更像是Firefox还是Selenium?我认为这与代码无关 - 我克隆了repo for chapter 5并且发生了同样的崩溃。

2 个答案:

答案 0 :(得分:4)

出现错误是因为在本章的前面我们在POST请求后添加了重定向。该页面简要刷新,这可能搞砸了Selenium。如果你想坚持使用Selenium 3,我在博客上找到了一个针对这本书的修复:http://www.obeythetestinggoat.com/how-to-get-selenium-to-wait-for-page-load-after-a-click.html

基本上,您可以向NewVisitorTest类添加一个方法,让您等待页面重新加载,然后继续执行断言测试。

...
from contextlib import contextmanager
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support.expected_conditions import staleness_of

class NewVisitorTest(unittest.TestCase):
    ...
    @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_can_start_list_and_retrieve_it_later(self):
        ...
        inputbox.send_keys("Buy peacock feathers")
        inputbox.send_keys(Keys.ENTER)

        with self.wait_for_page_load(timeout=10):
            self.check_for_row_in_list_table("1: Buy peacock feathers")

        inputbox = self.browser.find_element_by_id("id_new_item")
        inputbox.send_keys("Use peacock feathers to make a fly")
        inputbox.send_keys(Keys.ENTER)

        with self.wait_for_page_load(timeout=10):
            self.check_for_row_in_list_table("1: Buy peacock feathers")
            self.check_for_row_in_list_table("2: Use peacock feathers to make a fly")

答案 1 :(得分:1)

这是因为本书期待你使用Selenium 2,而不是Selenium 3. v3在隐式等待方面有很大不同的行为(上次检查时有很多错误)所以它是这样的最简单的是现在坚持使用Selenium 2.

再看一下安装说明:http://www.obeythetestinggoat.com/book/pre-requisite-installations.html