def _find_element(self, locator, is_need_displayed=True): """查找单个元素,如果有多个返回第一个 Args: locator: 定位器 is_need_displayed: 是否需要定位的元素必须展示 Returns: 元素 Raises: NotFoundElementError 未找到元素会抛 NotFoundElementError 异常 """ if 'timeOutInSeconds' in locator: wait = locator['timeOutInSeconds'] else: wait = 20 try: if is_need_displayed: WebDriverWait(self.driver, wait).until( lambda driver: self._get_element_by_type(driver, locator).is_displayed()) else: WebDriverWait(self.driver, wait).until( lambda driver: self._get_element_by_type(driver, locator) is not None) return self._get_element_by_type(self.driver, locator) except Exception as e: L.e("[element] 页面中未能找到 %s 元素" % locator) raise NotFoundElementError
def is_text_displayed(self, text, is_retry=True, retry_time=5, is_raise=False): """检查页面中是否有文本关键字 如果希望检查失败的话,不再继续执行case,使用 is_raise = True Args: text: 关键字(请确保想要的检查的关键字唯一) is_retry: 是否重试,默认为true retry_time: 重试次数,默认为5 is_raise: 是否抛异常 Returns: True: 存在关键字 Raises: 如果is_raise = true,可能会抛NotFoundElementError """ try: if is_retry: return WebDriverWait(self.driver, retry_time).until( lambda driver: self._find_text_in_page(text)) else: return self._find_text_in_page(text) except TimeoutException: L.w("[Text]页面中未找到 %s 文本" % text) if is_raise: raise NotFoundTextError else: return False
def test_login(self, action: ElementActions): L.d('test_login') account = Steps.get_account() action.text(LoginPage.账号, account[0]) action.text(LoginPage.密码, account[1]) action.sleep(1) action.click(LoginPage.登录) action.click(HomePage.发布练习)
def parse(): L.i('解析yaml, Path:' + pages_path) pages = {} for root, dirs, files in os.walk(pages_path): for name in files: watch_file_path = os.path.join(root, name) with open(watch_file_path, 'r', encoding='utf-8') as f: page = yaml.safe_load(f) pages.update(page) return pages
def _find_text_in_page(self, text): """检查页面中是否有文本关键字 拿到页面全部source,暴力检查text是否在source中 Args: text: 检查的文本 Returns: True : 存在 """ L.i("[查找] 文本 %s " % text) return text in self.driver.page_source
def check_environment(self): L.i('检查环境...') # 检查appium版本 if '1.17.1' not in self.appium_v: L.e('appium 版本有问题') exit() else: L.i('appium version {}'.format(self.appium_v)) # 检查设备 if not self.devices: L.e('没有设备连接') exit() else: L.i('已连接设备:', self.devices)
def __init__(self): self.path = Config.DEFAULT_CONFIG_DIR self.cp = ConfigParser() self.cp.read(self.path) L.i('初始化config...config path: ' + self.path) apk_name = self.get_config(Config.TITLE_NAME, Config.VALUE_APP) self.apk_path = Config.BASE_PATH_DIR + '/Apk/' + apk_name self.xml_report_path = Config.BASE_PATH_DIR + '/Report/xml' self.html_report_path = Config.BASE_PATH_DIR + '/Report/html' self.pages_yaml_path = Config.BASE_PATH_DIR + '/Page/yaml' self.env_yaml_path = Config.BASE_PATH_DIR + '/Data/environment_info.yaml' self.app_activity = self.get_config(Config.TITLE_NAME, Config.VALUE_APP_ACTIVITY) self.app_package = self.get_config(Config.TITLE_NAME, Config.VALUE_APP_PACKAGE) self.account_success = self.get_config(Config.TITLE_ACCOUNT, Config.VALUE_ACCOUNT_SUCCESS) self.password_success = self.get_config(Config.TITLE_ACCOUNT, Config.VALUE_PASSWORD_SUCCESS)
def save_environment(self): infos = [] env_path = self.config.env_yaml_path apk_path = self.config.apk_path pages_yaml_path = self.config.pages_yaml_path xml_report_path = self.config.xml_report_path html_report_path = self.config.html_report_path app_activity = self.config.app_activity app_package = self.config.app_package for deviceName in self.devices: info = DeviceInfo(deviceName, "Android", ADB(deviceName).get_android_version()) infos.append(info) env_info = EnvironmentInfo(self.appium_v, infos, apk_path, pages_yaml_path, xml_report_path, html_report_path, app_activity, app_package) with open(env_path, 'w') as f: yaml.dump(env_info, f, default_flow_style=False) L.i('保存环境配置 Path:' + env_path)
def is_toast_show(self, message, wait=20): """Android检查是否有对应Toast显示,常用于断言 Args: message: Toast信息 wait: 等待时间,默认20秒 Returns: True 显示Toast """ locator = {'name': '[Toast] %s' % message, 'timeOutInSeconds': wait, 'type': 'xpath', 'value': '//*[contains(@text,\'%s\')]' % message} try: el = self._find_element(locator, is_need_displayed=False) return el is not None except NotFoundElementError: L.w("[Toast] 页面中未能找到 %s toast" % locator) return False
def _find_elements(self, locator): """查找多元素(不会抛异常) Args: locator: 定位器 Returns:元素列表 或 [] """ if 'timeOutInSeconds' in locator: wait = locator['timeOutInSeconds'] else: wait = 20 try: WebDriverWait(self.driver, wait).until( lambda driver: self._get_element_by_type(driver, locator, False).__len__() > 0) return self._get_element_by_type(self.driver, locator, False) except: L.w("[elements] 页面中未能找到 %s 元素" % locator) return []
def _get_element_by_type(driver, locator, element=True): """通过locator定位元素(默认定位单个元素) Args: driver:driver locator:定位器 element: true:查找单个元素 false:查找多个元素 Returns:单个元素 或 元素list """ value = locator['value'] ltype = locator['type'] L.i("[查找]元素 %s " % locator) if ltype == 'name': ui_value = 'new UiSelector().textContains' + '(\"' + value + '\")' return driver.find_element_by_android_uiautomator( ui_value) if element else driver.find_elements_by_android_uiautomator(ui_value) else: return driver.find_element(ltype, value) if element else driver.find_elements(ltype, value)
# -*- coding: utf-8 -*- # @Pjname ; AppGuiTesting # @Time : 2020/05/21/17:46 # @Author : Yuye # @File : Tools.py from Utils.Shell import Shell from Utils import L class Device: @staticmethod def get_android_devices(): android_devices_list = [] for device in Shell.invoke('adb devices').splitlines(): if 'device' in device and 'devices' not in device: device = device.split('\t')[0] android_devices_list.append(device) return android_devices_list if __name__ == '__main__': devices = Device.get_android_devices() L.i("devices: ", devices)
def get_account(): account = Environment().get_inited_config().account_success pwd = Environment().get_inited_config().password_success L.d('账号:%s 密码 %s' % (account, pwd)) return [account, pwd]