Ejemplo n.º 1
0
    def start_activity(self, app_activity, **opts):
        message='start_activity:    '+app_activity
        log.info(message)
        self.driver.start_activity(self.env.appium.get("appPackage"), app_activity, **opts)

        self.driver.wait_activity(app_activity, 10, interval=0.3)
        return self
Ejemplo n.º 2
0
 def home(self, action: ElementActions):
     action.driver.wait_activity(self.activity, 8, interval=0.3)
     try:
         action.click(self.关闭初始化弹出窗, wait=3)
     except:
         log.info('无弹窗需要关闭,所以不会找到元素 关闭初始化弹出窗')
     action.tap(self.关闭初始化浮窗)
Ejemplo n.º 3
0
    def generate_report(self):

        #给报告中添加执行环境信息
        env_dict={}

        env=self.env.conf

        #修改把yaml格式改成对应的键值对
        devices=env.get('devices')
        env.pop('devices')
        new_env=dict(env, **devices)

        env_dict.update(new_env)
        env_dict.update(self.conf.info)


        env_properties = {}

        for key0,value0 in env_dict.items():
            for key,value in value0.items():
                env_properties['{}.{}'.format(key0,key)]=str(value)

        try:
            with open( self.properties_path,'w',encoding='utf-8') as fp:
                jprops.store_properties(fp, env_properties)
        except:
            log.error('配置环境未输出到报告中')

        #执行生成报告命令
        cmd = 'allure generate %s -o %s --clean' % (self.xml_report_path, self.html_report_path)
        try:
            Shell.invoke(cmd)
            log.info("测试报告成功生成")
        except:
            log.error("Html测试报告生成失败,确保已经安装了Allure-Commandline")
Ejemplo n.º 4
0
def check_page(Pages,action: ElementActions):

    #只能检测静态页面,即有固定进入方法的:pageinto

    pagesname_list=get_attrsname(Pages)

    for page_name in pagesname_list:
        page=getattr(Pages,page_name)


        #如果为静态页面时可通过page的跳转方法进入对应页面
        if hasattr(page,'pageinto')==False:
            continue
        else:
            log.info(' ----检测静态页面: {}----'.format(page_name))
            elements_name = get_attrsname(page)
            getattr(page,'pageinto')(action)

            # 对元素进行遍历查询
            for element_name in elements_name:
                element=getattr(page,element_name)
                if isinstance(element,dict):
                    if element.get('dynamic')==False:
                        if element.get('switch')!=None:
                            #如果该元素在当前页面有前置步骤,则执行该前置步骤
                            getattr(page,element.get('switch'))(action)

                        action.is_element_exist(locator=element)
Ejemplo n.º 5
0
    def find_ele_child_byelement(self, element_parent, locator_child, is_Multiple=False, wait=6):
        #通过父结点元素查找子结点元素,不支持name定位方式

        if locator_child['type'] == 'name':
            log.error('find_ele_child_byelement的定位方式错误')
            raise NotFoundElementError

        value_child, type_child = locator_child['value'], locator_child['type']
        try:
            WebDriverWait(self.driver, wait).until(
                lambda driver: element_parent.find_element(type_child, value_child))

            log.info(
                "页面【{}】的元素【{}】成功查询到查找子节点 元素【{}】"
                    .format(locator_child.get("page"), element_parent,
                            locator_child.get('name')))

            if is_Multiple == False:
                return element_parent.find_element(type_child, value_child)
            else:
                return element_parent.find_elements(type_child, value_child)
        except:
            log.info(
                "页面【{}】的元素【{}】未能查询到查找子节点 元素【{}】\n locator_child{}"
                    .format(locator_child.get("page"), element_parent,
                            locator_child.get('name'), locator_child))

            if is_Multiple == False:
                return None
            else:
                return []
Ejemplo n.º 6
0
    def is_text_displayed(self, text, retry_time=0, is_raise=False):
        """检查页面中是否有文本关键字

        如果希望检查失败的话,不再继续执行case,使用 is_raise = True

        Args:
            text: 关键字(请确保想要的检查的关键字唯一)
            is_retry: 是否重试,默认为true
            retry_time: 重试次数,默认为5
            is_raise: 是否抛异常
        Returns:
            True: 存在关键字
        Raises:
            如果is_raise = true,可能会抛NotFoundElementError

        """

        try:
            if retry_time!=0:
                result= WebDriverWait(self.driver, retry_time).until(
                    lambda driver: self._find_text_in_page(text))
            else:
                result=self._find_text_in_page(text)
            if result == True:
                log.info("[Text]页面中找到了 %s 文本" % text)
            return result
        except TimeoutException:
            log.error("[Text]页面中未找到 %s 文本" % text)
            if is_raise:
                raise NotFoundTextError
            else:
                return False
Ejemplo n.º 7
0
    def _batch_exec_pytest(platform,current_device,testsuite_paths):
        # 通过多进程调度执行用例(多台设备)
        #testsuite_paths 为list ,格式为[tests/test_suit2,tests/test_suit3]

        log.info('Run task pid={}  testsuite_paths: {}...'.format(os.getpid(), testsuite_paths))

        #清除log对象已有的handler
        for handle in log.handlers:
            log.removeHandler(handle)

        # 定义handler的输出格式
        formatter = logging.Formatter('pid:{} %(levelname)s %(message)s'.format(os.getpid()), "%H:%M:%S")

        #添加用于输出到控制台的handler
        console_handler=Logbuilder().get_consolehandler(formatter)

        log.addHandler(console_handler)


        run=Run(platform)

        #当前进程的环境对象通过回调写入current_device
        run.env.callback_current_device(current_device)

        #导入参数执行pytest
        args=testsuite_paths+run.get_run_args()

        pytest.main(args)
Ejemplo n.º 8
0
def driverenv():


    env=EnvironmentAndroid()
    current_device=env.current_device

    capabilities = {
                    'platformName': current_device.get("platformName"),
                    'platformVersion': current_device.get("platformVersion"),
                    'deviceName': current_device.get("deviceName"),
                    'udid': current_device.get("deviceName"),
                    'systemPort':current_device.get('systemPort'),
                    'app': env.appium.get("app"),
                    'clearSystemFiles': True,
                    'appActivity': env.appium.get("appActivity"),
                    'appPackage': env.appium.get("appPackage"),
                    'automationName': 'UIAutomator2',
                    'noSign': True,
                    'recreateChromeDriverSessions': True,
                    "unicodeKeyboard": True,
                    "noReset":True,
                    "fullReset":False,
                    "newCommandTimeout": 300
                    }
    # systemPort=current_device.get('systemPort')
    # if systemPort!=None:
    #     capabilities['systemPort']=systemPort
    #
    log.info('当前执行的appium相关配置为:'+str(capabilities))

    host=current_device.get('appiumserver')

    driver = webdriver.Remote(host, capabilities)

    return driver
Ejemplo n.º 9
0
 def pageinto(self, action: ElementActions):
     action.sleep(0.5).start_activity(self.activity)
     usercenterpage = UserCenterPage()
     # usercenterpage.pageinto(action)
     if action.find_ele(usercenterpage.注册登陆) != None:
         action.click(usercenterpage.注册登陆)
     else:
         log.info('app已是登陆状态,无法进入登陆页')
Ejemplo n.º 10
0
def check_pageset(Pagesset,action: ElementActions):
    #参数Pagesset为元素是Pages的list

    for Pages in Pagesset:

        log.info('\n ++++++检测静态页面集: {}++++++\n'.format(Pages.__name__))

        check_page(Pages,action)
Ejemplo n.º 11
0
    def is_element_exist(self, locator,wait=2):
        """检查元素是否存在"""

        if self._find_element(locator,is_raise=False,wait=wait)==None:
            log.error("没有查找到  页面【{}】的元素【{}】".format(locator.get("page"),locator.get("name")))
            return False
        else:
            log.info("已查找到  页面【{}】的元素【{}】".format(locator.get("page"),locator.get("name")))
            return True
Ejemplo n.º 12
0
    def swip_right(self,count=1):
        """
            向右滑
        """

        for x in range(count):
            self.driver.swipe(self.width / 10, self.height / 2, self.width * 9/ 10, self.height / 2, 1000)
        log.info("----------向右滑动----------")
        return self
Ejemplo n.º 13
0
    def swip_up(self, count=1):
        """向上滑动,常用于下拉刷新

        Args:
            count: 滑动次数
        """

        for x in range(count):
            self.driver.swipe(self.width / 2, self.height *1 / 10, self.width / 2, self.height * 9 / 10, 1000)

        log.info("----------向上滑动---------")
        return self
Ejemplo n.º 14
0
    def swip_left(self, count=1):
        """向左滑动,一般用于ViewPager

        Args:
            count: 滑动次数

        """

        for x in range(count):
            self.driver.swipe(self.width * 9 / 10, self.height / 2, self.width / 10, self.height / 2, 1000)
        log.info("----------向左滑动----------")
        return self
Ejemplo n.º 15
0
    def get_conf(self):

        environment_info_path = str(
            os.path.abspath(
                os.path.join(os.path.dirname(__file__), os.pardir,
                             "data/config_android.yaml")))

        log.info('获取环境配置 Path:' + environment_info_path)
        with open(environment_info_path, "r") as f:
            conf = yaml.load(f)

        return conf
Ejemplo n.º 16
0
    def _find_text_in_page(self, text):
        """检查页面中是否有文本关键字
        拿到页面全部source,暴力检查text是否在source中
        Args:
            text: 检查的文本

        Returns:
            True : 存在

        """
        log.info("[查找] 文本 %s " % text)

        return text in self.driver.page_source
Ejemplo n.º 17
0
    def swip_down(self, count=1,half=False):
        """向下滑动,常用于下拉刷新

        Args:
            count: 滑动次数
            half:是否为滑动一半
        """
        for x in range(count):
            if half==False:
                self.driver.swipe(self.width / 2, self.height * 9 / 10, self.width / 2, self.height * 1 / 10, 1000)
            else:
                self.driver.swipe(self.width / 2, self.height * 3 / 5, self.width / 2, self.height * 1 / 5, 1000)
        log.info("---------向下滑动----------")
        return self
Ejemplo n.º 18
0
    def _scheduling_process(self):
        #给多台设备分配测试任务的调度算法(简单平均调度)
        #其中suit1是文件夹的名字、device1是配置中device设备的key

        """
        :return:
        {
        device1:[suit1,suit2]
        device2:[suit3,suit4]
        device3:[suit5]
        }

        """

        tests_path=self.env.path.get('tests')
        suitname_list=ls_by_key(tests_path,'test')


        if len(suitname_list)==0 or len(self.devices)==0:
            raise IndexError('data is bad')

        task_num,mod =divmod(len(suitname_list),len(self.devices))

        suitname_list_slice=[]
        tmp=[]
        count=0
        for suitname in suitname_list:
            tmp.append(suitname)
            if count<(len(suitname_list)-mod):
                if len(tmp)==task_num:
                    suitname_list_slice.append(tmp)
                    tmp=[]
            count+=1

        #对最后一个加入整除后剩余的
        last_ele=suitname_list_slice[-1]
        suitname_list_slice[-1]=last_ele+tmp


        scheduling_info={}
        count=0
        for device_key in self.devices:
            scheduling_info[device_key]=suitname_list_slice[count]
            count=count+1

        log.info("多设备分配的测试集执行为: {}\n".format(str(scheduling_info)))


        return scheduling_info
Ejemplo n.º 19
0
    def click(self, locator, count=1,wait=5):
        """基础的点击事件

        Args:
            locator:定位器
            count: 点击次数
        """
        msg="[点击]  页面【{}】的元素【{}】".format(locator.get("page"),locator.get("name"))
        log.info(msg)

        element = self._find_element(locator,wait=wait)

        self.click_ele(element,count,is_log=False)

        return self
Ejemplo n.º 20
0
 def invoke(cmd, cwd=None, is_log=True):
     # shell设为true,程序将通过shell来执行
     # stdin, stdout, stderr分别表示程序的标准输入、输出、错误句柄。
     # 他们可以是PIPE,文件描述符或文件对象,也可以设置为None,表示从父进程继承。
     # subprocess.PIPE实际上为文本流提供一个缓存区
     if is_log == True:
         log.info("执行命令: {}".format(cmd))
     p = subprocess.Popen(cmd,
                          shell=True,
                          stdout=subprocess.PIPE,
                          stderr=subprocess.PIPE,
                          cwd=cwd)
     output, errors = p.communicate()
     o = output.decode("utf-8")
     return o
Ejemplo n.º 21
0
    def find_ele(self,locator,is_Multiple=False,wait = 5):
        #通过定位器查找元素,不用于断言(断言元素存在用 is_element_exist ,断言页面是否含有对应文本关键字的请用is_text_displayed)
        #需要查找多个时,返回list
        #没有查找到时,返回None 或 []

        """
               Args:
                   locator:  定位器对象
                   is_Multiple: 是否查找多个
        """


        log.info("查找 页面【{}】的元素【{}】".format(locator.get("page"), locator.get("name")))
        if is_Multiple==False:
            return self._find_element(locator,is_raise=False,wait=wait)
        else:
            return self._find_elements(locator,is_raise=False,wait=wait)
Ejemplo n.º 22
0
    def get_text(self, locator):
        """获取元素中的text文本
        查找到单个元素,返回文本字符串

        Args:
            locator:定位器
            count: 点击次数

        Returns:
            如果没有该控件返回None

        Examples:
            TextView 是否显示某内容
        """
        element = self._find_element(locator,wait=1)
        log.info("获取元素中的text文本\n locator: \n{}".format(locator))
        return self.get_text_ele(element)
Ejemplo n.º 23
0
    def tap(self,locator):
        #获取当前屏幕的分辨率,元素通过相对位置点击
        """

        :param locator: value格式为 "x,y"
        :return:
        """
        if locator.get('type')!="tap":
            log.error('定位方式错误,不能通过坐标位置定位点击 \nlocator: {}'.format(str(locator)))
        else:
            position=locator.get('value').split(',')
            x=int(position[0])*self.width/1080
            y=int(position[1])*self.height/1920
            positions=[(x,y)]
            log.info("通过坐标({},{}), 成功点击 页面【{}】的元素【{}】".format(x,y,locator.get('page'),locator.get('name')))

            self.driver.tap(positions,duration=400)
Ejemplo n.º 24
0
    def text(self, locator, value, clear_first=False, click_first=True):
        """输入文本

        Args:
            locator: 定位器
            value: 文本内容
            clear_first: 是否先清空原来文本
            click_first: 是否先点击选中
        Raises:
            NotFoundElementError

        """
        element=self._find_element(locator)
        log.info("在【{}】页面 对元素【{}】输入文本【{}】".format(locator.get("page"), locator.get("name"), value))

        self.text_ele(element,value,clear_first, click_first)

        return self
Ejemplo n.º 25
0
    def test_case1(self, action):
        count = 5
        action.click(p.特卖首页.发布)

        for index in range(count):
            action.click(p.特卖首页.发布_上传视频)
            videoele = action.find_ele(vp.视频发布页.视频选择, is_Multiple=True)[0]
            action.click_ele(videoele)

            action.click(vp.视频发布页.视频选择后下一步).click(vp.视频发布页.视频处理后下一步)

            action.sleep(8).click(vp.视频发布页.视频发布, wait=15)

            result = action.is_toast_show('视频发布成功', wait=20)
            log.info('result: {}'.format(result))
            action.get_img('上传后截图')

            action.back_press()
Ejemplo n.º 26
0
    def long_press(self,locator,time=2000):
        #长按操作,locator的type为tap时支持坐标位置长按
        """
        :param locator:
        :param time: 单位毫秒
        :return:
        """
        if locator.get('type')=="tap":
            position = locator.get('value').split(',')
            x = int(position[0]) * self.width / 1080
            y = int(position[1]) * self.height / 1920
            TouchAction(self.driver).long_press(x=x,y=y,duration=time).perform()

        else:
            ele=self._find_element(locator)
            TouchAction(self.driver).long_press(el=ele, duration=time).perform()

        log.info("[长按] 页面【{}】的元素【{}】".format(locator.get('page'), locator.get('name')))
Ejemplo n.º 27
0
    def find_ele_fromparent(self,locator_tmp,locator_target,is_Multiple=False,wait=5):
        #通过uiautomator查找定位元素的兄弟节点元素,不支持xpath,且兄弟节点必须同级
        """
        支持的定位方式有:text(name),description(特有的),id,class name
        """

        log.info("页面【{}】通过元素【{}】查找兄弟元素【{}】".format(locator_tmp.get("page"), locator_tmp.get('name'), locator_target.get("name")))

        map={
            "name":"textContains",
            "description":"descriptionContains",
            "id":"resourceId",
            "class name":"className"
        }
        type_tmp=map.get(locator_tmp["type"])
        type_target=map.get(locator_target["type"])

        if type_tmp==None or type_target==None:
            log.error('当前定位方式不支持')
            raise NotFoundElementError

        value_tmp=locator_tmp["value"]
        value_target =locator_target["value"]


        ui_value='new UiSelector().{}(\"{}\").fromParent(new UiSelector().{}(\"{}\"))'.format(type_tmp,value_tmp,type_target,value_target)


        try:
            WebDriverWait(self.driver, wait).until(
            lambda driver: driver.find_element_by_android_uiautomator(ui_value))

            if is_Multiple == False:
                return self.driver.find_element_by_android_uiautomator(ui_value)
            else:
                return self.driver.find_elements_by_android_uiautomator(ui_value)

        except:
            log.info('页面【{}】未找到 元素【{}】\n locator: {}'.format(locator_tmp.get("page"), locator_target.get('name'),str(locator_target)))
            if is_Multiple == False:
                return None
            else:
                return []
Ejemplo n.º 28
0
    def _find_ele_child_byname(self, locator_parent, locator_child, is_Multiple=False, wait=8):
        #使用uiautomator通过父节点,定位子节点。

        value_parent, type_parent = locator_parent['value'], locator_parent['type']
        value_child, type_child = locator_child['value'], locator_child['type']

        try:
            map = {
                "name": "textContains",
                "id": "resourceId",
                "class name": "className"
            }
            type_parent = map.get(type_parent)

            if type_parent == None:
                log.error('当前定位方式不支持')
                raise NotFoundElementError

            ui_value = 'new UiSelector().{}(\"{}\").childSelector(new UiSelector().textContains(\"{}\"))'.format(
                type_parent, value_parent, value_child)

            WebDriverWait(self.driver, wait).until(
                lambda driver: driver.find_element_by_android_uiautomator(ui_value))

            log.info("页面【{}】的元素【{}】成功查找子节点 元素【{}】".format(locator_parent.get("page"), locator_parent.get("name"),
                                                        locator_child.get('name')))

            if is_Multiple == False:
                return self.driver.find_element_by_android_uiautomator(ui_value)
            else:
                return self.driver.find_elements_by_android_uiautomator(ui_value)


        except:
            log.info(
                "页面【{}】的元素【{}】未能查询到查找子节点 元素【{}】\n locator_parent:{} \n locator_child{}"
                    .format(locator_parent.get("page"), locator_parent.get("name"),
                            locator_child.get('name'), locator_parent, locator_child))

            if is_Multiple == False:
                return None
            else:
                return []
Ejemplo n.º 29
0
    def click_ele(self,element,count=1,is_log=True):
        #对元素对象进行点击
        if is_log==True:
            log.info("[点击]{}次元素 {}".format(count,element))


        if count == 1:

            element.click()
        else:
            touch_action = TouchAction(self.driver)
            try:
                for x in range(count):
                    self.sleep(0.1, islog=False)
                    touch_action.tap(element).perform()
            except:
                pass


        self.sleep(0.1, islog=False)

        return self
Ejemplo n.º 30
0
    def is_toast_show(self, message, wait=5):
        """Android检查是否有对应Toast显示,常用于断言

        Args:
            message: Toast信息
            wait:  等待时间

        Returns:
            True 显示Toast

        """

        toast_loc = ("xpath", ".//*[contains(@text,'%s')]" % message)
        try:
            WebDriverWait(self.driver, wait, 0.2).until(expected_conditions.presence_of_element_located(toast_loc))

            log.info("当前页面成功找到toast: %s" % message)
            return True

        except :
            log.error("当前页面中未能找到toast为: %s" % message)

            return False