selenium2-元素管理方式及解析
1.管理文件格式:yaml
2.Yaml里面的内容格式:
3.格式说明:
baidu_input后面接上":",直接回车,然后空两格
type与value这两个key是固定的,后面接上":",然后空一格,也可以不空,如果value后面是xpath,建议用加上引号
在webdriver中,有By.id,By.name,By.xpath,By.className,By.linkText等,我们选取这几种常见的,所以type的冒包后面可用的值为id,name,xpath
value的值为type中对应的类型的值,比如百度首页上的输入框的id='kw'
4.解析yaml文件
5.我们在写脚本时,元素对象一般是这样写的WebElement element = driver.findElement(By.id(“kw”));所以接下来我们要把ml变量里的“value”转换成By对象。添加如下代码,这样通过ml中的type与value的值就对产生一个By对象。
6.By对象产生后,就可以把这个对象传给driver.findElement方法,继而生成一个WebElement对象.
7.到这里,已经成功了一半,因为已经把yaml文件中保存的元素成功的转化成了WebElement对象。但是还不够,接下来我们引入一下同步点的概念,就 是在调用locator时,保证locator是显示在页面上的,webdriver中有个WebDriverWait对象,代码如下:
8.于是乎getElement方法里面就可以改为
9.到这一步,又改进了一点,新的问题也随之产生了,watiForElement这个方法,返回的WebElement对象包括隐藏的,如果是隐藏的,那么在操作的时候,自然而然会报错,所以,我们得把隐藏的去掉,只显示displayed的元素对象,增加一个方法。
10.如此一来,getElement方法又可以改进一下了。
11.既然有等待元素对象显示的,那么反之就有等待元素对象消失的方法。
12.看上去一切很美好了,but....如果我们要验证一个元素对象不出现在页面上,就会出现问题了,于是增加一个方法
13.现在的问题是getElement与getElementNoWait的方法体很接近,于是我们来重构下这部分的代码,先增加一个方法,存放相同的方法体
14.再把getElement与getElementNoWait方法进行修改
15.元素对象的参数化:
16.在这里面的参数用%s来表示,于是在脚本中,我们调用getElement与getElementNoWait方法时需要我们把value给传进去,我们再来处理下这部分,增加一个方法。
17.重构getLocator方法:
18.可以看到getLocator方法的参数变了,于是要重新的更改getElement与getElementNoWait方法,同时重载这两个方法。
具体代码如下
Locator.java:
package com.test.util; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.util.HashMap; import java.util.Map; import org.ho.yaml.Yaml; import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.support.ui.ExpectedCondition; import org.openqa.selenium.support.ui.WebDriverWait; public class Locator { private String yamlfile; private WebDriver driver; private Map<String, Map<String, String>> ml; public Locator(WebDriver driver) { yamlfile = "TestBaidu"; this.getYamlFile(); this.driver = driver; } public void getYamlFile() { File f = new File("locator/" + yamlfile + ".yaml"); try { ml = Yaml.loadType(new FileInputStream(f.getAbsolutePath()), HashMap.class); } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } } private By getBy(String type, String value) { By by = null; if (type.equals("id")) { by = By.id(value); } if (type.equals("xpath")) { by = By.xpath(value); } return by; } public WebElement getElement(String key) { // String type = ml.get(key).get("type"); // String value = ml.get(key).get("value"); // // return driver.findElement(this.getBy(type, value)); // // return this.waitForElement(this.getBy(type, value)); // WebElement element; // element = this.waitForElement(this.getBy(type, value)); // if (!this.waitElementToBeDisplayed(element)) // element = null; // return element; // return this.getLocator(key, true); return this.getLocator(key, null, true); } public WebElement getElement(String key, String[] replace) { return this.getLocator(key, replace, false); } private boolean waitElementToBeDisplayed(final WebElement element) { boolean wait = false; if (element == null) return wait; try { wait = new WebDriverWait(driver, config.waitTime) .until(new ExpectedCondition<Boolean>() { public Boolean apply(WebDriver d) { return element.isDisplayed(); } }); } catch (Exception e) { System.out.println(element.toString() + " is not displayed"); } return wait; } private boolean waitElementToBeNonDisplayed(final WebElement element) { boolean wait = false; if (element == null) return wait; try { wait = new WebDriverWait(driver, config.waitTime) .until(new ExpectedCondition<Boolean>() { public Boolean apply(WebDriver d) { return !element.isDisplayed(); } }); } catch (Exception e) { System.out.println(element.toString() + " is also displayed"); } return wait; } private WebElement waitForElement(final By by) { WebElement element = null; int waitTime = config.waitTime; try { element = new WebDriverWait(driver, waitTime) .until(new ExpectedCondition<WebElement>() { public WebElement apply(WebDriver d) { return d.findElement(by); } }); } catch (Exception e) { System.out.println(by.toString() + " is not exist until " + waitTime); } return element; } public WebElement getElementNoWait(String key) { // WebElement element; // String type = ml.get(key).get("type"); // String value = ml.get(key).get("value"); // try { // element = driver.findElement(this.getBy(type, value)); // } catch (Exception e) { // element = null; // } // return element; // return this.getLocator(key, false); return this.getLocator(key, null, false); } // 多态形式,字符串替换 public WebElement getElementNoWait(String key, String[] replace) { return this.getLocator(key, replace, false); } // 由于getElement和getElementNoWait非常相似,所以重构一下这两个方法 private WebElement getLocator(String key, String[] replace, boolean wait) { WebElement element = null; if (ml.containsKey(key)) { Map<String, String> m = ml.get(key); String type = m.get("type"); String value = m.get("value"); if (replace != null) { value = this.getLocatorString(value, replace); } By by = this.getBy(type, value); if (wait) { element = this.waitForElement(by); boolean flag = this.waitElementToBeDisplayed(element); if (!flag) element = null; } else { try { element = driver.findElement(by); } catch (Exception e) { element = null; } } } else { System.out.println("Locator " + key + " is not exists in " + yamlfile + ".yaml"); } return element; } private String getLocatorString(String locatorString, String[] ss) { for (String s : ss) { locatorString = locatorString.replaceFirst("%s", s); } return locatorString; } /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub SeleniumDriver selenium = new SeleniumDriver(); WebDriver driver = selenium.getDriver(); Locator l = new Locator(driver); driver.navigate().to("http://www.baidu.com"); WebElement element; element = l.getElement("baidu_input1"); // String[] replace = new String[] { "kw" };// element = l.getElement("baidu_input", replace); element.sendKeys("aa"); } }
TestBaidu.yaml:
baidu_input:
type:id
value:"%s"
baidu_button:
type:id
value:"%s%s"
baidu_input1:
type:id
value:kw
baidu_button1:
type:xpath
value:"//div[@id='%productId%']//div"
最后打个广告,不要介意哦~
最近我在Dataguru学了《软件自动化测试Selenium2》网络课程,挺不错的,你可以来看看!要是想报名,可以用我的优惠码 G863,立减你50%的固定学费!
链接:http://www.dataguru.cn/invite.php?invitecode=G863