def __init__(self, url: str, username: str, password: str):
     self.url = url
     self.username = username
     self.password = password
     self.url = urljoin(self.url, '/api/v3')
     self.doRequest = DoRequest(self.url)
     self.private_token = self._get_private_token()
     self._path_private_token = '?private_token=%s' % self.private_token
示例#2
0
    def __init__(self):
        if self.__inited is None:
            self.demoProjectConfig = DemoProjectReadConfig().config
            self.demoProjectDBClients = DemoProjectDBClients()
            self.doRequest = DoRequest(self.demoProjectConfig.url)
            self.csrftoken = self._initCsrftoken()

            self.__inited = True
示例#3
0
class Gitlab_Client:
    def __init__(self, url: str, access_token: str):
        self.url = url
        self.access_token = access_token
        self.url = urljoin(self.url, '/api/v4')
        self.doRequest = DoRequest(self.url)
        self.doRequest.updateHeaders({'PRIVATE-TOKEN': self.access_token})

    def get_projects(self,
                     page: int = 1,
                     per_page: int = 100,
                     search='',
                     simple=True):
        params = {'page': page, 'per_page': per_page}
        httpResponseResult = self.doRequest.get(
            '/projects?simple=%s&search=%s' % (simple, search), params=params)
        return ujson.loads(httpResponseResult.body)

    def _get_project_id(self, project_name: str):
        projects = self.get_projects(search=project_name)
        for project_info in projects:
            if project_info['name'] == project_name.strip():
                return project_info['id']

    def get_project_file(self, project_name, ref, file_path):
        """
        @param project_name:
        @param ref: 分支名、tag名、commit
        @param file_path:
        @return:
        """
        project_id = self._get_project_id(project_name)
        params = {'ref': ref}
        httpResponsResult = self.doRequest.get(
            '/projects/%s/repository/files/%s' % (project_id, file_path),
            params=params)
        return ujson.loads(httpResponsResult.body)

    def update_project_file(self, project_name: str, branch_name: str,
                            file_path: str, content: str, commit_message: str):
        """
        @param project_name:
        @param branch_name:
        @param file_path:
        @param content:
        @param commit_message:
        @return:
        """
        project_id = self._get_project_id(project_name)
        params = {
            'branch': branch_name,
            'content': content,
            'commit_message': commit_message
        }
        httpResponsResult = self.doRequest.put(
            '/projects/%s/repository/files/%s' % (project_id, file_path),
            params=params)
        return ujson.loads(httpResponsResult.body)
示例#4
0
 def _delete_last_device_session(self, device_desc):
     if os.path.exists('config/app_ui_tmp/%s_session' % device_desc):
         with open('config/app_ui_tmp/%s_session' % device_desc, 'r') as f:
             last_session = f.read()
             last_session = last_session.strip()
             if last_session:
                 doRequest = DoRequest(self._appium_hub)
                 doRequest.setHeaders({'Content-Type': 'application/json'})
                 httpResponseResult = doRequest.delete('/session/' +
                                                       last_session)
示例#5
0
 def __init__(self,
              url: str,
              username: str,
              password: str,
              is_verify_ssl_cer=True):
     self.url = url
     self.username = username
     self.password = password
     self.doRequest = DoRequest(self.url)
     self.doRequest.setVerify(is_verify_ssl_cer)
     self._login()
示例#6
0
 def __init__(self, driver, appium_hub):
     self._doRequest = DoRequest(appium_hub)
     self._doRequest.setHeaders({'Content-Type': 'application/json'})
     self._driver = driver
     self._session_id = driver.session_id
     # 获得设备支持的性能数据类型
     self._performance_types = ujson.loads(
         self._doRequest.post_with_form(
             '/session/' + self._session_id +
             '/appium/performanceData/types').body)['value']
     # 获取当前窗口大小
     self._windows_size = self.get_window_size()
示例#7
0
class Robot:
    def __init__(self,webhook:str,secret_key:str=None):
        self.webhook=webhook
        self.secret_key=secret_key
        self.doRequest=DoRequest(self.webhook)
        self.doRequest.setHeaders({'Content-Type':'application/json'})

    def _generator_sign(self,timestamp:str,secret_key:str):
        secret_key_enc = secret_key.encode('utf-8')
        string_to_sign = '{}\n{}'.format(timestamp, secret_key)
        string_to_sign_enc = string_to_sign.encode('utf-8')
        hmac_code = hmac.new(secret_key_enc, string_to_sign_enc, digestmod=hashlib.sha256).digest()
        sign = urllib.parse.quote_plus(base64.b64encode(hmac_code))
        return sign

    def send_by_text(self,content:str,atMobiles:list=(),isAtAll=False):
        params={}
        params.update({'msgtype':'text'})
        params.update({'text':{'content':content}})
        at_params={}
        if not isinstance(atMobiles,list):
            atMobiles=list(atMobiles)
        at_params.update({'at':{'atMobiles':atMobiles,'isAtAll':isAtAll}})
        params.update(at_params)
        params=ujson.dumps(params)
        # 构造path
        path='/'
        if self.secret_key:
            timestamp = DateTimeTool.getNowTimeStampWithMillisecond()
            path='&timestamp={}&sign={}'.format(timestamp,self._generator_sign(timestamp,self.secret_key))
        # 发送文本
        httpResponseResult=self.doRequest.post_with_form(path,params)
        return httpResponseResult

    def send_by_markdown(self,title:str,text:str,atMobiles:list=(),isAtAll=False):
        params = {}
        params.update({'msgtype': 'markdown'})
        params.update({'markdown': {'title': title,'text':text}})
        at_params = {}
        if not isinstance(atMobiles, list):
            atMobiles = list(atMobiles)
        at_params.update({'at': {'atMobiles': atMobiles, 'isAtAll': isAtAll}})
        params.update(at_params)
        params = ujson.dumps(params)
        # 构造path
        path = '/'
        if self.secret_key:
            timestamp = DateTimeTool.getNowTimeStampWithMillisecond()
            path = '&timestamp={}&sign={}'.format(timestamp, self._generator_sign(timestamp, self.secret_key))
        # 发送文本
        httpResponseResult = self.doRequest.post_with_form(path, params)
        return httpResponseResult
示例#8
0
class DemoProjectClient(object):
    __instance = None
    __inited = None

    def __new__(cls, *args, **kwargs):
        if cls.__instance is None:
            cls.__instance = object.__new__(cls)
        return cls.__instance

    def __init__(self):
        if self.__inited is None:
            self.demoProjectConfig = DemoProjectReadConfig().config
            self.demoProjectDBClients = DemoProjectDBClients()
            self.doRequest = DoRequest(self.demoProjectConfig.url)
            self.csrftoken = self._initCsrftoken()

            self.__inited = True

    def _initCsrftoken(self):
        # 测试接口如果都需要先授权,可以在再次操作,将授权信息放到httpclient的headers或者cookies
        httpResponseResult = self.doRequest.get(
            "/horizon/auth/login/?next=/horizon/")
        cookies = httpResponseResult.cookies
        csrftoken = StrTool.getStringWithLBRB(cookies, 'csrftoken=', ' for')
        return csrftoken
    def __init__(self):
        if self.__inited is None:
            self.demoProjectConfig = API_DemoProject_Read_Config().config
            self.demoProjectDBClients = API_DemoProject_DB_Clients()
            self.doRequest = DoRequest(self.demoProjectConfig.url)

            self.__inited = True
示例#10
0
class DemoProjectClient():
    def __init__(self):
        self.demoProjectConfig=DemoProjectInit().getDemoProjectConfig()
        self.doRequest=DoRequest(self.demoProjectConfig.url)
        self.csrftoken=None

        self._initCsrftoken()

    def _initCsrftoken(self):
        # 测试接口如果都需要先授权,可以在再次操作,将授权信息放到httpclient的headers或者cookies
        httpResponseResult = self.doRequest.get("/horizon/auth/login/?next=/horizon/")
        cookies = httpResponseResult.cookies
        csrftoken = StrTool.getStringWithLBRB(cookies, 'csrftoken=', ' for')
        self.csrftoken = csrftoken
示例#11
0
class Robot:
    def __init__(self, webhook: str):
        self.webhook = webhook
        self.doRequest = DoRequest(self.webhook)
        self.doRequest.setVerify(False)
        self.doRequest.setHeaders({'Content-Type': 'application/json'})

    def send_by_text(self,
                     content: str,
                     atUserIds: list = (),
                     atMobiles: list = ()):
        """[summary]

        Args:
            content (str): [description]
            atUserIds (list, optional): userid的列表,提醒群中的指定成员(@某个成员),@all表示提醒所有人,如果开发者获取不到userid,可以使用mentioned_mobile_list. Defaults to ().
            atMobiles (list, optional): 手机号列表,提醒手机号对应的群成员(@某个成员),@all表示提醒所有人. Defaults to ().

        Returns:
            [type]: [description]
        """
        params = {}
        params.update({'msgtype': 'text'})
        if not isinstance(atUserIds, list):
            atUserIds = list(atUserIds)
        if not isinstance(atMobiles, list):
            atMobiles = list(atMobiles)
        params.update({
            'text': {
                'content': content,
                'mentioned_list': atUserIds,
                'mentioned_mobile_list': atMobiles
            }
        })
        params = ujson.dumps(params)
        # 发送文本
        httpResponseResult = self.doRequest.post_with_form('', params)
        return httpResponseResult

    def send_by_markdown(self, content: str):
        params = {}
        params.update({'msgtype': 'markdown'})
        params.update({'markdown': {'content': content}})
        params = ujson.dumps(params)
        # 发送文本
        httpResponseResult = self.doRequest.post_with_form('', params)
        return httpResponseResult
                        type=str)
    parser.add_argument('-r', '--reruns', help='失败重跑次数,默认为0', type=str)
    parser.add_argument('-lf',
                        '--lf',
                        help='是否运行上一次失败的用例,1:是、0:否,默认为0',
                        type=str)
    parser.add_argument('-clr',
                        '--clr',
                        help='是否清空已有测试结果,1:是、0:否,默认为0',
                        type=str)
    args = parser.parse_args()

    print('%s开始初始化......' % DateTimeTool.getNowTime())
    print('%s开始检测selenium server是否可用......' % DateTimeTool.getNowTime())
    try:
        doRquest = DoRequest(Read_WEB_UI_Config().web_ui_config.selenium_hub)
        httpResponseResult = doRquest.get('/status')
        result = ujson.loads(httpResponseResult.body)
        if result['status'] == 0:
            print('%sselenium server状态为可用......' % DateTimeTool.getNowTime())
        else:
            sys.exit('%sselenium server状态为不可用' % DateTimeTool.getNowTime())
    except:
        sys.exit('%sselenium server状态为不可用' % DateTimeTool.getNowTime())

    # 处理pytest文件
    deal_pytest_ini_file()

    # 初始化java依赖的libs
    java_maven_init()
示例#13
0
 def __init__(self,webhook:str,secret_key:str=None):
     self.webhook=webhook
     self.secret_key=secret_key
     self.doRequest=DoRequest(self.webhook)
     self.doRequest.setHeaders({'Content-Type':'application/json'})
示例#14
0
 def __init__(self, url: str, access_token: str):
     self.url = url
     self.access_token = access_token
     self.url = urljoin(self.url, '/api/v4')
     self.doRequest = DoRequest(self.url)
     self.doRequest.updateHeaders({'PRIVATE-TOKEN': self.access_token})
示例#15
0
def start_app_device_test(index,device_info,keyword,dir,markexpr,capture,reruns,lf,clr):
    for path, dirs, files in os.walk('config/app_ui_tmp'):
        for file in files:
            if(int(file)==index):
                os.rename(os.path.join(path,file),os.path.join(path,str(os.getpid())))

    print('%s开始检测appium server是否可用......'%DateTimeTool.getNowTime())
    try:
        doRquest = DoRequest('http://'+device_info['server_ip']+':%s/wd/hub'%device_info['server_port'].strip())
        httpResponseResult = doRquest.get('/status')
        result = ujson.loads(httpResponseResult.body)
        if result['status'] == 0:
            print('%sappium server状态为可用......'%DateTimeTool.getNowTime())
        else:
            sys.exit('%sappium server状态为不可用'%DateTimeTool.getNowTime())
    except:
        print('%sappium server状态为不可用'%DateTimeTool.getNowTime())
        raise Exception('%sappium server状态为不可用'%DateTimeTool.getNowTime())

    a_devices_desired_capabilities = device_info['capabilities']
    print('%s开始设备%s测试......'%(DateTimeTool.getNowTime(),device_info['device_desc']))
    print('%s当前设备所需测试的desired_capabilities为:%s'%(DateTimeTool.getNowTime(),a_devices_desired_capabilities))
    for desired_capabilities in a_devices_desired_capabilities:
        FileTool.writeObjectIntoFile(desired_capabilities,'config/app_ui_tmp/'+str(os.getpid())+'_current_desired_capabilities')
        desired_capabilities_desc=None
        if 'appPackage' in desired_capabilities.keys():
            desired_capabilities_desc = desired_capabilities['appPackage']
        elif 'app' in desired_capabilities.keys():
            desired_capabilities_desc = desired_capabilities['app'].split('/')[-1]
        elif 'bundleId' in desired_capabilities.keys():
            desired_capabilities_desc = desired_capabilities['bundleId']
        print('%s当前设备开始测试的desired_capabilities为:%s'%(DateTimeTool.getNowTime(),desired_capabilities))
        # 执行pytest前的参数准备
        pytest_execute_params = ['-c', 'config/pytest.ini', '-v', '--alluredir', 'output/app_ui/%s/%s/report_data/'%(device_info['device_desc'],desired_capabilities_desc)]
        # 判断目录参数
        if not dir:
            dir = 'cases/app_ui/'
        # 判断关键字参数
        if keyword:
            pytest_execute_params.append('-k')
            pytest_execute_params.append(keyword)
        # 判断markexpr参数
        if markexpr:
            pytest_execute_params.append('-m')
            pytest_execute_params.append(markexpr)
        # 判断是否输出日志
        if capture:
            if int(capture):
                pytest_execute_params.append('-s')
        # 判断是否失败重跑
        if reruns:
            if int(reruns):
                pytest_execute_params.append('--reruns')
                pytest_execute_params.append(reruns)
        # 判断是否只运行上一次失败的用例
        if lf:
            if int(lf):
                pytest_execute_params.append('--lf')
        # 判断是否清空已有测试结果
        if clr:
            if int(clr):
                pytest_execute_params.append('--clean-alluredir')
        pytest_execute_params.append(dir)
        # 构建孙进程
        process = multiprocessing.Process(target=pytest_main,args=(pytest_execute_params,))
        process.start()
        process.join()
        print('%s当前设备结束测试的desired_capabilities为:%s' % (DateTimeTool.getNowTime(),desired_capabilities))
    print('%s结束设备%s测试......'%(DateTimeTool.getNowTime(),device_info['device_desc']))
示例#16
0
 def __init__(self,url:str,username:str,password:str):
     self.url=url
     self.username=username
     self.password=password
     self.doRequest=DoRequest(self.url)
     self._login()
class Gitlab_Client:
    def __init__(self, url: str, username: str, password: str):
        self.url = url
        self.username = username
        self.password = password
        self.url = urljoin(self.url, '/api/v3')
        self.doRequest = DoRequest(self.url)
        self.private_token = self._get_private_token()
        self._path_private_token = '?private_token=%s' % self.private_token

    def _login(self):
        httpResponseResult = self.doRequest.post_with_form(
            '/session?login=%s&password=%s' % (self.username, self.password))
        return httpResponseResult

    def _get_private_token(self):
        user_info = self._login().body
        user_info = ujson.loads(user_info)
        return user_info['private_token']

    def get_user(self):
        return ujson.loads(self._login().body)

    def get_projects(self, page: int = 1, per_page: int = 100):
        params = {'page': 1, 'per_page': 100}
        httpResponseResult = self.doRequest.get('/projects%s' %
                                                self._path_private_token,
                                                params=params)
        return ujson.loads(httpResponseResult.body)

    def _get_project_id(self, project_name: str):
        projects = self.get_projects()
        for project_info in projects:
            if project_info['name'] == project_name.strip():
                return project_info['id']

    def get_project_tree(self, project_name: str):
        project_id = self._get_project_id(project_name)
        httpResponsResult = self.doRequest.get(
            '/projects/%s/repository/tree%s' %
            (project_id, self._path_private_token))
        return ujson.loads(httpResponsResult.body)

    def get_project_file(self, project_name, ref, file_path):
        """
        @param project_name:
        @param ref: 分支名、tag名、commit
        @param file_path:
        @return:
        """
        project_id = self._get_project_id(project_name)
        params = {'file_path': file_path, 'ref': ref}
        httpResponsResult = self.doRequest.get(
            '/projects/%s/repository/files%s' %
            (project_id, self._path_private_token),
            params=params)
        return ujson.loads(httpResponsResult.body)

    def update_project_file(self, project_name: str, branch_name: str,
                            file_path: str, content: str, commit_message: str):
        """
        @param project_name:
        @param branch_name:
        @param file_path:
        @param content:
        @param commit_message:
        @return:
        """
        project_id = self._get_project_id(project_name)
        params = {
            'file_path': file_path,
            'branch_name': branch_name,
            'content': content,
            'commit_message': commit_message
        }
        httpResponsResult = self.doRequest.put(
            '/projects/%s/repository/files%s' %
            (project_id, self._path_private_token),
            params=params)
        return ujson.loads(httpResponsResult.body)
示例#18
0
 def __init__(self, webhook: str):
     self.webhook = webhook
     self.doRequest = DoRequest(self.webhook)
     self.doRequest.setVerify(False)
     self.doRequest.setHeaders({'Content-Type': 'application/json'})
示例#19
0
class AppOperator:
    """
    类中的element参数可以有appium.webdriver.webelement.WebElement和pojo.elementInfo.ElementInfo类型
    """
    def __init__(self, driver):
        self._config = ReadConfig().config
        self._doRequest = DoRequest(self._config.appium_hub)
        self._doRequest.setHeaders({'Content-Type': 'application/json'})
        self._driver = driver
        self._session_id = driver.session_id
        # 获得设备支持的性能数据类型
        self._performance_types = json.loads(
            self._doRequest.post_with_form(
                '/session/' + self._session_id +
                '/appium/performanceData/types').body)['value']
        # 获取当前窗口大小
        self._windows_size = self.get_window_size()

    def _change_element_to_webElement_type(self, element):
        if isinstance(element, ElementInfo):
            webElement = self.getElement(element)
        elif isinstance(element, WebElement):
            webElement = element
        else:
            return None
        return webElement

    def get(self, url):
        self._driver.get(url)

    def get_current_url(self):
        return self._driver.current_url.encode('utf-8')

    def getTitle(self):
        return self._driver.title.encode('utf-8')

    def getText(self, element):
        webElement = self._change_element_to_webElement_type(element)
        if webElement:
            return webElement.text.encode('utf-8')

    def click(self, element):
        webElement = self._change_element_to_webElement_type(element)
        if webElement:
            webElement.click()

    def submit(self, element):
        webElement = self._change_element_to_webElement_type(element)
        if webElement:
            webElement.submit()

    def sendText(self, element, text):
        text = text.decode('utf-8')
        webElement = self._change_element_to_webElement_type(element)
        if webElement:
            webElement.clear()
            webElement.send_keys(text)

    def is_displayed(self, element):
        webElement = self._change_element_to_webElement_type(element)
        if webElement:
            flag = webElement.is_displayed()
            return flag

    def is_enabled(self, element):
        webElement = self._change_element_to_webElement_type(element)
        if webElement:
            flag = webElement.is_enabled()
            return flag

    def is_selected(self, element):
        webElement = self._change_element_to_webElement_type(element)
        if webElement:
            flag = webElement.is_selected()
            return flag

    def select_dropDownBox_by_value(self, element, value):
        """
        适用单选下拉框
        :param element:
        :param value:
        :return:
        """
        webElement = self._change_element_to_webElement_type(element)
        if webElement:
            webElement = Select(webElement)
            webElement.select_by_value(value)

    def select_dropDownBox_by_text(self, element, text):
        """
        适用单选下拉框
        :param element:
        :param text:
        :return:
        """
        webElement = self._change_element_to_webElement_type(element)
        if webElement:
            webElement = Select(webElement)
            webElement.select_by_visible_text(text)

    def select_dropDownBox_by_index(self, element, index):
        """
        适用单选下拉框,下标从0开始
        :param element:
        :param index:
        :return:
        """
        webElement = self._change_element_to_webElement_type(element)
        if webElement:
            webElement = Select(webElement)
            webElement.select_by_index(index)

    def select_dropDownBox_by_values(self, element, values):
        """
        适用多选下拉框
        :param element:
        :param values:以数组传参
        :return:
        """
        webElement = self._change_element_to_webElement_type(element)
        if webElement:
            webElement = Select(webElement)
            webElement.deselect_all()
            for value in values:
                webElement.select_by_value(value)

    def select_dropDownBox_by_texts(self, element, texts):
        """
        适用多选下拉框
        :param element:
        :param texts:以数组传参
        :return:
        """
        webElement = self._change_element_to_webElement_type(element)
        if webElement:
            webElement = Select(webElement)
            webElement.deselect_all()
            for text in texts:
                webElement.select_by_visible_text(text)

    def select_dropDownBox_by_indexs(self, element, indexs):
        """
        适用多选下拉框,下标从0开始
        :param element:
        :param indexs: 以数组传参
        :return:
        """
        webElement = self._change_element_to_webElement_type(element)
        if webElement:
            webElement = Select(webElement)
            webElement.deselect_all()
            for index in indexs:
                webElement.select_by_index(index)

    def switch_to_window(self, window_name):
        """
        仅使用web
        :param window_name:
        :return:
        """
        self._driver.switch_to.window(window_name)

    def switch_to_frame(self, frame_name):
        """
        仅使用web
        :param frame_name:
        :return:
        """
        self._driver.switch_to.frame(frame_name)

    def page_forward(self):
        """
        仅使用web
        :return:
        """
        self._driver.forward()

    def pag_back(self):
        """
        仅使用web
        :return:
        """
        self._driver.back()

    def dismiss_alert(self):
        """
        仅使用web
        :return:
        """
        alert = self._driver.switch_to.alert
        alert.dismiss()

    def accept_alert(self):
        """
        仅使用web
        :return:
        """
        alert = self._driver.switch_to.alert
        alert.accept()

    def get_alert_test(self):
        """
        仅使用web
        :return:
        """
        alert = self._driver.switch_to.alert
        return alert.text

    def get_screenshot(self, fileName):
        fileName = DateTimeTool.getNowTime('%Y%m%d%H%M%S%f_') + fileName
        allure.attach(name=fileName,
                      body=self._driver.get_screenshot_as_png(),
                      attachment_type=allure.attachment_type.PNG)

    def refresh(self):
        self._driver.refresh()

    def uploadFile(self, element, filePath):
        """
        仅适用于web
        适用于元素为input且type="file"的文件上传
        :param element:
        :param filePath:
        :return:
        """
        webElement = self._change_element_to_webElement_type(element)
        if webElement:
            webElement.send_keys(os.path.abspath(filePath))

    def switch_to_parent_frame(self):
        """
        切换到父frame(仅使用web)
        :return:
        """
        self._driver.switch_to.parent_frame()

    def get_property(self, element, property_name):
        webElement = self._change_element_to_webElement_type(element)
        if webElement:
            return webElement.get_property(property_name)

    def get_attribute(self, element, attribute_name):
        webElement = self._change_element_to_webElement_type(element)
        if webElement:
            return webElement.get_attribute(attribute_name)

    def get_element_outer_html(self, element):
        return self.get_attribute(element, 'outerHTML').encode('utf-8')

    def get_element_inner_html(self, element):
        return self.get_attribute(element, 'innerHTML').encode('utf-8')

    def get_captcha(self, element, language='eng'):
        """
        识别图片验证码
        :param element: 验证码图片元素
        :param language: eng:英文,chi_sim:中文
        :return:
        """
        # 为防止截图包含高亮影响识别,元素不进行高亮
        captcha_webElement = self._change_element_to_webElement_type(element)
        left = captcha_webElement.location['x']
        top = captcha_webElement.location['y']
        right = captcha_webElement.location['x'] + captcha_webElement.size[
            'width']
        bottom = captcha_webElement.location['y'] + captcha_webElement.size[
            'height']
        # 首先进行屏幕截图
        captcha_image_file_name = DateTimeTool.getNowTime(
            '%Y%m%d%H%M%S%f_') + 'captcha.png'
        captcha_image_file_name = os.path.abspath('output/' +
                                                  captcha_image_file_name)
        self._driver.get_screenshot_as_file(captcha_image_file_name)
        img = Image.open(captcha_image_file_name)
        # 验证码图片裁切并保存
        img = img.crop((left, top, right, bottom))
        img.save(captcha_image_file_name)
        # 识别图片验证码
        captcha = CaptchaRecognitionTool.captchaRecognition(
            captcha_image_file_name, language)
        captcha = captcha.strip()
        captcha = captcha.replace(' ', '')
        return captcha

    def get_table_data(self, element, data_type='text'):
        """
        以二维数组返回表格每一行的每一列的数据[[row1][row2][colume1,clume2]]
        :param element:
        :param data_type: text-返回表格文本内容,html-返回表格html内容,webElement-返回表格元素
        :return:
        """
        if isinstance(element, ElementInfo):
            # 由于表格定位经常会出现【StaleElementReferenceException: Message: stale element reference: element is not attached to the page document 】异常错误,
            # 解决此异常只需要用显示等待,保证元素存在即可,显示等待类型中visibility_of_all_elements_located有实现StaleElementReferenceException异常捕获,
            # 所以强制设置表格定位元素时使用VISIBILITY_OF
            element.wait_type = Wait_By.VISIBILITY_OF
            webElement = self.getElement(element)
        elif isinstance(element, WebElement):
            webElement = element
        else:
            return None
        table_data = []
        table_trs = webElement.find_elements_by_tag_name('tr')
        try:
            for tr in table_trs:
                tr_data = []
                tr_tds = tr.find_elements_by_tag_name('td')
                if data_type.lower() == 'text':
                    for td in tr_tds:
                        tr_data.append(td.text.encode('utf-8'))
                elif data_type.lower() == 'html':
                    for td in tr_tds:
                        tr_data.append(td.get_attribute('innerHTML'))
                elif data_type.lower() == 'webelement':
                    tr_data = tr_tds
                table_data.append(tr_data)
        except StaleElementReferenceException, e:
            print '获取表格内容异常:' + e.message
        return table_data
示例#20
0
import pytest
import sys

if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument('-k',
                        '--keyword',
                        help='只执行匹配关键字的用例,会匹配文件名、类名、方法名',
                        type=str)
    parser.add_argument('-d', '--dir', help='指定要测试的目录', type=str)
    args = parser.parse_args()

    print '开始初始化......'
    print '开始检测selenium server是否可用......'
    try:
        doRquest = DoRequest(ReadConfig().config.selenium_hub)
        httpResponseResult = doRquest.get('/status')
        result = json.loads(httpResponseResult.body)
        if result['status'] == 0:
            print 'selenium server状态为可用......'
        else:
            sys.exit('selenium server状态为不可用')
    except:
        sys.exit('selenium server状态为不可用')

    print '初始化基础数据......'
    init()
    print '初始化基础数据完成......'
    print '初始化完成......'

    print '开始测试......'
示例#21
0
 def __init__(self, url):
     self._url = url
     self._doRequest = DoRequest(self._url)
     self._doRequest.setProxies({'http': '127.0.0.1:8888'})
示例#22
0
class Solr_Dataimport:
    """
    solr数据导入API说明:
    https://wiki.apache.org/solr/DataImportHandler

    The handler exposes all its API as http requests . The following are the possible operations

    full-import : Full Import operation can be started by hitting the URL http://<host>:<port>/solr/dataimport?command=full-import

        This operation will be started in a new thread and the status attribute in the response should be shown busy now.
        The operation may take some time depending on size of dataset.

        When full-import command is executed, it stores the start time of the operation in a file located at conf/dataimport.properties (this file is configurable)
        This stored timestamp is used when a delta-import operation is executed.
        Queries to Solr are not blocked during full-imports.
        It takes in extra parameters:

            entity : Name of an entity directly under the <document> tag. Use this to execute one or more entities selectively. Multiple 'entity' parameters can be passed on to run multiple entities at once. If nothing is passed, all entities are executed.

            clean : (default 'true'). Tells whether to clean up the index before the indexing is started.

            commit : (default 'true'). Tells whether to commit after the operation.

            optimize : (default 'true' up to Solr 3.6, 'false' afterwards). Tells whether to optimize after the operation. Please note: this can be a very expensive operation and usually does not make sense for delta-imports.

            debug : (default 'false'). Runs in debug mode. It is used by the interactive development mode (see here).
                Please note that in debug mode, documents are never committed automatically. If you want to run debug mode and commit the results too, add 'commit=true' as a request parameter.

    delta-import : For incremental imports and change detection run the command http://<host>:<port>/solr/dataimport?command=delta-import . It supports the same clean, commit, optimize and debug parameters as full-import command.

    status : To know the status of the current command, hit the URL http://<host>:<port>/solr/dataimport . It gives an elaborate statistics on no. of docs created, deleted, queries run, rows fetched, status etc.

    reload-config : If the data-config is changed and you wish to reload the file without restarting Solr. Run the command http://<host>:<port>/solr/dataimport?command=reload-config .

    abort : Abort an ongoing operation by hitting the URL http://<host>:<port>/solr/dataimport?command=abort .
    """
    def __init__(self, url):
        self._url = url
        self._doRequest = DoRequest(self._url)
        self._doRequest.setProxies({'http': '127.0.0.1:8888'})

    def _import(self,
                coreName,
                import_type=0,
                entity=None,
                clean=False,
                commit=True,
                optimize=False,
                debug=False):
        params = {}
        params.update({'entity': entity})
        params.update({'clean': str(clean).lower()})
        params.update({'commit': str(commit).lower()})
        params.update({'optimize': str(optimize).lower()})
        params.update({'debug': str(debug).lower()})
        # post或者get方法都支持
        if 0 == import_type:
            httpResponseResult = self._doRequest.post_with_form(
                '/solr/' + coreName + '/dataimport?command=full-import',
                params=params)
        else:
            httpResponseResult = self._doRequest.post_with_form(
                '/solr/' + coreName + '/dataimport?command=delta-import',
                params=params)
        return httpResponseResult

    def full_import(self,
                    coreName,
                    entity=None,
                    clean=False,
                    commit=True,
                    optimize=False,
                    debug=False):
        """
        全量导入
        :param coreName:
        :param entity:
        :param clean:
        :param commit:
        :param optimize:
        :param debug:
        :return:
        """
        return self._import(coreName, 0, entity, clean, commit, optimize,
                            debug)

    def delta_import(self,
                     coreName,
                     entity=None,
                     clean=False,
                     commit=True,
                     optimize=False,
                     debug=False):
        """
        增量导入
        :param coreName:
        :param entity:
        :param clean:
        :param commit:
        :param optimize:
        :param debug:
        :return:
        """
        return self._import(coreName, 1, entity, clean, commit, optimize,
                            debug)
示例#23
0
    def __init__(self):
        self.demoProjectConfig=DemoProjectInit().getDemoProjectConfig()
        self.doRequest=DoRequest(self.demoProjectConfig.url)
        self.csrftoken=None

        self._initCsrftoken()
示例#24
0
class AppOperator:
    """
    类中的element参数可以有appium.webdriver.webelement.WebElement和pojo.elementInfo.ElementInfo类型
    """
    def __init__(self, driver):
        self._config = Read_APP_UI_Config().app_ui_config
        self._doRequest = DoRequest(self._config.appium_hub)
        self._doRequest.setHeaders({'Content-Type': 'application/json'})
        self._driver = driver
        self._session_id = driver.session_id
        # 获得设备支持的性能数据类型
        self._performance_types = json.loads(
            self._doRequest.post_with_form(
                '/session/' + self._session_id +
                '/appium/performanceData/types').body)['value']
        # 获取当前窗口大小
        self._windows_size = self.get_window_size()

    def _change_element_to_webElement_type(self, element):
        if isinstance(element, ElementInfo):
            webElement = self.getElement(element)
        elif isinstance(element, WebElement):
            webElement = element
        else:
            return None
        return webElement

    def get(self, url):
        self._driver.get(url)

    def get_current_url(self):
        return self._driver.current_url

    def getTitle(self):
        return self._driver.title

    def getText(self, element):
        webElement = self._change_element_to_webElement_type(element)
        if webElement:
            return webElement.text

    def click(self, element):
        webElement = self._change_element_to_webElement_type(element)
        if webElement:
            webElement.click()

    def submit(self, element):
        webElement = self._change_element_to_webElement_type(element)
        if webElement:
            webElement.submit()

    def sendText(self, element, text):
        webElement = self._change_element_to_webElement_type(element)
        if webElement:
            webElement.clear()
            webElement.send_keys(text)

    def is_displayed(self, element):
        webElement = self._change_element_to_webElement_type(element)
        if webElement:
            flag = webElement.is_displayed()
            return flag

    def is_enabled(self, element):
        webElement = self._change_element_to_webElement_type(element)
        if webElement:
            flag = webElement.is_enabled()
            return flag

    def is_selected(self, element):
        webElement = self._change_element_to_webElement_type(element)
        if webElement:
            flag = webElement.is_selected()
            return flag

    def select_dropDownBox_by_value(self, element, value):
        """
        适用单选下拉框
        :param element:
        :param value:
        :return:
        """
        webElement = self._change_element_to_webElement_type(element)
        if webElement:
            webElement = Select(webElement)
            webElement.select_by_value(value)

    def select_dropDownBox_by_text(self, element, text):
        """
        适用单选下拉框
        :param element:
        :param text:
        :return:
        """
        webElement = self._change_element_to_webElement_type(element)
        if webElement:
            webElement = Select(webElement)
            webElement.select_by_visible_text(text)

    def select_dropDownBox_by_index(self, element, index):
        """
        适用单选下拉框,下标从0开始
        :param element:
        :param index:
        :return:
        """
        webElement = self._change_element_to_webElement_type(element)
        if webElement:
            webElement = Select(webElement)
            webElement.select_by_index(index)

    def select_dropDownBox_by_values(self, element, values):
        """
        适用多选下拉框
        :param element:
        :param values:以数组传参
        :return:
        """
        webElement = self._change_element_to_webElement_type(element)
        if webElement:
            webElement = Select(webElement)
            webElement.deselect_all()
            for value in values:
                webElement.select_by_value(value)

    def select_dropDownBox_by_texts(self, element, texts):
        """
        适用多选下拉框
        :param element:
        :param texts:以数组传参
        :return:
        """
        webElement = self._change_element_to_webElement_type(element)
        if webElement:
            webElement = Select(webElement)
            webElement.deselect_all()
            for text in texts:
                webElement.select_by_visible_text(text)

    def select_dropDownBox_by_indexs(self, element, indexs):
        """
        适用多选下拉框,下标从0开始
        :param element:
        :param indexs: 以数组传参
        :return:
        """
        webElement = self._change_element_to_webElement_type(element)
        if webElement:
            webElement = Select(webElement)
            webElement.deselect_all()
            for index in indexs:
                webElement.select_by_index(index)

    def switch_to_window(self, window_name):
        """
        仅使用web
        :param window_name:
        :return:
        """
        self._driver.switch_to.window(window_name)

    def switch_to_frame(self, frame_name):
        """
        仅使用web
        :param frame_name:
        :return:
        """
        self._driver.switch_to.frame(frame_name)

    def page_forward(self):
        """
        仅使用web
        :return:
        """
        self._driver.forward()

    def pag_back(self):
        """
        仅使用web
        :return:
        """
        self._driver.back()

    def dismiss_alert(self):
        """
        仅使用web
        :return:
        """
        alert = self._driver.switch_to.alert
        alert.dismiss()

    def accept_alert(self):
        """
        仅使用web
        :return:
        """
        alert = self._driver.switch_to.alert
        alert.accept()

    def get_alert_text(self):
        """
        仅使用web
        :return:
        """
        alert = self._driver.switch_to.alert
        return alert.text

    def get_screenshot(self, fileName):
        fileName = DateTimeTool.getNowTime('%Y%m%d%H%M%S%f_') + fileName
        allure.attach(name=fileName,
                      body=self._driver.get_screenshot_as_png(),
                      attachment_type=allure.attachment_type.PNG)

    def refresh(self):
        self._driver.refresh()

    def uploadFile(self, element, filePath):
        """
        仅适用于web
        适用于元素为input且type="file"的文件上传
        :param element:
        :param filePath:
        :return:
        """
        webElement = self._change_element_to_webElement_type(element)
        if webElement:
            webElement.send_keys(os.path.abspath(filePath))

    def switch_to_parent_frame(self):
        """
        切换到父frame(仅使用web)
        :return:
        """
        self._driver.switch_to.parent_frame()

    def get_property(self, element, property_name):
        webElement = self._change_element_to_webElement_type(element)
        if webElement:
            return webElement.get_property(property_name)

    def get_attribute(self, element, attribute_name):
        webElement = self._change_element_to_webElement_type(element)
        if webElement:
            return webElement.get_attribute(attribute_name)

    def get_element_outer_html(self, element):
        return self.get_attribute(element, 'outerHTML')

    def get_element_inner_html(self, element):
        return self.get_attribute(element, 'innerHTML')

    def get_page_source(self):
        return self._driver.page_source

    def get_captcha(self, element, language='eng'):
        """
        识别图片验证码
        :param element: 验证码图片元素
        :param language: eng:英文,chi_sim:中文
        :return:
        """
        # 为防止截图包含高亮影响识别,元素不进行高亮
        captcha_webElement = self._change_element_to_webElement_type(element)
        left = captcha_webElement.location['x']
        top = captcha_webElement.location['y']
        right = captcha_webElement.location['x'] + captcha_webElement.size[
            'width']
        bottom = captcha_webElement.location['y'] + captcha_webElement.size[
            'height']
        # 首先进行屏幕截图
        captcha_image_file_name = DateTimeTool.getNowTime(
            '%Y%m%d%H%M%S%f_') + 'captcha.png'
        captcha_image_file_name = os.path.abspath('output/' +
                                                  captcha_image_file_name)
        self._driver.get_screenshot_as_file(captcha_image_file_name)
        img = Image.open(captcha_image_file_name)
        # 验证码图片裁切并保存
        img = img.crop((left, top, right, bottom))
        img.save(captcha_image_file_name)
        # 识别图片验证码
        captcha = CaptchaRecognitionTool.captchaRecognition(
            captcha_image_file_name, language)
        captcha = captcha.strip()
        captcha = captcha.replace(' ', '')
        return captcha

    def get_table_data(self, element, data_type='text'):
        """
        以二维数组返回表格每一行的每一列的数据[[row1][row2][colume1,clume2]]
        :param element:
        :param data_type: text-返回表格文本内容,html-返回表格html内容,webElement-返回表格元素
        :return:
        """
        if isinstance(element, ElementInfo):
            # 由于表格定位经常会出现【StaleElementReferenceException: Message: stale element reference: element is not attached to the page document 】异常错误,
            # 解决此异常只需要用显示等待,保证元素存在即可,显示等待类型中visibility_of_all_elements_located有实现StaleElementReferenceException异常捕获,
            # 所以强制设置表格定位元素时使用VISIBILITY_OF
            element.wait_type = Wait_By.VISIBILITY_OF
            webElement = self.getElement(element)
        elif isinstance(element, WebElement):
            webElement = element
        else:
            return None
        table_data = []
        table_trs = webElement.find_elements_by_tag_name('tr')
        try:
            for tr in table_trs:
                tr_data = []
                tr_tds = tr.find_elements_by_tag_name('td')
                if data_type.lower() == 'text':
                    for td in tr_tds:
                        tr_data.append(td.text)
                elif data_type.lower() == 'html':
                    for td in tr_tds:
                        tr_data.append(td.get_attribute('innerHTML'))
                elif data_type.lower() == 'webelement':
                    tr_data = tr_tds
                table_data.append(tr_data)
        except StaleElementReferenceException as e:
            print('获取表格内容异常:' + e.msg)
        return table_data

    def get_window_size(self):
        return self._driver.get_window_size()

    def get_geolocation(self):
        """
        返回定位信息,纬度/经度/高度
        :return:
        """
        httpResponseResult = self._doRequest.get('/session/' +
                                                 self._session_id +
                                                 '/location')
        return httpResponseResult.body

    def set_geolocation(self, latitude, longitude, altitude):
        """
        设置定位信息
        :param latitude: 纬度 -90 ~ 90
        :param longitude: 精度 ~180 ~ 180
        :param altitude: 高度
        :return:
        """
        geolocation = {}
        location = {}
        location.update({'latitude': latitude})
        location.update({'longitude': longitude})
        location.update({'altitude': altitude})
        geolocation.update({'location': location})
        self._doRequest.post_with_form('/session/' + self._session_id +
                                       '/location',
                                       params=json.dumps(geolocation))

    def get_current_activity(self):
        """
        获得Android的activity
        :return:
        """
        return self._driver.current_activity

    def get_current_package(self):
        """
        获得Android的package
        :return:
        """
        return self._driver.current_package

    def execute_javascript(self, script):
        """
        仅适用于web
        :param script:
        :return:
        """
        self._driver.execute_script(script)

    def install_app(self, filePath):
        self._driver.install_app(os.path.abspath(filePath))

    def remove_app(self, app_id):
        self._driver.remove_app(app_id)

    def launch_app(self):
        self._driver.launch_app()

    def reset_app(self):
        """
        重置app,可以进入下一轮app测试
        :return:
        """
        return self._driver.reset()

    def close_app(self):
        self._driver.close_app()

    def background_app(self, seconds):
        """
        后台运行
        :param seconds:
        :return:
        """
        self._driver.background_app(seconds)

    def push_file_to_device(self, device_filePath, local_filePath):
        """
        上传文件设备
        :param device_filePath:
        :param local_filePath:
        :return:
        """
        local_filePath = os.path.abspath(local_filePath)
        with open(local_filePath, 'rb') as f:
            data = base64.b64encode(f.read())
            f.close()
        self._driver.push_file(device_filePath, data)

    def pull_file_from_device(self, device_filePath, local_filePath):
        """
        从设备上下载文件
        :param device_filePath:
        :param local_filePath:
        :return:
        """
        local_filePath = os.path.abspath(local_filePath)
        data = self._driver.pull_file(device_filePath)
        with open(local_filePath, 'wb') as f:
            f.write(base64.b64decode(data))
            f.close()

    def shake_device(self):
        """
        仅支持IOS,详见https://github.com/appium/appium/blob/master/docs/en/commands/device/interactions/shake.md
        :return:
        """
        self._driver.shake()

    def lock_screen(self, seconds=None):
        self._driver.lock(seconds)

    def unlock_screen(self):
        self._driver.unlock()

    def press_keycode(self, keycode):
        """
        按键盘按键
        :param keycode: 键盘上每个按键的ascii
        :return:
        """
        self._driver.press_keycode(keycode)

    def long_press_keycode(self, keycode):
        """
        长按键盘按键
        :param keycode:
        :return:
        """
        self._driver.long_press_keycode(keycode)

    def hide_keyboard(self, key_name=None, key=None, strategy=None):
        """
        隐藏键盘,ios需要指定key_name或strategy,Android无需参数
       :param key_name:
        :param key:
        :param strategy:
        :return:
        """
        self._driver.hide_keyboard(key_name, key, strategy)

    def toggle_airplane_mode(self):
        """
        切换飞行模式(开启关闭),仅支持Android
        :return:
        """
        self._doRequest.post_with_form('/session/' + self._session_id +
                                       '/appium/device/toggle_airplane_mode')

    def toggle_data(self):
        """
        切换蜂窝数据模式(开启关闭),仅支持Android
        :return:
        """
        self._doRequest.post_with_form('/session/' + self._session_id +
                                       '/appium/device/toggle_data')

    def toggle_wifi(self):
        """
        切换wifi模式(开启关闭),仅支持Android
        :return:
        """
        self._doRequest.post_with_form('/session/' + self._session_id +
                                       '/appium/device/toggle_wifi')

    def toggle_location_services(self):
        """
        切换定位服务模式(开启关闭),仅支持Android
        :return:
        """
        self._driver.toggle_location_services()

    def get_performance_date(self,
                             data_type,
                             package_name=None,
                             data_read_timeout=10):
        """
        获得设备性能数据
        :param package_name:
        :param data_type: cpuinfo、batteryinfo、networkinfo、memoryinfo
        :param data_read_timeout:
        :return:
        """
        if data_type in self._performance_types:
            params = {}
            if not package_name:
                package_name = self.get_current_package()
            params.update({'packageName': package_name})
            params.update({'dataType': data_type})
            params.update({'dataReadTimeout': data_read_timeout})
            httpResponseResult = self._doRequest.post_with_form(
                '/session/' + self._session_id + '/appium/getPerformanceData',
                params=json.dumps(params))
            return httpResponseResult.body
        else:
            return None

    def start_recording_screen(self):
        """
        默认录制为3分钟,android最大只能3分钟,ios最大只能10分钟。如果录制产生的视频文件过大无法放到手机内存里会抛异常,所以尽量录制短视频
        :return:
        """
        self._driver.start_recording_screen(forcedRestart=True)

    def stop_recording_screen(self, fileName=''):
        """
        停止录像并将视频附加到报告里
        :param fileName:
        :return:
        """
        fileName = DateTimeTool.getNowTime('%Y%m%d%H%M%S%f_') + fileName
        data = self._driver.stop_recording_screen()
        allure.attach(name=fileName,
                      body=base64.b64decode(data),
                      attachment_type=allure.attachment_type.MP4)

    def get_device_time(self):
        """
        获得设备时间
        :return:
        """
        return self._driver.device_time

    def get_element_location(self, element):
        """
        获得元素在屏幕的位置,x、y坐标
        :param element:
        :return:
        """
        webElement = self._change_element_to_webElement_type(element)
        if webElement:
            return webElement.location

    def get_element_size_in_pixels(self, element):
        """
        返回元素的像素大小
        :param element:
        :return:
        """
        webElement = self._change_element_to_webElement_type(element)
        if webElement:
            return webElement.size

    def get_all_contexts(self):
        """
        获得能够自动化测所有上下文(混合应用中的原生应用和web应用)
        :return:
        """
        return self._driver.contexts

    def get_current_context(self):
        """
        获得当前appium中正在运行的上下文(混合应用中的原生应用和web应用)
        :return:
        """
        return self._driver.current_context

    def switch_context(self, context_name):
        """
        切换上下文(混合应用中的原生应用和web应用)
        :param context_name:
        :return:
        """
        context = {}
        context.update({'name': context_name})
        self._doRequest.post_with_form('/session/' + self._session_id +
                                       '/context',
                                       params=json.dumps(context))

    def mouse_move_to(self, element, xoffset=None, yoffset=None):
        """
        移动鼠标到指定位置(仅适用于Windows、mac)
        1、如果xoffset和yoffset都None,则鼠标移动到指定元素的正中间
        2、如果element、xoffset和yoffset都不为None,则根据元素的左上角做x和y的偏移移动鼠标
        :param element:
        :param xoffset:
        :param yoffset:
        :return:
        """
        webElement = self._change_element_to_webElement_type(element)
        if element:
            actions = ActionChains(self._driver)
            if xoffset and yoffset:
                actions.move_to_element_with_offset(webElement, xoffset,
                                                    yoffset)
            actions.move_to_element(webElement)
            actions.perform()

    def mouse_click(self):
        """
        点击鼠标当前位置(仅适用于Windows、mac)
        :return:
        """
        actions = ActionChains(self._driver)
        actions.click()
        actions.perform()

    def mouse_double_click(self):
        """
        双击鼠标当前位置(仅适用于Windows、mac)
        :return:
        """
        actions = ActionChains(self._driver)
        actions.double_click()
        actions.perform()

    def mouse_click_and_hold(self):
        """
        长按鼠标(仅适用于Windows、mac)
        :return:
        """
        actions = ActionChains(self._driver)
        actions.click_and_hold()
        actions.perform()

    def mouse_release_click_and_hold(self):
        """
        停止鼠标长按(仅适用于Windows、mac)
        :return:
        """
        actions = ActionChains(self._driver)
        actions.release()
        actions.perform()

    def touch_tap(self,
                  element,
                  xoffset=None,
                  yoffset=None,
                  count=1,
                  is_perfrom=True):
        """
        触屏点击
        1、如果xoffset和yoffset都None,则在指定元素的正中间进行点击
        2、如果element、xoffset和yoffset都不为None,则根据元素的左上角做x和y的偏移然后进行点击
        :param element:
        :param xoffset:
        :param yoffset:
        :param count: 点击次数
        :param is_perfrom 是否马上执行动作,不执行可以返回动作给多点触控执行
        :return:
        """
        webElement = self._change_element_to_webElement_type(element)
        if webElement:
            actions = TouchAction(self._driver)
            actions.tap(element, xoffset, yoffset, count)
            if is_perfrom:
                actions.perform()
            return actions

    def touch_long_press(self,
                         element,
                         xoffset=None,
                         yoffset=None,
                         duration_sconds=10,
                         is_perfrom=True):
        """
        触屏长按
        1、如果xoffset和yoffset都None,则在指定元素的正中间进行长按
        2、如果element、xoffset和yoffset都不为None,则根据元素的左上角做x和y的偏移然后进行长按
        :param element:
        :param xoffset:
        :param yoffset:
        :param duration_sconds: 长按秒数
        :param is_perfrom 是否马上执行动作,不执行可以返回动作给多点触控执行
        :return:
        """
        webElement = self._change_element_to_webElement_type(element)
        if webElement:
            actions = TouchAction(self._driver)
            actions.long_press(webElement, xoffset, yoffset,
                               duration_sconds * 1000)
            if is_perfrom:
                actions.perform()
            return actions

    def multi_touch_actions_perform(self, touch_actions):
        """
        多点触控执行
        :param touch_actions:
        :return:
        """
        multiActions = MultiAction(self._driver)
        for actions in touch_actions:
            multiActions.add(actions)
        multiActions.perform()

    def touch_slide(self,
                    start_element=None,
                    start_x=None,
                    start_y=None,
                    end_element=None,
                    end_x=None,
                    end_y=None,
                    duration=None):
        """
        滑动屏幕,在指定时间内从一个位置滑动到另外一个位置
        1、如果start_element不为None,则从元素的中间位置开始滑动
        2、如果end_element不为None,滑动结束到元素的中间位置
        :param start_element:
        :param end_element:
        :param start_x:
        :param start_y:
        :param end_x:
        :param end_y:
        :param duration: 毫秒
        :return:
        """
        start_webElement = self._change_element_to_webElement_type(
            start_element)
        end_webElement = self._change_element_to_webElement_type(end_element)
        if start_webElement:
            start_webElement_location = self.get_element_location(
                start_webElement)
            start_x = start_webElement_location['x']
            start_y = start_webElement_location['y']
        if end_webElement:
            end_webElement_location = self.get_element_location(end_webElement)
            end_x = end_webElement_location['x']
            end_y = end_webElement_location['y']
        self._driver.swipe(start_x, start_y, end_x, end_y, duration)

    def touch_left_slide(self, duration=500):
        """
        从屏幕正中间进行左滑
        :return:
        """
        start_x = self._windows_size['width'] * 0.45
        start_y = self._windows_size['height'] * 0.45
        end_x = 0
        end_y = start_y
        self._driver.swipe(start_x, start_y, end_x, end_y, duration)

    def touch_right_slide(self, duration=500):
        """
        从屏幕正中间进行右滑
        :return:
        """
        start_x = self._windows_size['width'] * 0.45
        start_y = self._windows_size['height'] * 0.45
        end_x = self._windows_size['width'] * 0.9
        end_y = start_y
        self._driver.swipe(start_x, start_y, end_x, end_y, duration)

    def touch_up_slide(self, duration=500):
        """
        从屏幕正中间进行上滑
        :return:
        """
        start_x = self._windows_size['width'] * 0.45
        start_y = self._windows_size['height'] * 0.45
        end_x = start_x
        end_y = 0
        self._driver.swipe(start_x, start_y, end_x, end_y, duration)

    def touch_down_slide(self, duration=500):
        """
        从屏幕正中间进行下滑
        :return:
        """
        start_x = self._windows_size['width'] * 0.45
        start_y = self._windows_size['height'] * 0.45
        end_x = start_x
        end_y = self._windows_size['height'] * 0.9
        self._driver.swipe(start_x, start_y, end_x, end_y, duration)

    def getElement(self, elementInfo):
        """
        定位单个元素
        :param elementInfo:
        :return:
        """
        webElement = None
        locator_type = elementInfo.locator_type
        locator_value = elementInfo.locator_value
        wait_type = elementInfo.wait_type
        wait_seconds = elementInfo.wait_seconds
        wait_expected_value = elementInfo.wait_expected_value
        if wait_expected_value:
            wait_expected_value = wait_expected_value

        # 查找元素,为了保证元素被定位,都进行显式等待
        if wait_type == Wait_By.TITLE_IS:
            webElement = WebDriverWait(self._driver, wait_seconds).until(
                expected_conditions.title_is(wait_expected_value))
        elif wait_type == Wait_By.TITLE_CONTAINS:
            webElement = WebDriverWait(self._driver, wait_seconds).until(
                expected_conditions.title_contains(wait_expected_value))
        elif wait_type == Wait_By.PRESENCE_OF_ELEMENT_LOCATED:
            webElement = WebDriverWait(self._driver, wait_seconds).until(
                expected_conditions.presence_of_element_located(
                    (locator_type, locator_value)))
        elif wait_type == Wait_By.ELEMENT_TO_BE_CLICKABLE:
            webElement = WebDriverWait(self._driver, wait_seconds).until(
                expected_conditions.element_to_be_clickable(
                    (locator_type, locator_value)))
        elif wait_type == Wait_By.ELEMENT_LOCATED_TO_BE_SELECTED:
            webElement = WebDriverWait(self._driver, wait_seconds).until(
                expected_conditions.element_located_to_be_selected(
                    (locator_type, locator_value)))
        elif wait_type == Wait_By.VISIBILITY_OF:
            webElements = WebDriverWait(self._driver, wait_seconds).until(
                (expected_conditions.visibility_of_all_elements_located(
                    (locator_type, locator_value))))
            if len(webElements) > 0:
                webElement = webElements[0]
        else:
            if locator_type == By.ID:
                webElement = WebDriverWait(self._driver, wait_seconds).until(
                    lambda driver: driver.find_element_by_id(locator_value))
            elif locator_type == By.NAME:
                webElement = WebDriverWait(self._driver, wait_seconds).until(
                    lambda driver: driver.find_element_by_name(locator_value))
            elif locator_type == By.LINK_TEXT:
                webElement = WebDriverWait(self._driver, wait_seconds).until(
                    lambda driver: driver.find_element_by_link_text(
                        locator_value))
            elif locator_type == By.XPATH:
                webElement = WebDriverWait(self._driver, wait_seconds).until(
                    lambda driver: driver.find_element_by_xpath(locator_value))
            elif locator_type == By.PARTIAL_LINK_TEXT:
                webElement = WebDriverWait(self._driver, wait_seconds).until(
                    lambda driver: driver.find_element_by_partial_link_text(
                        locator_value))
            elif locator_type == By.CSS_SELECTOR:
                webElement = WebDriverWait(self._driver, wait_seconds).until(
                    lambda driver: driver.find_element_by_css_selector(
                        locator_value))
            elif locator_type == By.CLASS_NAME:
                webElement = WebDriverWait(self._driver, wait_seconds).until(
                    lambda driver: driver.find_element_by_class_name(
                        locator_value))
            elif locator_type == By.TAG_NAME:
                webElement = WebDriverWait(self._driver, wait_seconds).until(
                    lambda driver: driver.find_element_by_tag_name(
                        locator_value))
            elif locator_type == Locator_Type.ACCESSIBILITY_ID:
                webElement = WebDriverWait(self._driver, wait_seconds).until(
                    lambda driver: driver.find_element_by_accessibility_id(
                        locator_value))
            elif locator_type == Locator_Type.IMAGE:
                webElement = WebDriverWait(self._driver, wait_seconds).until(
                    lambda driver: driver.find_element_by_image(locator_type))
        return webElement

    def getElements(self, elementInfo):
        """
        定位多个元素
        :param elementInfo:
        :return:
        """
        webElements = None
        locator_type = elementInfo.locator_type
        locator_value = elementInfo.locator_value
        wait_type = elementInfo.wait_type
        wait_seconds = elementInfo.wait_seconds

        # 查找元素,为了保证元素被定位,都进行显式等待
        if wait_type == Wait_By.PRESENCE_OF_ELEMENT_LOCATED:
            webElements = WebDriverWait(self._driver, wait_seconds).until(
                expected_conditions.presence_of_all_elements_located(
                    (locator_type, locator_value)))
        elif wait_type == Wait_By.VISIBILITY_OF:
            webElements = WebDriverWait(self._driver, wait_seconds).until(
                expected_conditions.visibility_of_all_elements_located(
                    (locator_type, locator_value)))
        else:
            if locator_type == By.ID:
                webElements = WebDriverWait(self._driver, wait_seconds).until(
                    lambda driver: driver.find_elements_by_id(locator_value))
            elif locator_type == By.NAME:
                webElements = WebDriverWait(self._driver, wait_seconds).until(
                    lambda driver: driver.find_elements_by_name(locator_value))
            elif locator_type == By.LINK_TEXT:
                webElements = WebDriverWait(self._driver, wait_seconds).until(
                    lambda driver: driver.find_elements_by_link_text(
                        locator_value))
            elif locator_type == By.XPATH:
                webElements = WebDriverWait(
                    self._driver,
                    wait_seconds).until(lambda driver: driver.
                                        find_elements_by_xpath(locator_value))
            elif locator_type == By.PARTIAL_LINK_TEXT:
                webElements = WebDriverWait(self._driver, wait_seconds).until(
                    lambda driver: driver.find_elements_by_partial_link_text(
                        locator_value))
            elif locator_type == By.CSS_SELECTOR:
                webElements = WebDriverWait(self._driver, wait_seconds).until(
                    lambda driver: driver.find_elements_by_css_selector(
                        locator_value))
            elif locator_type == By.CLASS_NAME:
                webElements = WebDriverWait(self._driver, wait_seconds).until(
                    lambda driver: driver.find_elements_by_class_name(
                        locator_value))
            elif locator_type == By.TAG_NAME:
                webElements = WebDriverWait(self._driver, wait_seconds).until(
                    lambda driver: driver.find_elements_by_tag_name(
                        locator_value))
            elif locator_type == Locator_Type.ACCESSIBILITY_ID:
                webElements = WebDriverWait(self._driver, wait_seconds).until(
                    lambda driver: driver.find_elements_by_accessibility_id(
                        locator_value))
            elif locator_type == Locator_Type.IMAGE:
                webElements = WebDriverWait(self._driver, wait_seconds).until(
                    lambda driver: driver.find_elements_by_image(locator_type))
        return webElements

    def getSubElement(self, parent_element, sub_elementInfo):
        """
        获得元素的单个子元素
        :param parent_element: 父元素
        :param sub_elementInfo: 子元素,只能提供pojo.elementInfo.ElementInfo类型
        :return:
        """
        webElement = self._change_element_to_webElement_type(parent_element)
        if not webElement:
            return None
        if not isinstance(sub_elementInfo, ElementInfo):
            return None

        # 通过父元素查找子元素
        locator_type = sub_elementInfo.locator_type
        locator_value = sub_elementInfo.locator_value
        wait_seconds = sub_elementInfo.wait_seconds

        # 查找元素,为了保证元素被定位,都进行显式等待
        if locator_type == By.ID:
            subWebElement = WebDriverWait(
                webElement,
                wait_seconds).until(lambda webElement: webElement.
                                    find_element_by_id(locator_value))
        elif locator_type == By.NAME:
            subWebElement = WebDriverWait(
                webElement,
                wait_seconds).until(lambda webElement: webElement.
                                    find_element_by_name(locator_value))
        elif locator_type == By.LINK_TEXT:
            subWebElement = WebDriverWait(
                webElement,
                wait_seconds).until(lambda webElement: webElement.
                                    find_element_by_link_text(locator_value))
        elif locator_type == By.XPATH:
            subWebElement = WebDriverWait(
                webElement,
                wait_seconds).until(lambda webElement: webElement.
                                    find_element_by_xpath(locator_value))
        elif locator_type == By.PARTIAL_LINK_TEXT:
            subWebElement = WebDriverWait(webElement, wait_seconds).until(
                lambda webElement: webElement.
                find_element_by_partial_link_text(locator_value))
        elif locator_type == By.CSS_SELECTOR:
            subWebElement = WebDriverWait(webElement, wait_seconds).until(
                lambda webElement: webElement.find_element_by_css_selector(
                    locator_value))
        elif locator_type == By.CLASS_NAME:
            subWebElement = WebDriverWait(
                webElement,
                wait_seconds).until(lambda webElement: webElement.
                                    find_element_by_class_name(locator_value))
        elif locator_type == By.TAG_NAME:
            subWebElement = WebDriverWait(
                webElement,
                wait_seconds).until(lambda webElement: webElement.
                                    find_element_by_tag_name(locator_value))
        elif locator_type == Locator_Type.ACCESSIBILITY_ID:
            subWebElement = WebDriverWait(webElement, wait_seconds).until(
                lambda webElement: webElement.find_element_by_accessibility_id(
                    locator_value))
        elif locator_type == Locator_Type.IMAGE:
            subWebElement = WebDriverWait(
                webElement,
                wait_seconds).until(lambda webElement: webElement.
                                    find_element_by_image(locator_type))
        else:
            return None
        return subWebElement

    def getSubElements(self, parent_element, sub_elementInfo):
        """
        获得元素的多个子元素
        :param parent_element: 父元素
        :param sub_elementInfo: 子元素,只能提供pojo.elementInfo.ElementInfo类型
        :return:
        """
        webElement = self._change_element_to_webElement_type(parent_element)
        if not webElement:
            return None
        if not isinstance(sub_elementInfo, ElementInfo):
            return None

        # 通过父元素查找多个子元素
        locator_type = sub_elementInfo.locator_type
        locator_value = sub_elementInfo.locator_value
        wait_seconds = sub_elementInfo.wait_seconds

        # 查找元素,为了保证元素被定位,都进行显式等待
        if locator_type == By.ID:
            subWebElements = WebDriverWait(
                webElement,
                wait_seconds).until(lambda webElement: webElement.
                                    find_elements_by_id(locator_value))
        elif locator_type == By.NAME:
            subWebElements = WebDriverWait(
                webElement,
                wait_seconds).until(lambda webElement: webElement.
                                    find_elements_by_name(locator_value))
        elif locator_type == By.LINK_TEXT:
            subWebElements = WebDriverWait(
                webElement,
                wait_seconds).until(lambda webElement: webElement.
                                    find_elements_by_link_text(locator_value))
        elif locator_type == By.XPATH:
            subWebElements = WebDriverWait(
                webElement,
                wait_seconds).until(lambda webElement: webElement.
                                    find_elements_by_xpath(locator_value))
        elif locator_type == By.PARTIAL_LINK_TEXT:
            subWebElements = WebDriverWait(webElement, wait_seconds).until(
                lambda webElement: webElement.
                find_elements_by_partial_link_text(locator_value))
        elif locator_type == By.CSS_SELECTOR:
            subWebElements = WebDriverWait(webElement, wait_seconds).until(
                lambda webElement: webElement.find_elements_by_css_selector(
                    locator_value))
        elif locator_type == By.CLASS_NAME:
            subWebElements = WebDriverWait(
                webElement,
                wait_seconds).until(lambda webElement: webElement.
                                    find_elements_by_class_name(locator_value))
        elif locator_type == By.TAG_NAME:
            subWebElements = WebDriverWait(
                webElement,
                wait_seconds).until(lambda webElement: webElement.
                                    find_elements_by_tag_name(locator_value))
        elif locator_type == Locator_Type.ACCESSIBILITY_ID:
            subWebElements = WebDriverWait(webElement, wait_seconds).until(
                lambda webElement: webElement.
                find_elements_by_accessibility_id(locator_value))
        elif locator_type == Locator_Type.IMAGE:
            subWebElements = WebDriverWait(
                webElement,
                wait_seconds).until(lambda webElement: webElement.
                                    find_elements_by_image(locator_type))
        else:
            return None
        return subWebElements

    def explicit_wait_page_title(self, elementInfo):
        """
        仅适用于web
        显式等待页面title
        :param elementInfo:
        :return:
        """
        self.getElement(elementInfo)

    def getDriver(self):
        return self._driver
示例#25
0
def start_app_device_test(index,device_info,keyword,dir,markexpr,capture,reruns,lf):
    for path, dirs, files in os.walk('config/app_ui_tmp'):
        for file in files:
            if(int(file)==index):
                os.rename(os.path.join(path,file),os.path.join(path,str(os.getpid())))

    print('开始检测appium server是否可用......')
    try:
        doRquest = DoRequest('http://'+device_info['server_ip']+':%s/wd/hub'%device_info['server_port'].strip())
        httpResponseResult = doRquest.get('/status')
        result = ujson.loads(httpResponseResult.body)
        if result['status'] == 0:
            print('appium server状态为可用......')
        else:
            sys.exit('appium server状态为不可用')
    except:
        sys.exit('appium server状态为不可用')

    a_devices_desired_capabilities = device_info['capabilities']
    print('开始设备' + device_info['device_desc'] + '测试......')
    for desired_capabilities in a_devices_desired_capabilities:
        FileTool.writeObjectIntoFile(desired_capabilities,
                                     'config/app_ui_tmp/' + str(os.getpid()) + '_current_desired_capabilities')
        if desired_capabilities['appPackage']:
            desired_capabilities_desc = desired_capabilities['appPackage']
        else:
            desired_capabilities_desc = os.path.basename(desired_capabilities['app'])
        print('当前设备开始测试的desired_capabilities为:%s' % desired_capabilities)
        # 执行pytest前的参数准备
        pytest_execute_params = ['-c', 'config/pytest.ini', '-v', '--alluredir',
                                 'output/app_ui/' + device_info['device_desc'] + '/' + desired_capabilities_desc]
        # 判断目录参数
        if not dir:
            dir = 'cases/app_ui/'
        # 判断关键字参数
        if keyword:
            pytest_execute_params.append('-k')
            pytest_execute_params.append(keyword)
        # 判断markexpr参数
        if markexpr:
            pytest_execute_params.append('-m')
            pytest_execute_params.append(markexpr)
        # 判断是否输出日志
        if capture:
            if int(capture):
                pytest_execute_params.append('-s')
        # 判断是否失败重跑
        if reruns:
            if int(reruns):
                pytest_execute_params.append('--reruns')
                pytest_execute_params.append(reruns)
        # 判断是否只运行上一次失败的用例
        if lf:
            if int(lf):
                pytest_execute_params.append('--lf')
        pytest_execute_params.append(dir)
        # 构建孙进程
        process = multiprocessing.Process(target=pytest_main, args=(pytest_execute_params,))
        process.start()
        process.join()
        print('当前设备结束测试的desired_capabilities为:%s' % desired_capabilities)
    print('结束设备' + device_info['device_desc'] + '测试......')
示例#26
0
import jpype
import json
import pytest
import sys

if __name__=='__main__':
    parser=argparse.ArgumentParser()
    parser.add_argument('-k','--keyword',help='只执行匹配关键字的用例,会匹配文件名、类名、方法名',type=str)
    parser.add_argument('-d','--dir',help='指定要测试的目录',type=str)
    parser.add_argument('-s', '--capture', help='是否在标准输出流中输出日志,1:是、0:否')
    args=parser.parse_args()

    print('开始初始化......')
    print('开始检测appium server是否可用......')
    try:
        doRquest=DoRequest(Read_APP_UI_Config().app_ui_config.appium_hub)

        httpResponseResult=doRquest.get('/status')
        result=json.loads(httpResponseResult.body)
        if result['status']==0:
            print('appium server状态为可用......')
        else:
            sys.exit('appium server状态为不可用')
    except:
        sys.exit('appium server状态为不可用')

    print('启动jvm......')
    jpype.startJVM(jpype.get_default_jvm_path(),"-ea","-Djava.class.path="+JavaTool.getAllJar())
    print('启动jvm成功')

    java_maven_init()
示例#27
0
class Disconf_Client:
    def __init__(self,
                 url: str,
                 username: str,
                 password: str,
                 is_verify_ssl_cer=True):
        self.url = url
        self.username = username
        self.password = password
        self.doRequest = DoRequest(self.url)
        self.doRequest.setVerify(is_verify_ssl_cer)
        self._login()

    def _login(self):
        params = {
            'name': 'admin_test',
            'password': '******',
            'remember': '1'
        }
        httpResponseResult = self.doRequest.post_with_form(
            '/api/account/signin', params)
        return ujson.loads(httpResponseResult.body)

    def get_app_list(self):
        httpResponseResult = self.doRequest.get('/api/app/list')
        app_list = ujson.loads(httpResponseResult.body)
        app_list = app_list['page']['result']
        return app_list

    def get_app_id(self, app_name: str):
        app_list = self.get_app_list()
        for app_info in app_list:
            if app_info['name'] == app_name:
                return app_info['id']

    def get_env_list(self):
        httpResponseResult = self.doRequest.get('/api/env/list')
        env_list = ujson.loads(httpResponseResult.body)
        env_list = env_list['page']['result']
        return env_list

    def get_env_id(self, env_name: str):
        env_list = self.get_env_list()
        for env_info in env_list:
            if env_info['name'] == env_name:
                return env_info['id']

    def get_version_list(self, app_id: int, env_id: int):
        params = {'appId': app_id, 'envid': env_id}
        httpResponseResult = self.doRequest.get('/api/web/config/versionlist',
                                                params)
        version_list = ujson.loads(httpResponseResult.body)
        version_list = version_list['page']['result']
        return version_list

    def get_config_list(self,
                        app_id: int,
                        env_id: int,
                        version: str,
                        pageSize: int = 50,
                        pageNo: int = 1):
        params = {
            'appId': app_id,
            'envId': env_id,
            'version': version,
            "page.pageSize": pageSize,
            "page.pageNo": pageNo
        }
        httpResponseResult = self.doRequest.get('/api/web/config/list', params)
        config_list = ujson.loads(httpResponseResult.body)
        config_list = config_list['page']['result']
        return config_list

    def get_config_id(self, app_name: str, env_name: str, version: str,
                      config_name: str):
        now_page = 1
        # 最多从500个文件获取
        while (not now_page > 10):
            config_list = self.get_config_list(self.get_app_id(app_name),
                                               self.get_env_id(env_name),
                                               version,
                                               pageSize=50,
                                               pageNo=now_page)
            for config_info in config_list:
                if config_info['key'] == config_name:
                    return config_info['configId']
            now_page += 1

    def get_config_info(self, config_id: int):
        httpResponseResult = self.doRequest.get('/api/web/config/%s' %
                                                config_id)
        config_info = ujson.loads(httpResponseResult.body)
        config_info = config_info['result']['value']
        return config_info

    def update_config_info(self, config_id: int, content: str):
        params = {'fileContent': content}
        httpResponseResult = self.doRequest.put(
            '/api/web/config/filetext/%s' % config_id, params)
        config_info = ujson.loads(httpResponseResult.body)
        return config_info