def on_created(self, event): L.i('监听到文件: yaml 发生了变化') try: gen_page_py() except Exception as e: L.e('\n!!!!!!!---pages.yaml---!!!!!!\n解析文件 pages.yaml 错误\n' '请到{}路径下检查修改后重新保存.'.format(self.watch_path))
def swip_up(self, count=1, method=None): """向上滑动,常用于上拉加载 Args: count: 滑动次数 method: 传入的方法 method(action) ,如果返回为True,则终止加载 Examples: swip_down(self, count=100, method=is_text_displayed(self, "没有更多了")) 上面代码意思:当页面不展示"暂无可配送的订单"时停止加载,即有单停止加载 """ if count == 1: self.driver.swipe(width / 2, height * 4 / 5, width / 2, height * 2 / 5, 2000) time.sleep(1) else: x = 0 for x in range(count): self.driver.swipe(width / 2, height * 4 / 5, width / 2, height * 2 / 5, 2000) time.sleep(1) try: if method(self): break except: pass L.i('上拉加载的次数:' + str(x))
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 _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)
def GetSeasonFolder(show_name, season_id, check_updates=False): season = GetSeasonCacheOrCreate(show_name, season_id, as_string=False) PushToHistory(season) oc = ObjectContainer(title2=season['title']) if season['playlist']: oc.add( DirectoryObject(key=Callback(GetTranslatesFolder, show_name=show_name, season_id=season_id, check_updates=check_updates), title=L('SEASON_TRANSLATES_FOLDER'), thumb=season['thumb'], art=season['thumb'])) if 'other_season' in season: oc.add( DirectoryObject(key=Callback(GetOtherSeasonsFolder, show_name=show_name, season_id=season_id), title=L('SEASON_OTHER_SEASONS_FOLDER'), thumb=season['thumb'], art=season['thumb'])) # TODO: add check if exists in bookmarks and related stuff oc.add( DirectoryObject(key=Callback(Dummy), title=L('SEASON_ADD_BOOKMARK'), thumb=R('icon_add.png'), art=season['thumb'])) oc.add( DirectoryObject(key=Callback(Dummy), title=L('SEASON_DEL_BOOKMARK'), thumb=R('icon_del.png'), art=season['thumb'])) return oc
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 SearchFolder(query=None, genre=[], country=[]): oc = ObjectContainer(title2=L('MAIN_SEARCH')) genres_title = 'GENRE' # TODO: localize countries_title = 'COUNTRY' # TODO: localize if Client.Product in DumbKeyboard.clients: genres_title = genres_title + ': %s' % ''.join('[%s]' % i for i in genre) countries_title = countries_title + ': %s' % ''.join('[%s]' % i for i in country) DumbKeyboard(PREFIX + '/search', oc, GetSearchResultFolder, genre=genre, country=country, dktitle=L('SEARCH_INPUT')) else: oc.add( InputDirectoryObject(key=Callback(GetSearchResultFolder, genre=genre, country=country), title=L('SEARCH_INPUT'))) if Prefs['api_key']: oc.add( DirectoryObject(key=Callback(GetSearchGenreFolder, query=query, genre=genre, country=country), title=L('SEARCH_PICK_GENRE'))) # TODO: localize oc.add( DirectoryObject(key=Callback(GetSearchCountryFolder, query=query, genre=genre, country=country), title=L('SEARCH_PICK_COUNTRY'))) # TODO: localize return oc
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.smtpserver = self.get_config(Config.TITLE_MAIL, Config.VALUE_SMTPSERVER) self.sender = self.get_config(Config.TITLE_MAIL, Config.VALUE_SENDER) self.receiver = self.get_config(Config.TITLE_MAIL, Config.VALUE_RECEIVER) self.username = self.get_config(Config.TITLE_MAIL, Config.VALUE_USERNAME) self.password = self.get_config(Config.TITLE_MAIL, Config.VALUE_PASSWORD)
def open_danm(self): # 开启弹幕 try: bottom_control = get_id(self, 'tv.yunxi.app:id/rl_bottom_control') danm = get_id(self, 'tv.yunxi.app:id/img_danmaku_control') result02 = lambda action: action.is_element_displayed(danm) if result02: print(result02) bottom_control.click() L.i('点击屏幕') if result02: danm.click() print('点击opdanm按钮01') else: danm.click() print('点击opdanm按钮02') od = 1 except: L.w("open_danm failed") od = 2 print(od) return od
class ERROR(object): HEADER = 'ERROR' API_KEY_NO_PREMIUM = L('MSG_ERROR_API_KEY_NO_PREMIUM') IP_NO_PREMIUM = L('MSG_ERROR_IP_NO_PREMIUM') # NB: Further usage with F() and IP as arg # MISSING_API_KEY = L('MSG_ERROR_MISSING_API_KEY') # MISSING_CREDENTIALS = L('MSG_ERROR_MISSING_CREDENTIALS') NOT_IMPLEMENTED = L('MSG_ERROR_NOT_IMPLEMENTED') ONLY_NUMBERS_ALLOWED = L('MSG_ERROR_ONLY_NUMBERS_ALLOWED')
def test_login(self, action: ElementActions): L.d('test_login') account = Steps.get_account() action.click(HomePage.登录入口) action.text(LoginPage.账户, account[0]) action.text(LoginPage.密码, account[1]) action.sleep(1) action.click(LoginPage.登录) assert action.is_toast_show('欢迎回来')
class INFO(object): HEADER = 'INFO' # API_KEY_UPDATED = L('MSG_INFO_API_KEY_UPDATED') API_KEY_VALID = L('MSG_INFO_API_KEY_VALID') # DISPLAY_API_KEYS = 'Prefs: {} || Web: {}' HISTORY_CLEARED = L('MSG_INFO_HISTORY_CLEARED') HISTORY_EMPTY = L('MSG_INFO_HISTORY_EMPTY') CACHE_CLEARED = L('MSG_INFO_CACHE_CLEARED') IP_ALLOWED = L('MSG_INFO_IP_ALLOWED') # NB: Further usage with F() and IP as arg
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') as f: page = yaml.safe_load(f) pages.update(page) return pages
def get_text(self, locator): """获取元素中的text文本 :param locator: 定位器 """ L.i("[获取]元素 %s " % locator.get('name')) if locator.get('index'): el = self._find_elements(locator)[locator['index']] else: el = self._find_element(locator) return el.text
def swip_right(self, height=0.5, count=1, speed=1000): """向右滑动 :param height: 高度满屏幕为1 :param count: 滑动次数 :param speed: 滑动速度 ms :return: """ for x in range(count): self.sleep(1) self.driver.swipe(self.width / 8, self.height * height, self.width * 7 / 8, self.height * height, speed) self.sleep(2) L.i("[滑动]向右滑动 ")
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 test_rrtv_login(self, action: ElementActions): L.d('rrtv login') account = Steps.get_account() action.click(MyPage.我的) action.click(MyPage.头像) action.click(LoginPage.账号密码登录) action.text(LoginPage.账户, account[0]) action.back_press() action.text(LoginPage.密码, account[1]) action.back_press() action.click(LoginPage.登录) assert action.is_text_displayed("test")
def _find_elements(self, locator): """ 查找多元素 :param locator: 定位器 :return: [] """ with allure.step("检查:'{0}'".format(locator.get('name'))): try: return WebDriverWait(self.driver, locator['time']).until( lambda driver: self._get_element_by_type(driver, locator, False)) except: L.w("[elements] 页面中未能找到 %s 元素" % locator) return []
def receive(self, params, epoch): """ updates parameters from the server. does some validation, writes config file to disk. Returns True on success, False failure """ if epoch != self._epoch: return def same_type(a, b): ta = type(a) tb = type(b) if ta == int: ta = float if tb == int: tb = float return ta == tb if self.keys() != params.keys(): diff = self.keys() ^ params.keys() E("Mismatching params, %s" % str(diff)) return False for k, v in params.items(): if not same_type(v, self[k]): E("Bad type for %s" % k) return False dir = os.path.dirname(config.PARAMS_FILE) try: t = tempfile.NamedTemporaryFile( prefix='config', mode='w+t', # NamedTemporaryFile is binary by default dir=dir, delete=False) out = json.dumps(params, sort_keys=True, indent=4) + '\n' t.write(out) name = t.name t.close() os.rename(name, config.PARAMS_FILE) except Exception as e: EX("Problem: %s" % e) return False self.update(params) L("Received parameters") L(self.save_string()) return True
def test_login(self, action: ElementActions): L.d('test_login') allure.attach('描述', '这是一个登陆的case') account = Steps.get_account() action.sleep(3) # action.test_SwipeGuideImages() action.click(HomePage.登录入口) action.text(LoginPage.账户, account[0]) action.text(LoginPage.密码, account[1]) action.sleep(1) action.click(LoginPage.登录) action.sleep(3) assert action._find_text_in_page("我的")
def test_login_empty_password(self, action: ElementActions): account = Steps.get_account() time.sleep(20) action.swip_left(3) time.sleep(5) L.d('test_login_empty_password') L.i('账户{0},密码为空'.format(account[0])) action.click(HomePage.登录) login(account[0], "", action) action.sleep(5) try: assert action.is_text_displayed('密码能为空1') except Exception as e: action.save_failure_pic(sys._getframe().f_code.co_name)
def open_fullScreen(self): # 开启全屏 sleep(5) fusc = get_id(self, 'tv.yunxi.app:id/img_full_Screen') # fusc = get_id(self,'tv.yunxi.app:id/img_full_Screen') giftLl = get_id(self, 'tv.yunxi.app:id/giftLl') # result01 = self.assertIsNotNone(fusc) result01 = lambda action: action.is_element_displayed(fusc) try: if result01: fusc.click() L.i('点击op全屏按钮02') print(result01) a = 1 else: giftLl.click() L.i('点击屏幕') if result01: fusc.click() L.i('点击op全屏按钮01') a = 1 except: a = 2 L.w("横屏播放failed") print(a) return a
def set_text(self, locator, clear_first=False, click_first=True): """ 输入文本 :param locator: 定位器 :param clear_first: 是否先清空原来文本 :param click_first: 是否先点击选中 """ value = locator.get('text') if click_first: self._find_element(locator).click() if clear_first: self._find_element(locator).clear() L.i("[输入]元素 %s " % value) with allure.step("输入元素:{0}".format(value)): self._find_element(locator).send_keys(value)
def check_environment(self): L.i('检查环境...') # 检查appium版本 if '1.4' 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 save_environment(self): infos = [] env_path = self.config.env_yaml_path apk_path = self.config.apk_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) L.i('已连接的设备版本:' + ADB(deviceName).get_android_version()) env_info = EnvironmentInfo(self.appium_v, infos, apk_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 GetTranslatesFolder(show_name, season_id, check_updates): season = GetSeasonCacheOrCreate(show_name, season_id, as_string=False) oc = ObjectContainer(title2=season['title'], content=ContainerContent.Seasons) for trans_index, translate in enumerate(season['playlist'].keys()): fake_url = make_fake_url(show_name=show_name, season_id=season_id, translate=translate) title = translate if check_updates: if season_id in Dict[UPDATES_CACHE_KEY]: update_messages = Dict[UPDATES_CACHE_KEY][season_id][ 'update_messages'] # NB: know why? because F**K YOU! that's why... NameError: global name 'any' is not defined if True in [ translate in message for message in update_messages ]: title = '(*) ' + translate oc.add( SeasonObject(key=Callback(GetEpisodesFolder, show_name=show_name, season_id=season_id, translate=translate), rating_key=fake_url, index=trans_index + 1, title=L(title), source_title=TITLE, thumb=season['thumb'], summary=season['summary'])) return oc
def suite(self, node): node = L(node) node.code = [] for child in node: if DEBUG: print(child) node.code += pushExpr(child) return node
def reload_signal(self, no_file=False): try: if not no_file: self.params.load() L("Reloaded.") self._wakeup.set() self._wakeup.clear() except Error as e: W("Problem reloading: %s" % str(e))
def _find_element(self, locator, is_need_displayed=True): """ :单个元素,如果有多个返回第一个 :param locator: 定位器 :param is_need_displayed: 是否需要定位的元素必须展示 :return: :raises:NotFoundElementError """ with allure.step("检查:'{0}'".format(locator.get('name'))): try: if is_need_displayed: return WebDriverWait(self.driver, locator['time']).until( lambda driver: self._get_element_by_type(driver, locator), '查找元素'.format(locator.get('name'))) except Exception as e: print(e) L.e("页面中未能找到 %s 元素" % locator) raise Exception("页面中未能找到 [%s]" % locator.get('name'))
def run(self): if self.server.params.disabled: L("Fridge is disabled") while True: try: self.do() yield from self.server.sleep(config.FRIDGE_SLEEP) except Exception as e: EX("fridge failed")