Macaca [转] selenium webdriver 的工作原理

小马 · November 30, 2016 · Last by yangqinyuan replied at March 01, 2018 · 5071 hits

通过调试一些小的Appium官方样例,或其他博客中的样例程序,发现Appium大部分底层用了selenium webdriver进行封装,目前发现的有WebDriver(来自 selenium-api-2.52.0.jar的org.openqa.selenium.WebDriver) 和 AndroidDriver(来自java-client-3.4.0.jar的 io.appium.java_client.android.AndroidDriver)他们都可以实现对官方样例安卓程序ContactManager.apk的自动化回放测试。

下边我们来看下webdriver的工作原理。

大致就是通过命令请求webdriver,然后webdriver通过浏览器的api去做操作,并返回响应结果。用的协议是json wire protocol,下面简单画了个流程图,不一定准确,只是个人理解。

详细的可以参考官方W3C介绍:https://www.w3.org/TR/2016/WD-webdriver-20160120/

webdriver和浏览器的信息交互:

1 需要chromedriver,之前安装过npm版本的Appium所以到本地硬盘D: 搜索chromedriver 发现在位置

D:\nodejs\node-global\node_modules\appium\node_modules\appium-chromedriver\chromedriver\win 的目录 2016/02/29 09:36

. 2016/02/29 09:36 .. 2016/02/29 09:36 5,285,376 chromedriver.exe 1 个文件 5,285,376 字节 2 个目录 102,209,937,408 可用字节

2 然后我们在该目录下执行

D:\nodejs\node-global\node_modules\appium\node_modules\appium-chromedriver\chromedriver\win>java -Dwebdriver.chrome.driver="chromedriver.exe" -jar D:\Install\Appium\selenium-server-standalone-2.52.0.jar 
11:42:46.756 INFO - Launching a standalone Selenium Server
11:42:46.999 INFO - Java: Oracle Corporation 25.60-b23
11:42:47.000 INFO - OS: Windows 10 10.0 amd64
11:42:47.014 INFO - v2.52.0, with Core v2.52.0. Built from revision 4c2593c
11:42:47.072 INFO - Driver class not found: com.opera.core.systems.OperaDriver
11:42:47.074 INFO - Driver provider com.opera.core.systems.OperaDriver is not registered
11:42:47.085 INFO - Driver provider org.openqa.selenium.safari.SafariDriver registration is skipped: registration capabilities Capabilities [{browserName=safari, version=, platform=MAC}] does not match the current platform WIN10
11:42:47.399 INFO - RemoteWebDriver instances should connect to: http://127.0.0.1:4444/wd/hub
11:42:47.401 INFO - Selenium Server is up and running

3 编辑一段小的测试代码

package com_appium.my_app;

import java.net.URL;

import org.openqa.selenium.By;
import org.openqa.selenium.Platform;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.junit.Test;

public class TestWebdriverChrome {
static WebDriver dr;

@Test
public void testChrome() {
DesiredCapabilities aDesiredcap = DesiredCapabilities.chrome();
//aDesiredcap.setBrowserName("chrome");
aDesiredcap.setPlatform(Platform.WINDOWS);

try {
dr = new RemoteWebDriver(new URL("http://localhost:4444/wd/hub"), aDesiredcap);
dr.get("http://www.baidu.com");
dr.findElement(By.id("kw")).sendKeys("webdriver");
Thread.sleep(3000);
dr.quit();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}

通过Junit执行后,将打开谷歌浏览器,自动打开百度 搜索webdriver。日志输出如下:

11:43:06.897 INFO - Executing: [new session: Capabilities [{browserName=chrome, version=, platform=WINDOWS}]]) 
11:43:06.909 INFO - Creating a new session for Capabilities [{browserName=chrome, version=, platform=WINDOWS}] Starting ChromeDriver 2.21.371459 (36d3d07f660ff2bc1bf28a75d1cdabed0983e7c4) on port 33920 Only local connections are allowed. 11:43:09.301 INFO - Done: [new session: Capabilities [{browserName=chrome, version=, platform=WINDOWS}]]
11:43:09.325 INFO - Executing: [get: http://www.baidu.com])
11:43:10.944 INFO - Done: [get: http://www.baidu.com] 1
1:43:10.984 INFO - Executing: [find element: By.id: kw])
11:43:11.028 INFO - Done: [find element: By.id: kw]
11:43:11.057 INFO - Executing: [send keys: 0 [[ChromeDriver: chrome on XP (bd7bf32a4c4977e883ebb9920d63ebe4)] -> id: kw], [webdriver]])
11:43:11.396 INFO - Done: [send keys: 0 [[ChromeDriver: chrome on XP (bd7bf32a4c4977e883ebb9920d63ebe4)] -> id: kw], [webdriver]]
11:43:14.406 INFO - Executing: [delete session: 7848fa1d-edd7-4b04-b16e-cd07188b718b])
11:43:15.932 INFO - Done: [delete session: 7848fa1d-edd7-4b04-b16e-cd07188b718b]

由此可见,代码的一个请求命令,webdriver都会封装一个executing,发送过去,发送成功后,再返回一个done表示处理成功。如果发生了异常,如找不到页面元素,则会在执行时抛异常

如果上面的看着还不够透彻,下面我们直接用webdriver的协议提供给我们的接口去操作。

您需要HttpRequester 这款火狐插件来构造模拟http请求 https://addons.mozilla.org/En-us/firefox/addon/httprequester/

1.首先在浏览器输入http://localhost:4444/wd/hub

通过以下方式拿到 sessionid:fc6f9497-330f-4d6c-abe0-bd0587e57101

2.拿到session后,就可以请求拉

首先我们用接口访问个百度,接口地址:http://localhost:4444/wd/hub/session/5c81a944-55c6-4c2a-9e01-689bc43d335d/urljson内容:{"url":,请求 "http://www.baidu.com/"}。

post后见下图

3.查找百度搜索的输入框

使用接口/session/{session id}/element,post请求,json内容:{ "using": "id", "value": "kw" }

4.查找到后,我们要往输入框输入内容

调用接口:/session/{session id}/element/{element id}/value,post请求,json内容:{ "value": [ "qiaoyeye" ] }

注意:element id是第三步中的响应结果json中的{"ELEMENT":"0"}0值

以上三步的请求和json内容
http://localhost:4444/wd/hub/session/6d67fc28-fdce-48fc-b895-0de598287f7c/url
{"url": "http://www.baidu.com/"}

http://localhost:4444/wd/hub/session/6d67fc28-fdce-48fc-b895-0de598287f7c/element
{
"using": "id",
"value": "kw"
}

http://localhost:4444/wd/hub/session/6d67fc28-fdce-48fc-b895-0de598287f7c/element/0/value

{ "value": [ "webdriver" ] }

Firefox来说,selenium webdriver是基于这个平台开发的,WebDriver实现了FireFoxDriver,无需用户下载FireFoxDriver。

chrome需要,chromedriver.exe

IE需要,IEDriverServer.exe

备注:年代久远的研究appium时的wiz保存下来的网页,出处原贴已找不到了。但对于分析研究appium macaca类似的工具原理应该有帮助,故分享出来。

比如 升级最新 macaca-cli 可以在http://localhost:3456/ 
看到目前server端支持的webdriver方法,那么通过看macaca server --verbose 或脚本的 --verbose日志,
我们也可以发现 大量的类似的这种请求

proxy.js:52:14 [master] pid:14960 Proxy: /wd/hub/session/temp/window:POST to http://localhost:9515/wd/hub/session/0f7e2af16cfbc92f86558c78618edfc8/window:POST with body: {"name":"CDwindow-EB102075-20E4-4CC4-8621-881F04FF0D3F"}

所以 底层上基本都相似的,也应该可以通过该方式尝试理解macaca的工作与封装处理流程。

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

点赞,明白了selenium的原理

需要 Sign In 后方可回复, 如果你还没有账号请点击这里 Sign Up