Selenium3筆記-WebDriver源碼初探

Selenium3 有哪些變化?                                                        

其實相對於與Selenium2,Selenium3沒有作太多的改動。下面給出官方的文檔說明,供參考。node

參考文檔https://seleniumhq.wordpress.com/2013/08/28/the-road-to-selenium-3/ios

  1. 「We aim for Selenium 3 to be 「a tool for user-focused automation of mobile and web apps」,Developers from projects such as Appium, ios-driver and selendroidwill be working on the suite of tests to enable this.」
  2. 「Selenium 3 will see the removal of the original Selenium Core implementations, and consequently we’ll be deprecating the RC APIs too,the original implementation will be available as a download, but it will no longer be actively developed once we release 3.0.」

因此對於Selenium3來講最大的變更可能就是更加專一於手機和web的測試,尤爲是手機的支持,由於你曉得的,如今更多的是移動的時代。git

對於Selenium2中對於RemotControl的實現我看了下Selenium3的源碼發現確實不在支持,而更多的轉向了W3C standard,不是獨成一套Selenium本身的WebDriver API.關於這個須要插如一下有關W3C WebDriver的知識。github

有關W3C WebDriver                                                                           

參考文檔https://www.w3.org/TR/webdriver/https://www.w3.org/testing/Activityhttps://github.com/w3c/webdriverweb

W3C組織制定了一套瀏覽器自動化的規範叫作WebDriver,這套規範規定了全部的瀏覽器生產商都必須遵照這個規範。其實定義了好多的遵循的接口和WebDriver的概念。對於Chrome,Firefox,Opera,Safari.etc他們都須要遵照這個規範而且實現規範裏面的接口,這些實現通常都是伴隨瀏覽器的開發進行的。chrome

因此你應該明白了,Selenium無論是WebDriver仍是RemoteWebDriver都是W3C WebDriver的一種實現而已。真正的核心瀏覽器的交互在對應的瀏覽器的WebDriver上,其實你有了對應的瀏覽器的WebDriver,參考W3C的標準接口文檔HTTP-based wire protocol你就能夠單獨實現瀏覽器的操做。就是Client-Server的溝通。全部支持的命令列表以下:api

 

舉個ChromeDriver的例子。。。瀏覽器

  • 首先咱們找到ChromeDriver ,這個天然到chromium項目上去下載就行了。

https://sites.google.com/a/chromium.org/chromedriver/這裏也有不少詳細的接口的說明,這裏的接口說明跟上面的W3C的接口說明差很少。你須要針對不一樣的瀏覽器下載對應的版本。下面我如下載的一個win版本的爲例(下載地址:http://chromedriver.storage.googleapis.com/2.23/chromedriver_win32.zipsession

WebDriver的使用                                                                  

1.1 查看下chromedriver.exe提供給咱們的一些可用的命令。app

image

 

裏面的使用很詳細,這裏咱們只須要使用一個參數來啓動ChromeDriver的server, –port ,命令以下:chromedriver.exe –port 9514,或者直接不輸入端口直接回車,界面命令以下:

image

 

啓動後chromedriver會在本地的9514端口號上進行監聽通訊,根據不一樣的命令發送到瀏覽器上,瀏覽器進行交互。好比啓動一個chrome瀏覽器對應的命令是session,單獨的ChromeDriver的HTTP通訊URI是:http://localhost:9514/session,對於經過RemoteWebDriver的URL是:http://localhost:9514/wd/hub/session

WebDriver -New Session              

 

看一下這個說明: https://www.w3.org/TR/webdriver/#dfn-new-session,操做流程以下:

The remote end steps are:

  1. If the remote end is an intermediary node, take implementation-defined steps that either result in returning an error with error code session not created, or in returning a success with data that is isomorphic to that returned by remote ends according to the rest of this algorithm.

  2. If the maximum active sessions is equal to the length of the list of active sessions, return error with error code session not created.

  3. If there is a current user prompt, return error with error code session not created.

  4. Let capabilities be the result of getting a property named "capabilities" from the parameters argument.

  5. Let capabilities result be the result of processing capabilities with capabilities as an argument.

  6. If capabilities result is an error, return error with error code session not created.

  7. Let capabilities be capabilities result’s data.

  8. Let session id be the result of generating a UUID.

  9. Let session be a new session with the session ID of session id.

  10. Set the current session to session.

  11. Append session to active sessions.

上面的流程已經在最新的Selenium WebDriver中實現了。全部啓動一個瀏覽器作的session操做能夠參考以下核心Selenium代碼邏輯。

1. 第一步設置chromeDriver的路徑後面代碼用到:System.setProperty("webdriver.chrome.driver", "chromedriver.exe");

2. 第二步構建一個命令行對象用於執行chromedriver.exe的命令:

org.openqa.selenium.remote.service.DriverService.Builder.build()

public DS build() {
     if (port == 0) {
       port = PortProber.findFreePort(); //可用的端口號,例如232323,那麼後面用到的命令就是:chromedriver.exe –port 232323
     }

     if (exe == null) {
       exe = findDefaultExecutable();
     }

     ImmutableList<String> args = createArgs();

     return createDriverService(exe, port, args, environment);
   }

1. 核心selenium命令執行類:org.openqa.selenium.remote.RemoteWebDriver.RemoteWebDriver(CommandExecutor, Capabilities, Capabilities)

public RemoteWebDriver(CommandExecutor executor, Capabilities desiredCapabilities,
      Capabilities requiredCapabilities) {
    this.executor = executor;

    init(desiredCapabilities, requiredCapabilities);

    if (executor instanceof NeedsLocalLogs) {
      ((NeedsLocalLogs)executor).setLocalLogs(localLogs);
    }

    try {
      startClient(desiredCapabilities, requiredCapabilities);
    } catch (RuntimeException e) {
      try {
        stopClient(desiredCapabilities, requiredCapabilities);
      } catch (Exception ignored) {
        // Ignore the clean-up exception. We'll propagate the original failure.
      }

      throw e;
    }

    try {
      startSession(desiredCapabilities, requiredCapabilities);
    } catch (RuntimeException e) {
      try {
        quit();
      } catch (Exception ignored) {
        // Ignore the clean-up exception. We'll propagate the original failure.
      }

      throw e;
    }
  }

 

以上的代碼完成了以下的操做:

1. 初始化desiredCapabilities對象,這是發送到客戶端的JSON 數據,

2. 啓動一個session,這裏包含一個判斷,若是這是一個NEW_SESSION,那麼會在上面構建的chromedriver上啓動chromedriver而後在發送session命令。後臺操做HTTP請求用到的是Apache HttpClient的API.

上面說明下WebDriver的通訊是HTTP的協議,所以這裏全部的通訊都是經過JSON Wired進行溝通的RESTFul格式。也就是說全部的溝通都是一次RESTFul的request和response的過程。

參考以下Selenium的說明: https://github.com/SeleniumHQ/selenium/wiki/JsonWireProtocol#command-summary

JSON Request:

image

JSON Response:

image

相關文章
相關標籤/搜索