Macaca 混合 H5 应用 UI 自动化进阶

Yinxl · 2017年11月08日 · 最后由 joweywen 回复于 2018年10月25日 · 3741 次阅读

混合 H5 应用 UI 自动化进阶

混合 H5 应用 UI 自动化是移动应用自动化中无法绕过的一节,针对混合 H5 应用的 UI 自动化入门之前已经写过一篇文章:https://testerhome.com/topics/9651 ,入门的同学可移步学习。本文主要针对 H5 应用 UI 自动化高级使用进行一些分享。

如何定位元素

参考上述入门文章:https://testerhome.com/topics/9651

进阶

本文中所涉及的 demo 示例代码已开源:

https://github.com/macaca-sample/macaca-java-biz-sample

H5 基础知识储备

要对 H5 应用进行 UI 自动化,首先要掌握一些基础的 H5 知识,HTML,CSS,JQuery 这些是最基础的,建议有此类需求的同学先简单补充下此类基础知识,主要是选择器以及事件触发等,笔者主要参考的是 W3school 的教程,教程地址如下http://www.w3school.com.cn/。掌握了最基础的 H5 知识,就可以进入下一步了。

H5 内多个 webview 跳转后操作失败

部分同学反馈,自动化中当从一个 H5 页面跳转到另一个 H5 页面后对新的 H5 页面的操作无效,这大部分是因为 H5 页面内发生跳转后没有更新上下文导致的,当我们从 Native 进入一个 H5 页面后,当前上下文会存在两个,一个是 Native,一个是 webview,但是当 webview 内发生跳转时,也会生成新的上下文,比如当我们从上面这个 H5 跳转到另一个页面后,此时的上下文信息如下:

responseHandler.js:49:14 [master] pid:62034 Send HTTP Respone to Client[2017-11-08 20:45:31]: {"sessionId":"fecd1f1b-1ca4-4c54-9905-97a7af0c0a52","status":0,"value":"[\"NATIVE_APP\",\"CDwindow-b35eb442-86e4-4dec-913d-ea3b0b69bf6a\",\"CDwindow-59160ffd-74f4-4425-949a-30eb52786ba0\"]"}

这里面我们可以发现 NATIVE_APP 表示 Native 的上下文,两个 CDWindow 代表的是两个 H5 页面,此时如果要对上层的 H5 页面操作,则必须更新当前上下文到栈顶的上下文,在 biz 层提供了用于上下文更新的 API,如下:

/**
     * 当存在多个上下文时,切换当前上下文为当前最顶部的window,当webview发生跳转时可以通过此API更新上下文
     * @throws Exception
     */
    public void updateTopContext() throws  Exception {
        JSONArray contexts = contexts();
        this.context(contexts.get(contexts.size() - 1).toString());
    }

万能的 'driver.execute()'

Macaca 提供了一些常用的 H5 操作的 API,但有些时候这些 API 无法满足我们的特殊需要,比如我们想拿到页面内所有的跳转链接并跳转以此来完成二级页面的遍历,此时已有的 API 显然无法满足我们的需要,这时候就需要用到 driver.excute(),excute() API 可以用来执行 js 脚本,如此,我们便可以执行任何可以通过 js 脚本实现的功能,比如我们的 demo 中百度页面的 href 属性基本上表示了可跳转的二级页面链接,那我们可以通过如下代码实现二级页面遍历的需求:

如下代码在 com.javademo.cases.SampleTest 中,可前往https://github.com/macaca-sample/macaca-java-biz-sample查看

// com.javademo.cases.SampleTest
public void  iterateBaiDuPage() throws  Exception{
        JSONObject schemaJson = driver.execute("var arr=[];function getSchemas(){$.each($('[href]'),function(index,item){arr.push(item.getAttribute('href'))}); return arr;};return getSchemas();");
        JSONArray schemas = schemaJson.getJSONArray("value");
        System.out.println("schemas===========" + schemas);

        if (schemas!=null && schemas.size() > 0) {
            // 循环进入各个二级跳转链接
            for (int i = 0; i < schemas.size(); i++) {

                String tmpHref = (String) schemas.get(i);
                String jsCode = "location.assign(\"" + tmpHref + "\")";
                driver.execute(jsCode);
                driver.sleep(3000);
                saveScreen(tmpHref);

                driver.execute("history.back();");

            }

        }
    }

在编写如上脚本所需要的 js 脚本时,我们可以在 inspector 页面的 console 中先进行调试,调试成功后放入 driver.excute('') 中执行,如下:
img

如此,通过 driver.execute(),我们便可以实现通过 js 脚本能够实现的功能,是不是很强大呢。

注意事项

  • 所有对 H5 上下文的操作需要在 dom ready 后执行才会生效,因此建议在 H5 页面跳转后 sleep 几秒等待页面 ready 再进行相应操作

有其他问题,欢迎补充讨论。

如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
共收到 4 条回复 时间 点赞

其实很多框架都有 execute() 方法,不过这个方法的成本还是蛮高的,通常用来解决一些特殊的问题

楼主这个是 JAVA 写的吧,请问 python 怎样实现呢

枫叶 回复

python 的实现和 Java 没太大差别的 原理是一样的 将对应的 API 替换成 python 版的就可以的 都可以找到一一对应的

求助,pc 桌面版基于 electronjs 的桌面版应用的 UI 页面中,需要使用到鼠标右键的操作,试问鼠标右键的模拟操作 macaca 如何实现呢,api 中未发现,借问求分享哦

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册