最近在項(xiàng)目過(guò)程中使用selenium 判斷元素是否存在的時(shí)候 遇到一個(gè)很坑爹的問(wèn)題, 用以下方法執(zhí)行的時(shí)候每次都會(huì)等待很長(zhǎng)一段時(shí)間绪撵,原因是因?yàn)閷?duì)selenium實(shí)現(xiàn)方法了解不足導(dǎo)致一直找不到解決方法。
privateboolean isElementPresent(By by) {
? ? try {
? ? ? driver.findElement(by);
? ? ? returntrue;
? ? } catch (NoSuchElementException e) {
? ? ? returnfalse;
? ? }
}
不明所以祝蝠,
經(jīng)過(guò)追蹤源碼才發(fā)現(xiàn)啟動(dòng)Driver的時(shí)候?使用driver.manage().timeouts().implicitlyWait(30,
TimeUnit.SECONDS); 此處設(shè)置的等待時(shí)間 是針對(duì)全局設(shè)置的音诈,webdriver中執(zhí)行所有命令 的超時(shí)時(shí)間都設(shè)置為30秒了,
如上面的findElement方法绎狭,找不到元素會(huì)默認(rèn)等待三十秒细溅。? 有些時(shí)候只需簡(jiǎn)單判斷元素是否存在,立馬執(zhí)行儡嘶,而此處的設(shè)置導(dǎo)致
腳本執(zhí)行緩慢喇聊。? 將Selenium中的等待時(shí)間貼出來(lái)給大家張張經(jīng)驗(yàn)。
Selenium的延遲等待分為 顯式等待(Explicit Wait) & 隱式等待(Implicit Wait).
1.顯式等待
顯式等待,就是明確的要等到某個(gè)元素的出現(xiàn)或者是某個(gè)元素的可點(diǎn)擊等條件,等不到,就一直等,除非在規(guī)定的時(shí)間之內(nèi)都沒(méi)找到,那么就跳出Exception.如:
newWebDriverWait(driver,15).until(? ? ? ?
? ? ? ? ? ? ? ? ? ExpectedConditions.presenceOfElementLocated(By.cssSelector("css locator")));
這里,15是要等待的秒數(shù).如果沒(méi)有滿足until()方法中的條件,就會(huì)始終在這里wait 15秒,依然找不到,就拋出異常.
也可以這樣寫:
WebDriver driver =new FirefoxDriver();
? ? driver.get(www.baidu.com);
? ? WebElement e = (newWebDriverWait( driver,10)) .until(
? ? ? ? newExpectedCondition< WebElement>(){
? ? ? ? ? ? @Override
? ? ? ? ? ? public WebElement apply( WebDriver d) {
? ? ? ? ? ? ? ? returndriver.findElement( By.id("id locator"));
? ? ? ? ? ? }
? ? ? ? }
這樣就通過(guò)回調(diào)函數(shù),直接獲得了這個(gè)WebElement.也就是頁(yè)面元素.
如果只是僅僅想判斷頁(yè)面是不是加載到某個(gè)地方了,就可以用第一種方法; 但如果需要得到某個(gè)WebElement,兩種方式都可以,只是第一種方式還需要再多一步獲取的操作.
Wait w =newWait(){
? ? ? ? @Override
? ? ? ? publicbooleanuntil() {
? ? ? ? ? ? returnwebElement.isDisplayed();
? ? ? ? }
另外這種等待的方式,在加載js代碼的時(shí)候做判斷會(huì)比較方便,反正我只在代碼里這么見(jiàn)過(guò),但是沒(méi)用過(guò),有興趣的朋友可以研究一下.
2.隱式等待
driver.manage().timeouts().implicitlyWait(second, TimeUnit.SECONDS);
隱式等待, 此處的隱式等待是針對(duì)Driver 每次執(zhí)行命令的 最長(zhǎng)執(zhí)行時(shí)間也可以理解為超時(shí)時(shí)間蹦狂,?
一些人對(duì)此處有誤解誓篱,認(rèn)為是讓Driver等一段時(shí)間,? 確實(shí)某些時(shí)候能讓Driver等一段時(shí)間凯楔, 但是影響是全局的窜骄,每次Driver執(zhí)行
找不到元素都會(huì)等待此處設(shè)置的時(shí)間,?
假設(shè)某處將此值設(shè)置的太長(zhǎng)摆屯,必須在執(zhí)行完成之后還原回來(lái)邻遏,否則判斷一個(gè)元素是否存在的時(shí)候,就會(huì)遇到很坑爹的問(wèn)題虐骑。?? 改進(jìn)后的方法如下:
WebDriver會(huì)進(jìn)行一個(gè)隱式等待,但參數(shù)只有時(shí)間,這就導(dǎo)致我需要什么元素出現(xiàn),我不一定能等到它,
privateboolean isElementPresent(By by) {
? ? try {
? ? ? driver.manage().timeouts().implicitlyWait(1, TimeUnit.SECONDS);
? ? ? driver.findElement(by);
? ? ? returntrue;
? ? } catch (NoSuchElementException e) {
? ? ? returnfalse;
? ? }
? }
得不到某個(gè)元素,我們就延遲一下...
3.線程休眠
Thread.sleep()