1

使用selenium 操作 electron 应用

 2 years ago
source link: https://www.yangyanxing.com/article/use-selenium-opt-electron.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

近期的自动化测试项目中有个关于测试内部IM通信软件的需求,在了解到各个客户端的相应技术栈实现以后,在mac中的应用使用的是electron 技术,我们也对相应的技术进行调研,此文记录一下在关于electron应用的自动化测试。

一、electron 简介

electron利用 Chromium 和 Node.js, 为使用 JavaScript,HTML 和 CSS 构建跨平台的桌面应用程序,可以实现代码一次编译,多端运行的效果,可以生成mac app, windows exe等,但是它编译出来的文件由于包含Chromium,所以体积一般会比较大。

二、使用 selenium 操作Chrome 浏览器

先确定一下系统中的chrome浏览器的版本,由于selenium 操作Chrome浏览器需要使用到ChromeDriver,不同版本的Chrome对应着不同的ChromeDriver,如果不对应的话可能会失败。

然后到 https://chromedriver.chromium.org/downloads 这里下载对应的ChromeDriver,国内的用户如果访问不了的话可以使用淘宝镜像源 https://npm.taobao.org/mirrors/chromedriver

需要将chromedriver放到环境变量里,如果不放到环境变量里的话,也可以在代码中指定chromedriver的路径

from selenium import webdriver
from selenium.webdriver.common.keys import Keys
import time

driver = webdriver.Chrome()
# webdriver.Chrome 在初始化的时候也可以指定chromedriver路径,这种对于系统中有多个版本的chromedriver非常有用
# driver = webdriver.Chrome(executable_path="/Users/qihoo/Desktop/chromedriver94")
driver.get("https://www.google.com")
assert "Google" in driver.title
elem = driver.find_element_by_name("q")
elem.clear()
elem.send_keys("360")
elem.send_keys(Keys.RETURN)
assert "No results found." not in driver.page_source
driver.close()

image-20211014195859378

三、使用 selenium 操作 electron 应用

想要使用 selenium 操作electron app, 首先要确认的是该app使用的是哪个版本的Chromium

那么该如何确认electron应用的Chromium版本号呢?

一般情况下,我们是测试的app都是由开发打包之后的app,对于这种应用,我们很难在代码上做些hook,如果我们打开chrome devTools面板,(mac下使用option+command+i), 在console标签中输入 process.versions 可以查看到 chrome 版本,那么最好不过了,可以直接去下载对应的chromedriver, 但是更多的时候这个 process 对象是没有定义的,如果想要在控制台使用process,在编写app时,应该加上

function createWindow () {
  const win = new BrowserWindow({
    width: 800,
    height: 600,
    webPreferences: {
      preload: path.join(__dirname, 'preload.js'),
      nodeIntegration: true, contextIsolation: false //加上这个配置才可以在控制台使用process对象
    }
  })

image-20211014172936368

更多的时候我们可以随便找一下版本的 chromedriver, 在初始化的过程中,如果程序报错了,会提示出app用的是哪个版本的chrome

selenium.common.exceptions.SessionNotCreatedException: Message: session not created: This version of ChromeDriver only supports Chrome version 94
Current browser version is 80.0.3987.86 with binary path /Applications/360家.app/Contents/MacOS/360家

这里有显示我当前的 chromedriver 版本号是94,但是要被测试的应用的版本号是80,所以就知道了需要下载哪个版本的 chromedriver了。

我们使用electron来创建一个mac 应用,代码使用官方提供的示例,https://www.electronjs.org/zh/docs/latest/tutorial/quick-start , 但是打包我这里和官方的不太一样

mkdir electroltest 
cd electrontest
npm init -y
  1. 安装electron 和相应的打包工具
npm install electron electron-packager electron-installer-dmg --save
  1. 修改 package.json
{
  "name": "electroltest",
  "version": "1.0.0",
  "description": "",
  "main": "main.js",  //修改为main.js 
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "start": "electron .", // 添加一个启动指令
    "build": "electron-packager .", //添加打包指令
    "dmg": "electron-installer-dmg ./electroltest-darwin-x64/electroltest.app/ electroltest" // 添加生成dmg指令
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "electron": "^15.1.2",
    "electron-installer-dmg": "^3.0.0",
    "electron-packager": "^15.4.0"
  }
}

  1. 添加 main.js
const { app, BrowserWindow } = require('electron')
const path = require('path')

function createWindow () {
  const win = new BrowserWindow({
    width: 800,
    height: 600,
    webPreferences: {
      preload: path.join(__dirname, 'preload.js')
    }
  })

  win.loadFile('index.html')
}

app.whenReady().then(() => {
  createWindow()

  app.on('activate', () => {
    if (BrowserWindow.getAllWindows().length === 0) {
      createWindow()
    }
  })
})

app.on('window-all-closed', () => {
  if (process.platform !== 'darwin') {
    app.quit()
  }
})


  1. 添加index.html
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Hello YYX!</title>
    <meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline';" />
</head>
<body>
    <h1>Hello 杨彦星!</h1>
    <p>
        We are using Node.js <span id="node-version"></span>,
        Chromium <span id="chrome-version"></span>,
        and Electron <span id="electron-version"></span>.
    </p>
</body>
</html>

  1. 添加 proload.js
window.addEventListener('DOMContentLoaded', () => {
    const replaceText = (selector, text) => {
      const element = document.getElementById(selector)
      if (element) element.innerText = text
    }
  
    for (const type of ['chrome', 'node', 'electron']) {
      replaceText(`${type}-version`, process.versions[type])
    }
  })

写完代码以后可以使用npm run start 看下效果,是否可以正常的显示electron应用

image-20211014184536826

如果正常显示则可以进行打包操作

  1. 打包electron应用

这里只是将electron 应用打成app,并没有生成dmg安装包

npm run build   #这里是由于在package.json中定义了build指令,如果没有定义也可以运行 npx electron-packager .
  1. 生成mac下的 dmg 安装包
npm run dmg  # 同build指令,这里也可以使用 npx electron-installer-dmg ./electroltest-darwin-x64/electroltest.app/ electroltest

如果一切顺利,则会在当前目录下生成 electroltest.dmg 文件 ,双击这个文件就可以安装在mac中了

image-20211014184855362

接下来我们来写一个简单的测试,就是打开app,查看一下html,再跳转到google,输入一些文字,再点击搜素按钮

该electron 应用安装的位置是

/Applications/electroltest.app/Contents/MacOS/electroltest

自己根据安装的位置进行相应的修改

  1. 安装 selenium
pip install selenium
  1. 写测试用例
# -*- coding: utf-8 -*-
"""
-------------------------------------------------
   File Name:     eletest
   Description :  electrol自动化测试
   Author :       杨彦星
   date:          2021/10/14
-------------------------------------------------
"""

from selenium import webdriver
from selenium.webdriver.common.keys import Keys
import time


options = webdriver.ChromeOptions()
options.binary_location = "/Applications/electroltest.app/Contents/MacOS/electroltest"
driver = webdriver.Chrome(chrome_options=options)
time.sleep(3)
print(driver.page_source)
driver.get("http://www.google.com")
elem = driver.find_element_by_name("q")
elem.clear()
elem.send_keys("360") # 这里也可以输入中文
elem.send_keys(Keys.RETURN)
driver.close()
driver.quit()


这里比较重要的是定义 options.binary_location 需要设置为 electron 应用的路径

20211014190302

四、使用 selenium 操作已经打开的electron应用

通过以上方式我们其实是重新打开了某个app, 但是更多的时候,我们是期望测试一个已经打开的app,试想一下如下的场景,某个app需要登录,登录的方式又比较复杂,扫码登录或者短信登录,或者有验证码,但是如果成功登录以后,一段时间以后再次打开就不会进入到登录界面,此时,我们不希望每次运行用例的时候,都重新登录,这时,我们就需要使用 selenium 来测试一个打开着的应用。

使用 electron 构建的app, 在启动的时候可以加上一个用于调试的端口

/Applications/electroltest.app/Contents/MacOS/electroltest --remote-debugging-port=9222

这样就可以正常的启动应用的同时,也会开启远程调试功能,我们在使用selenium时,就可以直接对该app进行测试了而不需要再次重新打开一个新的app

这里的端口需要一个没有被占用的端口,初始化driver时可以

options = webdriver.ChromeOptions()
options.add_experimental_option("debuggerAddress", "127.0.0.1:9222") # 设置debuggerAddress
driver = webdriver.Chrome(chrome_options=options)

通过上面的设置以后,我们就可以直接在打开着的应用上进行测试了,非常适合那种登录比较复杂的应用。

使用 selenium 测试 electron 应用的测试有几个几点总结

  1. 找到对应的 chromedriver
  2. 通过 binary_location 参数设置app路径
  3. 对于测试打开着的app, 需要在app启动的时候添加远程调试参数 --remote-debugging-port

Selenium-Python中文文档

打包 electron 应用到 mac


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK