def clear(self, locator): """ 清除元素中的内容 :param locator: 定位方法+定位表达式组合字符串,用逗号分隔,如'css,.username' """ self.get_element(locator).clear() log.info(u'清空内容:%s' % locator)
def click_link(self, text): """ 按部分链接文字查找并点击链接 :param text: 链接的部分文字 """ self.get_element('plink,' + text).click() log.info(u'点击连接:%s' % text)
def close(self): """ 关闭当前页 """ self.driver.close() self.driver.switch_to.window(self.driver.window_handles[0]) log.info(u'关闭当前Tab')
def alert_text(self): """ 返回alert文本 :return: alert文本 """ log.info(u'获取弹框文本:%s' % self.driver.switch_to.alert.text) return self.driver.switch_to.alert.text
def js(self, script): """ 执行JavaScript :param script:js语句 """ self.driver.execute_script(script) log.info(u'执行JS语句:%s' % script)
def enter(self, locator): """ 在元素上按回车键 :param locator: 定位方法+定位表达式组合字符串,用逗号分隔,如'css,.username' """ self.get_element(locator).send_keys(Keys.ENTER) log.info(u'在元素 %s 上按回车' % locator)
def open(self, url): """ 打开网址 :param url: 网址连接 """ self.driver.get(url) log.info(u'打开网址:%s' % url)
def click(self, locator): """ 在元素上单击 :param locator: 定位方法+定位表达式组合字符串,用逗号分隔,如'css,.username' """ self.get_element(locator).click() log.info(u'点击元素:%s' % locator)
def move_to_element(self, locator): """ 鼠标指向元素 :param locator: 定位方法+定位表达式组合字符串,用逗号分隔,如'css,.username' """ element = self.get_element(locator) ActionChains(self.driver).move_to_element(element).perform() log.info(u'指向元素%s' % locator)
def type(self, locator, text): """ 在元素中输入内容 :param locator: 定位方法+定位表达式组合字符串,用逗号分隔,如'css,.username' :param text: 输入的内容 """ self.get_element(locator).send_keys(text) log.info(u'向元素 %s 输入文字:%s' % (locator, text))
def right_click(self, locator): """ 鼠标右击元素 :param locator: 定位方法+定位表达式组合字符串,用逗号分隔,如'css,.username' """ element = self.get_element(locator) ActionChains(self.driver).context_click(element).perform() log.info(u'在元素上右击:%s' % locator)
def double_click(self, locator): """ 双击元素 :param locator: 定位方法+定位表达式组合字符串,用逗号分隔,如'css,.username' """ element = self.get_element(locator) ActionChains(self.driver).double_click(element).perform() log.info(u'在元素上双击:%s' % locator)
def switch_ifarme(self, selector): """切换ifarme""" element = self.get_element(selector) # noinspection PyBroadException try: self.driver.switch_to.frame(element) log.info('Successful to switch_to_frame! ') except BaseException: log.error('Failed to switch_to_frame', exc_info=1)
def scroll_element(self, locator): """ 拖动滚动条至目标元素 :param locator: 定位方法+定位表达式组合字符串,如'css,.username' """ script = "return arguments[0].scrollIntoView();" element = self.get_element(locator) self.driver.execute_script(script, element) log.info(u'滚动至元素:%s' % locator)
def get_ele_text(self, locator): """ 返回元素的文本 :param locator: 定位方法+定位表达式组合字符串,用逗号分隔,如'css,.username' :return: 元素的文本 """ log.info(u'获取元素 %s 的文本为:%s' % (locator, self.get_element(locator).text)) return self.get_element(locator).text
def get_attribute(self, locator, attribute): """ 返回元素某属性的值 :param locator: 定位方法+定位表达式组合字符串,用逗号分隔,如'css,.username' :param attribute: 属性名称 :return: 属性值 """ value = self.get_element(locator).get_attribute(attribute) log.info(u'获取元素 %s 的属性值 %s 为:%s' % (locator, attribute, value)) return value
def drag_and_drop(self, locator, target_locator): """ 拖动一个元素到另一个元素位置 :param locator: 要拖动元素的定位 :param target_locator: 目标位置元素的定位 """ element = self.get_element(locator) target_element = self.get_element(target_locator) ActionChains(self.driver).drag_and_drop(element, target_element).perform() log.info(u'把元素 %s 拖至元素 %s' % (locator, target_locator))
def is_text_on_page(self, text): """ 返回页面源代码 :return: 页面源代码 """ if text in self.driver.page_source: log.info(u'判断页面上有文本:%s' % text) return True else: log.info(u'判断页面上没有文本:%s' % text) return False
def drag_and_drop_by_offset(self, locator, xoffset, yoffset): """ 拖动一个元素向右下移动x,y个偏移量 :param locator: 定位方法+定位表达式组合字符串,用逗号分隔,如'css,.username' :param xoffset: X offset to move to :param yoffset: Y offset to move to """ element = self.get_element(locator) ActionChains(self.driver).drag_and_drop_by_offset( element, xoffset, yoffset).perform() log.info(u'把元素 %s 拖至坐标:%s %s' % (locator, xoffset, yoffset))
def screenshot(self, info='-'): """ 截图,起名为:文件名-方法名-注释 :param info: 截图说明 """ catalog_name = cf.get_value('screenshot_path') # 从全局变量取截图文件夹位置 if not os.path.exists(catalog_name): os.makedirs(catalog_name) class_object = inspect.getmembers( inspect.stack()[1][0])[-3][1]['self'] # 获得测试类的object classname = str(class_object).split('.')[1].split(' ')[0] # 获得测试类名称 testcase_name = inspect.stack()[1][3] # 获得测试方法名称 filepath = catalog_name + classname + "@" + testcase_name + info + ".png" self.driver.get_screenshot_as_file(filepath) log.info(u'截图:%s.png' % info)
def get_elements(self, locator): """ 获取一组元素 :param locator: 定位方法+定位表达式组合字符串,用逗号分隔,如'css,.username' :return: elements """ by, value = self.split_locator(locator) try: elements = WebDriverWait( self.driver, 60, 1).until(lambda x: x.find_elements(by=by, value=value)) log.info(u'获取元素列表:%s' % locator) return elements except Exception as e: raise e
def wait_element(self, locator, sec=30): """ 等待元素出现 :param locator: 定位方法+定位表达式组合字符串,用逗号分隔,如'css,.username' :param sec:等待秒数 """ by, value = self.split_locator(locator) try: WebDriverWait(self.driver, sec, 1).until( lambda x: x.find_element(by=by, value=value), message='element not found!!!') log.info(u'等待元素:%s' % locator) return True except TimeoutException: return False except Exception as e: raise e
def report_zip(self): ''' :param dir_path: 目标文件夹路径 :param zip_path: 压缩后的文件夹路径 :return: ''' log.info("执行打包程序") zip = zipfile.ZipFile(self.zip_path, "w", zipfile.ZIP_DEFLATED) for (root, dirnames, filenames) in os.walk(self.dir_path): file_path = root.replace(self.dir_path, '') # 去掉根路径,只对目标文件夹下的文件及文件夹进行压缩 # 循环出一个个文件名 for filename in filenames: zip.write(os.path.join(root, filename), os.path.join(file_path, filename)) log.info("压缩成功") zip.close() return zip
def get_element(self, locator, sec=60): """ 获取一个元素 :param locator: 定位方法+定位表达式组合字符串,用逗号分隔,如'css,.username' :param sec:等待秒数 :return: 元素可找到返回element对象,否则返回False """ if self.wait_element(locator, sec): by, value = self.split_locator(locator) print(by, value) try: element = self.driver.find_element(by=by, value=value) log.info(u'获取元素:%s' % locator) return element except Exception as e: raise e else: return False
def test_case01(self, quit_driver, data): ''' 搜索测试 ''' sp = SearchPage() # sp.test_search(keyword=sp.get_excel_datas()[0]['操作输入值']) # assert sp.op_title() == sp.get_excel_datas()[0]['断言'] log.info(ed.get_excel_datas()) log.info(el.get_ids()) log.info(data['操作输入值']) sp.test_search(keyword=data['操作输入值']) assert sp.op_title() == data['断言'] log.info(sp.op_title())
def quit_driver(): # log.info("conftest文件初始化") # cf.init() binary_location = '/usr/bin/google-chrome' chrome_driver_binary = '/usr/local/bin/chromedriver' # chrome_options = webdriver.ChromeOptions() chrome_options = Options() chrome_options.binary_location = binary_location chrome_options.add_argument('--no-sandbox') # 解决DevToolsActivePort文件不存在的报错 chrome_options.add_argument( '--headless') # 浏览器不提供可视化页面. linux下如果系统不支持可视化不加这条会启动失败 chrome_options.add_argument('--disable-gpu') # 谷歌文档提到需要加上这个属性来规避bug chrome_options.add_argument('--disable-dev-shm-usage') chrome_options.add_argument( 'blink-settings=imagesEnabled=false') # 不加载图片, 提升速度 chrome_options.add_argument('--start-maximized') # 窗口最大化 # 新版google不显示正在受自动化软件控制 chrome_options.add_experimental_option('excludeSwitches', ['enable-automation']) # driver = webdriver.Chrome(options=chrome_options) os.environ["webdriver.chrome.driver"] = chrome_driver_binary driver = webdriver.Chrome(executable_path='/usr/local/bin/chromedriver', chrome_options=chrome_options) driver.get(cf.get_value('site')) log.info('打开的网址是:' + cf.get_value('site')) log.info("初始化driver") cf.set_value('driver', driver) yield driver.quit() log.info('关闭浏览器')
def switch_menue(self, parentelement, secelement, targetelement): """三级菜单切换""" self.sleep(3) # noinspection PyBroadException try: self.driver.switch_to_default_content() self.click(parentelement) log.info('成功点击一级菜单:%s' % parentelement) self.click(secelement) log.info('成功点击二级菜单:%s' % secelement) self.click(targetelement) log.info('成功点击三级菜单:%s' % targetelement) except BaseException: log.error('切换菜单报错', exc_info=1)
def get_args(self): log.info("Argprase命令行类初始化") cf.init() """命令行参数解析""" parser = argparse.ArgumentParser(description=u'可选择参数:') parser.add_argument('-e', '--environment', choices=['test', 'prod'], default='test', help=u'测试环境test,线上环境prod') parser.add_argument('-m', '--mark', choices=['mock', 'jenkins'], default='mock', help=u'测试环境百度mock,线上环境jenkins登录') args = parser.parse_args() args_env = args.environment log.info('args数据:' + str(args_env)) log.info('args传递的参数:' + str(args)) if args.environment in ('test', 'test'): cf.set_value('environment', 'test') cf.set_value('site', 'http://www.baidu.com/') elif args.environment in ('prod', 'prod'): cf.set_value('environment', 'prod') cf.set_value('site', 'a') else: exit() print("请输入test/prod") if args.mark in ('jen', 'jenkins'): cf.set_value('mark', 'jenkins') elif args.mark in ('mo', 'mock'): cf.set_value('mark', 'mock') else: exit() print("请输入jenkins/mock") log.info('获取到的site地址:' + cf.get_value('site'))
@pytest.mark.jenkins def test_case02(self, quit_driver): ''' jenkins ''' jp = JenkinsPage() jp.login_success('a', 'a') if __name__ == '__main__': arg = argparse.Argprase() arg.get_args() # log.info('配置初始化') # cf.init() log.info('主程序中获取到的site地址:' + cf.get_value('site')) log.info('开始运行代码') report_time = time.strftime("%Y-%m-%d-%H_%M_%S", time.localtime(time.time())) report_name = 'search' + report_time + '.html' # pytest.main(['-q', '-s', 'TestSearch.py', '-m mock']) # mock标记测试 # 生成html报告 # pytest.main(['-q', '-s', 'TestSearch.py', '--reruns', '1', '--html=./report/' + report_name , '--self-contained-html']) # 生成allure报告 mark = cf.get_value('mark') log.info('获取到的mark数据:' + mark) # 本地运行 # pytest.main(['-q', '-s', 'TestSearch.py', '-m' + mark, '--alluredir', # './report']) # 服务器运行 allure_path = cf.get_value('allure')
def sleep(self, sec): time.sleep(sec) log.info(u'等待%s秒' % sec)