import yaml
from appium.webdriver import WebElement
from appium.webdriver.webdriver import WebDriver
from selenium.webdriver.common.by import By
import logging
def exception_handle(fun):
def magic(*args, **kwargs):
_self: BasePage = args[0]
try:
result = fun(*args, **kwargs)
# 清空错误次数
_self._error_count = 0
return result
except Exception as e:
# 如果次数太多,就退出异常逻辑,直接报错
if _self._error_count > _self._error_max:
raise e
# 记录一直异常的次数
_self._error_count += 1
# 对黑名单里的弹框进行处理
for element in _self._black_list:
logging.info(element)
elements = _self._driver.find_elements(*element)
if len(elements) > 0:
elements[0].click()
# 继续寻找原来的正常控件
return magic(*args, **kwargs)
# 如果黑名单也没有,就报错
logging.warning("black list no one found")
raise e
return magic
class BasePage:
logging.basicConfig(level=logging.INFO)
_driver: WebDriver
_black_list = [
(By.ID, 'tv_agree'),
(By.XPATH, '//*[@text="确定"]'),
(By.ID, 'image_cancel'),
(By.XPATH, '//*[@text="下次再说"]')
]
_error_max = 10
_error_count = 0
_params = {}
def __init__(self, driver: WebDriver = None):
self._driver = driver
# done: 当有广告、评价等各种弹框出现的时候,要进行异常流程处理
@exception_handle
def find(self, locator, value: str = None):
# 寻找控件
if isinstance(locator, tuple):
return self._driver.find_element(*locator)
else:
return self._driver.find_element(locator, value)
import os
import sys
from time import sleep
from appium import webdriver
from selenium.webdriver.support.wait import WebDriverWait
from page.base_page import BasePage
from page.login import Login
from page.main import Main
class App(BasePage):
_package = "cn.billicomm.watch"
_activity = "cn.billicomm.watch.MainActivity"
def start(self):
if self._driver is None:
caps = {}
caps["platformName"] = "android"
caps["deviceName"] = "RGWSUCPVEIMRJJHE"
caps["appPackage"] = self._package
caps["appActivity"] = self._activity
caps["noReset"] = True
udid=os.getenv("udid", None)
if udid is not None:
caps["udid"] = os.getenv("udid", "")
# caps["noReset"] = True
# caps["dontStopAppOnReset"] = True
# caps["unicodeKeyboard"] = True
# caps["resetKeyboard"] = True
# caps["skipServerInstallation"] = True
# caps["chromedriverExecutableDir"]="/Users/seveniruby/projects/chromedriver/all"
caps["chromedriverExecutable"] = "/Users/seveniruby/projects/chromedriver/all/chromedriver_2.20"
# caps['avd'] = 'Pixel_2_API_23'
self._driver = webdriver.Remote("http://localhost:4723/wd/hub", caps)
#grid模式
# self._driver = webdriver.Remote("http://localhost:4444/wd/hub", caps)
self._driver.implicitly_wait(5)
else:
print(self._driver)
# todo:
self._driver.execute("mobile:startActivity",
{"appPackage": "cn.billicomm.watch", "appActivity": "cn.billicomm.watch.MainActivity"})
return self
def restart(self):
pass
def stop(self):
pass
def login(self) -> Login:
return Login(self._driver)
def main(self) -> Main:
# todo: wait main page
# def wait_load(driver):
# print(datetime.datetime.now())
# source=self._driver.page_source
#
# if "我的" in source:
# return True
# if "同意" in source:
# return True
# if "image_cancel" in source:
# return True
# return False
#
# WebDriverWait(self._driver, 60).until(wait_load)
return Main(self._driver)
from time import sleep
from selenium.webdriver.common.by import By
from page.base_page import BasePage
from page.main import Main
class Login(BasePage):
def login_By_Password(self, loginName, password):
self._driver.find_element(By.XPATH, "//*[@content-desc='密码登录'][1]").click()
sleep(2)
self._driver.find_element(By.XPATH, "//*[@class ='android.widget.EditText'][1]").click()
self._driver.find_element(By.XPATH, "//*[@class ='android.widget.EditText'][1]").send_keys(loginName)
self._driver.find_element(By.XPATH, "//*[@class ='android.widget.EditText'][2]").click()
self._driver.find_element(By.XPATH, "//*[@class ='android.widget.EditText'][2]").send_keys(password)
self._driver.hide_keyboard()
self._driver.find_element(By.XPATH,
"//*[@content-desc='我已阅读并同意']/../../*[@class ='android.view.View'][2]/android.view.View/android.widget.ImageView").click()
self._driver.find_element(By.XPATH, "//*[@content-desc='立即登录']").click()
try:
return Main(self._driver)
except:
return self.get_toast()
from selenium.webdriver.common.by import By
from page.app import App
class TestLogin:
def setup(self):
self.app = App().start().login()
self.main = App().main()
# @pytest.mark.parametrize("loginName, password",[('15129212935',''),('','Xjn@123456'),('15129212935','Xjn@123457')])
def test_login_Success_By_Password(self):
self.app.login_By_Password('18710750235', 'Xjn@123456')
ele = self.main.find(By.XPATH, "//*[@content-desc='首页']").text
print(ele)
执行报错,提示:
self = <page.main.Main object at 0x000001FAD88BE488>, locator = ‘xpath’
value = “//*[@content-desc=‘首页’]”
@exception_handle
def find(self, locator, value: str = None):
# 寻找控件
if isinstance(locator, tuple):
return self._driver.find_element(*locator)
else:
return self._driver.find_element(locator, value)
E AttributeError: ‘NoneType’ object has no attribute ‘find_element’