整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:

4行代码,让app自动化框架支持 webview 混

4行代码,让app自动化框架支持 webview 混合应用操作

什么是混合应用

  移动端应用有两种典型的开发方式,一种是原生的 native app,一种是基于网页开发技术web app。 原生应用的体验感更好,但是如果想同时开发安卓应用和 ios 应用,需要不同的原生开发技术。 web 应用可以非常轻松的做到安卓和 ios 的跨平台开发,它的体验感要稍微差一些,不像原生应用那么流畅。

  Hybrid App(混合模式移动应用)是介于 web app和native app之间的开发方式,可以在原生界面中嵌套网页,因而可以同时具备体验感和跨平台能力。

  目前主流的移动端 app 测试框架 appium 具备混合应用测试的能力,但是这个框架搭建和使用都比较麻烦,封装的方法也没有那么 pythonic,因此有很多公司不想使用,他们更加喜欢简洁优雅的 python uiautomator2 框架。 非常遗憾,这个框架目前没有支持混合应用测试。

  混合应用测试步骤

  第一步,通过原生操作进入 webview 网页;

  第二步,使用 selenium 等网页测试工具进入网页;

  第三步,使用 selenium 等网页测试工具测试。

  这中间的关键步骤在于如何使用 selenium, 如果直接打开一个新的 selenium 会话,那么会打开一个新的页面,和 app 中的 webview 是分开的,因此无法测到嵌套网页。 selenium 必须要和 app 建立某种关系,使他们绑定在一起,操作 selenium 时就是直接操作 app 当中的网页。


  通过 uiautomator2 进入 webview

  这里就是最基本的 uiautomator2 操作,详细操作可以查看官方文档, 这里使用的 app 是 android bootstrap 。

  d=u2.connect()

  d.app_start('com.github.android_app_bootstrap')

  d(text='Login').click()

  d(text='Baidu').click()


  selenium 连接 webview

  APP 的第三个菜单可以直接打开 baidu 网页,从而到 webview 网页。 如果不使用 selenium 连接,直接通过 uiautomator2 定位网页中的元素,是会报错的。


  那如何通过 selenium 连接 webview 呢?

  首先,通过设备 d 获取当前操作的 app, 从而得到包名

  然后,初始化一个 Chrome 浏览器对象

  需要注意的是,Chrome 对象需要添加额外的参数,指定连接的设备,webview 绑定的报名,以及配置在 app 中使用 android 浏览器。

  之后的操作就和 selenium 做 web 自动化测试没有任何区别了,无非就是点击网页,做自动化操作:

  driver=webdriver.Chrome('chromedriver_68.exe', options=options)

  driver.implicitly_wait(8)

  driver.find_element('id', 'index-kw').send_keys('你好')


  这段代码我在哪里学到的

  是不是很好奇,我怎么知道要这么写代码,才能连接 webview ,达到测试效果? 其实世间没有那么多神秘的学习方法,只要你肯用心,一定是可以找到学习的路径的。 这段代码清清楚楚的写在 chrome webdriver 的官方文档中,只是,你可能打不开。 截屏看一下:


  其他 webdriver 的配置也可以查看 MDN web docs。


  展示效果:

合开发

我们都知道对于桌面应用开发来说,人们常用的方式就是采用c++或者c#,java等进行开发,然而这些语言开发效率不够高,不如网页开发灵活。因此,人们思考能否采用html+css+js的方式来开发桌面客户端呢,于是人们就提出了混合开发概念,并且开发了electron框架进行桌面开发。

提到electron开发的桌面应用,就不得不提vscode,这个采用css+js+html开发的编辑器从诞生以来就逐渐占据市场的份额,现在几乎绝大部分的前端开发者都采用vscode进行开发,而且也有很多后端开发者逐渐采用vscode进行后端开发,可以说vscode证明了electron也可以开发出优秀的桌面程序。当然,除了vscode之外,whatsapp和twitch还有slack也是采用electron开发的。

webview2

webview2是微软推出的一组控件,它可以让本地应用程序轻松嵌入web技术。WebView2 控件使用Microsoft Edge作为呈现引擎在本机应用程序中显示 Web 内容。使用 WebView2,您可以将 Web 代码嵌入到本机应用程序的不同部分,或在单个 WebView 实例中构建所有本机应用程序。

Webview2 应用程序允许广泛的覆盖范围。作为 Web 开发人员,您可以跨不同平台重用大部分代码。对于要访问本机平台的所有功能,则推荐直接使用本机应用程序。

webview2 由来

之所以称为 WebView2,是因为它取代了 WebView 控件,而后者又取代了 WebBrowser 控件,老派 Win32 开发人员可能还记得。WebView 使用原始的 Edge (Trident) 渲染引擎,是 Windows10 唯一的控件。WebView2 使用较新的 Edge 渲染引擎,并支持多种Windows 平台。

webview2优点

  • 丰富的网络生态,因为采用web技术,因此丰富的web框架和库都可以拿来直接使用。
  • 迭代和更新变得异常方便
  • 提供了全套访问本地的功能接口。
  • 多个平台的代码可以复用,一套代码多个平台。
  • 微软官方支持开发和维护。
  • 多个版本控制,可以选用不同的chromium进行打包。

webview2使用方式

  • 通过安装开发版的Edge (Chromium),可以支持webview2的开发。
  • 安装独立的WebView2 Runtime,它可以独立下载和升级
  • 将Edge chromium内核嵌入到程序之中。

webview2 vs electron

Electron 为常见的桌面应用程序需求提供 API,例如菜单、文件系统访问、通知等。

WebView2 是一个组件,旨在集成到 WinForms、WPF、WinUI 或 Win32 等应用程序框架中。

Node.js 被集成到 Electron 中。Electron 应用程序可以使用来自渲染器和主进程的 Node.js API、模块或 node-native-addon。

WebView2 应用程序支持嵌入到多种编程语言之中。您的 JavaScript 代码必须通过应用程序主机进程代理执行访问操作系统。

Electron 努力保持与 Web API 的兼容性。

Electron 具有可配置的 Web 内容安全模型,从完全访问到完全沙盒。WebView2 内容始终被沙盒化.

webview2未来

目前的webview2还只是支持windows的各个版本预览,未来,webview将会支持UWP 预览 ,macOS 预览,Xbox 预览,HoloLens 预览,Linux 预览,总之,webview2未来可期。


pring Boot中,你可能想要基于动态内容生成静态HTML页面。有几种方法可以实现这一目标,以下是其中的一些方法:

使用模板引擎:
你可以使用模板引擎(如Thymeleaf、Freemarker或Velocity)来动态渲染HTML内容,并将结果保存为静态文件。例如,你可以创建一个服务,该服务使用模板引擎渲染模板,并将结果写入文件。

下面是一个使用Thymeleaf的简单示例:

@Service  
public class StaticHtmlGeneratorService {  

    @Autowired  
    private TemplateEngine templateEngine;  

    @Autowired  
    private ApplicationContext applicationContext;  

    public void generateStaticHtml(String templateName, Map<String, Object> context, String outputPath) {  
        Context thContext=new Context();  
        thContext.setVariables(context);  

        String processedHtml=templateEngine.process(templateName, thContext);  

        try (BufferedWriter writer=new BufferedWriter(new FileWriter(outputPath))) {  
            writer.write(processedHtml);  
        } catch (IOException e) {  
            // Handle exception  
        }  
    }  
}

这段代码不是完整的实现,因为TemplateEngine类并不是Spring Boot标准库中的一部分。在实际应用中,你会使用具体的模板引擎的API(例如Thymeleaf的TemplateEngine),并相应地调整代码。

实际上,Spring Boot集成Thymeleaf后,你会这样使用Thymeleaf的API:

@Autowired  
private SpringTemplateEngine templateEngine;  

public void generateStaticHtml(String templateName, Map<String, Object> contextVars, String outputPath) {  
    Context context=new Context();  
    context.setVariables(contextVars);  

    String processedHtml=templateEngine.process(templateName, context);  

    // Write the processedHtml to a file  
    // ...  
}

使用WebView库(如Jsoup):
如果你想在没有模板引擎的情况下生成HTML,可以使用像Jsoup这样的库来构建HTML文档,然后保存为文件。

public void generateStaticHtmlWithJsoup(String title, String bodyContent, String outputPath) throws IOException {  
    Document doc=Jsoup.parse("<html><head><title></title></head><body></body></html>");  
    doc.title(title);  
    doc.body().append(bodyContent);  

    // 美化输出(Pretty-print)  
    doc.outputSettings().prettyPrint(true);  

    // 写入文件  
    Files.write(Paths.get(outputPath), doc.outerHtml().getBytes(StandardCharsets.UTF_8));  
}

使用RestTemplate或WebClient:
如果你的静态HTML内容来自另一个Web服务,你可以使用RestTemplate或WebClient来获取动态内容,然后将其保存为静态文件。

@Autowired  
private RestTemplate restTemplate;  

public void generateStaticHtmlFromWebService(String url, String outputPath) throws IOException {  
    ResponseEntity<String> response=restTemplate.getForEntity(url, String.class);  

    if (response.getStatusCode()==HttpStatus.OK) {  
        Files.write(Paths.get(outputPath), response.getBody().getBytes(StandardCharsets.UTF_8));  
    }  
}

在生成静态HTML时,请考虑以下几点:

  • 确保你有适当的权限来写入文件系统。
  • 小心处理用户提供的输入,以避免安全风险,如跨站脚本(XSS)攻击。
  • 考虑生成的静态文件如何与你的应用程序的其他部分(如静态资源处理程序)集成。
  • 监控文件系统的使用情况,以避免耗尽磁盘空间。
  • 考虑生成的静态内容的缓存和过期策略。