1 package pers.xeon.automate.auxt;
2
3 import java.awt.AWTException;
4 import java.awt.Robot;
5 import java.awt.Toolkit;
6 import java.awt.datatransfer.Clipboard;
7 import java.awt.datatransfer.StringSelection;
8 import java.awt.event.KeyEvent;
9 import java.io.File;
10 import java.util.Iterator;
11 import java.util.Set;
12 import java.util.concurrent.TimeUnit;
13
14 import org.openqa.selenium.Alert;
15 import org.openqa.selenium.By;
16 import org.openqa.selenium.NoSuchElementException;
17 import org.openqa.selenium.WebDriver;
18 import org.openqa.selenium.WebElement;
19 import org.openqa.selenium.support.ui.ExpectedCondition;
20 import org.openqa.selenium.support.ui.Select;
21 import org.openqa.selenium.support.ui.WebDriverWait;
22
23 /**
24 * @version 创建时间:2016年2月19日 下午2:12:26
25 * 处理页面的高级操作
26 * 总有适合自己的默认方法,下面等待时间我设置默认方法.为了满足开闭原则,我那天也懒得改,还有很多比默认方法强大同类型方法
27 */
28 public class DefaultAdvancedHandle implements AdvanceHandle {
29
30
31
32 private Driver driver ;
33 private static String preWindowString;
34 private static String imagePath=(new File("").getAbsolutePath()).toString();
35
36 public DefaultAdvancedHandle(Driver driver) {
37 this.driver = driver;
38 }
39
40 /*
41 * 这个方法是用于切换为原来的窗口,但是前提是一定有弹框出现,并且使用过切换窗口方法
42 */
43 /* (non-Javadoc)
44 * @see pers.xeon.automate.auxt.AdvanceHandle#changeLastWindow()
45 */
46 @Override
47 public void changeLastWindow() {
48 driver.switchTo().window(preWindowString);
49 }
50
51 /*
52 * 当弹框出现的时候,调用就会切换到对应的窗口
53 */
54 /* (non-Javadoc)
55 * @see pers.xeon.automate.auxt.AdvanceHandle#changeWindow()
56 */
57 @Override
58 public void changeWindow() {// 这个方法是处理跳出页面
59 preWindowString = driver.getWindowHandle();
60 Set<String> handles = driver.getWindowHandles();
61 Iterator<String> it = handles.iterator();
62 String cruWindowString;
63 while (it.hasNext()) {
64 cruWindowString = it.next();
65 if (preWindowString == cruWindowString) {
66 continue;
67 }
68 driver.switchTo().window(cruWindowString);
69 }
70 }
71
72 /*
73 * 刷新页面之后继续,等待元素
74 */
75 /* (non-Javadoc)
76 * @see pers.xeon.automate.auxt.AdvanceHandle#waitElementByRefresh(org.openqa.selenium.By, int, int)
77 */
78 @Override
79 public boolean waitElementByRefresh(By locator,int time,int k){
80 int i = 0;
81 while(waitElementByWait(locator,time)){
82 driver.navigate().refresh();
83 i++;
84 if(i == k){
85 return false;
86 }
87 }
88 return true;
89 }
90
91
92
93 /*
94 * 刷新页面等待元素
95 * 不用指定时间,系统指定固定时间
96 * 方法重载
97 * 默认刷新页面2次,等待5秒
98 */
99 /* (non-Javadoc)
100 * @see pers.xeon.automate.auxt.AdvanceHandle#waitElementByRefresh(org.openqa.selenium.By)
101 */
102 @Override
103 public boolean waitElementByRefresh(By locator){
104 return waitElementByRefresh(locator,5,2);
105 }
106
107
108
109 /*
110 * 最好不用这个方法,但是我还是提供给你
111 * 这个方法是处理等待元素方法1
112 */
113 /* (non-Javadoc)
114 * @see pers.xeon.automate.auxt.AdvanceHandle#waitElementByWait(org.openqa.selenium.By, int, boolean)
115 */
116 @Override
117 public boolean waitElementByWait(By locator,int time,boolean b){
118
119 long start = System.currentTimeMillis();
120
121 while(!isElementExsit(locator)){
122 if(b){
123 if(System.currentTimeMillis() >= (start +time*1000)){
124 break;
125 }
126 }
127 }
128 return isElementExsit(locator);
129 }
130
131 /*
132 * 等待无限时间
133 * 不建议使用,如果一直没有加载出来,线程就阻塞
134 */
135 /* (non-Javadoc)
136 * @see pers.xeon.automate.auxt.AdvanceHandle#waitElementByWait(org.openqa.selenium.By)
137 */
138 @Override
139 public boolean waitElementByWait(By locator){
140 return waitElementByWait(locator,0,false);
141 }
142
143 /*
144 * 等待指定时间
145 * 建议使用,我自己写的方法
146 * 方法与显性等待是一样的
147 */
148 /* (non-Javadoc)
149 * @see pers.xeon.automate.auxt.AdvanceHandle#waitElementByWait(org.openqa.selenium.By, int)
150 */
151 @Override
152 public boolean waitElementByWait(By locator,int time){
153 return waitElementByWait(locator,time,true);
154 }
155
156 /*
157 * 判断元素是否存在
158 */
159 /* (non-Javadoc)
160 * @see pers.xeon.automate.auxt.AdvanceHandle#isElementExsit(org.openqa.selenium.By)
161 */
162 @Override
163 public boolean isElementExsit(By locator) {
164 boolean flag = false;
165 try {
166 WebElement element=driver.findElement(locator);
167 flag= null != element;
168 } catch (NoSuchElementException e) {
169 return flag;
170 }
171 return flag;
172 }
173
174 /*
175 * 这个方法是处理元素加载方法2
176 * 显性等待指定时间
177 */
178 /* (non-Javadoc)
179 * @see pers.xeon.automate.auxt.AdvanceHandle#waitElement(org.openqa.selenium.By, int)
180 */
181 @Override
182 public WebElement waitElement(By by,int time){
183 WebDriverWait wait = new WebDriverWait(driver,time);
184 wait.until(new ExpectedCondition<WebElement>(){
185 @Override
186 public WebElement apply(WebDriver d) {
187 return d.findElement(by);
188 }});
189 return null;
190 }
191
192 /*
193 * 默认等10秒
194 * 10秒我比较喜欢所以搞一个单独方法,少写一个条件而已
195 * 显性等待10秒之内加载,比较好用,建议使用
196 */
197 /* (non-Javadoc)
198 * @see pers.xeon.automate.auxt.AdvanceHandle#waitElement(org.openqa.selenium.By)
199 */
200 @Override
201 public WebElement waitElement(By by){
202 return waitElement(by,10);
203 }
204
205 /*
206 * 这个方法是处理元素加载的方法3
207 */
208 /* (non-Javadoc)
209 * @see pers.xeon.automate.auxt.AdvanceHandle#waitElementByThread(int)
210 */
211 @Override
212 public void waitElementByThread(int ms) {
213 try {
214 Thread.sleep(ms);
215 } catch (InterruptedException e) {
216 System.out.println("Thread睡眠被唤醒,这本来是个异常,我已经手动处理:原因是因为我估计这个线程被其他线程唤醒,开始执行,所以并没有抛出异常,直接处理");
217 }
218 }
219
220 /*
221 * 这个方法是处理元素加载的方法4
222 * 建议不要使用这个,这个是隐形等待,当改变这个时候可能会影响其他元素等待
223 * 说白了是全局,注意不要使用
224 */
225 /* (non-Javadoc)
226 * @see pers.xeon.automate.auxt.AdvanceHandle#waitElementByInvisible(int)
227 */
228 @Override
229 public void waitElementByInvisible(int second) {
230 driver.manage().timeouts().implicitlyWait(second, TimeUnit.SECONDS);
231 }
232
233 /*
234 * 下拉框操作选择字符串为str
235 * 按照值定位
236 * 这个需要找到下拉框的value值定位
237 */
238 /* (non-Javadoc)
239 * @see pers.xeon.automate.auxt.AdvanceHandle#selectValue(java.lang.String, java.lang.String)
240 */
241 @Override
242 public void selectValue(String estr,String str){
243 Select select = new Select(driver.findElement(estr));
244 select.selectByValue(str);
245 }
246
247 /*
248 * 下拉框操作选择字符串为str
249 * 可见文本定位
250 * 建议用这个
251 */
252 /* (non-Javadoc)
253 * @see pers.xeon.automate.auxt.AdvanceHandle#select(java.lang.String, java.lang.String)
254 */
255 @Override
256 public void select(String estr,String str){
257 Select select = new Select(driver.findElement(estr));
258 select.selectByVisibleText(str);
259 }
260
261 /*
262 * 索引定位
263 * 下拉框操作选择字符串Index为index
264 */
265 /* (non-Javadoc)
266 * @see pers.xeon.automate.auxt.AdvanceHandle#select(java.lang.String, int)
267 */
268 @Override
269 public void select(String estr,int index){
270 Select select = new Select(driver.findElement(estr));
271 select.selectByIndex(index);
272 }
273
274
275 /*
276 * 最大化窗口
277 */
278 /* (non-Javadoc)
279 * @see pers.xeon.automate.auxt.AdvanceHandle#maximize()
280 */
281 @Override
282 public void maximize() {
283 driver.manage().window().maximize();
284 }
285
286 /*
287 * 弹框点击确定
288 */
289 /* (non-Javadoc)
290 * @see pers.xeon.automate.auxt.AdvanceHandle#alertAccept()
291 */
292 @Override
293 public void alertAccept(){
294 Alert alert = driver.switchTo().alert();
295 alert.accept();
296 }
297
298 /*
299 * 弹框点击确定
300 */
301 /* (non-Javadoc)
302 * @see pers.xeon.automate.auxt.AdvanceHandle#alertDismiss()
303 */
304 @Override
305 public void alertDismiss(){
306 Alert alert = driver.switchTo().alert();
307 alert.dismiss();
308 }
309
310 /*
311 * 得到弹框文本
312 */
313 /* (non-Javadoc)
314 * @see pers.xeon.automate.auxt.AdvanceHandle#alertGetText()
315 */
316 @Override
317 public void alertGetText(){
318 Alert alert = driver.switchTo().alert();
319 alert.getText();
320 }
321
322 /*
323 * 上传文件,上传图片等
324 * 方法可能无效,Driver自带的
325 */
326 /* (non-Javadoc)
327 * @see pers.xeon.automate.auxt.AdvanceHandle#UploadBySendKeys(java.lang.String, java.lang.String)
328 */
329 @Override
330 public void UploadBySendKeys(String estr,String strPath){
331 WebElement adFileUpload =driver.findElement(estr);
332 strPath=imagePath+"\"+strPath;
333 adFileUpload.sendKeys(strPath);
334 }
335
336 /*
337 * 上传文件,上传图片
338 * 建议使用这个,100%没得问题
339 * 我利用复制粘贴,然后你懂得
340 * 这里面的strPath,我使用的相对路径,相对项目的根路径写的(好处就是可以到处移动,他的参考点事这个项目的根路径)
341 */
342 /* (non-Javadoc)
343 * @see pers.xeon.automate.auxt.AdvanceHandle#upload(java.lang.String, java.lang.String)
344 */
345 @Override
346 public void upload(String estr,String strPath){
347 driver.click(estr);
348 try {
349 upload(strPath);
350 } catch (AWTException e) {
351 System.out.println("AWTException:由于Robot类初始化失败");
352 } catch (InterruptedException e) {
353 System.out.println("InterruptedException:可能导致上传失败,线程被唤醒");
354 }
355
356 }
357
358
359 /*
360 * 得到系统剪贴板
361 */
362 private void copy(String text) {
363 //拿到当前系统剪切板,首先拿到工具箱,然后得到系统剪切板
364 Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
365 //选中文本
366 StringSelection selection = new StringSelection(text);
367 //搞到剪切板里面去
368 clipboard.setContents(selection, null);
369 }
370
371 /*
372 * 这个方法是复制指定字符串的文本到剪切板 调用keyPressWithCtrl实现ctrl + v,然后enter操作
373 */
374 private void keyPressString(Robot r, String str) throws InterruptedException {
375 copy(str);
376 keyPressWithCtrl(r);// 粘贴
377 }
378
379 /*
380 * 实现ctrl + v,然后enter操作
381 */
382 private void keyPressWithCtrl(Robot r) throws InterruptedException {
383 r.keyPress(KeyEvent.VK_CONTROL);
384 r.keyPress(KeyEvent.VK_V);
385 r.keyRelease(KeyEvent.VK_V);
386 r.keyRelease(KeyEvent.VK_CONTROL);
387 Thread.sleep(1000);
388 r.keyPress(KeyEvent.VK_ENTER);
389 r.keyRelease(KeyEvent.VK_ENTER);
390 }
391
392 /*
393 * 对付上传按钮方法
394 */
395 private void upload(String image) throws AWTException, InterruptedException {
396 Robot robot = new Robot();
397 keyPressString(robot, image);
398 }
399
400 @Override
401 public void frame(String FrameName) {
402 driver.switchTo().frame(FrameName);
403 }
404 }