Web企业微信实战(二)作业元素定位失败求助

在完成Web企业微信实战(二)作业时遇到了如下问题:
在定位通讯录页面-添加成员按钮时:


通过

.ww_operationBar .qui_btn.ww_btn.js_add_member

可以在consul中定位到上下两个添加成员元素


于是我在我的代码中使用了如下定位方式:
main.py

from selenium.webdriver.common.by import By

from Hogwarts.PageObject.Page.add_member import AddMember
from Hogwarts.PageObject.Page.base_page import BasePage
from Hogwarts.PageObject.Page.contact import Contact
from Hogwarts.PageObject.Page.import_address_book import ImportAddressBook


class MainPage(BasePage):
    _url = "https://work.weixin.qq.com/wework_admin/frame"

    def go_to_contact(self):
        self.find(By.CSS_SELECTOR, "#menu_contacts").click()
        return Contact(self.driver)

    def go_to_add_member(self):
        self.find(By.CSS_SELECTOR, "[node-type=addmember]").click()
        return AddMember(self.driver)

    def go_to_import_address_book(self):
        self.find(By.CSS_SELECTOR, "[node-type=memberJoin]").click()
        return ImportAddressBook(self.driver)

contact.py

from selenium.webdriver.common.by import By

from Hogwarts.PageObject.Page.add_department import AddDepartment
from Hogwarts.PageObject.Page.add_member import AddMember
from Hogwarts.PageObject.Page.base_page import BasePage
from Hogwarts.PageObject.Page.import_address_book import ImportAddressBook


class Contact(BasePage):

    def go_to_add_department(self):
        self.find(By.CSS_SELECTOR, "#js_contacts73 > div > div.member_colLeft > ul > li:nth-child(1) > a").click()
        return AddDepartment(self.driver)

    def go_to_add_member(self):
        self.find(By.CSS_SELECTOR, ".ww_operationBar .qui_btn.ww_btn.js_add_member").click()
        return AddMember(self.driver)

    def go_to_import_address_book(self):
        return ImportAddressBook(self.driver)

调试使用的测试用例如下:

from Hogwarts.PageObject.Page.first import First
from Hogwarts.PageObject.Page.main import MainPage


class TestAddDepartment:
    def test_login(self):
        # first = First()
        # first.go_to_login()
        main = MainPage()
        main.go_to_contact().go_to_add_member()

在执行测试用例后,遇到如下报错:

E       selenium.common.exceptions.StaleElementReferenceException: Message: stale element reference: element is not attached to the page document
E         (Session info: chrome=81.0.4044.138)

C:\Program Files\Python38\lib\site-packages\selenium\webdriver\remote\errorhandler.py:242: StaleElementReferenceException

请问该如何解决,谢谢!

你把错误信息修改为文字完整贴下吧 别截图。

好的老师,已修改

这个报错意思是定位到了当前元素,但是操作的时候,当前页面已经改变了,大概率是页面刷新或者重新跳转之类的情况,所以重新定位就好了

  • self.find(By.CSS_SELECTOR, ".ww_operationBar .qui_btn.ww_btn.js_add_member").click()
    在这句语句前面加一个强制等待先试一下 如果没有报错了再优化为显式等待 可能是页面切换的速度没有语句执行的速度快 导致页面还没切过去 语句就已经执行了 这时候这个按钮虽然能找到但是还不能点击。
  • 印象中这个按钮的显式等待是有点坑的,可以练一下。比较简单的办法是强制等待或者从首页的添加成员点击进去

如果不想使用强制等待的话,可以加入如下代码。这个机制类似于显式等待了,循环点击,直到下一个页面的元素出现就break掉

  # 确认添加成员按钮是可点的
        self.wait_for_clickable(self._add_member)
        # 进入死循环
        while True:
            self.find(*self._add_member).click()
            # 报错被捕获,执行except循环点击找元素操作,直到找到为主
            try:
                # 找到添加成员页面的某个元素
                res = self.find(*self._cancel)
                # 如果存在的话就跳出循环,如果不存在的话,就报错
                if res is not None:
                    break
            except:
                print("暂时没找到")