「Selenium Grid 3」- 使用 Java / Groovy 语言

  CREATED BY JENKINSBOT

我们更多的是在 Jenkins Pipeline 中使用 Selenium 框架,因此需要使用 Groovy 类库。由于没有与之对应的 Groovy 类库,因此只能使用 Java 类库。

还有另外种做法:使用 Python 实现,然后在 Groovy 中命令行调用。但是我们无法使用该方法,因为 Selenime 的自动化测试过程中需要交互、判断,而这种方法无法获取状态,只能输入执行然后等待输出。

相关链接

Maven Repository: org.seleniumhq.selenium » selenium-java(我们使用 Selenium Grid 3 版本)
下载页面:Downloads
接口文档:https://www.selenium.dev/selenium/docs/api/java/index.html

Selenium with Java: Best Practices

连接 Selenium Hub 节点

import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.Platform;

import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.WebDriver;
import java.net.URL;

DesiredCapabilities desiredCapabilities = DesiredCapabilities.chrome();
desiredCapabilities.setBrowserName("chrome");
desiredCapabilities.setPlatform(Platform.LINUX);

String seleniumHubUrl = "http://ip-address:port-number/wd/hub";
WebDriver webDriver = new RemoteWebDriver(new URL(seleniumHubUrl), desiredCapabilities);

设置窗口大小及位置

python – How do I set browser width and height in Selenium WebDriver? – Stack Overflow
Selenium Waits: Implicit, Explicit, Fluent And Sleep

import org.openqa.selenium.Dimension;
import org.openqa.selenium.Point;

webDriver.manage().window().setPosition(new Point(0, 0));
webDriver.manage().window().setSize(new Dimension(1366, 768));

// 窗口最大化
webDriver.manage().window().maximize();

在页面中,选择 HTML 元素

Find Element and FindElements in Selenium WebDriver

// 最常规的用法:通过 ID 选择元素
webDriver.findElement(By.id("buttoncheck"))

// 通过 XPath 选择元素
webDriver.findElement(By.xpath("//div[@id='writeArticleWrapper']//form//input[@type='text' and @name='title']"));

定位元素的方法有很多,比如 ID、Name、Class Name、Tag Name、Link Text、Partial Link Text、XPATH 等等

获取标签内的 HTML 代码(dom.innerHTML)

How to get HTML source of a Web Element in Selenium WebDriver | BrowserStack

element.getAttribute("innerHTML");

向标签内填充 HTML 代码

Modify innerHTML using Selenium – Stack Overflow

WebElement element = ...
((JavascriptExecutor)driver).executeScript("arguments[0].innerHTML = '<h1>H1</h1>';", element);

对于复杂的 HTML 代码填充

java – put a string with html/Javascript into selenium webdriver – Stack Overflow

在我们的 HTML 内容中,经常会包含复杂的内容,比如单引号、双引号,会破坏 Javascript 语法,导致代码无法执行。

解决方法如下(如下是 Groovy 代码):

@Grab(group='commons-lang', module='commons-lang', version='2.6') // 正好的 Jenkins 所依赖的版本一致
import org.apache.commons.lang.StringEscapeUtils;

String htmlContent = StringEscapeUtils.escapeJavaScript(postInfo.content)
((JavascriptExecutor) webDriver).executeScript("arguments[0].innerHTML = '${htmlContent}';", bodyElement);

判断页面是否加载完成

java – Wait for page load in Selenium – Stack Overflow
java – Selenium — How to wait until page is completely loaded – Stack Overflow

new WebDriverWait(webDriver, 30).until(new Function<WebDriver, Boolean>() {
	@Override
	public Boolean apply(WebDriver tmpWebDriver) {
		Object pageReady = ((JavascriptExecutor) tmpWebDriver).executeScript("return document.readyState;");
		return "complete".equals(pageReady.toString());
	}
});

切换标签 / 关闭标签

selenium – Is there a way to close a tab in WebDriver or Protractor? – Stack Overflow
java – Clicking links in newly opened tab using WebDriver – Stack Overflow
testing – Switch tabs using Selenium WebDriver with Java – Stack Overflow

我们在点击 a 标签之后,可能会打开新的标签,那么如何切换到新的标签页呢:

// 获取当前标签页句柄
String oldTab = driver.getWindowHandle();

// 获取所有标签句柄
ArrayList<String> handles = new ArrayList<String>(driver.getWindowHandles());

// 切换到新的标签页,
// handles.get(0) 是最开始的标签(即是 oldTab 变量),
// 而 handles.get(1) 新的标签页;
driver.switchTo().window(handles.get(1));

// 切换会原有标签
driver.switchTo().window(oldTab); // driver.switchTo().window(handles.get(0));

// 关闭当前标签页(按照如上代码顺序,这里关闭 oldTab 标签)
driver.close() // 注意区分 quit() 与 close() 方法,这里不再赘述

// 注意事项:因为我们清楚 a 标签打开页面的行为,即在新标签中打开,因此才这样编写代码。如果 a 标签在
// 当前页面中打开,则无需进行切换。
// 如果不清楚 a 标签的行为,则需要我们自己进行判断,比如根据 target 属性。

参考文献

Selenium Grid Tutorial: Hub & Node (with Example)
Selenium Java / API / Overview