Selenium系列之--07 操作远程浏览器

时间:2024-03-07 13:26:17

JsonWireProtocol(简称JWP)是通过使用webdriver与remote server进行通信的web service 协议。通过http请求,完成和remote server的交互。

 

Selenium远程控制浏览,可以通过如下两种方式实现,本质上都是Selenium Grid

a.  客户机启Selenium Standalone Server 作为远程服务,服务端通过调用RemoteWebDriver类来实现调用客户机浏览器;

b.  通过部署Selenium Grid 实现分布式执行UI自动化测试;

一、环境准备

1. 安装JDK(jdk1.8.0_101);
2. 下载安装firefox,chrome浏览器 ;
3. 下载selenium-server-standalone.jar (官方下载地址);
4. 下载InternetExplorerDriver,ChromeDriver,geckodriver(selenium3.0以及之后的版本支持的firefox driver)

二、RemoteWebDriver

Selenium框架的远程控制主要是通过RemoteWebDriver这个类来实现的。

本例中【测试代码放在服务器上,执行代码的机器为客户机】

客户机操作

2.1. 首先配置JDK,并配置环境变量,增加放WebDriver文件的地址(即将相应的WebDriver文件夹配置到环境变量的path中)

2.2. 启动独立测试jar包(注意JAR包的版本号)

java -jar E:\Selenium\selenium-server-standalone-2.46.0.jar

服务端操作

2.3. 验证客户端响应是否正常。在浏览器中输入地址:http://客户机IP地址:4444/wd/hub/ ,显示如下页面。

2.4. 写测试代码,通过RemoteWebDriver调用客户机

import java.net.MalformedURLException;
import java.net.URL;

import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.remote.RemoteWebDriver;

public class RemoteIEBrowser {
    public static void main(String[] args) throws MalformedURLException, InterruptedException {
        // RemoteWebDriver的基本使用

        //第一个参数:表示服务器的地址。第二个参数:表示预期的执行对象,其他的浏览器都可以以此类推
        WebDriver driver = new RemoteWebDriver(new URL("http://10.10.12.162:4444/wd/hub/"), DesiredCapabilities.internetExplorer());
        driver.manage().window().maximize();
        driver.get("http://www.baidu.com");
        Thread.sleep(2000);
        JavascriptExecutor js = (JavascriptExecutor)driver;
        js.executeScript("alert(\'我现在在服务器\')");
        Thread.sleep(2000);
        driver.quit();
   }
}

2.5. 执行脚本。执行过程中可以看到客户端的浏览器被调用,同时cmd窗口中打印出相关的运行信息,如下 

三、Selenium GRID

Selenium Grid 用于解决分布式执行UI测试的痛点,Selenium2之后Selenium Grid被集成到了 Selenium Server 中,即包含在 selenium-server-standalone-x-x-x.jar 包中,其结构图如下所示:

 

Selenium Grid实际它是基于Selenium RC的,而所谓的分布式结构就是由一个hub节点和若干个node代理节点组成。Hub用来管理各个代理节点的注册信息和状态信息,并且接受远程客户端代码的请求调用,然后把请求的命令转发给代理节点来执行。

  • 3.1. 启动HUB,脚本如下,

java -jar selenium-server-standalone-2.46.0.jar -role hub -maxSession 10 -port 4444
 
-role hub :启动的是HUB,
-maxSession :最大会话数量
-prot:指定端口

  • 3.2. 测试HUB是否启动成功

验证hub是否正常启动正常。在浏览器中输入地址:http://客户机IP地址:4444/grid/console/ ,显示如下页面。

  • 3.3. 启动NODE节点
java -Dwebdriver.IE.driver=E:\Selenium\IEDriverServer.exe -jar E:\Selenium\selenium-server-standalone-2.46.0.jar -role node -port 6666 -hub http://10.10.12.161:4444/grid/register -browser browserName=IE

-role node :启动的是node节点 -hub :hub 的地址及端口号 -Dwebdriver.chrome.driver:驱动类型 -maxSession :最大会话数量 -browserName:浏览器名称 -注意,有些参数如果不必要时,是可以不用写的,比如platform是系统.
  • 3.4. hub端浏览器刷新页面http://localhost:4444/grid/console,这里也可以看见node节点的情况.

  • 3.5. 调用NODE也是通过RemoteWebDriver对象. 代码同2.4
// 封装方法如下:

public static WebDriver getRemoteIEDriver(String myUrl) { try { DesiredCapabilities capabilities = DesiredCapabilities .internetExplorer(); URL urlInstance = new URL(myUrl); // 指定URL WebDriver driver = new RemoteWebDriver(urlInstance, capabilities); // 使用RemoteWebDriver初始化 logger.info("远程浏览器启动完成!"); return driver; } catch (Exception e) { logger.error("远程浏览器启动失败!"); logger.error("===============>" + e.getMessage().toString()); e.printStackTrace(); return null; } }

测试类如下:

public class RemoteIEBrowser {

    public static void main(String[] args) throws MalformedURLException, InterruptedException {
        // RemoteWebDriver的基本使用

        //第一个参数:表示服务器的地址。第二个参数:表示预期的执行对象,其他的浏览器都可以以此类推
        WebDriver driver = getRemoteIEDriver("http://10.10.12.162:6666/wd/hub/");

        // WebDriver driver = getRemoteIEDriver("http://10.10.12.161:4444/wd/hub/");
        driver.manage().window().maximize();
        driver.get("http://www.baidu.com");
        Thread.sleep(2000);
        JavascriptExecutor js = (JavascriptExecutor)driver;
        js.executeScript("alert(\'我现在在服务器\')");
        Thread.sleep(2000);
        driver.quit();
   }

}

 注意此时可以通过调用hub节点,由hub自动实现分发,也可以直接调用某个node节点

衍生问题

问题1. 直接调用hub分发任务时,怎么查看分发实际上运行在那台服务上(IP)

代码如下

public static String getRemoteIp(String hub, int port, WebDriver driver) {
        String node = "";
        try {
            HttpHost host = new HttpHost(hub, port);
            DefaultHttpClient client = new DefaultHttpClient();
            URL session = new URL("http://" + hub + ":" + port
                    + "/grid/api/testsession?session="
                    + ((RemoteWebDriver) driver).getSessionId());
            BasicHttpEntityEnclosingRequest req = new BasicHttpEntityEnclosingRequest(
                    "POST", session.toExternalForm());
            HttpResponse response = client.execute(host, req);
            Map<String, Object> map = new HashMap<String, Object>();
            map = new Gson().fromJson(
                    EntityUtils.toString(response.getEntity()), map.getClass());
            String proxyId = (String) map.get("proxyId");
            node = (proxyId.split("//")[1].split(":")[0]);
            logger.info("WebDriver running in node:" + node);
        } catch (Exception ex) {
            logger.error("===============>" + ex.getMessage().toString());
            ex.printStackTrace();
        }
        return node;
    }

 参考资料

问题2 Selenium grid configuration using JSON File:

SELENIUM 3.0 OR ABOVE

SELENIUM 2.0 

----hub
java -jar selenium-server-standalone-2.46.0.jar -role hub -hubConfig hubconfig.json

----node
Java -Dwebdriver.chrome.driver="chromedriver.exe" -Dwebdriver.ie.driver="IEDriverServer.exe" -Dwebdriver.gecko.driver="geckodriver.exe" -jar selenium-server-standalone-2.46.0.jar -role node -nodeConfig grid-node.json

 Selenium grid配置参数:

-throwOnCapabilityNotPresent: [true|false]
默认为true,如果为true则hub只有在当前有测试代理注册的情况下才会接受测试请求;如果为false则如果当前没有代理注册也会接受请求保存到队列直到有代理注册为止。

-capabilityMatcher:xxx
一个实现了CapabilityMatcher接口的类,默认指向org.openqa.grid.internal.utils.DefaultCapabilityMatcher;该类用于实现grid在分布测试任务到对应代理时所使用的匹配规则,如果想要更精确的测试分配规则,那么就注册一个自己定义的匹配类。

-prioritizer:XXXclass
一个实现了Prioritizer接口的类。设置grid执行test任务的优先逻辑;默认为null,先来先执行。

-newSessionWaitTimeout:XXX
默认-1,即没有超时;指定一个新的测试session等待执行的间隔时间。即一个代理节点上前后2个测试中间的延时时间,单位为毫秒。

-servlets: XXXserlet
在hub上注册一个新的serlet,访问地址为/grid/admin/XXXserlet

-browserTimeout:
浏览器无响应的超时时间

-role: [node|wd|rc]
为node值时表示注册的RC可以支持selenium1、selenium2两种方式的测试请求,推荐;
为wd值时表示注册的RC仅支持selenium2的webdriver方式的测试请求,遗留;
为rc值时表示注册的RC仅支持selenium1方式的测试请求,遗留。

-hub:url_to_hub
url_to_hub值为hub启动的注册地址,默认为ttp://ip_for_hub:4444/grid/register;具体的根据你启动hub时的参数所对应。
该选项包含了-hubHost和-hubPort两个选项

-registerCycle:xxx
代理节点自动重新注册的周期,单位毫秒;适应于重启了hub时不需要重启所有的代理节点。

-nodePolling:XXX
hub检查代理节点的周期

-unregisterIfStillDownAfter:XXX
单位毫秒,设定代理节点在无响应多长时间后hub才会注销代理节点注册信息;默认1分钟

-nodeTimeout:xxx
客户端的无心跳超时时间

-maxSession:xx
一个代理节点可以同时启动的浏览器最大数量,即session数量

-cleanupCycle:XXX
代理节点检查超时的周期

Selenium Grid 总结(转)

  • Selenium Grid is used to run multiple tests simultaneously on different browsers and platforms.
  • Grid uses the hub-node concept.
  • The hub is the central point wherein you load your tests.
  • Nodes are the Selenium instances that will execute the tests that you loaded on the hub.
  • To install Selenium Grid, you only need to download the Selenium Server jar file - the same file used in running Selenium RC tests.
  • There are 2 ways to verify if the hub is running: one was through the command prompt, and the other was through a browser
  • To run test scripts on the Grid, you should use the DesiredCapabilities and the RemoteWebDriver objects.
  • DesiredCapabilites is used to set the type of browser and OS that we will automate
  • RemoteWebDriver is used to set which node (or machine) that our test will run agains

Original URL: https://www.guru99.com/introduction-to-selenium-grid.html