def wait_until_element_disappear(self, locator_type, locator_value, timeout=10): try: message = "Unable to wait the element disappear by {0}: '{1}' in the page '{2}' during timeout '{3}'".format( locator_type, locator_value, self.driver.current_url, timeout) except WebDriverException: message = "Unable to wait the element disappear by {0}: '{1}' during timeout '{2}'".format( locator_type, locator_value, timeout) wait_time = 0 while wait_time < timeout: elements = self.find_elements(locator_type, locator_value) if len(elements) == 0: log.info("the element disappear by {0}: '{1}' after wait {2}s". format(locator_type, locator_value, wait_time)) break else: time.sleep(0.5) wait_time += 0.5 continue if wait_time >= timeout: log.info(message) return False else: return True
def upload_by_win32(self, files): """win32方式 —— 打开窗口,并上传文件。(支持多文件上传,files参数传入list)""" self._window_open() self._files(files) log.info('upload {0} by win32'.format(self.files)) upload = win32gui.FindWindow('#32770', self.window_name) # find Edit ComboBoxEx32 = win32gui.FindWindowEx(upload, 0, 'ComboBoxEx32', None) ComboBox = win32gui.FindWindowEx(ComboBoxEx32, 0, 'ComboBox', None) Edit = win32gui.FindWindowEx(ComboBox, 0, 'Edit', None) # find confirm button button = win32gui.FindWindowEx(upload, 0, 'Button', None) # 验证是否打开窗口 if upload and Edit and button: self.window_open_flag = 1 else: raise UploadWindowNotOpenError('未发现上传文件对话框!') win32gui.SendMessage(Edit, win32con.WM_SETTEXT, 0, self.files) win32gui.SendMessage(upload, win32con.WM_COMMAND, 1, button) self.window_open_flag = 0
def get_by_type(self, locator_type): """ 返回查找位置的类型 :param locator_type: str set by def which implement on SeleniumDriver class :return: tag type or False """ locator_type = locator_type.lower() if locator_type == 'id': return By.ID elif locator_type == 'name': return By.NAME elif locator_type == 'xpath': return By.XPATH elif locator_type == 'css': return By.CSS_SELECTOR elif locator_type == 'class': return By.CLASS_NAME elif locator_type == 'link': return By.LINK_TEXT elif locator_type == 'partial_link': return By.PARTIAL_LINK_TEXT elif locator_type == 'tag': return By.TAG_NAME elif locator_type == 'text' or locator_type == 'partial_text': return By.XPATH else: log.info("Locator type" + locator_type + " not correct/supported") return False
def get_webdriver_instance(self): """ 返回webdriver实例 """ if self.browser == 'chrome': if self.headless is True: chrome_option = ChromeOptions() chrome_option.add_argument('--headless') driver = webdriver.Chrome(executable_path=chrome_driver_path, chrome_options=chrome_option) else: driver = webdriver.Chrome(executable_path=chrome_driver_path) elif self.browser == 'firefox': if self.headless is True: firefox_options = FirefoxOptions() firefox_options.set_headless() driver = webdriver.Firefox(options=firefox_options, executable_path=firfox_driver_path) else: driver = webdriver.Firefox(executable_path=firfox_driver_path) elif self.browser == 'remote_firefox': driver = webdriver.Remote(command_executor='http://' + '1' + ':4444/wd/hub', desired_capabilities={ 'browserName': 'firefox', 'javascriptEnabled': True, }) elif self.browser == 'remote_chrome': driver = webdriver.Remote(command_executor='http://' + '2' + ':4444/wd/hub', desired_capabilities={ 'browserName': 'chrome', 'javascriptEnabled': True, }) elif self.browser == 'ie': ie_options = IEOptions() driver = webdriver.Ie(ie_options=ie_options, executable_path=ie_driver_path) elif self.browser == 'edge': driver = webdriver.Edge() elif self.browser == 'safari': driver = webdriver.Safari() else: driver = None if self.browser not in [ 'chrome', 'firefox', 'remote_firefox', 'remote_chrome', 'ie', 'edge', 'safari' ]: log.info('Driver "%s" is not defined' % self.browser) else: log.info('Driver is set as for browser "%s". Headless is %s' % (self.browser, self.headless)) driver.maximize_window() driver.implicitly_wait(5) driver.set_page_load_timeout(load_page_timeout) return driver
def get_element_text(self, locator_type, locator_value, time=5, poll=0.5): """返回元素的文本值""" element = self.wait_for_element(locator_type, locator_value, time, poll) if element is not None: log.info("得到元素的text值是:" + element.text) return element.text
def get_element_size(self, locator_type, locator_value, time=5, poll=0.5): """获取元素的大小(高和宽)""" element = self.wait_for_element(locator_type, locator_value, time, poll) if element is not None: log.info("元素的大小{0}: ".format(element.size)) return element.size
def element_get(self, locator, locator_type='id', parent_element=None): """ 通过dom的方式查找单个元素 :param locator: str from page class ex LoginPage :param locator_type: str from page class ex LoginPage :param parent_element: parent_element 父节点 :return: WebElement """ element = parent_element try: locator_type = locator_type.lower() by_type = self.get_by_type(locator_type) if locator_type == 'text': locator = '//*[text()="' + locator + '"]' elif locator_type == 'partial_text': locator = '//*[contains(text(),"' + locator + '"]' if element: element = parent_element.find_element(by_type, locator) log.info("child element is Found with locator: " + locator + " locator_type " + locator_type) else: element = self.driver.find_element(by_type, locator) log.info("Element Found with locator: " + locator + " locator_type " + locator_type) except: log.error("Element not found") return element
def get_search_data(priority): log.info("读取excel的数据") #ExcelReader会返回标题和值键值对的方式 test_data = ExcelReader(search_excel, 0) #如下方法是提取出case中需要的信息 data_list = [(i['keyword'].decode('utf-8'),i['description'].decode('utf-8')) for i in test_data.data if i["priority"].decode('utf-8') in priority] return data_list
def element_get_text(self, locator="", locator_type="", element=None, info=""): """ 返回元素文本 :param locator: str from page class ex LoginPage :param locator_type: str from page class ex LoginPage :param element: WebElement returned by method ex element_get :param info: :return: str """ try: if locator: element = self.element_get(locator, locator_type) text = element.text if len(text) == 0: text = element.get_attribute('InnerText') if len(text) != 0: log.info("Getting text on element :: " + info) log.info("The text is :: '" + text + "'") text = text.strip() except: log.error("Failed to get text on element " + info) print_stack() text = None return text
def element_send_keys(self, locator, data, locator_type='id', element=None): """ 将值传入对应的组件 :param locator: str from page class ex LoginPage :param data: value which send :param locator_type: str from page class ex LoginPage :param element: WebElement returned by method ex element_get :return: """ try: if element is not None: element.clear() element.send_keys(data) else: element = self.element_get(locator, locator_type) element.clear() element.send_keys(data) log.info("Send data on element with locator: " + locator + " locator_type: " + locator_type) except: log.info("Cannot send data on the element with locator: " + locator + " locator_type: " + locator_type)
def switch_to_webview(self): """切换到webview""" try: n = 1 while n < 10: time.sleep(2) n = n + 1 log.info(self.driver.contexts) for cons in self.driver.contexts: if cons.lower().startswith("webview"): self.driver.switch_to.context(cons) # print(self.driver.page_source) self.driver.execute_script( 'document.querySelectorAll("html")[0].style.display="block"' ) self.driver.execute_script( 'document.querySelectorAll("head")[0].style.display="block"' ) self.driver.execute_script( 'document.querySelectorAll("title")[0].style.display="block"' ) log.info("切换webview成功") return {"result": True} return {"result": False} except appium.common.exceptions.NoSuchContextException: log.error("切换webview失败") return { "result": False, "text": "appium.common.exceptions.NoSuchContextException异常" }
def adb_image(path): shell_cmd("rm /sdcard/screenshot.png") shell_cmd("/system/bin/screencap -p /sdcard/screenshot.png") log.info(">>>截取屏幕成功,在桌面查看文件。") c_time = time.strftime("%Y_%m_%d_%H-%M-%S") image_path = os.path.join(path, c_time + ".png") adb_cmd('pull /sdcard/screenshot.png %s"' % image_path)
def drivers(): PATH = lambda p: os.path.abspath(p) driver_list = [] yaml_desires = yaml_action.load(desired_caps_param) yaml_desires_length = len(yaml_desires) if yaml_desires_length <1: log.error("yaml文件中没有设备信息") return None else: for desired_caps_return in yaml_desires: app_path = PATH(desired_caps_return["app"]) for value in desired_caps_return.values(): if value == "": log.info("发现desired_caps中有的元素值为空, 初始化env类,动态获取相应的值") apk_info = Apk_Info(app_path) device_info = Device_Info() desired_caps = dict() desired_caps['automationName'] = desired_caps_return["automationName"] desired_caps['platformName'] = desired_caps_return["platformName"] if desired_caps_return["platformVersion"] != None and desired_caps_return["platformVersion"] != "": desired_caps['platformVersion'] = desired_caps_return["platformVersion"] else: desired_caps['platformVersion'] = device_info.os_version() if desired_caps_return["deviceName"] != None and desired_caps_return["deviceName"] != "": desired_caps['deviceName'] = desired_caps_return["deviceName"] else: desired_caps['deviceName'] = device_info.device_sn() desired_caps['newCommandTimeout'] = desired_caps_return["newCommandTimeout"] desired_caps['app'] = app_path if desired_caps_return["appPackage"] != None and desired_caps_return["appPackage"] != "": desired_caps['appPackage'] = desired_caps_return["appPackage"] else: desired_caps['appPackage'] = apk_info.package_name() if desired_caps_return["appActivity"] != None and desired_caps_return["appActivity"] != "": desired_caps['appActivity'] = desired_caps_return["appActivity"] else: desired_caps['appActivity'] = apk_info.startup_activity() desired_caps['resetKeyboard'] = desired_caps_return["resetKeyboard"] desired_caps['unicodeKeyboard'] = desired_caps_return["unicodeKeyboard"] desired_caps['noReset'] = desired_caps_return["noReset"] desired_caps['recreateChromeDriverSessions'] = desired_caps_return["recreateChromeDriverSessions"] host_name = desired_caps_return["ip"] host_port = desired_caps_return["port"] # eval("device_desire_{0}".format(yaml_desires.index(device_desire)))["recreateChromeDriverSessions"] server_address = "http://" + str(host_name) + ":" + str(host_port) + "/wd/hub" log.debug("server address is: " + server_address + "current server match desire_Caps are below: " ) log.debug(desired_caps) driver = webdriver.Remote(server_address, desired_caps) driver.implicitly_wait(5) driver_list.append(driver) return driver_list
def swipe_to_right(self): width = self.get_screen_size()["width"] height = self.get_screen_size()["height"] x1 = int(width * 0.05) y1 = int(height * 0.5) x2 = int(width * 0.75) self.swipe(x1, y1, x1, x2, 1000) log.info("--swipe to right--")
def swipe_to_up(self): width = self.get_screen_size()["width"] height = self.get_screen_size()["height"] x1 = int(width * 0.5) y1 = int(height * 0.75) y2 = int(height * 0.25) self.swipe(x1, y1, x1, y2, 1000) log.info("--swipe to up--")
def swipe_left(self): """左滑动""" width = self.get_screen_size()["width"] height = self.get_screen_size()["height"] x1 = int(width * 0.75) y1 = int(height * 0.5) x2 = int(width * 0.05) self.swipe(x1, y1, x2, y1, 600) log.info("--swipe to left--")
def upload(self, files, autoit=False): """综合判断,如果为<input>标签,则直接上传。否则默认用win32方式,如果传入autoit=True,则用autoit上传。""" if self.Element.tag_name == 'input' and type(files) != list: log.info('it is a <input> tag.') self.upload_by_input(files) elif not autoit: self.upload_by_win32(files) else: self.upload_by_autoit(files)
def swipe_to_down(self): """swipe start_x: 200, start_y: 200, end_x: 200, end_y: 400, duration: 2000 从200滑动到400""" width = self.get_screen_size()["width"] height = self.get_screen_size()["height"] x1 = int(width * 0.5) y1 = int(height * 0.25) y2 = int(height * 0.75) self.swipe(x1, y1, x1, y2, 1000) log.info("--swipe to down--")
def wrapper(*args, **kwargs): try: result = func(*args, **kwargs) # 1/0 except Exception as msg: # browser_instance().capture_screen(img_path) print(img_path) raise msg else: log.info(" %s 脚本运行正常" % (func.__name__))
def inputbox_send_key(self, locator_type, locator_value, parameter, time=5, poll=0.5): element = self.wait_for_element(locator_type, locator_value, time, poll) if element is not None: log.info("元素{0}输入参数{1}".format(locator_value, parameter)) element.send_keys(parameter)
def element_is_enabled(self, locator_type, locator_value, time=5, poll=0.5): """返回元素是否可用True of False""" element = self.wait_for_element(locator_type, locator_value, time, poll) if element is not None: log.info("元素{0}enabled ?".format(element.is_enabled())) return element.is_enabled()
def get_element_tag_name(self, locator_type, locator_value, time=5, poll=0.5): """返回元素的tagName属性, 经实践返回的是class name""" element = self.wait_for_element(locator_type, locator_value, time, poll) if element is not None: log.info("得到元素的tag_name值是:" + element.text()) return element.tag_name()
def get_element_location(self, locator_type, locator_value, time=5, poll=0.5): """获取元素左上角的坐标""" element = self.wait_for_element(locator_type, locator_value, time, poll) if element is not None: log.info("元素{0}is displayed ?".format(element.is_enabled())) return element.location()
def element_is_selected(self, locator_type, locator_value, time=5, poll=0.5): """返回元素是否选择。可以用来检查一个复选框或单选按钮被选中。用法 element.is_slected()""" element = self.wait_for_element(locator_type, locator_value, time, poll) if element is not None: log.info("元素{0}selected ?".format(element.is_selected())) return element.is_selected()
def check_port(host, port): mysocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) try: mysocket.connect((host,port)) mysocket.shutdown(2) except OSError as e: log.info("port %s is available!"%port) log.debug("尝试测试端口是否可以用,except返回信息:"+str(e)) return True else: log.info("port %s already be in use!"%port) return False
def get_url(self): """ 返回当前web页面的url :return: str """ current_url = None try: current_url = self.driver.current_url log.info('Current URL is :: ' + current_url) except: log.error('Failed to get current URL ' + current_url) print_stack() return current_url
def element_is_displayed(self, locator_type, locator_value, time=5, poll=0.5): """此元素用户是否可见,简单地说就是隐藏元素和被控件挡住无法操作的元素 (仅限 Selenium,appium是否实现了类似功能不是太确定) 这一项都会返回 False用法 driver.element.is_displayed()""" element = self.wait_for_element(locator_type, locator_value, time, poll) if element is not None: log.info("元素{0}is displayed ?".format(element.is_enabled())) return element.is_displayed()
def get_title(self): """ 得到当前页面的标题 :return: WebElement """ title = None try: title = self.driver.title log.info('Current title is :: ' + title) except: log.error('Failed to get title ' + title) print_stack() return title
def login(self, username, password): try: self.browser.open(self._main_url, "") self.click_element(self._login_link) self.click_element(self._login_enter) self.input_key(self._username, username) self.input_key(self._password, password) self.click_element(self._login_submit) if self.browser.element_is_present(username, "link"): log.info("登录成功") else: log.error("登陆失败") except Exception as e: log.error("没有进入登录界面,异常信息是:" + str(e))
def find_ele_fromparent(self, locator_tmp, locator_target, is_Multiple=False, wait=5): """ 通过uiautomator查找定位元素的兄弟节点元素,不支持xpath,且兄弟节点必须同级 支持的定位方式有:text(name),description(特有的),id,class name """ log.info("页面【{}】通过元素【{}】查找兄弟元素【{}】".format(locator_tmp.get("page"), locator_tmp.get('name'), locator_target.get("name"))) map = { "name": "textContains", "description": "descriptionContains", "id": "resourceId", "class name": "className" } type_tmp = map.get(locator_tmp["type"]) type_target = map.get(locator_target["type"]) if type_tmp == None or type_target == None: log.error('当前定位方式不支持') value_tmp = locator_tmp["value"] value_target = locator_target["value"] ui_value = 'new UiSelector().{}(\"{}\").fromParent(new UiSelector().{}(\"{}\"))'.format( type_tmp, value_tmp, type_target, value_target) try: WebDriverWait( self.driver, wait).until(lambda driver: driver. find_element_by_android_uiautomator(ui_value)) if is_Multiple == False: return self.driver.find_element_by_android_uiautomator( ui_value) else: return self.driver.find_elements_by_android_uiautomator( ui_value) except: log.info('页面【{}】未找到 元素【{}】\n locator: {}'.format( locator_tmp.get("page"), locator_target.get('name'), str(locator_target))) if is_Multiple == False: return None else: return []