继续获取元素未附加到页面文档

时间:2017-03-06 16:29:46

标签: python selenium

我正在运行以下代码来验证页面上的文字:

def verifyText(self, Text):
    try:
       self.switchToFrame(*MainPageLocatars.FRAMEONE)
       self.switchToFrame(*MainPageLocatars.SUBLISTFRAME)
    except:
       pass
    self.row.find_element_by_xpath(ListViewLocatars.VERIFYTEXT % Text)

我尝试在每一步之后添加time.sleep(2)但是当我运行此功能时它仍然给我一个错误 - >>继续获取元素没有附加到此代码行的页面文档错误

self.row.find_element_by_xpath(ListViewLocatars.VERIFYTEXT % Text)

我在这里调用函数,我应该在哪里重新定义它?

 listview = ListView(self.driver, 'First')
 listview.verifyText("comp1")

请注意,该行是父级:

self.row = self.driver.find_element_by_xpath(ListViewLocatars.ROWPARENT % INDEX_MAP[index])

这就是我定义函数的方法:

class ListView(Page):

    def __init__(self, driver, index):

        if index not in INDEX_MAP:
            raise ValueError("Invalid index %s" % index)

        self.driver = driver

        try:
            self.row = self.driver.find_element_by_xpath(ListViewLocatars.ROWPARENT % INDEX_MAP[index])
        # used for VerifyText function only
        except:
            self.row = self.driver.find_element_by_xpath(ListViewLocatars.TEXTPARENT % INDEX_MAP[index])


    def verifyText(self, Text):
        try:
            self.switchToFrame(*MainPageLocatars.FRAMEONE)
            self.switchToFrame(*MainPageLocatars.SUBLISTFRAME)
        except:
            pass
        self.row.find_element_by_xpath(ListViewLocatars.VERIFYTEXT % Text)

这里是完整代码:

# all locaters for this class are defined here only
class ListView(Page):

    def __init__(self, driver, index):

        if index not in INDEX_MAP:
            raise ValueError("Invalid index %s" % index)

        self.driver = driver

        try:
            self.row = self.driver.find_element_by_xpath(ListViewLocatars.ROWPARENT % INDEX_MAP[index])
        # used for VerifyText function only
        except:
            self.row = self.driver.find_element_by_xpath(ListViewLocatars.TEXTPARENT % INDEX_MAP[index])

    @property       
    def row(self):
        return self.driver.find_element_by_xpath(ListViewLocatars.ROWPARENT % INDEX_MAP[index])


    def verifyText(self, Text):
        try:
            self.switchToFrame(*MainPageLocatars.FRAMEONE)
            self.switchToFrame(*MainPageLocatars.SUBLISTFRAME)
        except:
            pass
        self.row.find_element_by_xpath(ListViewLocatars.VERIFYTEXT % Text)

现在它给了我这个错误:

Traceback (most recent call last):
  File "autoLoaderTest.py", line 56, in test02_AutoLoaderSubCompany
    listview = ListView(self.driver, 'First')
  File "C:\Users\cverma\Desktop\SOAPProject\mainPage.py", line 44, in __init__
    self.row = self.driver.find_element_by_xpath(ListViewLocatars.TEXTPARENT % INDEX_MAP[index])
AttributeError: can't set attribute

1 个答案:

答案 0 :(得分:1)

这是StaleElementReferenceException如何触发的简化版本以及如何避免它。

我认为您的代码的工作原理如下:

self.row = self.driver.find_element_by_xpath(ListViewLocatars.ROWPARENT % INDEX_MAP[index])
# Now your self.row is accessible. You can use it
self.driver.find_element_by_xpath('//input[@type="text"]').send_keys('some data')
# This action could trigger page refresh
# Now your self.row is not accessible as it was found on previous page
self.row.find_element_by_xpath(ListViewLocatars.VERIFYTEXT % Text)
# Here comes StaleElementReferenceException

如何避免它:

@property
def row(self):
    return self.driver.find_element_by_xpath(ListViewLocatars.ROWPARENT % INDEX_MAP[index])

def verifyText(self, Text):
   try:
       self.switchToFrame(*MainPageLocatars.FRAMEONE)
       self.switchToFrame(*MainPageLocatars.SUBLISTFRAME)
    except:
       pass
    self.row.find_element_by_xpath(ListViewLocatars.VERIFYTEXT % Text)
    # only now self.row is defined and even if page refreshed
    # next time you call self.row, element will be re-defined