def delete_or_rename_holidays_or_workday(self, timezone_name, is_delete="删除"): """ 删除时间条件 """ # 定位到当前假期或特殊工作日 SELECT_TIMEZONE = (By.XPATH, f'//span[text()="{timezone_name}"]/ancestor::tr') BasePage(self.driver).mouse_move_ele(SELECT_TIMEZONE) if is_delete == "重命名": # TODO # 定位到 "重命名" 元素 ELE_LOC = ( By.XPATH, '//div[@class="timezone-left-popper"]//span[contains(text(), "重命名")]' ) elif is_delete == "删除": # 定位到 "删除" 元素 ELE_LOC = ( By.XPATH, '//div[@class="timezone-left-popper"]//span[contains(text(), "删除")]' ) BasePage(self.driver).mouse_move_ele_and_click( SELECT_TIMEZONE, ELE_LOC) # 执行删除操作 GlobalDelete(self.driver).dialog_delete()
def create_holidays(self, tile_name, holidays, num=0): """ 添加假期 :param tile_name: 动态传入定位表达式的标题名称 :param holidays: 假期名称 :param num: 设置动态数值,保证时间选择不同 """ # 定位 - 未定义假期 - 按钮 SET_HOLIDAY = (By.XPATH, '//span[contains(text(), "未定义假期")]') if not self.driver.find_element(*SET_HOLIDAY).is_displayed(): # 元素滚动到页面可见区域 BasePage(self.driver).scroll_visibility_region(loc=SET_HOLIDAY) # 点击 - 未定义假期 - 按钮 BasePage(self.driver).click_ele(SET_HOLIDAY) # 调用封装方法 - 添加假期 self.dialog_info_com(tile_name, holidays) # 点击 - 设定日期 - 按钮 SET_TIME = ( By.XPATH, '//header[contains(text(), "假期定义")]/following-sibling::div//span[contains(text(), "设定日期")]' ) BasePage(self.driver).click_ele(SET_TIME) # 调用封装方法 - 选择假期的时间区间 self.check_time(num)
def dialog_info_com(self, til_name, val, confirm=True): """ 封装dialog弹框 :param til_name: 弹框标题 :param val: 传入input输入框值 :param confirm: dialog按钮选项。默认确定 """ INPUT_TEXT = ( By.XPATH, f'//div[@class="timezone-rename-dialog-header"]//span[contains(text(), "{til_name}")]/ancestor::div[@class="el-dialog__header"]/following-sibling::div[@class="el-dialog__body"]//input' ) BasePage(self.driver).update_input_text(INPUT_TEXT, val, img_describe="时间条件") if confirm: CONFIRM_BUTTON = ( By.XPATH, f'//div[@class="timezone-rename-dialog-header"]//span[contains(text(), "{til_name}")]/ancestor::div[@class="el-dialog__header"]/following-sibling::div[@class="el-dialog__footer"]//span[contains(text(), "确定")]' ) BasePage(self.driver).click_ele(CONFIRM_BUTTON) else: CANCEL_BUTTON = ( By.XPATH, f'//div[@class="timezone-rename-dialog-header"]//span[contains(text(), "{til_name}")]/ancestor::div[@class="el-dialog__header"]/following-sibling::div[@class="el-dialog__footer"]//span[contains(text(), "取消")]' ) BasePage(self.driver).click_ele(CANCEL_BUTTON)
def create_workday(self, tile_name, val, num=0): """ 添加特殊工作日 :param tile_name: 动态传入定位表达式的标题名称 :param val: 特殊工作日名称 :param num: 设置动态数值,保证时间选择不同 """ # 定位 - 未定义工作日 - 按钮 SET_WORKDAY = (By.XPATH, '//span[contains(text(), "未定义工作日")]') if not self.driver.find_element(*SET_WORKDAY).is_displayed(): # TODO 判断元素在页面是否可见 ele.is_displayed(),默认可见 # 元素滚动到页面可见区域 BasePage(self.driver).scroll_visibility_region(loc=SET_WORKDAY) # 点击 - 未定义工作日 - 按钮 BasePage(self.driver).click_ele(SET_WORKDAY) # 调用封装方法 - 添加特殊工作日 self.dialog_info_com(tile_name, val) # 点击 - 设定日期 - 按钮 SET_TIME = ( By.XPATH, '//header[contains(text(), "特殊工作日定义")]/following-sibling::div//span[contains(text(), "设定日期")]' ) BasePage(self.driver).click_ele(SET_TIME) # 调用封装方法 - 选择特殊工作日的时间区间 self.check_time(num)
def delete_or_rename_timezone_name(self, timezone_name, is_delete="删除"): """ 删除时间条件 """ # 定位到当前时间条件名称 SELECT_TIMEZONE = ( By.XPATH, f'//div[@role="tablist"]//button/span[contains(text(), "{timezone_name}")]' ) BasePage(self.driver).mouse_move_ele(SELECT_TIMEZONE) if is_delete == "重命名": # TODO # 定位到 "重命名" 元素 ELE_LOC = ( By.XPATH, '//div[@role="tooltip" and contains(@style, "position")]//span[contains(text(), "重命名")]' ) BasePage(self.driver).mouse_move_ele_and_click( SELECT_TIMEZONE, ELE_LOC) # 执行重命名操作 self.dialog_info_com("重命名时间条件", "UPDATE" + timezone_name) elif is_delete == "删除": # 定位到 "删除" 元素 ELE_LOC = ( By.XPATH, '//div[@role="tooltip" and contains(@style, "position")]//span[contains(text(), "删除")]' ) BasePage(self.driver).mouse_move_ele_and_click( SELECT_TIMEZONE, ELE_LOC) # 执行删除操作 GlobalDelete(self.driver).dialog_delete()
def create_department_group(self, group_name, til_name, confirm=True): """ 方法封装:用于创建 同级/下一级 分组 :param dep_name: 部分分组名称 :param til_name: dialog弹框中的标题 - 作为识别打开的当前弹框页面 :param confirm: 判断是点击确定还是点击取消按钮 True默认创建点击确定按钮 :return: """ # 定位input框 # //span[contains(text(), "创建同级")]/parent::div/following-sibling::div[@class="el-dialog__body"]//input INPUT_TEXT = ( By.XPATH, f'//span[contains(text(),"{til_name}")]/parent::div/following-sibling::div[@class="el-dialog__body"]//input' ) BasePage(self.driver).update_input_text(INPUT_TEXT, group_name) if confirm: # 点击确认 CONFIRM_BTN = ( By.XPATH, f'//span[contains(text(),"{til_name}")]/parent::div/following-sibling::div[@class="el-dialog__footer"]//span[contains(text(),"确定")]' ) BasePage(self.driver).click_ele(CONFIRM_BTN) else: # 点击取消 CONFIRM_BTN = ( By.XPATH, f'//span[contains(text(),"{til_name}")]/parent::div/following-sibling::div[@class="el-dialog__footer"]//span[contains(text(),"取消")]' ) BasePage(self.driver).click_ele(CONFIRM_BTN)
def is_login_success(self): # 判断是否登录成功:用户名元素在页面中存在,说明页面成功跳转,登录成功 LOGIN_SUCCESS_USERNAME = (By.CSS_SELECTOR, 'span[class="avatar-name"]') BasePage( self.driver).wait_for_ele_to_be_presence(LOGIN_SUCCESS_USERNAME) if BasePage(self.driver).get_ele_locator(LOGIN_SUCCESS_USERNAME): return True else: return False
def search_dep_by_name(self, group_name): # 定位搜索文本框 SEARCH_INPUT = (By.XPATH, '//aside[@class="el-aside"]//div[contains(@class,"el-input--suffix")]/input') BasePage(self.driver).update_input_text(SEARCH_INPUT, group_name, "左侧组件-tree") # 点击搜索 SEARCH_BTN = (By.XPATH, '//aside[@class="el-aside"]//div[contains(@class,"el-input--suffix")]/span') BasePage(self.driver).click_ele(SEARCH_BTN, "左侧组件-tree")
def click_menu_by_name(self, department_name, menu_name): """ 滑动到左侧树图右侧icon - 出现列表项 """ # 部门分组右侧icon GROUP_ICON = (By.XPATH, f'//div[@title="{department_name}"]/parent::div/following-sibling::div[contains(text(), "︙")]') BasePage(self.driver).mouse_move_ele(GROUP_ICON, "左侧组件-tree") # 通过传入不同的 menu_name 滑动到不同的操作 GROUP_MENU_NAME = (By.XPATH, f'//div[@id="menu"]//li[@class="menu" and contains(text(), "{menu_name}")]') BasePage(self.driver).mouse_move_ele_and_click(GROUP_ICON, GROUP_MENU_NAME, img_describe="左侧组件-tree")
def dialog_delete(self, is_delete=True): if is_delete: # 点击删除按钮 # //div[@class="el-dialog__header"] CONFIRM_BTN = (By.XPATH, '//button//span[contains(text(), "删除")]') BasePage(self.driver).click_ele(CONFIRM_BTN) else: # 点击取消按钮 CONFIRM_BTN = (By.XPATH, '//button//span[contains(text(), "取消")]') BasePage(self.driver).click_ele(CONFIRM_BTN)
def check_face_property(self, path): """ 人脸属性检测 """ # 图片上传按钮 IMAGE_UPLOAD_INPUT = (By.CSS_SELECTOR, 'input[type="file"]') # 点击检测 CHECK_CONTENT_FACE_BUTTON = (By.CSS_SELECTOR, '.app-tools-content-face-detectbtn') BasePage(self.driver).upload_file(IMAGE_UPLOAD_INPUT, path) BasePage(self.driver).click_ele(CHECK_CONTENT_FACE_BUTTON)
def check_one_img_quality(self, path): """ 质量分数检测 """ # 上传人脸图片 IMAGE_UPLOAD_INPUT = (By.CSS_SELECTOR, 'input[type="file"]') # 点击检测按钮 CHECK_CONTENT_DETECTION_BUTTON = ( By.CSS_SELECTOR, '.app-tools-content-detection-detectbtn') BasePage(self.driver).upload_file(IMAGE_UPLOAD_INPUT, path) BasePage(self.driver).click_ele(CHECK_CONTENT_DETECTION_BUTTON)
def delete_dep_group_com(self, delete=True): # 删除分组 if delete: # 点击删除按钮 CONFIRM_BTN = (By.XPATH, '//span[contains(text(),"删除")]/parent::div/following-sibling::div[@class="el-dialog__footer"]//span[contains(text(),"删除")]') BasePage(self.driver).click_ele(CONFIRM_BTN, "左侧组件-tree") else: # 点击取消按钮 CONFIRM_BTN = (By.XPATH, '//span[contains(text(),"删除")]/parent::div/following-sibling::div[@class="el-dialog__footer"]//span[contains(text(),"取消")]') BasePage(self.driver).click_ele(CONFIRM_BTN, "左侧组件-tree")
def assert_timezone_section(self): # 判断选定的时间条件下的时间段是否成功添加 CHECK_CON_RESULT = ( By.XPATH, '//div[@class="el-tab-pane" and @style=""]//div[contains(@class, "el-row")]//span[contains(text(), ":")]' ) return BasePage(self.driver).get_text(CHECK_CON_RESULT)
def login(self, username, password, code=None, login_way="default"): """ 登录 """ # 登录用户名文本框 USERNAME_INPUT = (By.CSS_SELECTOR, 'input[name="username"]') # 登录密码文本框 PASSWORD_INPUT = (By.CSS_SELECTOR, 'input[name="password"]') # 登录验证码文本框 CODE_INPUT = (By.CSS_SELECTOR, 'input[name="verifyCode"]') # 定位到登录按钮 LOGIN_BUTTON = (By.XPATH, '//button//span[contains(text(), "登录")]') # 输入用户名 - 等待元素可见并输入文本 BasePage(self.driver).update_input_text(USERNAME_INPUT, username) # 输入密码 BasePage(self.driver).update_input_text(PASSWORD_INPUT, password) """ 获取登录验证码的不同方式 """ if login_way == "default": # 1、通过redis的方式获取登录验证码 code = self.get_captcha_from_redis() elif login_way == "cjy": # 2、通过调用第三方接口<cjy>识别登录验证码 code = self.get_code_cjy() elif login_way == "ssh": # 定位到刷新验证码按钮,并在读取验证码之前先点击刷新 CAPTCHA_REFRESH_BUTTON = (By.CSS_SELECTOR, 'div.verify-code > div.refresh > i') BasePage(self.driver).click_ele(CAPTCHA_REFRESH_BUTTON) time.sleep(0.2) # 3、通过ssh连接到服务器,从日志里获取登录验证码 code = self.get_captcha_from_k8s_log() elif login_way == 'ocr': # 4、通过ocr智能识别获取登录验证码 # code = get_code_by_ocr() pass elif login_way == 'debug': # 调试的时候,通过手动从控制台输入的方式获取登录验证码 print("请手动输入登录页面的验证码:") code = input() # 输入得到的验证码 BasePage(self.driver).update_input_text(CODE_INPUT, code) # 点击登录网站 BasePage(self.driver).click_ele(LOGIN_BUTTON, "登录")
def get_facial_attribute_by_name(self, name): """ 获取返回的人脸属性内容 :param name: 人脸属性名称,可选性别、年龄、表情、胡子、眼睛、口罩、安全帽、帽子 """ CHECK_CONTENT = ( By.XPATH, f'//div[@class="app-tools-content-detection-right"]//li//span[contains(text(), "{name}")]/parent::li' ) return BasePage(self.driver).get_text(CHECK_CONTENT, "小工具")
def create_dep_group_com(self, group_name, loc_by_til_name, confirm=True): """ 创建 同级/下一级 分组 :param group_name: 部门组名称 :param loc_by_til_name: 通过dialog弹框的标题定位唯一元素 :param confirm: 判断是点击确定还是点击取消按钮 True默认创建点击确定按钮 """ # 组名称input框 GROUP_INPUT = (By.XPATH, f'//span[contains(text(),"{loc_by_til_name}")]/parent::div/following-sibling::div[@class="el-dialog__body"]//input') BasePage(self.driver).update_input_text(GROUP_INPUT, group_name, "左侧组件-tree") if confirm: # 点击确认按钮 CONFIRM_BTN = (By.XPATH, f'//span[contains(text(),"{loc_by_til_name}")]/parent::div/following-sibling::div[@class="el-dialog__footer"]//span[contains(text(),"确定")]') BasePage(self.driver).click_ele(CONFIRM_BTN, "左侧组件-tree") else: # 点击取消按钮 CONFIRM_BTN = (By.XPATH, f'//span[contains(text(),"{loc_by_til_name}")]/parent::div/following-sibling::div[@class="el-dialog__footer"]//span[contains(text(),"取消")]') BasePage(self.driver).click_ele(CONFIRM_BTN, "左侧组件-tree")
def one_to_one_face_compare(self, path1, path2): """ 1:1人脸验证 """ # 上传左侧图片 IMAGE_UPLOAD_INPUT_L = ( By.CSS_SELECTOR, '.app-tools-content-pics .imageselsect-container:first-child > input[type="file"]' ) # 上传右侧图片 IMAGE_UPLOAD_INPUT_R = ( By.CSS_SELECTOR, '.app-tools-content-pics .imageselsect-container:last-child > input[type="file"]' ) # 点击比对按钮 CHECK_CONTENT_FACE_BUTTON = (By.CLASS_NAME, "app-tools-content-pics-vsbtn") # input类型的file文件上传 BasePage(self.driver).upload_file(IMAGE_UPLOAD_INPUT_L, path1) BasePage(self.driver).upload_file(IMAGE_UPLOAD_INPUT_R, path2) BasePage(self.driver).click_ele(CHECK_CONTENT_FACE_BUTTON)
def get_code_cjy(self): """ 通过调用第三方接口获取验证码""" CODE_IMG = (By.CSS_SELECTOR, '.code-pic > img') BasePage(self.driver).wait_for_ele_to_be_visible(CODE_IMG, "登录") code_img_src = BasePage( self.driver).get_ele_locator(CODE_IMG).get_attribute("src") # 将获取到的图片地址保存到本地目录 urllib.request.urlretrieve( code_img_src, r'{}\cjy_read_code\save_cur_code.jpg'.format( SharePath.DATA_FOLDER)) # 调第三方接口_识别验证码 cjy = Chaojiying_Client( '18500379756', '123456', '9bf661c27903e244883b5af71ed0c5da') # 用户中心>>软件ID 生成一个 img = open( r'{}\cjy_read_code\save_cur_code.jpg'.format( SharePath.DATA_FOLDER), 'rb').read() # 本地图片文件路径,有时WIN系统须要// result = cjy.PostPic(img, 1902) # 1902 验证码类型 print(f"-------第三方接口识别当前的验证码为:{result['pic_str']}-----------") return result['pic_str']
def check_time(self, num=1): """ 封装时间控件 """ # 定位到时间控件并通过鼠标操作 TIME_CONTROL = ( By.XPATH, '//div[contains(@class, "el-date-range-picker") and contains(@style, "position")]//td[contains(@class, "today")]' ) BasePage(self.driver).mouse_move_ele(TIME_CONTROL) # 滑动时间控件点击对应的日期 TIME_TODAY = ( By.XPATH, '//div[contains(@class, "el-date-range-picker") and contains(@style, "position")]//div[contains(@class,"is-left")]//td[contains(@class, "today")]' ) BasePage(self.driver).mouse_move_ele_and_click(TIME_CONTROL, TIME_TODAY) TODAY_TEXT = ( By.XPATH, '//div[contains(@class, "el-date-range-picker") and contains(@style, "position")]//div[contains(@class,"is-left")]//td[contains(@class, "today")]//span' ) today_text = BasePage(self.driver).get_text(TODAY_TEXT) if int(today_text) >= 28: # 结束时间为下月1号 today_text = "1" TIME_END = ( By.XPATH, f'//div[contains(@class, "el-date-range-picker") and contains(@style, "position")]//div[contains(@class,"is-right")]//td//span[contains(text(),{today_text})]' ) else: # 结束时间为今天的后两天 today_text = str(int(today_text) + num) # 默认选择时间段为全天24小时 TIME_END = ( By.XPATH, f'//div[contains(@class, "el-date-range-picker") and contains(@style, "position")]//div[contains(@class,"is-left")]//td//span[contains(text(),{today_text})]' ) BasePage(self.driver).mouse_move_ele_and_click(TIME_CONTROL, TIME_END)
def add_timezone_name(self, timezone_name): """ 添加时间条件 :param timezone_name: 时间条件的名称 """ # icon的识别率不高,添加强制等待提高用例成功率 time.sleep(2) # 定位 -添加时间条件- 的按钮icon ICON = (By.XPATH, '//span[contains(text(), "时间条件名称")]/i') BasePage(self.driver).click_ele(ICON) # 调用封装方法 - 添加时间条件名称 self.dialog_info_com("添加时间条件", timezone_name)
def add_timezone_section_by_timezone_name(self, timezone_name): """ 添加时间段 :param timezone_name: 选择指定的时间条件添加时间段 """ # 定位到 -时间条件名称- SELECT_TIMEZONE = ( By.XPATH, f'//div[@role="tablist"]//button/span[contains(text(), "{timezone_name}")]' ) # 定位到 -时间段- ICON = (By.XPATH, '//span[contains(text(), "时间段")]/i') if not self.driver.find_element(*SELECT_TIMEZONE).is_displayed(): time.sleep(0.5) # 元素滚动到页面可见区域 BasePage(self.driver).scroll_visibility_region(loc=SELECT_TIMEZONE) # 点击元素 BasePage(self.driver).click_ele(SELECT_TIMEZONE) # 点击添加时间段 time.sleep(0.5) BasePage(self.driver).click_ele(ICON)
def close_tool_current_win(self, current_btn): """ common 关闭当前操作的小工具 """ if current_btn == "tools-face-verification": CLOSE_BTN = ( By.XPATH, f'//div[contains(@class, "{current_btn}")]//i[contains(@class, "app-tools-header-close")]' ) elif current_btn == "tools-score-detection": CLOSE_BTN = ( By.XPATH, f'//div[contains(@class, "{current_btn}")]//i[contains(@class, "app-tools-header-close")]' ) elif current_btn == "tools-test-detection": CLOSE_BTN = ( By.XPATH, f'//div[contains(@class, "{current_btn}")]//i[contains(@class, "app-tools-header-close")]' ) BasePage(self.driver).click_ele(CLOSE_BTN)
def get_face_score_detection_result(self): # 获取人脸质量分数的检测结果 CHECK_CONTENT_DETECTION_BUTTON_RESULT = ( By.XPATH, '//div[@class="app-tools-content-center"]//span') return BasePage( self.driver).get_text(CHECK_CONTENT_DETECTION_BUTTON_RESULT)
def close_alert(self): # 关闭alert弹框 CLOSE_BTN = ( By.XPATH, '//div[@role="alert"]//i[contains(@class, "el-icon-close")]') BasePage(self.driver).click_ele(CLOSE_BTN)
def judge_alert_info(self): # 定位alert弹框的文本 INFO_TEXT = (By.XPATH, '//div[@role="alert"]//p') # 强制等待元素可见 BasePage(self.driver).wait_for_ele_to_be_visible(INFO_TEXT) return BasePage(self.driver).get_text(INFO_TEXT)
def get_face_compare_result(self): # 获取人脸比对成功的结果 CHECK_RESULT_CONTENT = ( By.CSS_SELECTOR, '.app-tools-content-pics-vsbtn-popover > strong') return BasePage(self.driver).get_text(CHECK_RESULT_CONTENT)
def click_group_by_name(self, department_name): """ 点击左侧树图分组 """ # 部门分组名称 DEPARTMENT_NAME = (By.XPATH, f'//div[@title="{department_name}"]') BasePage(self.driver).click_ele(DEPARTMENT_NAME, "左侧组件-tree")
def judge_search_success(self, group_name): # 判断 tree分组下搜索到对应的分组 RESULT_TEXT = (By.XPATH, f'//div[@role="tree"]//div[contains(@title,"{group_name}")]') return BasePage(self.driver).get_text(RESULT_TEXT, "左侧组件-tree")