一、 What? 什么是PageObject?
简称PO,这是一个设计模式,其实设计模式就是代码的架构,一个整体的框架。例如mvc 就是模型-视图-控制的一个代码架构,mvp就是-模型-视图-主持 这样的一个架构。PageObject翻译过来就是页面对象的意思,就是把页面对象和逻辑操作分开。结合封装,更加方便使用(不明白? 下面看demo)
二、 PageObject的好处
做UI自动化时定位特别依赖页面,一旦页面发生变更就不得不跟着去修改页面定位。
,假设你想对一个元素定位操作,你可能会编写下面的代码:
driver.findElement(By.id("comit")).click()
于是问题就出来了,这样代码冗余就高了。都写一块了,后期难维护。你有10个地方对这个元素做了这个操作,哪天这个控件的元素变了,你就不得不去修改10个地方。
那么po的好处就出来了,方便维护、减少代码冗余、逼格高
三、PO模式重封装
1.目录格式结构
- base //放封装好的基类
- cases //用例
- opeartion //放逻辑处理
- pages //页面元素处理
2. 重新封装
每层一个父类,driver使用静态,每个用例可以连续执行。封装类里面用到的Builder和Assertion在之前的文章已经贴出来了,这里就不再次贴了。
用例基类 InitAppium.Java,每个用例继承这个类,直接加注解@Test,调用operate 层的方法即可
package com.example.base;
import org.apache.http.util.TextUtils;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.testng.annotations.AfterClass;
import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeSuite;
import org.testng.annotations.Listeners;
import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
import io.appium.java_client.android.AndroidDriver;
import io.appium.java_client.android.AndroidElement;
/**
* 测试用例的父类
* Created by LITP on 2016/9/7.
*/
@Listeners({com.example.base.AssertionListener.class})
public class InitAppium {
public static String deviceName = "minote";
public static String platformVersion = "4.4.2";
public static String appPath = System.getProperty("user.dir") + "/src/main/java/apps/shouhu2.2.3.apk";
public static String appPackage = "com.minstone.mdoctor";
public static String noReset = "True";
public static String noSign = "True";
public static String unicodeKeyboard = "True";
public static String resetKeyboard = "True";
public static String appActivity = "";
public static AndroidDriver<AndroidElement> driver = null;
public InitAppium() {
this(new Builder());
}
public InitAppium(Builder builder) {
appActivity = builder.appActivity;
appPackage = builder.appPackage;
appPath = builder.appPath;
deviceName = builder.deviceName;
noReset = builder.noReset;
noSign = builder.noSign;
unicodeKeyboard = builder.unicodeKeyboard;
resetKeyboard = builder.resetKeyboard;
}
/**
* appium启动参数
*
* @throws MalformedURLException
*/
@BeforeSuite
public void beforeSuite() throws MalformedURLException {
DesiredCapabilities capabilities = new DesiredCapabilities();
capabilities.setCapability("deviceName", deviceName);
capabilities.setCapability("platformVersion", platformVersion);
capabilities.setCapability("app", new File(appPath).getAbsolutePath());
capabilities.setCapability("appPackage", appPackage);
capabilities.setCapability("unicodeKeyboard", unicodeKeyboard);
capabilities.setCapability("resetKeyboard", resetKeyboard);
capabilities.setCapability("noReset", noReset);
capabilities.setCapability("noSign", noSign);
if(!TextUtils.isEmpty(appActivity)){
capabilities.setCapability("appActivity", appActivity);
}
driver = new AndroidDriver<>(new URL("http://127.0.0.1:4723/wd/hub"), capabilities);
}
@AfterTest
public void afterTest() {
driver.quit();
}
@AfterClass
public void afterClass(){
}
/**
* 打印字符
*
* @param str 要打印的字符
*/
public <T> void print(T str) {
if (!TextUtils.isEmpty(String.valueOf(str))) {
System.out.println(str);
} else {
System.out.println("输出了空字符");
}
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
- 117
- 118
- 119
- 120
- 121
- 122
- 123
- 124
- 125
- 126
- 127
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
- 117
- 118
- 119
- 120
- 121
- 122
- 123
- 124
- 125
- 126
- 127
逻辑操作基类OperateAppium.java:,逻辑功能类继承这个类,在这里获取页面控件使用page层的对象
package com.example.base;
import org.apache.http.util.TextUtils;
import org.openqa.selenium.By;
import org.openqa.selenium.TimeoutException;
import java.util.List;
import java.util.concurrent.TimeUnit;
import io.appium.java_client.MultiTouchAction;
import io.appium.java_client.TouchAction;
import io.appium.java_client.android.AndroidDriver;
import io.appium.java_client.android.AndroidElement;
import static com.example.base.InitAppium.appPackage;
import static io.appium.java_client.android.AndroidKeyCode.BACKSPACE;
import static io.appium.java_client.android.AndroidKeyCode.KEYCODE_MOVE_END;
/**
* 逻辑处理父类
* Created by LITP on 2016/9/22.
*/
public class OperateAppium {
AndroidDriver driver;
TouchAction touchAction;
MultiTouchAction multiTouchAction;
private static int WAIT_TIME = 10;
private final int SWIPE_DEFAULT_PERCENT = 5;
public final String SWIP_UP = "UP",
SWIP_DOWN = "DOWN",
SWIP_LEFT = "LEFT",
SWIP_RIGHT = "RIGHT";
public OperateAppium(AndroidDriver androidDriver) {
this.driver = androidDriver;
}
/**
* 打印字符
*
* @param str 要打印的字符
*/
public <T> void print(T str) {
if (!TextUtils.isEmpty(String.valueOf(str))) {
System.out.println(str);
} else {
System.out.println("输出了空字符");
}
}
/**
* Click点击空格键
*
* @param ae 要点击的控件
* @return 返回是否点击
*/
public boolean clickView(AndroidElement ae) {
return clickView(ae, "");
}
/**
* Click点击控件
*
* @param ae 控件
* @param str 控件的文字描述,供错误时候输出
* @return 返回是否存在控件
*/
public boolean clickView(AndroidElement ae, String str) {
if (ae != null) {
ae.click();
return true;
} else {
print(str + "为空,点击错误");
}
return false;
}
/**
* 线程休眠秒数,单位秒
*
* @param s 要休眠的秒数
*/
public void sleep(long s) {
try {
Thread.sleep(s);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
/**
* 获取当前的activity,返回文件名
*
* @return
*/
public String getCurrActivity() {
String str = driver.currentActivity();
return str.substring(str.lastIndexOf(".") + 1);
}
/**
* 获取触摸实例
*
* @return
*/
public TouchAction getTouch() {
if (driver == null) {
print("单点触摸时候driver为空");
return null;
} else {
if (touchAction == null) {
return new TouchAction(driver);
} else {
return touchAction;
}
}
}
/**
* 获取多点触摸实例
*
* @return
*/
public MultiTouchAction getMultiTouch() {
if (driver == null) {
print("多点触摸时候driver为空");
return null;
} else {
if (multiTouchAction == null) {
return new MultiTouchAction(driver);
} else {
return multiTouchAction;
}
}
}
/**
* 往控件输入字符串
*
* @param ae 要输入的控件
* @param str 要输入的字符串
*/
public void input(AndroidElement ae, String str) {
if (ae == null) {
print("控件为空,输入内容失败:" + str);
} else {
ae.sendKeys(str);
}
}
public void swipeToUp(int during) {
swipeToUp(during, SWIPE_DEFAULT_PERCENT);
}
/**
* 向上滑动,
*
* @param during
*/
public void swipeToUp(int during, int percent) {
int width = getScreenWidth();
int height = getScreenHeight();
driver.swipe(width / 2, height * (percent - 1) / percent, width / 2, height / percent, during);
}
public void swipeToDown(int during) {
swipeToDown(during, SWIPE_DEFAULT_PERCENT);
}
/**
* 向下滑动,
*
* @param during 滑动时间
*/
public void swipeToDown(int during, int percent) {
int width = getScreenWidth();
int height = getScreenHeight();
driver.swipe(width / 2, height / percent, width / 2, height * (percent - 1) / percent, during);
}
public void swipeToLeft(int during) {
swipeToLeft(during, SWIPE_DEFAULT_PERCENT);
}
/**
* 向左滑动,
*
* @param during 滑动时间
* @param percent 位置的百分比,2-10, 例如3就是 从2/3滑到1/3
*/
public void swipeToLeft(int during, int percent) {
int width = getScreenWidth();
int height = getScreenHeight();
driver.swipe(width * (percent - 1) / percent, height / 2, width / percent, height / 2, during);
}
public void swipeToRight(int during) {
swipeToRight(during, SWIPE_DEFAULT_PERCENT);
}
/**
* 向右滑动,
*
* @param during 滑动时间
* @param percent 位置的百分比,2-10, 例如3就是 从1/3滑到2/3
*/
public void swipeToRight(int during, int percent) {
int width = getScreenWidth();
int height = getScreenHeight();
driver.swipe(width / percent, height / 2, width * (percent - 1) / percent, height / 2, during);
}
/**
* 显示等待,等待Id对应的控件出现time秒,一出现马上返回,time秒不出现也返回
*/
public AndroidElement waitAuto(By by, int time) {
try {
return new AndroidDriverWait(driver, time)
.until(new ExpectedCondition<AndroidElement>() {
@Override
public AndroidElement apply(AndroidDriver androidDriver) {
return (AndroidElement) androidDriver.findElement(by);
}
});
} catch (TimeoutException e) {
print("查找元素超时!! " + time + " 秒之后还没找到元素 [" + by.toString() + "]");
return null;
}
}
public AndroidElement waitAutoById(String id) {
return waitAutoById(id, WAIT_TIME);
}
public AndroidElement waitAutoById(String id, int time) {
return waitAuto(By.id(id), time);
}
public AndroidElement waitAutoByName(String name) {
return waitAutoByName(name, WAIT_TIME);
}
public AndroidElement waitAutoByName(String name, int time) {
return waitAuto(By.name(name), time);
}
public AndroidElement waitAutoByXp(String xPath) {
return waitAutoByXp(xPath, WAIT_TIME);
}
public AndroidElement waitAutoByXp(String xPath, int time) {
return waitAuto(By.xpath(xPath), time);
}
public void waitAuto() {
waitAuto(WAIT_TIME);
}
/**
* ,隐式等待,如果在指定时间内还是找不到下个元素则会报错停止脚本
* 全局设定的,find控件找不到就会按照这个事件来等待
*
* @param time 要等待的时间
*/
public void waitAuto(int time) {
driver.manage().timeouts().implicitlyWait(time, TimeUnit.SECONDS);
}
/**
* 打开Activity
*
* @param activityName activity的名字
*/
public void startActivity(String activityName) {
driver.startActivity(appPackage, activityName);
}
/**
* 获取当前界面的所有EditText,并依次输入内容
*
* @param str 要输入的数组
*/
public void inputManyText(String... str) {
List<AndroidElement> textFieldsList = driver.findElementsByClassName("android.widget.EditText");
for (int i = 0; i < str.length; i++) {
textFieldsList.get(i).click();
clearText(textFieldsList.get(i));
textFieldsList.get(i).sendKeys(str[i]);
}
}
/**
* 点击屏幕中间
*/
public void press() {
press(getScreenWidth() / 2, getScreenHeight() / 2);
}
/**
* 点击某个控件
*
* @param ae 要点击的控件
*/
public void press(AndroidElement ae) {
try {
getTouch().tap(ae).perform();
} catch (Exception e) {
print("tab点击元素错误" + e.getMessage());
e.printStackTrace();
}
}
/**
* 点击某个坐标
*
* @param x
* @param y
*/
public void press(int x, int y) {
try {
driver.tap(1, x, y, 500);
print("tab点击位置(" + x + "," + y + ")");
} catch (Exception e) {
print("tab点击元素位置异常" + e.getMessage());
e.printStackTrace();
}
}
/**
* 长按某个控件
*
* @param ae 要点击的控件
*/
public void longPress(AndroidElement ae) {
try {
getTouch().longPress(ae).release().perform();
} catch (Exception e) {
print("长按点击元素错误" + e.getMessage());
e.printStackTrace();
}
}
/**
* 长按某个坐标
*
* @param x
* @param y
*/
public void longPress(int x, int y) {
try {
getTouch().longPress(x, y).release().perform();
} catch (Exception e) {
print("长按点击元素错误" + e.getMessage());
e.printStackTrace();
}
}
/**
* 在控件上滑动
*
* @param element 要滑动的控件
* @param direction 方向,事件不设置默认1秒
*/
public void swipOnElement(AndroidElement element, String direction) {
swipOnElement(element, direction, 1000);
}
/**
* 在某一个控件上滑动
*
* @param element 在那个元素上滑动
* @param direction 方向,UP DOWN LEFT RIGHT
*/
public void swipOnElement(AndroidElement element, String direction, int duration) {
int x = element.getLocation().getX();
int y = element.getLocation().getY();
int width = element.getSize().getWidth();
int height = element.getSize().getHeight();
switch (direction) {
case SWIP_UP:
int startX = x + width / 2;
driver.swipe(startX, y + height * 4 / 5, startX, y + height / 5, duration);
break;
case SWIP_DOWN:
startX = x + width / 2;
driver.swipe(startX, y + height / 5, startX, y + height * 4 / 5, duration);
break;
case SWIP_LEFT:
int startY = y + width / 2;
driver.swipe(x + width * 4 / 5, startY, x + width / 5, startY, duration);
break;
case SWIP_RIGHT:
startY = y + width / 2;
driver.swipe(x + width / 5, startY, x + width * 4 / 5, startY, duration);
break;
}
}
/**
* 在某个方向上滑动
*
* @param direction 方向,UP DOWN LEFT RIGHT
* @param duration 持续时间
*/
public void swip(String direction, int duration) {
switch (direction) {
case "UP":
swipeToUp(duration);
break;
case "DOWN":
swipeToDown(duration);
break;
case "LEFT":
swipeToLeft(duration);
break;
case "RIGHT":
swipeToRight(duration);
break;
}
}
/**
* 在指定次数的条件下,某个方向滑动,直到这个元素出现
*
* @param by 控件
* @param direction 方向,UP DOWN LEFT RIGHT
* @param duration 滑动一次持续时间
* @param maxSwipNum 最大滑动次数
*/
public void swipUtilElementAppear(By by, String direction, int duration, int maxSwipNum) {
int i = maxSwipNum;
Boolean flag = true;
while (flag) {
try {
if (i <= 0) {
flag = false;
}
driver.findElement(by);
flag = false;
} catch (Exception e) {
i--;
swip(direction, duration);
}
}
}
/**
* 在某个方向滑动直到这个元素出现
*
* @param by 控件
* @param direction 方向,UP DOWN LEFT RIGHT
* @param duration 滑动一次持续时间
*/
public void swipUtilElementAppear(By by, String direction, int duration) {
Boolean flag = true;
while (flag) {
try {
driver.findElement(by);
flag = false;
} catch (Exception e) {
swip(direction, duration);
}
}
}
/**
* 获取屏幕的宽高
*
* @return 返回宽高的数组
*/
public int[] getScreen() {
int width = driver.manage().window().getSize().getWidth();
int height = driver.manage().window().getSize().getHeight();
return new int[]{width, height};
}
/**
* 获取屏幕宽度
*
* @return
*/
public int getScreenWidth() {
return driver.manage().window().getSize().getWidth();
}
/**
* 获取屏幕高度
*
* @return
*/
public int getScreenHeight() {
return driver.manage().window().getSize().getHeight();
}
/**
* 逐字删除编辑框中的文字
*
* @param element 文本框架控件
*/
public void clearText(AndroidElement element) {
String text = element.getText();
driver.pressKeyCode(KEYCODE_MOVE_END);
for (int i = 0; i < text.length(); i++) {
driver.pressKeyCode(BACKSPACE);
}
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
- 117
- 118
- 119
- 120
- 121
- 122
- 123
- 124
- 125
- 126
- 127
- 128
- 129
- 130
- 131
- 132
- 133
- 134
- 135
- 136
- 137
- 138
- 139
- 140
- 141
- 142
- 143
- 144
- 145
- 146
- 147
- 148
- 149
- 150
- 151
- 152
- 153
- 154
- 155
- 156
- 157
- 158
- 159
- 160
- 161
- 162
- 163
- 164
- 165
- 166
- 167
- 168
- 169
- 170
- 171
- 172
- 173
- 174
- 175
- 176
- 177
- 178
- 179
- 180
- 181
- 182
- 183
- 184
- 185
- 186
- 187
- 188
- 189
- 190
- 191
- 192
- 193
- 194
- 195
- 196
- 197
- 198
- 199
- 200
- 201
- 202
- 203
- 204
- 205
- 206
- 207
- 208
- 209
- 210
- 211
- 212
- 213
- 214
- 215
- 216
- 217
- 218
- 219
- 220
- 221
- 222
- 223
- 224
- 225
- 226
- 227
- 228
- 229
- 230
- 231
- 232
- 233
- 234
- 235
- 236
- 237
- 238
- 239
- 240
- 241
- 242
- 243
- 244
- 245
- 246
- 247
- 248
- 249
- 250
- 251
- 252
- 253
- 254
- 255
- 256
- 257
- 258
- 259
- 260
- 261
- 262
- 263
- 264
- 265
- 266
- 267
- 268
- 269
- 270
- 271
- 272
- 273
- 274
- 275
- 276
- 277
- 278
- 279
- 280
- 281
- 282
- 283
- 284
- 285
- 286
- 287
- 288
- 289
- 290
- 291
- 292
- 293
- 294
- 295
- 296
- 297
- 298
- 299
- 300
- 301
- 302
- 303
- 304
- 305
- 306
- 307
- 308
- 309
- 310
- 311
- 312
- 313
- 314
- 315
- 316
- 317
- 318
- 319
- 320
- 321
- 322
- 323
- 324
- 325
- 326
- 327
- 328
- 329
- 330
- 331
- 332
- 333
- 334
- 335
- 336
- 337
- 338
- 339
- 340
- 341
- 342
- 343
- 344
- 345
- 346
- 347
- 348
- 349
- 350
- 351
- 352
- 353
- 354
- 355
- 356
- 357
- 358
- 359
- 360
- 361
- 362
- 363
- 364
- 365
- 366
- 367
- 368
- 369
- 370
- 371
- 372
- 373
- 374
- 375
- 376
- 377
- 378
- 379
- 380
- 381
- 382
- 383
- 384
- 385
- 386
- 387
- 388
- 389
- 390
- 391
- 392
- 393
- 394
- 395
- 396
- 397
- 398
- 399
- 400
- 401
- 402
- 403
- 404
- 405
- 406
- 407
- 408
- 409
- 410
- 411
- 412
- 413
- 414
- 415
- 416
- 417
- 418
- 419
- 420
- 421
- 422
- 423
- 424
- 425
- 426
- 427
- 428
- 429
- 430
- 431
- 432
- 433
- 434
- 435
- 436
- 437
- 438
- 439
- 440
- 441
- 442
- 443
- 444
- 445
- 446
- 447
- 448
- 449
- 450
- 451
- 452
- 453
- 454
- 455
- 456
- 457
- 458
- 459
- 460
- 461
- 462
- 463
- 464
- 465
- 466
- 467
- 468
- 469
- 470
- 471
- 472
- 473
- 474
- 475
- 476
- 477
- 478
- 479
- 480
- 481
- 482
- 483
- 484
- 485
- 486
- 487
- 488
- 489
- 490
- 491
- 492
- 493
- 494
- 495
- 496
- 497
- 498
- 499
- 500
- 501
- 502
- 503
- 504
- 505
- 506
- 507
- 508
- 509
- 510
- 511
- 512
- 513
- 514
- 515
- 516
- 517
- 518
- 519
- 520
- 521
- 522
- 523
- 524
- 525
- 526
- 527
- 528
- 529
- 530
- 531
- 532
- 533
- 534
- 535
- 536
- 537
- 538
- 539
- 540
- 541
- 542
- 543
- 544
- 545
- 546
- 547
- 548
- 549
- 550
- 551
- 552
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
- 117
- 118
- 119
- 120
- 121
- 122
- 123
- 124
- 125
- 126
- 127
- 128
- 129
- 130
- 131
- 132
- 133
- 134
- 135
- 136
- 137
- 138
- 139
- 140
- 141
- 142
- 143
- 144
- 145
- 146
- 147
- 148
- 149
- 150
- 151
- 152
- 153
- 154
- 155
- 156
- 157
- 158
- 159
- 160
- 161
- 162
- 163
- 164
- 165
- 166
- 167
- 168
- 169
- 170
- 171
- 172
- 173
- 174
- 175
- 176
- 177
- 178
- 179
- 180
- 181
- 182
- 183
- 184
- 185
- 186
- 187
- 188
- 189
- 190
- 191
- 192
- 193
- 194
- 195
- 196
- 197
- 198
- 199
- 200
- 201
- 202
- 203
- 204
- 205
- 206
- 207
- 208
- 209
- 210
- 211
- 212
- 213
- 214
- 215
- 216
- 217
- 218
- 219
- 220
- 221
- 222
- 223
- 224
- 225
- 226
- 227
- 228
- 229
- 230
- 231
- 232
- 233
- 234
- 235
- 236
- 237
- 238
- 239
- 240
- 241
- 242
- 243
- 244
- 245
- 246
- 247
- 248
- 249
- 250
- 251
- 252
- 253
- 254
- 255
- 256
- 257
- 258
- 259
- 260
- 261
- 262
- 263
- 264
- 265
- 266
- 267
- 268
- 269
- 270
- 271
- 272
- 273
- 274
- 275
- 276
- 277
- 278
- 279
- 280
- 281
- 282
- 283
- 284
- 285
- 286
- 287
- 288
- 289
- 290
- 291
- 292
- 293
- 294
- 295
- 296
- 297
- 298
- 299
- 300
- 301
- 302
- 303
- 304
- 305
- 306
- 307
- 308
- 309
- 310
- 311
- 312
- 313
- 314
- 315
- 316
- 317
- 318
- 319
- 320
- 321
- 322
- 323
- 324
- 325
- 326
- 327
- 328
- 329
- 330
- 331
- 332
- 333
- 334
- 335
- 336
- 337
- 338
- 339
- 340
- 341
- 342
- 343
- 344
- 345
- 346
- 347
- 348
- 349
- 350
- 351
- 352
- 353
- 354
- 355
- 356
- 357
- 358
- 359
- 360
- 361
- 362
- 363
- 364
- 365
- 366
- 367
- 368
- 369
- 370
- 371
- 372
- 373
- 374
- 375
- 376
- 377
- 378
- 379
- 380
- 381
- 382
- 383
- 384
- 385
- 386
- 387
- 388
- 389
- 390
- 391
- 392
- 393
- 394
- 395
- 396
- 397
- 398
- 399
- 400
- 401
- 402
- 403
- 404
- 405
- 406
- 407
- 408
- 409
- 410
- 411
- 412
- 413
- 414
- 415
- 416
- 417
- 418
- 419
- 420
- 421
- 422
- 423
- 424
- 425
- 426
- 427
- 428
- 429
- 430
- 431
- 432
- 433
- 434
- 435
- 436
- 437
- 438
- 439
- 440
- 441
- 442
- 443
- 444
- 445
- 446
- 447
- 448
- 449
- 450
- 451
- 452
- 453
- 454
- 455
- 456
- 457
- 458
- 459
- 460
- 461
- 462
- 463
- 464
- 465
- 466
- 467
- 468
- 469
- 470
- 471
- 472
- 473
- 474
- 475
- 476
- 477
- 478
- 479
- 480
- 481
- 482
- 483
- 484
- 485
- 486
- 487
- 488
- 489
- 490
- 491
- 492
- 493
- 494
- 495
- 496
- 497
- 498
- 499
- 500
- 501
- 502
- 503
- 504
- 505
- 506
- 507
- 508
- 509
- 510
- 511
- 512
- 513
- 514
- 515
- 516
- 517
- 518
- 519
- 520
- 521
- 522
- 523
- 524
- 525
- 526
- 527
- 528
- 529
- 530
- 531
- 532
- 533
- 534
- 535
- 536
- 537
- 538
- 539
- 540
- 541
- 542
- 543
- 544
- 545
- 546
- 547
- 548
- 549
- 550
- 551
- 552
页面元素基类PageAppium.java:, 界面元素的存放获取类继承这个类,
package com.example.base;
import org.apache.http.util.TextUtils;
import org.openqa.selenium.By;
import org.openqa.selenium.NoSuchElementException;
import org.openqa.selenium.TimeoutException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
import io.appium.java_client.android.AndroidDriver;
import io.appium.java_client.android.AndroidElement;
import static com.example.base.InitAppium.appPackage;
/**
* 页面UI获取定位父类,供给Page层使用
* Created by LITP on 2016/9/23.
*/
public class PageAppium {
AndroidDriver driver;
private static int WAIT_TIME = 3;
public PageAppium(AndroidDriver androidDriver) {
this.driver = androidDriver;
waitAuto(WAIT_TIME);
}
public boolean isIdElementExist(String id) {
return isIdElementExist(id, 0);
}
public boolean isIdElementExist(String id,int timeOut) {
return isIdElementExist(id,timeOut ,false);
}
/**
* 根据id判断当前界面是否存在并显示这个控件
*
* @param id 要查找的id
* @param isShow 是否判断控件显示
* @return 返回对应的控件
*/
public boolean isIdElementExist(String id,int timeOut, boolean isShow) {
return isElementExist(By.id(appPackage + ":id/" +id),timeOut,isShow);
}
/**
* 选择当前界面的有这个文字的控件
*
* @param name
* @return
*/
public boolean isNameElementExist(String name) {
return isNameElementExist(name, 0);
}
public boolean isNameElementExist(String name, int timeOut) {
return isNameElementExist(name, timeOut,false);
}
public boolean isNameElementExist(String name, int timeOut, boolean isShow) {
return isElementExist(By.name(name),timeOut, isShow);
}
/**
* 判断当前界面有没有这个字符串存在
*
* @param text 要判断的字符串
* @return 存在返回真
*/
public boolean isTextExist(String text) {
String str = driver.getPageSource();
print(str);
return str.contains(text);
}
/**
* 判断当前界面有没有这个Xpath控件存在
*
* @param text 要判断的字符串
* @return 存在返回真
*/
public boolean isXpathExist(String text) {
return isXpathExist(text,0);
}
public boolean isXpathExist(String text,int timeOut) {
return isXpathExist(text,timeOut, false);
}
public boolean isXpathExist(String text,int timeOut,boolean isShow) {
return isElementExist(By.xpath(text), timeOut,isShow);
}
/**
* 判断控件时候存在
*
* @param by By
* @param timeout 等待的事件
* @return
*/
public boolean isElementExist(By by, int timeout,boolean isShow) {
try {
AndroidElement element = waitAuto(by, timeout);
if(element == null){
return false;
}else{
if(isShow){
return element.isDisplayed();
}
}
return true;
} catch (Exception e) {
return false;
}
}
/**
* 获取当前的activity,返回文件名
*
* @return
*/
public String getCurrActivity() {
String str = driver.currentActivity();
return str.substring(str.lastIndexOf(".") + 1);
}
/**
* 根据id获取当前界面的一个控件
*
* @param id 要查找的id
* @return 返回对应的控件
*/
public AndroidElement findById(String id,String desc) {
return findElementBy(By.id(id),desc);
}
public AndroidElement findById(String id) {
return findElementBy(By.id(id),"");
}
public AndroidElement findByFullId(String id) {
try {
if (driver != null) {
return (AndroidElement) driver.findElement(By.id(id));
} else {
print("driver为空");
}
} catch (NoSuchElementException e) {
print("找不到控件:" +" 异常信息:"+ e.getMessage());
}
return null;
}
/**
* 选择当前界面的有这个文字的控件
*
* @param name 内容
* @return 找到的控件
*/
public AndroidElement findByName(String name,String desc) {
return findElementBy(By.name(name),desc);
}
public AndroidElement findByName(String name) {
return findByName(name,"");
}
/**
* 根据id获取当前界面的一个控件
*
* @param name 要查找的控件的类名
* @return 返回对应的控件
*/
public AndroidElement findByClassName(String name,String desc) {
return findElementBy(By.className(name),desc);
}
public AndroidElement findByClassName(String name) {
return findByClassName(name,"");
}
public AndroidElement findByXpath(String str) {
return findByXpath(str,"");
}
public AndroidElement findByXpath(String str,String desc) {
return findElementBy(By.xpath(str),desc);
}
public AndroidElement findElementBy(By by){
return findElementBy(by,"");
}
/**
* 获取控件
* @param by by
* @param str 报错提示信息
* @return
*/
public AndroidElement findElementBy(By by,String str){
try {
if (driver != null) {
return (AndroidElement) driver.findElement(by);
} else {
print("driver为空");
}
} catch (NoSuchElementException e) {
print("找不到控件:" +str+" 异常信息:"+ e.getMessage());
}
return null;
}
/**
* 打印字符
*
* @param str 要打印的字符
*/
public <T> void print(T str) {
if (!TextUtils.isEmpty(String.valueOf(str))) {
System.out.println(str);
} else {
System.out.println("输出了空字符");
}
}
/**
* 线程休眠秒数,单位秒
*
* @param s 要休眠的秒数
*/
public void sleep(long s) throws InterruptedException {
Thread.sleep(s);
}
/**
* 显示等待,等待Id对应的控件出现time秒,一出现马上返回,time秒不出现也返回
*/
public AndroidElement waitAuto(By by, int time) {
try {
return new AndroidDriverWait(driver, time)
.until(new ExpectedCondition<AndroidElement>() {
@Override
public AndroidElement apply(AndroidDriver androidDriver) {
return (AndroidElement) androidDriver.findElement(by);
}
});
} catch (TimeoutException e) {
return null;
}
}
public AndroidElement waitAutoById(String id) {
return waitAutoById(id, WAIT_TIME);
}
public AndroidElement waitAutoById(String id, int time) {
return waitAuto(By.id(id), time);
}
public AndroidElement waitAutoByName(String name) {
return waitAutoByName(name, WAIT_TIME);
}
public AndroidElement waitAutoByName(String name, int time) {
return waitAuto(By.name(name), time);
}
public AndroidElement waitAutoByXp(String xPath) {
return waitAutoByXp(xPath, WAIT_TIME);
}
public AndroidElement waitAutoByXp(String xPath, int time) {
return waitAuto(By.xpath(xPath), time);
}
public void waitAuto() {
waitAuto(WAIT_TIME);
}
/**
* ,隐式等待,如果在指定时间内还是找不到下个元素则会报错停止脚本
* 全局设定的,find控件找不到就会按照这个事件来等待
*
* @param time 要等待的时间
*/
public void waitAuto(int time) {
driver.manage().timeouts().implicitlyWait(time, TimeUnit.SECONDS);
}
/**
* 获取屏幕的宽高
*
* @return 返回宽高的数组
*/
public int[] getScreen() {
int width = driver.manage().window().getSize().getWidth();
int height = driver.manage().window().getSize().getHeight();
return new int[]{width, height};
}
/**
* 获取屏幕宽度
*
* @return
*/
public int getScreenWidth() {
return driver.manage().window().getSize().getWidth();
}
/**
* 获取屏幕高度
*
* @return
*/
public int getScreenHeight() {
return driver.manage().window().getSize().getHeight();
}
/**
* 根据ClassName获取多个控件
*
* @param className 控件的类名字,例如 android.widget.EditText
* @param num 返回的数量
* @return
*/
public List<AndroidElement> getManyElementByClassName(String className, int num) {
List<AndroidElement> textFieldsList = driver.findElementsByClassName(className);
List<AndroidElement> list = new ArrayList<>();
try{
for(int i=0; i<num; i++){
list.add(textFieldsList.get(i));
}
return list;
}catch (Exception e){
print("获取多个控件异常"+e.getMessage());
}
return null;
}
/**
* 根据Id获取多个控件
*
* @param id 控件的类名字,例如 android.widget.EditText
* @param num 返回的数量
* @return
*/
public List<AndroidElement> getManyElementById(String id, int num) {
if(driver != null){
List<AndroidElement> textFieldsList = driver.findElementsById(id);
List<AndroidElement> list = new ArrayList<>();
try{
for(int i=0; i<num; i++){
list.add(textFieldsList.get(i));
}
return list;
}catch (Exception e){
print("获取多个控件异常"+e.getMessage());
}
}else{
print("获取多个控件"+id+"时候driver为空");
}
return null;
}
/**
* 获取同id的list的控件
* @param id id
* @param num 取那一个控件
* @return
*/
public AndroidElement getListOneElementById(String id,int num){
if(driver != null){
try{
return (AndroidElement) driver.findElementsById(appPackage+":id/"+id).get(num);
}catch (Exception e){
print("getListOneElementById找不到第"+num+"个控件"+id);
return null;
}
}else{
print("getListOneElementById:"+id+" 时候driver为空");
return null;
}
}
}