SeldomQA / poium

Page Objects design pattern test library, support selenium、appium、playwright, etc
https://pypi.org/project/poium
Apache License 2.0
416 stars 140 forks source link

页面跳转后元素定位怎么处理? #38

Open Sanmejie opened 2 years ago

Sanmejie commented 2 years ago

在实际项目中,一个测试项目有很多测试页面, 元素定位类是每个页面写一个页面元素类继承一个Page,还是一个网站所有元素都在这个继承Page的页面元素类中? 在调用元素的时候感觉页面元素不是很好区分...比如a页面有个登录,b页面有个登录按钮这种,两个都是登录元素命名一样的实际代表不同页面的元素。 如果是每个页面都继承Page,在使用的时候每个页面都需要实例化一个页面类传入driver? 有最佳实践的demo可参考吗?

Sanmejie commented 2 years ago

看到这个用生产者模式对页面操作再做了个封装 可以让代码更简洁点 #9 ,还有什么更好的办法吗?

from poium import Page, Element  
import time  
from selenium import webdriver  
from selenium.webdriver.chrome.service import Service as ChromeService  
from webdriver_manager.chrome import ChromeDriverManager  

class BaiduIndexPage(Page):  
    search_input = Element(css="#kw", describe="搜索框")  
    search_button = Element(css="#su", describe="搜索按钮")  
    login = Element(css='a.lb', describe='登录')  

class LoginPage(Page):  
    uesr_input = Element(id_="TANGRAM__PSP_11__userName", describe='用户名')  
    password_input = Element(id_="TANGRAM__PSP_11__password", describe='密码')  
    login_submit = Element(id_="TANGRAM__PSP_11__submit", describe='提交登录')  

class TotalPage(BaiduIndexPage, LoginPage):  
    pass  

if __name__ == '__main__':  
    driver = webdriver.Chrome(service=ChromeService(ChromeDriverManager().install()))  
    page = TotalPage(driver)  
    page.open('https://www.baidu.com')  
    page.search_input.send_keys('poium')  
    page.search_button.click()  
    time.sleep(1)  
    page.login.click()  
    page.uesr_input.input("张三")  
    page.password_input.input("我是密码")  
    page.login_submit.click()  
    time.sleep(3)  
    driver.quit()
Sanmejie commented 2 years ago

看到这个selenium_sample/test_mouse.py,然后做了尝试

from poium import Page, Element
import time
from selenium import webdriver
from selenium.webdriver.chrome.service import Service as ChromeService
from webdriver_manager.chrome import ChromeDriverManager

class BaiduIndexPage(Page):
    search_input = Element(css="#kw", describe="搜索框")
    search_button = Element(css="#su", describe="搜索按钮")
    login = Element(css='a.lb', describe='登录')

class LoginPage(Page):
    uesr_input = Element(id_="TANGRAM__PSP_11__userName", describe='用户名')
    password_input = Element(id_="TANGRAM__PSP_11__password", describe='密码')
    login = Element(id_="TANGRAM__PSP_11__submit", describe='提交登录')

def baiduindex(driver):
    """
    百度首页的行为
    """
    page=BaiduIndexPage(driver)
    page.search_input.send_keys('poium')
    page.search_button.click()
    time.sleep(1)
    page.login.click() #点击右上角

def baidu_login(driver):
    """
    百度登录页面的行为
    """
    page=LoginPage(driver)
    page.uesr_input.input("张三")
    page.password_input.input("我是密码")
    page.login.click()   #不同页面元素变量命名相同
    time.sleep(3)

if __name__ == '__main__':
    driver = webdriver.Chrome(service=ChromeService(ChromeDriverManager().install()))
    driver.get("https://www.baidu.com")
    baiduindex(driver)
    baidu_login(driver)
    driver.quit()
Sanmejie commented 2 years ago

😴 这里是个好地方-->dependents

defnngj commented 1 year ago

page object 大的原则是按照page来定义xxPage 类,是因为我们默认 一个完整的功能是在一个页面当中的;一个页面可以包含多个功能。但实际在定义 xxPage 类的时候应该是按照 业务功能。如你上面的登录例子:登录 和 登录后的验证点 分别在不同的页面,但他们应该被放到一个loginPage类中。

不同 page类之间的继承完全是可以的。例如我在用appium 做App自动化的时候。

class xxPage:
    ...

class  xxiOSPage(xxPage):
    ...

class xxAndPage(xxPage):
    ...

两端通用的定位放到xxPage,然后再实现(iOS、Android)各自差异的部分。