selenium 常见面试题以及答案
1.怎么 判断元素是否存在?
判断元素是否存在和是否出现不同, 判断是否存在意味着如果这个元素压根就不存在, 就会抛出NoSuchElementException
这样就可以使用try catch,如果catch到NoSuchElementException 就返回false
2.如何判断元素是否出现?
判断元素是否出现,存在两种情况,一种是该元素压根就没有,自然不会出现;另外一种是有这样的元素,但是是hidden状态
可以通过先判断是否存在,如果不存在返回false;如果存在再去判断是否displayed
3. 怎样选择下拉菜单的元素
下拉菜单分两种,一种是直接使用select标签的,这种情况可以直接使用selenium API
参考:http://www.cnblogs.com/tobecrazy/p/4570494.html
![](/assets/blank.gif)
WebElement selector = driver.findElement(By.id("Selector")); Select select = new Select(selector); 选择select的option有以下三种方法selectByIndex(int index) 通过index selectByVisibleText(String text) 通过匹配到的可见字符 selectByValue(String value) 通过匹配到标签里的value
![](/assets/blank.gif)
第二种下拉菜单不是通过select实现的,可以通过JS进行操作
类似这样的:http://css3menu.com/ (关于怎么使用DevTools 请自行百度,不解释)
那么这样的菜单该怎么去选取?
可以收工演示一下,第一步鼠标移动到how to use,此时菜单出现;第二步,点击Technical Question
要实现第一步,使用selenium 的Action clickAndHold,接着就可findByElement进行操作
![](/assets/blank.gif)
WebElement menu = driver.findElement(By.xpath("//span[.='How to Use']"));Actions action = new Actions(driver);action.clickAndHold(menu).build().perform();WebElement technicalQuestion = driver.findElement(By.xpath("//ul[@id='css3menu_top']/li[position()=3]/div[@class='submenu']/div[@class='column']//a[contains(text(),'Technical')]"));technicalQuestion.click();
![](/assets/blank.gif)
4. selenium 有几种定位方式,你最常用哪种, 为什么?
selenium有八种定位方式,和name有关的3个ByName,ByClassName,ByTagName
和link有关的2个ByLinkText,ByPartialLinkText
和id有关的1个ById
剩下两个全能的ByXpath和ByCssSelector
我最常用的事ByXpath(或CssSelector)因为很多情况下,html标签的属性不够规范,无法通过单一的属性定位,这个时候就只能使用xpath可以去重实现定位唯一element
事实上定位最快的应当属于ById,因为id是唯一的,然而大多数开发并没有设置id
5.去哪网面试题Java实现
一、 UI自动化测试
1、 Qunar机票搜索场景
1) 访问Qunar机票首页http://flight.qunar.com,选择“单程”,输入出发、到达城市,选择today+7日后的日期,点“搜索”,跳转到机票单程搜索列表页。
2) 在列表页停留1分钟,至到页面上出现“搜索结束”。
3) 如果出现航班列表,对于出现“每段航班均需缴纳税费”的行随机点选“订票”按钮,在展开的列表中会出现“第一程”、 “第二程”;对于没有出现“每段航班均需缴纳税费”的行随机点选“订票”按钮,在展开的列表底部中会出现“报价范围”
4) 如果不出现航班列表,则页面会出现“该航线当前无可售航班”
参考我的blog, http://www.cnblogs.com/tobecrazy/p/4752684.html
去哪儿网输入框三种输入方式(selenium webdriver 干货)
在机票预定的页面,输入出发城市和到达城市输入框的时候, 发现直接使用sendkeys不好使,
大部分情况出现输入某城市后没有输入进去, 经过几天的研究,发现可以采取三种方式:
1. 先点击输入框,待弹出 城市选择框之后,点击相应的城市
2. 缓慢输入城市的缩略字母或者城市的名字的部分,会显示出待选城市的下拉列表,进而从下拉列表中选择相应的城市.
3. 直接执行 js脚本对input的value设置为想要的值
首先说一下第三种方式:
JavascriptExecutor js = (JavascriptExecutor) driver;js.executeScript("arguments[0].value=\"北京\"", from_inpox);
执行效果最好,
22:35:34.885 INFO - Executing: [execute script: arguments[0].value="北京", [[[Ch
romeDriver: chrome on XP (6452a4a961be7bffa2af9d1b63f3d111)] -> xpath: //div[@id
='js_flighttype_tab_domestic']//input[@name='fromCity']]]])
如上图所演示,两种方式均是用户真实行为。
采取第一种方式:
- 首先定位到输入框
- 点击输入框
- 从弹出的热门城市框中点击所需要的城市
![](/assets/blank.gif)
WebElement from_inpox = driver .findElement(By.xpath("//div[@id='js_flighttype_tab_domestic']//input[@name='fromCity']")); Actions actions = new Actions(driver); actions.moveToElement(from_inpox).click().perform(); driver.findElement(By .xpath("//div[@data-panel='domesticfrom-flight-hotcity-from']//a[@class='js-hotcitylist' and text()='西安']")) .click();
![](/assets/blank.gif)
这里我并没有直接使用click, 而是使用Actions,原因是我在对到达城市操作时,发现经常报element can't be clicked这样的错误,
大意是,当要点击到达城市输入框,其实是被上层的元素遮挡,没法使用click方法,但是可以使用Actions的moveToElement方法之后可以click
或者采取滚动到该元素,调用JS
JavascriptExecutor jse = (JavascriptExecutor) driver; jse.executeScript("arguments[0].scrollIntoView()",element);
之后就可进行click操作.
如果使用第二种方法,就会遇到一个很大的问题:
如何定位到JS生成的下拉列表的城市?Firebug定位之前列表就消失!
看上去很难哈,反复尝试无所成, 最后突然想起既然是JS生成的,何不使用浏览器的JS debug功能,设置断点一步一步
果不其然,药到病除。nice job~
思路有了,跟我一起做,点开firebug ,切换到“脚本”界面,首先在输入框输入单字母s,待弹出下拉列表后,单击左侧的插入断点操作
你会发现该下拉框被冻结,不错呦,之后切换到html界面进行定位。
不光是去哪网,像百度输入框也可以采取这样的办法,JS设置断点,js的弹出框,弹出菜单就会冻结.
接下来我的输入就是选择下拉菜单中所需城市:
![](/assets/blank.gif)
from_inpox.clear();from_inpox.sendKeys("BJ");Thread.sleep(8000);By bj=new By.ByXPath("//div[@class='qcbox-fixed js-suggestcontainer']//td[contains(text(),'北京')]");if(isElementPresent(driver,bj,20)){driver.findElement(bj).click();}
![](/assets/blank.gif)
所要注意的是,下拉菜单中未必弹出那么快,需要做一次等待,在选择下拉菜单的时候需要做一次判断,当然这个判断方法是使用WebDriverWait
![](/assets/blank.gif)
/*** @author Young* @param driver* @param by* @param timeOut* @return*/public static boolean isElementPresent(WebDriver driver, final By by, int timeOut) {WebDriverWait wait = new WebDriverWait(driver, timeOut);boolean isPresent = false;isPresent = wait.until(new ExpectedCondition<WebElement>() {@Overridepublic WebElement apply(WebDriver d) {return d.findElement(by);}}).isDisplayed();return isPresent;}
![](/assets/blank.gif)
依然不够完美,为什么这么说,如果元素没有出现,并不是返回的false而是直接抛异常,并不是期望的,所以修改为findElements
如果找不到,返回List长度必然为0,进而返回false而不是抛出异常
![](/assets/blank.gif)
/*** @author Young* @param driver* @param by* @param timeOut* @return* @throws InterruptedException*/public static boolean isElementPresent(WebDriver driver, final By by,int timeOut) throws InterruptedException {boolean isPresent = false;Thread.sleep(timeOut * 1000);List<WebElement> we = driver.findElements(by);if (we.size() != 0) {isPresent = true;}return isPresent;}
![](/assets/blank.gif)
测试步骤:
1.选择出发城市-> 北京
到达城市->上海
选择今天之后的七天
点击search button
2.选择某带“每段航班均需缴纳税费” 的订单
![](/assets/blank.gif)
public static void main(String[] args) throws InterruptedException {WebDriver driver = DriverFactory.getChromeDriver();driver.get("http://flight.qunar.com/");driver.manage().window().maximize();driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);driver.manage().timeouts().pageLoadTimeout(30, TimeUnit.SECONDS);WebElement from_inpox = driver.findElement(By.xpath("//div[@id='js_flighttype_tab_domestic']//input[@name='fromCity']"));WebElement to_inpox = driver.findElement(By.xpath("//div[@id='js_flighttype_tab_domestic']//input[@name='toCity']"));WebElement from_date = driver.findElement(By.xpath("//div[@id='js_flighttype_tab_domestic']//input[@name='fromDate']"));WebElement sigleWayCheckBox = driver.findElement(By.xpath("//div[@id='js_flighttype_tab_domestic']//input[@class='inp_chk js-searchtype-oneway']"));if (!sigleWayCheckBox.isSelected()) {sigleWayCheckBox.click();}from_inpox.clear();from_inpox.sendKeys("BJ");Thread.sleep(8000);By bj = new By.ByXPath("//div[@class='qcbox-fixed js-suggestcontainer']//td[contains(text(),'北京')]");if (isElementPresent(driver, bj, 20)) {driver.findElement(bj).click();}to_inpox.clear();to_inpox.sendKeys("SH");Thread.sleep(8000);By sh = new By.ByXPath("//div[@class='qcbox-fixed js-suggestcontainer']//td[contains(text(),'上海')]");if (isElementPresent(driver, sh, 20)) {driver.findElement(sh).click();}// Actions actions = new Actions(driver);// actions.moveToElement(from_inpox).click().perform();// driver.findElement(// By.xpath("//div[@data-panel='domesticfrom-flight-hotcity-from']//a[@class='js-hotcitylist' and text()='西安']"))// .click();// driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);// driver.manage().timeouts().pageLoadTimeout(30, TimeUnit.SECONDS);// actions.moveToElement(to_inpox).click().perform();// driver.findElement(// By.xpath("//div[@data-panel='domesticto-flight-hotcity-to']//a[@class='js-hotcitylist' and text()='北京']"))// .click();// driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);// driver.manage().timeouts().pageLoadTimeout(30, TimeUnit.SECONDS);from_date.clear();from_date.sendKeys(getDateAfterToday(7));WebElement search = driver.findElement(By.xpath("//div[@id='js_flighttype_tab_domestic']//button[@class='btn_search']"));search.submit();driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);driver.manage().timeouts().pageLoadTimeout(30, TimeUnit.SECONDS);WebElement page2 = driver.findElement(By.xpath("//div[@id='hdivPager']/a[@value='2']"));JavascriptExecutor jse = (JavascriptExecutor) driver;jse.executeScript("arguments[0].scrollIntoView()", page2);page2.click();driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);driver.manage().timeouts().pageLoadTimeout(30, TimeUnit.SECONDS);driver.findElement(By.xpath("(//div[@class='avt_trans']//p[contains(text(),'每段航班均需缴纳税费')]/ancestor::div//div[@class='a_booking']/a)[3]")).click();driver.findElement(By.xpath("//div[@id='flightbarXI883']//div[@class='t_bk']/a")).click();}public static String getDateAfterToday(int dateAfterToday) {Calendar cal = Calendar.getInstance();cal.add(Calendar.DATE, +dateAfterToday);System.out.println(cal.getTime().toString());Date date = cal.getTime();SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");System.out.println(df.format(date));return df.format(date);}/*** @author Young* @param driver* @param by* @param timeOut* @return* @throws InterruptedException*/public static boolean isElementPresent(WebDriver driver, final By by,int timeOut) throws InterruptedException {boolean isPresent = false;Thread.sleep(timeOut * 1000);List<WebElement> we = driver.findElements(by);if (we.size() != 0) {isPresent = true;}return isPresent;}
![](/assets/blank.gif)
效果如下:
6. 如何去定位页面上动态加载的元素?
触发动态事件事件,进而findElemnt
如果是动态菜单,需要一级一级find
7.如何去定位属性动态变化的元素?
属性动态变化是指该element没有固定的属性值,所以只能通过相对位置定位
比如通过xpath的轴, parent/following-sibling/precent-sibling等
另外也可以尝试findbyelements遍历
8.怎么提高selenium脚本的自动化执行效率?
- 优化测试用例,尽可不使用 sleep,减少使用ImplicitlyWait
,而使用selenium的wait/FluentWait,这样可以优化等待时间 - 使用selenium grid,通过testng实现并发执行
- 针对一些不稳定的动态控件通过JS实现操作
- 重载testng的listener实现retry机制,提高测试用例成功率
- 减少使用IE的driver,IE执行效率太低!!!
9. webdriver 的原理是什么?
结合上次研究的selenium webdriver potocol ,自己写http request调用remote driver代替selenium API
selenium web driver Json protocol 相关请看 http://www.cnblogs.com/tobecrazy/p/5020741.html
我这里使用的是Gson 和 httpclient
首先,起一个remote sever
java -Dwebdriver.ie.driver="IEDriverServer.exe" -Dwebdriver.chrome.driver="chromedriver.exe" -jar selenium-server-standalone-2.48.0.jar
这里要用到httpclient的Post 和delete method
创建一个httpclient对象
HttpClient httpClient = HttpClients.createDefault();
创建一个post请求
JsonObject setCapability = new JsonObject();setCapability.addProperty("browserName","firefox");JsonObject capability = new JsonObject();capability.add("desiredCapabilities",setCapability);HttpPost httpPost = new HttpPost(base);
创建一个delete 请求
url = base + sessionId ;HttpDelete httpDelete = new HttpDelete(url);
从respose 中获取session ID
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
|
HttpResponse response = httpClient.execute(httpPost);
try {
HttpEntity entity = response.getEntity();
if (entity != null ) {
System.out.println( "Response content length: "
+ entity.getContentLength());
String resultEntity = EntityUtils.toString(entity);
System.out.println( "Response content: " + resultEntity);
JsonObject result= new JsonParser().parse(resultEntity).getAsJsonObject();
JsonElement sessionIdJson = result.get( "sessionId" );
if (!sessionIdJson.isJsonNull())
sessionId =sessionIdJson.getAsString();
JsonElement valueJson = result.get( "value" );
if (!valueJson.isJsonNull())
{
JsonObject tm=valueJson.getAsJsonObject();
JsonElement elementIdJson = tm.get( "ELEMENT" );
if (elementIdJson!= null )
elementId=elementIdJson.getAsString();
}
}
} finally {
((Closeable) response).close();
}
|
全部代码如下:
![](/assets/blank.gif)
import java.io.Closeable; import java.io.IOException; import java.io.UnsupportedEncodingException;import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.client.ClientProtocolException; import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpDelete; import org.apache.http.client.methods.HttpPost; import org.apache.http.entity.StringEntity; import org.apache.http.impl.client.HttpClients; import org.apache.http.message.BasicHeader; import org.apache.http.protocol.HTTP; import org.apache.http.util.EntityUtils;import com.google.gson.JsonElement; import com.google.gson.JsonObject; import com.google.gson.JsonParser;public class webDriverJson {private static String base = "http://127.0.0.1:4444/wd/hub/session/";private static String elementId;static String sessionId = "";public static void main(String[] args) throws Exception, IOException {HttpClient httpClient = HttpClients.createDefault();JsonObject setCapability = new JsonObject();setCapability.addProperty("browserName","firefox");JsonObject capability = new JsonObject();capability.add("desiredCapabilities",setCapability);HttpPost httpPost = new HttpPost(base);//create session postExecutor(httpClient, httpPost, capability);String url = base + sessionId + "/url";httpPost = new HttpPost(url);JsonObject getUrl = new JsonObject();getUrl.addProperty("url", "http://www.baidu.com");postExecutor(httpClient, httpPost, getUrl);//find input boxurl = base + sessionId + "/element";httpPost = new HttpPost(url);JsonObject findElement = new JsonObject();findElement.addProperty("using", "id");findElement.addProperty("value", "kw");postExecutor(httpClient, httpPost, findElement);System.out.println(elementId);url = base + sessionId + "/element/"+elementId+"/value";httpPost = new HttpPost(url);JsonObject typeElement = new JsonObject();String json = "{\"value\":[\"webdriver\"]}";JsonParser jp = new JsonParser();typeElement = (JsonObject) jp.parse(json);postExecutor(httpClient, httpPost, typeElement);//find search buttonurl = base + sessionId + "/element";httpPost = new HttpPost(url);JsonObject findSearchButton = new JsonObject();findSearchButton.addProperty("using", "id");findSearchButton.addProperty("value", "su");postExecutor(httpClient, httpPost, findSearchButton);System.out.println(elementId);url = base + sessionId + "/element/"+elementId+"/click";httpPost = new HttpPost(url);postExecutor(httpClient, httpPost,null);//delete sessionurl = base + sessionId ;HttpDelete httpDelete = new HttpDelete(url);deleteExecutor(httpClient, httpDelete);}/*** @author Young* @param httpClient* @param httpPost* @param jo* @throws UnsupportedEncodingException* @throws IOException* @throws ClientProtocolException*/public static void postExecutor(HttpClient httpClient, HttpPost httpPost,JsonObject jo) throws UnsupportedEncodingException, IOException,ClientProtocolException {if(jo!=null){StringEntity input = new StringEntity(jo.toString());input.setContentEncoding("UTF-8");input.setContentEncoding(new BasicHeader(HTTP.CONTENT_TYPE,"application/json"));httpPost.setEntity(input);}HttpResponse response = httpClient.execute(httpPost);try {HttpEntity entity = response.getEntity();if (entity != null) {System.out.println("Response content length: "+ entity.getContentLength());String resultEntity = EntityUtils.toString(entity);System.out.println("Response content: " + resultEntity);JsonObject result= new JsonParser().parse(resultEntity).getAsJsonObject();JsonElement sessionIdJson = result.get("sessionId");if(!sessionIdJson.isJsonNull())sessionId =sessionIdJson.getAsString();JsonElement valueJson = result.get("value");if(!valueJson.isJsonNull()){JsonObject tm=valueJson.getAsJsonObject();JsonElement elementIdJson = tm.get("ELEMENT");if(elementIdJson!=null)elementId=elementIdJson.getAsString();}}} finally {((Closeable) response).close();}}/*** @author Young* @param httpClient* @param delete* @throws UnsupportedEncodingException* @throws IOException* @throws ClientProtocolException*/public static void deleteExecutor(HttpClient httpClient, HttpDelete delete) throws UnsupportedEncodingException, IOException,ClientProtocolException {HttpResponse response = httpClient.execute(delete);try {HttpEntity entity = response.getEntity();if (entity != null) {System.out.println("Response content length: "+ entity.getContentLength());String resultEntity = EntityUtils.toString(entity);System.out.println("Response content: " + resultEntity);JsonObject result= new JsonParser().parse(resultEntity).getAsJsonObject();JsonElement sessionIdJson = result.get("sessionId");if(!sessionIdJson.isJsonNull())sessionId =sessionIdJson.getAsString();JsonElement valueJson = result.get("value");if(!valueJson.isJsonNull()){JsonObject tm=valueJson.getAsJsonObject();JsonElement elementIdJson = tm.get("ELEMENT");if(elementIdJson!=null)elementId=elementIdJson.getAsString();}}} finally {((Closeable) response).close();}}}
![](/assets/blank.gif)
运行效果:
了解selenium 原理究竟有什么意义?
大多数人都会使用selenium去做自动化,但是不是每个人都了解selenium的原理,如果能掌握selenium原理
可以改造selenium API,使用webdriver protocol去做一些能够完善自动化测试框架的事情。、
比如,也许你在selenium自动化过程中会遇到get打开页面打不开,为了保证你脚本的健壮性,这时候你可以加入一段httprequest去获取
response的的关键值判断,如果不是2开头的可以设置refresh,再比如需要做一些准备性工作,比如环境配置也可以使用
参考:http://www.cnblogs.com/tobecrazy/p/5034408.html
10. selenium中如何保证操作元素的成功率?也就是说如何保证我点击的元素一定是可以点击的?
参考:http://www.cnblogs.com/tobecrazy/p/4817946.html
- 通过封装find方法实现waitforEmelentPresent,这样在对元素进行操作之前保证元素被找到,进而提高成功率
- 在对元素操作之前,比如click,如果该元素未display(非hidden),就需要先滚动到该元素,然后进行click操作
为啥使用滚动? 因为如果页面没有完全显示,element如果是在下拉之后才能显示出来,只能先滚动到该元素才能进行click,否则是不能click操作
1
2
3
|
JavascriptExecutor js=(JavascriptExecutor)driver;
// roll down and keep the element to the center of browser
js.executeScript( "arguments[0].scrollIntoViewIfNeeded(true);" , download);
|
selenium常用的js总结
1、 对input执行输入
直接设置value属性, 此方法主要应对输入框自动补全以及readonly属性的element,sendkeys不稳定
比如:
//inputbox is a WebElementJavascriptExecutor js = (JavascriptExecutor) driver;js.executeScript("arguments[0].value=\"北京\"", from_inpox);
对此可以封装一个typeQuick的方法
![](/assets/blank.gif)
/*** @author Young* @param locator* @param values* @throws Exception*/protected void typeQuick(Locator locator, String values) throws Exception {WebElement e = findElement(driver, locator);log.info("type value is: " + values);JavascriptExecutor js = (JavascriptExecutor) driver;js.executeScript("arguments[0].value=\""+values+"\"", e);
![](/assets/blank.gif)
去掉只读属性
JavascriptExecutor js = (JavascriptExecutor) driver;js.executeScript("arguments[0].removeAttribute(\"+"readonly"+\")", e);
2.对富文本框的操作
主要应对富文本框,可以封装获取富文本框内容和设置富文本路况内容的方法
JavascriptExecutor js = (JavascriptExecutor) driver;WebElement editor = driver.findElement(By.tagName("body"));js.executeScript("arguments[0].innerHTML = '<h1>Selenium Test </h1>I love Selenium <br> this article Post By Selenium WebDriver<br><h2>Create By Young</h2>'",editor);
设置富文本框内容
![](/assets/blank.gif)
/*** @author Young* @param locator* @param text*/protected void setRichTextBox(Locator locator, String text) {WebElement e = findElement(driver, locator);log.info("type value is: " + text);JavascriptExecutor js = (JavascriptExecutor) driver;js.executeScript("arguments[0].innerHTML = \"" + text + "\"", e);}
![](/assets/blank.gif)
获取富文本框内容:
![](/assets/blank.gif)
/*** @author Young* @param locator* @param text* @return*/protected String getRichTextBox(Locator locator, String text) {WebElement e = findElement(driver, locator);log.info("type value is: " + text);JavascriptExecutor js = (JavascriptExecutor) driver;String result=(String) js.executeScript("var result=arguments[0].innerHTML;return result", e);return result;}
![](/assets/blank.gif)
3. 滚动到指定位置
为啥使用滚动? 因为如果页面没有完全显示,element如果是在下拉之后才能显示出来,只能先滚动到该元素才能进行click,否则是不能click操作
1
2
3
|
JavascriptExecutor js=(JavascriptExecutor)driver;
// roll down and keep the element to the center of browser
js.executeScript( "arguments[0].scrollIntoViewIfNeeded(true);" , download);
|
可以封装滚动到元素的方法的
![](/assets/blank.gif)
/*** @author Young* @param locator*/protected void scrollToElement(Locator locator) {WebElement e = findElement(driver, locator);log.info("scroll view element");JavascriptExecutor js = (JavascriptExecutor) driver;// roll down and keep the element to the center of browserjs.executeScript("arguments[0].scrollIntoViewIfNeeded(true);", e);}
![](/assets/blank.gif)
4. 触发event,Dom event 事件的封装
![](/assets/blank.gif)
/*** For DOM Event * @author Young* @param locator* @param event* please refer to: http://www.w3school.com.cn/jsref/dom_obj_event.asp* */public void DOMEvent(Locator locator,String event){JavascriptExecutor jse=((JavascriptExecutor)driver);String js="var event;if (document.createEvent){event = document.createEvent(\"HTMLEvents\");event.initEvent(\""+event+"\", true, false);arguments[0].dispatchEvent(event);} else {arguments[0].fireEvent(\"on"+event+"\")}";jse.executeScript(js, findElement(driver,locator)) ;}
![](/assets/blank.gif)
五、获取元素属性
window.getComputedStyle(document.getElementById("su"),null).getPropertyValue("background")
六 、获取页面加载状态
document.readyState
11. 什么PO模式,什么是page factory?
网上有很多答案,都不全面
PO模式是page object model的缩写,顾名思义, 是一种 设计模式,实现脚本的page和真实的网站页面Map起来,一一对应起来。这样能测试框架更容易维护。 比如一个登陆页面,使用PO模式后,会创建一个LoginPage的class,该class会定义用户名输入框,密码输入框,登陆按钮的webElenent
针对相应的Element实现相应的方法,输入框是用来输入的,就需要创建输入用户名和输入密码的方法,这样就和真实的页面一致,所以这样的设计理念就是PO模式。 而PageFactory隶属PO模式,是用来初始化每个PO模式实现的Page Class,初始化对象库。
selenium 常见面试题以及答案相关推荐
- selenium 常见面试题以及答案(Java版)
1.怎么 判断元素是否存在? 判断元素是否存在和是否出现不同, 判断是否存在意味着如果这个元素压根就不存在, 就会抛出NoSuchElementException 这样就可以使用try catch,如 ...
- Spring常见面试题及答案汇总1000道(春招+秋招+社招)
Spring面试题以及答案整理[最新版]Spring高级面试题大全(2021版),发现网上很多Spring面试题都没有答案,所以花了很长时间搜集,本套Spring面试题大全,汇总了大量经典的Sprin ...
- Java多线程常见面试题及答案汇总1000道(春招+秋招+社招)
Java多线程面试题以及答案整理[最新版]Java多线程高级面试题大全(2021版),发现网上很多Java多线程面试题都没有答案,所以花了很长时间搜集,本套Java多线程面试题大全,汇总了大量经典的J ...
- MySQL常见面试题及答案汇总1000道(春招+秋招+社招)
MySQL面试题以及答案整理[最新版]MySQL高级面试题大全(2021版),发现网上很多MySQL面试题都没有答案,所以花了很长时间搜集,本套MySQL面试题大全,汇总了大量经典的MySQL程序员面 ...
- Jvm常见面试题及答案汇总1000道(春招+秋招+社招)
Jvm面试题以及答案整理[最新版]Jvm高级面试题大全(2021版),发现网上很多Jvm面试题都没有答案,所以花了很长时间搜集,本套Jvm面试题大全,汇总了大量经典的Jvm程序员面试题以及答案,包含J ...
- Dubbo常见面试题及答案汇总1000道(春招+秋招+社招)
Dubbo面试题以及答案整理[最新版]Dubbo高级面试题大全(2021版),发现网上很多Dubbo面试题都没有答案,所以花了很长时间搜集,本套Dubbo面试题大全,汇总了大量经典的Dubbo程序员面 ...
- JavaScript常见面试题和答案
原文地址:https://www.yisu.com/zixun/117910.html 这篇文章将为大家详细讲解有关JavaScript常见面试题和答案,小编觉得挺实用的,因此分享给大家做个参考,希望 ...
- 总结Java常见面试题和答案
转载自 总结Java常见面试题和答案 int和Integer有什么区别? 答:int是java的原始数据类型,Integer是java为int提供的封装类,java为每个原始数据类型都提供了封装 ...
- java常见面试题及答案 1-10(基础篇)
java常见面试题及答案 1.什么是Java虚拟机?为什么Java被称作是"平台无关的编程语言"? Java 虚拟机是一个可以执行 Java 字节码的虚拟机进程.Java 源文件被 ...
最新文章
- 判定两棵二叉树是否相似以及左右子树交换、层次编号
- datepicker 颜色 android,Android修改DatePicker字體顏色及分割線顏色
- 通用PE工具箱安装图解
- 从“电商合伙人”到“品牌掌柜”,快手电商“军训”进行时
- 命令点亮硬盘灯_macOS下移动硬盘无法挂载且硬盘灯一直闪烁的解决方法
- python 安装xpath_Python网络爬虫(四)- XPath1.XPath2.XPath在python中的应用
- 【转】ABP源码分析四十七:ABP中的异常处理
- JS_14 执行上下文与执行上下文栈
- unity底层运行机制_Unity跨平台的机制原理
- 执行AJAX返回HTML片段中的JavaScript脚本
- jquery中is()函数
- Python基础:内置异常(未完待续)
- asp.net web.config配置节说明
- 如何创造一个能和你对话的语音AI?
- python 100以内的奇数和_python入门:输出1-100之内的所有奇数和偶数
- 用HTML写一个简易的登录界面
- 全球及中国企业社交网络行业渠道营销分析及市场全面调研报告2021-2027年
- [微信] 微信商户号 资金解决方案 自动提现 关闭
- 读 活着 【思维导图版】
- Hive性能优化(全面)解决数据倾斜等问题