webdriver源码简要分析
webdriver简介
webdriver,又称selenium 2.0,是selenium公司推出的一款自动化测试利器。它支持市场上几乎所有的浏览器,ie,firefox,chrome,safari等,还支持移动终端设备。
由于最近的工作涉及webdriver,所以就从google code上拉下了所有源代码,对firefox模块的实现进行了学习和探索。
webdriver架构
webdriver采用了典型的"C-S"结构,对firefox模块来说,client端是firefox driver,server端是webdriver自己开发的一个firefox extension。
firefox driver
FirefoxDriver是RemoteWebDriver的一个子类,它还包含了一个LazyCommandExecutor。
FirefoxDriver在启动时遵循以下步骤。
- 创建FirefoxBinary和FirefoxProfile对象,webdriver提供了足够的API来对新创建的FirefoxBinary和FirefoxProfile进行自定义,例如指定Firefox的路径,指定Firefox的Profile,更改Profile的preference等等。
- 建立NewProfileExtensionConnection,启动Firefox。
- 用HttpCommandExecutor对象开启一个新的session。
webdriver的架构图如下图所示:
webdriver wire protocol
webdriver实现了自己的一个协议。用来进行client和server之间的通信。http和json是主要使用的技术,在源码中可以发现协议的定义:
nameToUrl = ImmutableMap.<String, CommandInfo>builder()
.put(NEW_SESSION, post("/session"))
.put(QUIT, delete("/session/:sessionId"))
.put(GET_CURRENT_WINDOW_HANDLE, get("/session/:sessionId/window_handle"))
.put(GET_WINDOW_HANDLES, get("/session/:sessionId/window_handles"))
.put(GET, post("/session/:sessionId/url"))
// The Alert API is still experimental and should not be used.
.put(GET_ALERT, get("/session/:sessionId/alert"))
.put(DISMISS_ALERT, post("/session/:sessionId/dismiss_alert"))
.put(ACCEPT_ALERT, post("/session/:sessionId/accept_alert"))
.put(GET_ALERT_TEXT, get("/session/:sessionId/alert_text"))
.put(SET_ALERT_VALUE, post("/session/:sessionId/alert_text"))
webdriver server
webdriver server是一个firefox extension。它主要包含了两个部分:WebDriverServer, CommandProcessor。
在firefox启动之后,也就是browser.xul被gecko加载之后,
- webdriver会在每个新开的window上创建一个FirefoxDriver和一个DomMessenger,多个tab window共享同一个FirefoxDriver和DomMessenge。
- WebDriverServer启动,它会创建一个Server,用来接收client端的消息。
当收到client端的消息之后:
- WebDriverServer把消息交给Dispatcher进行分发,Dispatcher保存了一份webdriver wire protocol,与client端一样。
- Dispatcher对消息进行分析之后,交给CommandProcessor。
- CommandProcessor对消息进行分析之后执行,如果是webelement,则交给WebElement类处理,如果不是,则自己调用相应方法。