Appium自动化-Android(二)
appium框架
基于pyse的基础上,再度进行封装-->补充安卓的方法
基于pyse添加android方法
pyse.py
#!/usr/bin/env python3 # -*- coding:utf-8 -*- """ selenium基类 本文件在selenium基类的基础上增加appium的封装方法 """ import allure import platform from selenium.common.exceptions import TimeoutException from selenium.webdriver.common.action_chains import ActionChains from selenium.webdriver.common.keys import Keys from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.support.ui import WebDriverWait from config.conf import cm from lib.logger import log from lib.times import sleep class pyse(object): """selenium+appium基类""" def __init__(self, driver): self.driver = driver self.timeout = 20 self.wait = WebDriverWait(self.driver, self.timeout) def open(self, url): """打开网址并验证""" self.driver.maximize_window() self.driver.set_page_load_timeout(60) try: self.driver.get(url) self.driver.implicitly_wait(10) except TimeoutException: self.allure_png("打开浏览器超时") raise TimeoutException("打开%s超时请检查网络或网址服务器" % url) else: log.info("成功打开网页:%s" % url) return True @staticmethod def element_locator(func, locator): """元素定位器""" name, value = locator loc_type = cm.LOCATE_MODE[name] return func(loc_type, value) def get_Screenshots_png(self, name): """截图""" self.driver.get_screenshot_as_file(cm.png_path(name)) def allure_png(self, name): """allure截图""" self.get_Screenshots_png(name) allure.attach.file(cm.png_path(name), name, allure.attachment_type.PNG) def find_clickable(self, locator): """寻找可点击元素""" try: ele = pyse.element_locator(lambda *args: self.wait.until(EC.element_to_be_clickable(args)), locator) return ele except Exception: self.allure_png('未找到元素') raise Exception('页面中未能找到可点击元素{}'.format(locator)) def scroll(self, item_name): """滚动以查找元素""" try: ele = self.driver.find_element_by_android_uiautomator( 'new UiScrollable(new UiSelector().scrollable(true).instance(0)).getChildByText(new UiSelector()' '.className("android.widget.TextView"), "'+ item_name + '")') return ele except Exception: self.allure_png('未找到元素') raise Exception('页面中未能找到元素{}'.format(item_name)) def find_element(self, locator): """寻找单个元素""" try: ele = pyse.element_locator(lambda *args: self.wait.until(EC.presence_of_element_located(args)), locator) return ele except Exception: self.allure_png('未找到元素') raise Exception('页面中未能找到元素:{}'.format(locator)) def find_elements(self, locator): """查找多个相同的元素""" try: ele = pyse.element_locator(lambda *args: self.wait.until(EC.presence_of_all_elements_located(args)), locator) return ele except Exception: self.allure_png('未找到元素') raise Exception('页面中未能找到元素{}'.format(locator)) def find_visibility(self, locator): """判断某个元素在是否存在于dom或不可见,如果不可见返回False,可见返回True""" try: ele = pyse.element_locator(lambda *args: self.wait.until(EC.visibility_of_element_located(args)), locator) return ele except Exception: self.allure_png('未找到元素') raise Exception('页面中未能找到元素:{}'.format(locator)) def find_invisibility(self, locator): """判断某个元素在是否存在于dom或不可见,如果可见返回False,不可见返回True""" try: ele = pyse.element_locator(lambda *args: self.wait.until(EC.invisibility_of_element_located(args)), locator) return ele except Exception: self.allure_png('未找到元素') raise Exception('页面中未能找到元素:{}'.format(locator)) def elements_num(self, locator): """获取相同元素的个数""" number = len(self.find_elements(locator)) log.info("相同元素总数:{}".format((locator, number))) return number def clear(self, locator): """清空输入框""" sleep(0.2) ele = self.find_element(locator) ele.clear() log.info("清空输入框:{}".format(locator)) return ele def type(self, locator, txt): """输入(输入前先清空)""" ele = self.find_element(locator) ele.clear() ele.send_keys(txt) log.info("输入文本:{}".format(txt)) def upload(self, locator, file): """上传附件""" ele = self.find_element(locator) ele.send_keys(file) log.info("上传附件:{} {}".format(locator, file)) def click(self, locator): """点击""" self.find_clickable(locator).click() sleep() log.info("点击元素:{}".format(locator)) def click_elements(self, locator, index): """根据索引点击多个元素中的一个元素""" self.find_elements(locator)[index].click() sleep() log.info("点击元素:{}".format(locator)) def get_text(self, locator): """获取当前的text""" _text = self.find_element(locator).text log.info("获取文本:{}".format(_text)) return _text def get_elements_text(self, locator): """获取相同元素多个text,并以列表形式返回""" el_text = [] for i in self.find_elements(locator): el_text.append(i.text) log.info('获取相同元素值:{}'.format(el_text)) return el_text def get_attribute(self, locator, attribute): """获取标签属性value""" _attribute = self.find_element(locator) log.info("获取标签的属性:{}的值:{}".format(attribute, _attribute.get_attribute(attribute))) return _attribute.get_attribute(attribute) def get_elements_attribute(self, locator, attribute): """获取相同元素多个attribute值""" el_attribute = [] for i in self.find_elements(locator): el_attribute.append(i.get_attribute(attribute)) log.info('获取相同元素[]属性值:{}'.format(attribute, el_attribute)) return el_attribute @property def get_source(self): """获取页面源代码""" return self.driver.page_source def is_display(self, locator): """获取要显示的元素,返回结果为true或false""" return self.find_element(locator).is_displayed() def is_enabled(self, locator): """获取要启用的元素,返回结果为true或false""" return self.find_element(locator).is_enabled() def is_selected(self, locator): """获取要选择的元素,返回结果为true或false""" return self.find_element(locator).is_selected() def F5(self): """刷新页面F5""" self.driver.refresh() self.driver.implicitly_wait(30) log.info("刷新页面") def right_click(self, locator): """右击""" ActionChains(self.driver).context_click(self.find_clickable(locator)).perform() log.info('右击') def double_click(self, locator): """双击""" ActionChains(self.driver).double_click(self.find_clickable(locator)).perform() log.info('双击') def drag_and_drop(self, locator, locator2): """从元素A拖到元素B""" ActionChains(self.driver).drag_and_drop(self.find_element(locator), self.find_element(locator2)).perform() log.info('拖拽元素') def close(self): """关闭浏览器窗口""" self.driver.close() log.info('关闭浏览器窗口') def quit(self): """退出浏览器""" self.driver.quit() log.info('退出浏览器') def js(self, script): """通过js操作""" return self.driver.execute_script(script) def get_title(self): """获取窗口title""" title = self.driver.title log.info('获取窗口title:{}'.format(title)) return title def get_current_url(self): """获取当前页面的URL地址""" current_url = self.driver.current_url log.info('获取当前页面的URL地址:{}'.format(current_url)) return current_url def assert_text(self, locator, text): """校验[文案]是否匹配""" try: assert text == self.get_text(locator) except Exception: self.allure_png('校验[文案]_{}异常'.format(text)) raise Exception('校验[文案]_{}异常'.format(text)) else: log.info('校验通过text:{}'.format(text)) return True def assert_in_text(self, locator, text): """校验[文案]是否被包含在内""" try: assert text in self.get_text(locator) except Exception: self.allure_png('校验[文案]_{}异常'.format(text)) raise Exception('校验[文案]_{}异常'.format(text)) else: log.info('校验通过text:{}'.format(text)) return True def assert_attribute(self, locator, attribute, text): """校验attribute是否匹配""" try: assert text == self.get_attribute(locator, attribute) except Exception: self.allure_png('校验attribute_{}异常'.format(attribute)) raise Exception('校验attribute_{}异常'.format(attribute)) else: log.info('校验通过attribute:{} {}'.format(attribute, text)) return True def assert_in_attribute(self, locator, attribute, text): """校验attribute包含特定字符串匹配""" try: assert text in self.get_attribute(locator, attribute) except Exception: self.allure_png('校验attribute_{}异常'.format(attribute)) raise Exception('校验attribute_{}异常'.format(attribute)) else: log.info('校验通过attribute:{} {}'.format(attribute, text)) return True def accept_alert(self): """切换到警告框""" self.driver.switch_to.alert.accept() def dismiss_alert(self): """解除可用警告框""" self.driver.switch_to.alert.dismiss() def switch_to_frame(self, attribute): """切换到frame""" self.driver.switch_to.frame(self.find_element(attribute)) def switch_to_frame_out(self): """ 释放frame,重新回到主页面上""" self.driver.switch_to.default_content() def open_new_window(self, locator): """打开新窗口并切换到新打开的窗口""" self.click(locator) all_handles = self.driver.window_handles for handle in all_handles: if handle != self.driver.current_window_handle: self.close() self.driver.switch_to.window(handle) log.info('通过元素:{}在新标签页打开链接并关闭老窗口'.format(locator)) def open_window(self, locator): """打开新窗口并切换到新打开的窗口""" self.click(locator) all_handles = self.driver.window_handles for handle in all_handles: if handle != self.driver.current_window_handle: self.driver.switch_to.window(handle) log.info('通过元素:{}在新标签页打开链接'.format(locator)) def add_attribute(self, locator, attributeName, value): """给页面标签添加新属性""" self.driver.execute_script("arguments[0].%s=arguments[1]" % attributeName, locator, value) log.info('给标签{}的属性{}添加新值:{}'.format(locator, attributeName, value)) def set_attribute(self, locator, attributeName, value): """设置页面对象的属性值""" self.driver.execute_script("arguments[0].setAttribute(arguments[1],arguments[2])", locator, attributeName, value) log.info('给标签{}的属性{}设置新值:{}'.format(locator, attributeName, value)) def remove_attribute(self, locator, attributeName): """删除页面属性""" self.driver.execute_script("arguments[0].removeAttribute(arguments[1])", locator, attributeName) log.info('删除标签{}的属性:{}'.format(locator, attributeName)) def ActionChains_ele_click(self, locator): """鼠标移动到某个元素,然后进行点击操作""" ActionChains(self.driver).move_to_element(self.find_element(locator)).click().perform() log.info('鼠标移动到某个元素{}并点击'.format(locator)) sleep() def ActionChains_move_to_click(self, x, y): """鼠标通过坐标方式移动到指定点,然后进行点击操作""" ActionChains(self.driver).move_by_offset(x, y).context_click().perform() log.info('鼠标移动到坐标(x:{},y:{})并点击'.format(x, y)) sleep() def ActionChains_move_to_ele_click(self, locator, x, y): """鼠标根据从元素位置为起点,通过坐标方式移动到指定点,然后进行点击操作""" ActionChains(self.driver).move_to_element_with_offset(self.find_element(locator), x, y).click().perform() log.info('鼠标从元素:{}移动到坐标(x:{},y:{})并点击'.format(locator, x, y)) sleep() def Keys_Backspace(self, locator): """通过键盘backspace来清空输入框""" count = 1 sum = len(self.get_attribute(locator, 'value')) + 1 while count < sum: self.find_element(locator).send_keys(Keys.BACKSPACE) count += 1 log.info("清空输入框:{}".format(locator)) def Keys_CONTROL(self, locator, key): """ win 键盘Control操作 mac 键盘COMMAND操作 """ if platform.system().lower() == "windows": self.find_element(locator).send_keys(Keys.CONTROL, key) log.info('通过键盘CTRL+{}操作元素:{}'.format(key, locator)) else: self.find_element(locator).send_keys(Keys.COMMAND, key) log.info('通过键盘COMMAND+{}操作元素:{}'.format(key, locator)) def contexts(self): """放回list包含当前所有界面环境WEBVIEW或native""" return self.driver.contexts def switch_to_context(self, context): """切换APP类型,WEBVIEW或native""" self.driver.switch_to.context(context) sleep() def get_sizes(self): """获取手机屏幕分辨率大小""" return self.driver.get_window_size() def swipe_left(self, star_x=0.9, stop_x=0.1, size_y=0.3, num=1, duration=2000): """向左滑动。Y轴保持不变,X轴:从大到小""" self.get_sizes() x = self.driver.get_window_size()['width'] y = self.driver.get_window_size()['height'] x1 = int(x * star_x) y1 = int(y * size_y) x2 = int(x * stop_x) y2 = int(y * size_y) for i in range(0, num): self.driver.swipe(x1, y1, x2, y2, duration) sleep() def swipe_right(self, star_x=0.1, stop_x=0.9, size_y=0.3, num=1, duration=2000): """向右滑动。y轴保持不变,X轴:由小变大""" self.get_sizes() x = self.driver.get_window_size()['width'] y = self.driver.get_window_size()['height'] x1 = int(x * star_x) y1 = int(y * size_y) x2 = int(x * stop_x) y2 = int(y * size_y) for i in range(0, num): self.driver.swipe(x1, y1, x2, y2, duration) sleep() def swipe_up(self, star_y=0.9, stop_y=0.1, size_x=0.5, num=1, duration=2000): """向上滑动。x轴保持不变,y轴:由大变小""" self.get_sizes() x = self.driver.get_window_size()['width'] y = self.driver.get_window_size()['height'] x1 = int(x * size_x) y1 = int(y * star_y) x2 = int(x * size_x) y2 = int(y * stop_y) for i in range(0, num): self.driver.swipe(x1, y1, x2, y2, duration) sleep() def swipe_down(self, star_y=0.1, stop_y=0.9, size_x=0.5, num=1, duration=2000): """向下滑动。x轴保持不变,y轴:由小变大""" self.get_sizes() x = self.driver.get_window_size()['width'] y = self.driver.get_window_size()['height'] x1 = int(x * size_x) y1 = int(y * star_y) x2 = int(x * size_x) y2 = int(y * stop_y) for i in range(0, num): self.driver.swipe(x1, y1, x2, y2, duration) sleep() def tap(self, size_y=0.9, size_x=0.5): """坐标点击""" x = self.driver.get_window_size()['width'] y = self.driver.get_window_size()['height'] x1 = int(x * size_x) y1 = int(y * size_y) self.driver.tap([(x1, y1)]) sleep() def scroll_click(self, item_name): """滚动以查找元素,然后单击""" self.scroll(item_name).click() sleep()