playwright解决重复登录问题,通过pytest夹具自动读取storage_state用户状态信息

playwright解决重复登录问题,通过pytest夹具自动读取storage_state用户状态信息

conftest.py文件下封装两个夹具

夹具一:将storage_state登录状态导出为json文件

  • 开启夹具自动调用 autouse=True
  • browser夹具,来源于pytest-playwright包封装的夹具,替代该代码browser = playwright.chromium.launch()。
  • base_url夹具,来源于pytest-base-url包封装好的夹具,用于在pytest.ini设置全局的base_url。
  • pytestconfig夹具,来源于pytest包,用于处理pytest.ini配置文件
python 复制代码
@pytest.fixture(scope='session', autouse=True)
def login(browser, base_url, pytestconfig):
    """
        封装统一的登录夹具,配置免登录
    :param browser: 插件pytest-playwright封装好的夹具
    :param base_url: 插件pytest-base-url插件,封装好的夹具,获取pytest.ini文件中的base_url=
    :param pytestconfig: pytest提供的夹具,用于获取pytest.ini配置文件
    :return:
    """
    context = browser.new_context(base_url=base_url)
    page = context.new_page()
    login = LoginPage(page)
    # 用户名和密码
    login.login_flow('test_0001', 'admin123')
    # pytestconfig.rootpath : 输出项目根目录,路径根据pytest.ini配置文件,定位项目目录
    context.storage_state(path=pytestconfig.rootpath.joinpath('auth').joinpath('ry_cookie.json'))
    page.close()
    context.close()

夹具二:重写夹具browser_context_args,添加storage_state登录状态

  • browser_context_args:来源于pytest-playwright包。
python 复制代码
@pytest.fixture(scope='session', autouse=True)
def browser_context_args(browser_context_args, pytestconfig):
    """
        重写browser_context_args方法,添加cookie用户状态信息
    :param browser_context_args: pytest-playwright插件中封装的方法
    :param pytestconfig: pytest封装的方法
    :return:
    """
    return {**browser_context_args, 'storage_state': pytestconfig.rootpath.joinpath('auth').joinpath('ry_cookie.json')}

登录LoginPage对象

python 复制代码
from playwright.sync_api import Page


class LoginPage:
    def __init__(self, page: Page):
        self.page = page
        # 使用xpath语法获取用户名文本框
        self.locator_username = page.locator("//form[@id='signupForm']/input[@class='form-control uname']")
        # 密码框
        self.locator_password = page.locator("//form[@id='signupForm']/input[@class='form-control pword']")
        # 登录按钮
        self.login_button = page.locator("//button[@id='btnSubmit']")

        # 必填提示
        self.username_tips = page.locator("//label[@id='username-error']")
        self.password_tips = page.locator("//label[@id='password-error']")

        self.login_error_tips = page.get_by_text("用户不存在/密码错误")
        self.login_error_tips2 = page.locator("text=用户不存在/密码错误")
        self.login_error_tips3 = page.locator("//div[@class='layui-layer-content']")

        self.navigate()

    def navigate(self):
        self.page.goto('/login')

    def fill_username(self, username):
        # 必须先点一下才能获取到
        self.locator_username.click()
        self.locator_username.fill(username)

    def fill_password(self, password):
        self.locator_password.click()
        self.locator_password.fill(password)

    def click_login(self):
        self.login_button.click()

    def login_flow(self, username, password):
        self.navigate()
        # 定位用户名
        self.fill_username(username)
        # 定位密码
        self.fill_password(password)
        # 点击登录按钮
        self.click_login()
        # 等待页面跳转,作为登录成功的标准,等待下个页面加载完成
        self.page.wait_for_url(url='/index')

    def clean_username_password(self):
        self.fill_password('')
        self.fill_username('')

演示示例:test_ry_login.py

  • 切记:设置login_page夹具,只能设置为function级别。保持默认即可。
python 复制代码
@pytest.fixture()
def login_page(page):
    yield LoginPage(page)

def test_login_success(login_page):
    """
    断言:登录成功
        断言title和url
    :param login_page:
    :return:
    """
    login_page.login_flow('admin', 'admin123')
    expect(login_page.page).to_have_title(re.compile('首页'))
    expect(login_page.page).to_have_url('/index')
相关推荐
IT_陈寒4 分钟前
Java项目实战经验分享:一次由JPA懒加载引发的生产事故
前端·人工智能·后端
环境栈笔记8 分钟前
浏览器多开同步怎么做?先分清设置、登录态和窗口操作
前端·人工智能·后端·自动化
weixin_4404016914 分钟前
大数据技术-数据分析(EXcel+Python数据处理+SQL)
大数据·python·数据分析·excel
是立不是利18 分钟前
CSS 的层叠与优先级——为什么我的样式不生效
前端·css
开开心心就好18 分钟前
电脑语音实时转文字工具,会议记录很省事
运维·服务器·前端·c#·ocr·perl·1024程序员节
甜到心里的蛋糕21 分钟前
AI 生成 MV 音频异响排查:频谱定位、片段替换与 Nginx 缓存
人工智能·python·nginx·ffmpeg·音视频·音频处理
aixingpan28 分钟前
aixingpan.cn API开发文档:api_docs_onechart_marks_secondary2接口指南
前端·php
2601_9679801131 分钟前
python中的静态方法和类方法
python·静态方法·类方法·实例化·方法调用
智购科技无人售货机厂家38 分钟前
自动售货机物联网平台为什么会出现在线状态不一致?~YH
python·单片机·嵌入式硬件·django·pygame
唔661 小时前
在透镜圆正中加了一个描边空心字
前端·javascript