有问题请回帖
下载地址
selenium下载地址
https://goo.gl/4g538W
http://shell.testing-studio.com/download/selenium/
appium grid的支持
https://github.com/appium/appium/blob/master/docs/en/advanced-concepts/grid.md
参考命令
tcpdump -i any port 4723 -w tcpdump.log
gem install em-proxy
em-proxy -l 5723 -r 127.0.0.1:4723 -v
#启动hub
java -jar ~/DownloadsMacBook-Pro-2:~ seveniruby$ java -jar ~/Downloads/selenium-server-standalone-3.13.0.jar -role hub
#启动node注册到hub
java -jar ~/Downloads/selenium-server-standalone-3.13.0.jar -role node -hub http://192.168.31.99:4444/grid/register
#appium注册为node
appium --nodeconfig android_1.json
参考用例代码
@Test
public void chrome() throws IOException {
DesiredCapabilities capabilities=new DesiredCapabilities();
ChromeOptions chromeOptions=new ChromeOptions();
//chromeOptions.addArguments("headless");
//chromeOptions.addArguments("window-size=400,1024");
//chromeOptions.addArguments("user-agent=\\"Mozilla/5.0 (Linux; Android 4.4.2; Nexus 4 Build/KOT49H) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/34.0.1847.114 Mobile Safari/537.36\\"");
capabilities.setCapability(ChromeOptions.CAPABILITY, chromeOptions);
RemoteWebDriver driver=new RemoteWebDriver(new URL("http://127.0.0.1:5555/wd/hub"), capabilities);
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
driver.get("http://www.baidu.com");
FileUtils.copyFile(driver.getScreenshotAs(OutputType.FILE), new File("1.png"));
}
appium node配置
{
"capabilities":
[
{
"browserName": "chrome",
"version": "6.0",
"maxInstances": 1,
"platform": "android"
}
],
"configuration":
{
"cleanUpCycle": 2000,
"timeout": 30000,
"proxy": "org.openqa.grid.selenium.proxy.DefaultRemoteProxy",
"url": "http://192.168.31.99:4723/wd/hub",
"host": "192.168.31.99",
"port": 4723,
"maxSession": 1,
"register": true,
"registerCycle": 5000,
"hubPort": 4444,
"hubHost": "192.168.31.99",
"hubProtocol": "http"
}
}
微信小程序测试
@Test
public void testDianPing() throws IOException, InterruptedException {
String processName = "com.tencent.mm:appbrand0";
String packageName = "com.tencent.mm";
String activityName = ".ui.LauncherUI";
DesiredCapabilities caps = new DesiredCapabilities();
caps.setCapability("deviceName", "dd");
caps.setCapability("automationName", "uiautomator2");
caps.setCapability("appPackage", packageName);
caps.setCapability("appActivity", activityName);
//如果没有这个设置你的微信聊天记录就会被清空
caps.setCapability("noReset", true);
//caps.setCapability("dontStopAppOnReset", true);
caps.setCapability("chromedriverExecutableDir", "/Users/seveniruby/projects/chromedriver/2.29");
caps.setCapability("showChromedriverLog", true);
//低版本的chromedriver在高版本的android上有个兼容性的bug,需要自己定制解决方案
//caps.setCapability("adbPort", 5038);
//todo: appium java client 6.0.0 有多个bug,待修复
ChromeOptions chromeOptions = new ChromeOptions();
//chromeOptions.setExperimentalOption("androidUseRunningApp", true);
//chromeOptions.setExperimentalOption("androidPackage", packageName);
//chromeOptions.setExperimentalOption("androidActivity", activityName);
chromeOptions.setExperimentalOption("androidProcess", processName);
//caps.setCapability(ChromeOptions.CAPABILITY, chromeOptions);
caps.setCapability("chromeOptions", chromeOptions);
//todo: 6.0.0独有的bug,会自动设置browserName
caps.setCapability("browserName", "");
System.out.println(caps.asMap());
URL url = new URL("http://127.0.0.1:4723/wd/hub");
AndroidDriver driver = new AndroidDriver(url, caps);
//todo: 5.0.3不支持1.8.1的timeout接口
//driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
Thread.sleep(5000);
driver.findElementByXPath("//*[@text='通讯录']");
//滑动
swipe(driver);
System.out.println("点击小程序");
driver.findElementByXPath("//*[contains(@text, '点评')]").click();
System.out.println("打印上下文");
for (int i = 0; i < 3; i++) {
System.out.println(driver.getContextHandles());
Thread.sleep(1000);
}
System.out.println("切换上下文到 " + "WEBVIEW_" + processName);
driver.context("WEBVIEW_" + processName);
System.out.println(driver.getContextHandles());
System.out.println(driver.getContext());
System.out.println(driver.getPageSource());
System.out.println("打印上下文,寻找小程序界面");
System.out.println(driver.getWindowHandles());
for (String window : driver.getWindowHandles()) {
driver.switchTo().window(window);
System.out.println("windows=" + window);
String source = driver.getPageSource();
if (source.contains("<wx-view")) {
System.out.println(source);
break;
}
}
driver.findElementByXPath("//*[contains(text(), '外卖')]").click();
//6.0 beta5 修复了timeout问题
}
/*
public void swipe(AppiumDriver driver) {
Dimension size = driver.manage().window().getSize();
System.out.println(size);
new TouchAction(driver)
.press(
(int) (size.getWidth() * 0.5),
(int) (size.getHeight() * 0.3)
)
.waitAction(Duration.ofSeconds(2))
.moveTo(
(int) (size.getWidth() * 0.5),
(int) (size.getHeight() * 0.9)
)
.release()
.perform();
}*/
public void swipe(AppiumDriver driver) {
Dimension size = driver.manage().window().getSize();
System.out.println(size);
new TouchAction(driver)
.press(
PointOption.point(
(int) (size.getWidth() * 0.5),
(int) (size.getHeight() * 0.3)
)
)
.waitAction(
WaitOptions.waitOptions(
Duration.ofSeconds(2)
)
)
.moveTo(
PointOption.point(
(int) (size.getWidth() * 0.5),
(int) (size.getHeight() * 0.9))
)
.release()
.perform();
}
PageObject
package xueqiu4.page;
import io.appium.java_client.AppiumDriver;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
public class Page首页 {
private AppiumDriver<WebElement> driver;
By 自选=By.xpath("//*[@text='自选']");
By 问答广场 =By.xpath("//*[@text='问答广场']");
By 跳过=By.xpath("//*[@text='跳过']");
public Page自选 进入自选() throws InterruptedException {
Thread.sleep(5000);
driver.findElement(跳过).click();
Thread.sleep(2000);
driver.findElement(自选).click();
return new Page自选(driver);
}
public Page首页(AppiumDriver driver){
this.driver=driver;
}
}
package xueqiu4.page;
import io.appium.java_client.AppiumDriver;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import java.util.ArrayList;
import java.util.List;
public class Page自选 {
private AppiumDriver<WebElement> driver;
By 股票=By.xpath("//*[@text='股票']");
By 沪深=By.xpath("//*[@text='沪深']");
By stockName=By.id("stockName");
List<String> stocks=new ArrayList<>();
public List<String> get沪深股票(){
driver.findElement(股票).click();
driver.findElement(沪深).click();
for(WebElement element: driver.findElements(stockName)){
stocks.add(element.getText());
};
return stocks;
}
public Page自选(AppiumDriver driver){
this.driver=driver;
}
}
package xueqiu4.testcase;
import io.appium.java_client.AppiumDriver;
import io.appium.java_client.android.AndroidDriver;
import io.appium.java_client.android.AndroidElement;
import org.junit.BeforeClass;
import org.junit.Test;
import org.openqa.selenium.remote.DesiredCapabilities;
import xueqiu4.page.Page首页;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.List;
import java.util.concurrent.TimeUnit;
import org.hamcrest.CoreMatchers.*;
import static org.junit.Assert.assertThat;
import static org.hamcrest.number.OrderingComparison.*;
public class Test自选 {
public static AppiumDriver driver;
@BeforeClass
public static void beforeClass() throws MalformedURLException, InterruptedException {
DesiredCapabilities capabilities = new DesiredCapabilities();
capabilities.setCapability("platformName", "Android");
capabilities.setCapability("deviceName", "iPhone 6");
capabilities.setCapability("appPackage", "com.xueqiu.android");
capabilities.setCapability("appActivity", ".view.WelcomeActivityAlias");
capabilities.setCapability("automationName", "uiautomator2");
capabilities.setCapability("noReset", false);
capabilities.setCapability("chromedriverExecutableDir", "/Users/seveniruby/projects/chromedriver/2.20");
driver=new AndroidDriver<AndroidElement>(new URL("http://127.0.0.1:4723/wd/hub"), capabilities);
driver.manage().timeouts().implicitlyWait(20, TimeUnit.SECONDS);
}
@Test
public void test沪深股票() throws InterruptedException {
Page首页 page首页=new Page首页(driver);
List<String> stocks=page首页.进入自选().get沪深股票();
assertThat(stocks.size(), greaterThan(5));
}
}
基于Java注解或者Python装饰器模式的代码
package pages.xueqiudemo;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
public class MainPage {
@FindBy(xpath = "//*[@text='自选']")
WebElement 自选;
@FindBy(xpath = "//*[@text='行情']")
WebElement 行情;
@FindBy(id = "cancel")
WebElement cancel;
public Page自选 goto自选(){
cancel.click();
自选.click();
return new Page自选();
}
}
作业
进入雪球的行情页,断言上证指数指数超过3000点。