Selenium 我写的显示等待封装,在测试用例里面使用报错

testjson · 2022年10月18日 · 最后由 testjson 回复于 2022年10月19日 · 4974 次阅读

basepage 页,对元素定位与显示等待的封装

#元素定位与显示等待结合
    def locator(self,loc):
        ele = self.driver.find_element(loc)
        try:
            WebDriverWait(self.driver,timeout=10).until(EC.visibility_of_element_located(ele))
            return ele
        except Exception:
            raise
    #输入
    def input(self,loc,txt):
        self.locator(loc).send_keys(txt)

页面对象的元素定位,与操作方法

class Input(Page):
    url = "https://www.baidu.com"
    input_loc = (By.ID,'kw')

    def send_keys(self,txt):
        self.open(self.url)
        self.input(self.input_loc,txt)
共收到 11 条回复 时间 点赞
selenium.common.exceptions.InvalidArgumentException: Message: invalid argument: 'using' must be a string

find_element() 需要传入 str visibility_of_element_located() 需传入元组

shelkio 回复

多谢,现在明白了

你这个封装方法, 显示等待写了和没有写一样

Tester_谜城 回复

那应该怎么写?

from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from appium.webdriver.common.mobileby import MobileBy

def locator(self, loc):
    try:
        return WebDriverWait(self.driver, timeout=10).until(EC.visibility_of_element_located((MobileBy.XPATH, loc)))
    except Exception:  # TimeoutException
        raise

1、如上供参考,还可以再结合你的项目优化,上面好几个写死的值还可以改成参数传递
2、WebDriverWait 是这样,如果找到了就返回元素,找不到就报 TimeoutException

青禾 回复

我有几个疑问
1、为啥要用 appium, MobileBy, 因为我这个是 webui 自动化框架,appium 不是搞移动端的吗?
2、元素定位,xpath, 那要是其他的怎么办?id ,name

MobileBy.XPATH
testjson 回复

find_element 放到等待后面啊 你这先执行了 find_element 在等待之前 等待了个寂寞
等待里面直接用定位,不用元素

def locator(self,loc):
    try:
        WebDriverWait(self.driver,timeout=10).until(EC.visibility_of_element_located(loc))
        ele = self.driver.find_element(*loc)
        return ele
    except Exception:
        raise
9楼 已删除
Tester_谜城 回复

好的,明白了

testjson 回复

不知道对不对哈
第一个疑问
查了一下,MobileBy 继承的是 selenium 里的 By,或者你可以直接使用 selenium 的方法,具体引入方式为

from selenium.webdriver.common.by import By

第二个疑问
可以封装一个方法,常用的定位方法可以单独出来
我们的项目常用的是 xpath

def by(locator: str | tuple[str, str]):
    if isinstance(locator, str):
        return By.XPATH, locator

    if isinstance(locator, tuple):
        # 固定格式,如果是元组,则写成(方式,定位)=>('xpath','//*[@class="name"]')

        method = locator[0]
        selector = locator[1]
        if not isinstance(method, str):  # 判断格式, 第一位应该是方法, name, id等, str格式
            raise InvalidSelectorException('locator is (method, selector)')
        if method.upper() == 'ID':
            return By.ID, selector
        if method.upper() == 'NAME':
            return By.NAME, selector
        ...

我是在,写页面元素对象的页面,引入的 from selenium.webdriver.common.by import By
元素定位的方式的话,我这也经常用的是 xpath, 但是我没有在 basepage 里去区分定位的方式,而是在这个页面,元素定位的时候加入了定位的方式

from selenium.webdriver.common.by import By
from basepage.BasePage import BasePage
from selenium import webdriver
import time

class LoginPage(BasePage):
    #页面url
    url = ''
    #页面元素定位
    username = (By.XPATH, '//input[@placeholder="请输入用户名"]')
    password = (By.XPATH, '//input[@placeholder="请输入密码"]')
    #登录业务逻辑
    def login(self,usr,pwd):
        self.open(self.url)
        self.input(self.username,usr)
        time.sleep(2)
        self.input(self.password,pwd)
        time.sleep(2)
需要 登录 后方可回复, 如果你还没有账号请点击这里 注册