重写 AppiumService 类,添加默认启动参数,并实时显示启动日志

这篇具有很好参考价值的文章主要介绍了重写 AppiumService 类,添加默认启动参数,并实时显示启动日志。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、前置说明

在Appium的1.6.0版本中引入了AppiumService类,可以很方便的通过该类来管理Appium服务器的启动和停止。经过测试,使用该类的实例执行关闭server时,并没有释放端口号,会导致第二次启动时失败。另外,使用该类启动server,不能在窗口中实时显示日志,不方便调试。因此,可以重写 AppiumService 类的 start 方法和 stop 方法,实现相应功能。

二、代码实现

import logging

from appium.webdriver.appium_service import *
from appium.webdriver.appium_service import AppiumService as OriginalServer

from libs import path, file_util
from libs.cmd_util import cmd_executor as cmd

logger = logging.getLogger(__name__)


class AppiumService(OriginalServer):

    def __init__(self, port=4723, log_file_path=None, tail_log=False):
        super().__init__()

        self.port = port
        self.log_file_path = log_file_path

        # 用于控制是否开启cmd窗口,实时展示日志内容,当调试代码时建议开启
        self.tail_log = tail_log

        if not self.log_file_path:
            self.log_file_path = os.path.join(path.get_log_dir(), f'appium_server_{port}.log')

        if os.path.exists(self.log_file_path):
            os.remove(self.log_file_path)

        self.default_start_args = ['-p', str(self.port),
                                   '-g', self.log_file_path,
                                   '--session-override',
                                   '--log-timestamp',
                                   '--session-override',
                                   '--local-timezone',
                                   '--allow-insecure',
                                   'chromedriver_autodownload'
                                   ]

    def start(self, **kwargs: Any) -> sp.Popen:
        self.stop()

        env = kwargs['env'] if 'env' in kwargs else None
        node: str = kwargs.get('node') or get_node()
        npm: str = kwargs.get('npm') or get_npm()
        main_script: str = kwargs.get('main_script') or get_main_script(node, npm)
        # A workaround for https://github.com/appium/python-client/issues/534
        default_std = sp.DEVNULL if sys.platform == 'win32' else sp.PIPE
        stdout = kwargs['stdout'] if 'stdout' in kwargs else default_std
        stderr = kwargs['stderr'] if 'stderr' in kwargs else default_std
        timeout_ms = int(kwargs['timeout_ms']) if 'timeout_ms' in kwargs else STARTUP_TIMEOUT_MS
        args: List[str] = [node, main_script]
        if 'args' in kwargs:
            args.extend(kwargs['args'])

        # ==================添加这段逻辑(开始):设置默认启动参数=======================
        if self.port:
            args.extend(self.default_start_args)
        # ==================添加这段逻辑(结束):设置默认启动参数=======================

        self._cmd = args
        self._process = sp.Popen(args=args, stdout=stdout, stderr=stderr, env=env)

        error_msg: Optional[str] = None
        startup_failure_msg = (
            'Appium server process is unable to start. Make sure proper values have been '
            f'provided to \'node\' ({node}), \'npm\' ({npm}) and \'main_script\' ({main_script}) '
            f'method arguments.'
        )
        if timeout_ms > 0:
            status_url_path = make_status_url(args)
            try:
                if not self._poll_status(parse_host(args), parse_port(args), status_url_path, timeout_ms):
                    error_msg = (
                        f'Appium server has started but is not listening on {status_url_path} '
                        f'within {timeout_ms}ms timeout. Make sure proper values have been provided '
                        f'to --base-path, --address and --port process arguments.'
                    )
            except AppiumStartupError:
                error_msg = startup_failure_msg
        elif not self.is_running:
            error_msg = startup_failure_msg
        if error_msg is not None:
            if stderr == sp.PIPE and self._process.stderr is not None:
                err_output = self._process.stderr.read()
                if err_output:
                    error_msg += f'\nOriginal error: {str(err_output)}'
            self.stop()
            raise AppiumServiceError(error_msg)

        # ==================添加这段逻辑(开始):是否启动cmd窗口跟踪log日志=======================
        if self.tail_log:
            file_util.tail_log_file(self.log_file_path)
        # ==================添加这段逻辑(结束):是否启动cmd窗口跟踪log日志=======================

        return self._process

    def stop(self) -> bool:
        status = super().stop()

        # 经过实测,原stop()方法执行之后,进程仍被占用,所以这里添加一个关闭进程的逻辑
        cmd.kill_process_by_port(self.port)

        return status


if __name__ == '__main__':
    logging.basicConfig(level=logging.INFO)
    service = AppiumService(port=4723, tail_log=True)
    service.start()

三、Demo验证

执行代码,顺利启动appium server,并启动了一个命令行窗口,实时展示了server的日志。
重写 AppiumService 类,添加默认启动参数,并实时显示启动日志,Appium,appium

欢迎技术交流:
重写 AppiumService 类,添加默认启动参数,并实时显示启动日志,Appium,appium文章来源地址https://www.toymoban.com/news/detail-755596.html

到了这里,关于重写 AppiumService 类,添加默认启动参数,并实时显示启动日志的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【QT】重写QAbstractLIstModel,使用ListView来显示多列数据

    qt提供了几个视图来进行信息的列表显示,QListView可以用来显示继承QStractListModel的字符串列表中的字符串,默认的模型里面只包含一列的内容: 这里以qml为例子,先新建一个qml的项目,示例代码如下: 先创建一个列表的只读模型,以QAbstractListModel为基类,最基础的只用实现

    2024年02月12日
    浏览(45)
  • nginx添加模块fastdfs-nginx-module(docker版,不需要重写dockerfile)

    至此 nginx添加fastdfs-nginx-module模块已经添加成功

    2024年02月15日
    浏览(56)
  • powershell@命令行提示符样式配置自定义@pwsh重写prompt显示电量内存时间等信息

    在 PowerShell 中,可以通过自定义 $prompt 变量来修改命令行提示符(Prompt)。以下是修改 PowerShell 提示符的一些基本方式: 简单修改 : 你可以直接覆盖 $prompt 变量的内容,例如将其设为任何你想要的文字: 动态提示符 : 利用 PowerShell 表达式来构造动态提示符,例如包含当前

    2024年04月23日
    浏览(49)
  • c++——默认参数和占位参数

    C++允许赋予函数参数默认值,即在调用该函数时,可以不写某些参数的值,编译器会自动把默认值传递给调用语句中。 1、基本语法 2、默认参数的规则 ①默认值只能在声明中设置 ②注意传参规则,实参给形参传参,是 从前往后 进行 ③给函数参数设置默认值,从 后往前 进

    2024年02月11日
    浏览(34)
  • Gson 添加数据默认值问题记录

    问题:在用Gson add(key(string类型),value(必须是JsonElement子类))时发现,value 传了 \\\"\\\" 空字符串(非null),默认解析后返回null? 虽说影响不大、但是给后端传数据时、如果后端没有进行null处理 就会抛异常(而且后端懒得睬你、人家就是不愿意改...)0.0!!  1、问题代码

    2024年02月14日
    浏览(49)
  • vue项目启动设置默认启动页

            当我们在启动vue项目时,默认打开的界面是白色的,需要输入正确的路由才能访问正确的页面。我们应该如何让项目打开的时候默认跳转到想启动的页面呢?         我们需要在router的index.ts(js)文件中设置路由规则,例如我们默认打开index页面,我们只需要设

    2024年02月14日
    浏览(37)
  • pycharm 创建python文件时添加默认信息

    1、settings - Editor - File and Code Templates - Python Script 2、添加默认格式 3、可用变量 ${PROJECT_NAME} - 当前项目的名称。 ${NAME} - 在文件创建过程中在“新建文件”对话框中指定的新文件的名称。 ${USER} - 当前用户的登录名。 ${DATE} - 当前的系统日期。 ${TIME} - 当前系统时间。 ${YEAR} - 今

    2024年02月02日
    浏览(34)
  • 【vue】vue项目启动设置默认启动页

    当我们在启动vue项目时,默认打开的界面是白色的,需要输入正确的路由才能访问正确的页面。我们应该如何让项目打开的时候默认跳转到想启动的页面呢? 我们需要在router的index.ts(js)文件中设置路由规则,例如我们默认打开index页面,我们只需要设置routes,内容如下: 这

    2024年02月11日
    浏览(38)
  • TypeScript - 函数 -函数的默认参数

    默认参数的写法就是,在函数的形参列表中 用 【=】给形参 赋值即可。 默认参数 必须放在形参列表中的普通参数的后面 , (这里的普通参数,就是常规的参数,是传的) 否则,ts中会直接提示错误。

    2024年02月08日
    浏览(32)
  • 用冒泡排序谈默认参数应用

     前面在调用函数提到为了将信息打印到ofil中,前面提到的办法是 ofstream ofil(\\\"text_out1\\\"); void bubble_sort(vectorint  vec){ } 在file scope中定义ofil,这是一个不受欢迎的举动。这样比较难在其他环境重用 一般的程序编写法则是,以“ 参数传递” 作为函数间的沟通方式,比直接将对象

    2024年01月18日
    浏览(32)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包