Selenium | 引用WebElement时报错stale element reference: element is not attached to the page document

当项目中需要断言文本是否在元素列表的文本集中时,在对元素列表中的元素for循环遍历进行WebElement.text 操作时,随机性的出现state element reference的报错信息

源代码如下:

def assertIsInTextSet(self,locator,expect,isIn=True):
    elems = self.findElements(locator)
    elems_text = [elem.text for elem in elems]
    try:
        if isIn:
            assert expect in elems_text
        else:
            assert expect not in elems_text
    except AssertionError as e:
        loggerHandler.logger.error('断言失败')
        raise e

报错信息如下:

stale element reference: element is not attached to the page document

过时的元素引用:元素未附加到页面文档

执行步骤: assertIsInTextSet(("xpath","//div[@class='s-table-header-wrapper']/table/thead/tr/th/div[@class='cell']"),"IP地址",False)
POST http://127.0.0.1:52589/session/8350c4f258317a9129c5da4bcf344a59/elements {"using": "xpath", "value": "//div[@class='s-table-header-wrapper']/table/thead/tr/th/div[@class='cell']"}
http://127.0.0.1:52589 "POST /session/8350c4f258317a9129c5da4bcf344a59/elements HTTP/1.1" 200 643
Finished Request
GET http://127.0.0.1:52589/session/8350c4f258317a9129c5da4bcf344a59/element/cc580c5f-9a67-4133-a773-02cd605f17d9/text {"id": "cc580c5f-9a67-4133-a773-02cd605f17d9"}
http://127.0.0.1:52589 "GET /session/8350c4f258317a9129c5da4bcf344a59/element/cc580c5f-9a67-4133-a773-02cd605f17d9/text HTTP/1.1" 404 1088
Finished Request
测试用例运行失败, 错误信息是: Message: stale element reference: element is not attached to the page document
  (Session info: chrome=98.0.4758.102)

根据报错信息可以分析出,for循环获得的元素列表只是元素在DOM中的唯一ID列表,当执行到element.text 获取元素文本信息时,会再次根据元素的唯一ID发起http请求获取text,这一点在selenium源码中也得到了验证。页面元素不断在渲染,导致元素会发生变化,所以当引用的元素在页面DOM发生变化后获取相关信息就会报引用错误的信息。

部分源码如下:

@property
def text(self):
    """The text of the element."""
    return self._execute(Command.GET_ELEMENT_TEXT)['value']

所以,要解决这个问题,就必须保证元素是最新的!即:在每次引用前重新定位获取新的ID即可

修改后的源码如下:

def assertIsInTextSet(self,locator,expect,isIn=True):
    elems = self.findElements(locator)
    elems_text = [self.findElements(locator)[index].text for index in range(len(elems))]
    try:
        if isIn:
            assert expect in elems_text
        else:
            assert expect not in elems_text
    except AssertionError as e:
        loggerHandler.logger.error('断言失败')
        raise e

你可能感兴趣的:(Selenium,实践经验总结,selenium)