最近看到了 playwright , 试着用了下,主要试了常用的 storage_state,handle 以及 参数化 cases 几个点
这次更新了下,基本几个常用的都有了。
from utils.handle_logging import log
from playwright.sync_api import Playwright
import time
'''
xxxxx page object
'''
class Treasury:
def __init__(self, page: Page):
self.page = page
self.base_url = 'https://xxxxxxxxx.com'
# page elements
self.logo_img = self.page.get_by_role('img', name='logo')
self.no_data = self.page.get_by_role("cell", name="No data").locator("div").nth(1)
## iframe
self.mint_DREX_confirm_frame = self.page.get_by_text("Mint DREXAmountDREXConfirmCancel")
## input
self.client_id_input = self.page.get_by_placeholder("Client ID")
self.start_day_input = self.page.get_by_placeholder("Start date")
## button
self.reset_buttton = self.page.get_by_role("button", name="Reset")
self.filter_buttton = self.page.get_by_role("button", name="Apply filters")
## top menu
self.DREX_menu = self.page.get_by_role("menuitem", name="DREX")
self.DVt_menu = self.page.get_by_role("menuitem", name="DVt")
self.clients_menu = self.page.get_by_role("menuitem", name="Clients")
## tab menu
self.wallet_balance_tab = self.page.get_by_role("tab",name="Wallet balance")
self.client_transactions_tab = self.page.get_by_role("tab",name="Client transactions")
def goto(self, endpoint: str, use_base_url=True):
if use_base_url:
self.page.goto(self.base_url + endpoint)
else:
self.page.goto(endpoint)
def login(self, username: str, password: str):
if self.page.url == self.base_url + "/user/login":
# self.page.goto(self.base_url + "/user/login")
self.page.get_by_placeholder("Email").fill(username)
self.page.get_by_placeholder("Password").fill(password)
self.page.get_by_role("button", name="Login").click()
time.sleep(2)
self.context.storage_state(path='./conf/xxxxxxxx.json')
else:
pass
def client_query(self, client_id: str, status: str) -> None:
log.info("client id : {}, status : {}".format(client_id, status))
status = status.upper()
self.client_id_input.fill(client_id)
self.page.locator("#status").click()
self.page.get_by_title(status).get_by_text(status).click()
self.filter_buttton.click()
self.page.wait_for_load_state()
def close(self):
self.page.close()
self.context.close()
self.browser.close()
import pytest
from playwright.sync_api import sync_playwright
@pytest.fixture(scope="session", autouse=True)
def treasury_login(base_info):
with sync_playwright() as pw:
chromium = pw.chromium
browser = chromium.launch()
page = browser.new_page()
page.goto(url = base_info['treasury_base_url'] + '/#/user/login')
page.get_by_placeholder("Email").fill(base_info['treasury_user'])
page.get_by_placeholder("Password").fill(base_info['treasury_pwd'])
page.get_by_role("button", name="Login").click()
page.wait_for_url(base_info['treasury_base_url']+ '/#/xxxx/xxxx')
# storage auth info
page.context.storage_state(path=AUTH_DIR + '/treasury_state.json')
page.close()
browser.close()
@pytest.fixture(scope="function",autouse=True)
def browser_context_args(browser_context_args):
return {
**browser_context_args,
# "storage_state": AUTH_DIR + '/treasury_state.json'
}
# 不使用已保存的storage_state 信息
@pytest.mark.browser_context_args()
def test_login_success(page:Page) -> None:
p = treasury_page_object.Treasury(page)
p.login(username='xxxxxx', password='xxxxxx')
p.page.wait_for_url(p.base_url+ '/#/xxxxxx')
assert p.DREX_menu.is_visible()
# 使用已保存的storage_state 信息
@pytest.mark.browser_context_args(storage_state=AUTH_DIR + '/treasury_state.json')
def test_login_and_logout_success(page:Page) ->None:
p = treasury_page_object.Treasury(page)
p.goto_home()
p.page.wait_for_load_state()
# click username to logout
p.page.get_by_text("xxxxxxxxxx").click()
p.page.get_by_text("Logout").click()
p.page.wait_for_load_state()
log.info(p.page.url)
assert p.page.url == p.base_url + '/#/user/login'
### 参数化
```code
none_para = ['APPROVED','PENDING','DECLINED']
@pytest.mark.parametrize("status", none_para)
@pytest.mark.browser_context_args(storage_state=AUTH_DIR + '/treasury_state.json')
def test_clients_query_with_status_success(page:Page,status) ->None:
client_id = '2883'
p = treasury_page_object.Treasury(page)
p.goto_home()
p.clients_menu.click()
p.client_query_with_status(client_id,status)
# time.sleep(1)
p.page.wait_for_load_state()
if p.no_data.is_visible():
pass
else:
expect(p.page.get_by_role("cell", name=client_id)).to_be_visible()
expect(p.page.get_by_role("cell", name=status)).to_be_visible()
# handle_mock
def handle_401(route):
# 用户没有权限(令牌、用户名、密码错误)
route.fulfill(
status=401,
json={
"error": "unauthorized",
"error_description": "Full authentication is required to access this resource"
})
def handle_500(route):
# 服务器发生错误,请检查服务器
route.fulfill(status=500)
def handle_login_under_review(route):
# mock 用户登录时,unser review
json = {
"traceId": "26e8edaf3c45474db05522a04a4408b9.263.16989832389060341",
"code": "SYSTEM_ERROR",
"message": "Your account is currently under review.",
"displayMessage": "Your account is currently under review.",
"data": None
}
log.info(json)
route.fulfill(status=200,json=json)
# case 里使用
@pytest.mark.browser_context_args(storage_state=AUTH_DIR + '/treasury_state.json')
def test_api_mock_401(page:Page) ->None:
p = treasury_page_object.Treasury(page)
p.goto_home()
# mock 401
p.page.route(p.base_url + '/api/**',handler=handle_mock.handle_401)
p.DREX_menu.click()
p.page.wait_for_url(p.base_url + '/#/user/login')
expect(p.page.get_by_text("Your session is over, please login again").first).to_be_visible()
p.page.screenshot(path='./results/BancoABC/Treasury/{}.png'.format(401))
@pytest.mark.browser_context_args(storage_state=AUTH_DIR + '/treasury_state.json')
def test_api_mock_500(page:Page) ->None:
p = treasury_page_object.Treasury(page)
p.goto_home()
# mock 500
p.page.route(p.base_url + '/api/**',handler=handle_mock.handle_500)
p.DREX_menu.click()
p.page.wait_for_load_state()
expect(p.page.get_by_text("Internal server error")).to_be_visible()
p.page.screenshot(path='./results/BancoABC/Treasury/{}.png'.format(500))
def run_tests_and_generate_html_report():
# Specify the test testcases to be executed
test_cases = [
"testcases/BancoABC/test_treasury.py",
]
# Set up pytest arguments
args = [
"-v",
# "-m smoke",
# "--template=html1/index.html",
'--browser', 'webkit','--browser', 'chromium','--browser', 'firefox',
# '--browser-channel','msedge',
# '--device',"iPhone 11 Pro",
"--html=./TestReport/Test_Report.html",
]
# Append test testcases to the arguments
args.extend(test_cases)
# Run pytest and capture the exit code
log.info(args)
exit_code = pytest.main(args)
# Return the exit code
return exit_code
第一次发帖子,写的不好,多包涵,后面继续深入使用了,有其它好用的或者困惑的,继续更新吧