眾所周知,java語言版本的selenium一般被認(rèn)為是最正宗的selenium版本,今天我們以java語言為例,來看看selenium 4.0的各種新特性以及新舊api的對比。
Capabilities
如果你需要對瀏覽器進(jìn)行一些全局設(shè)置,那么使用Capabilities是唯一的選擇。說實話,舊的Capabilities有點不太符合直覺,具體用法如下。
DesiredCapabilities?capabilities?=?DesiredCapabilities.chrome();
capabilities.setCapability("platform",?"Mac?OS?X");
capabilities.setCapability("version",?"94");
driver?=?new?RemoteWebDriver(capabilities);
在新版本中,我們直接設(shè)置options就可以了,語義上顯得更為自然。
ChromeOptions?options?=?new?ChromeOptions();
options.setBrowserVersion("94");
options.setPlatformName("Mac?OS?X");
driver?=?new?ChromeDriver(options);
Waits
在之前的版本里,我們實例化各種wait對象時候需要傳入2個參數(shù):time以及type of time,在新版本里我們只需要使用Duration類就可以了。
這是之前的做法
driver.manage().timeouts().implicitlyWait(10,?TimeUnit.SECONDS);
driver.manage().timeouts().pageLoadTimeout(10,?TimeUnit.SECONDS);
driver.manage().timeouts().setScriptTimeout(10,?TimeUnit.SECONDS);
新的方式
driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(10));
driver.manage().timeouts().pageLoadTimeout(Duration.ofMinutes(3));
driver.manage().timeouts().setScriptTimeout(Duration.ofHours(1));
當(dāng)然,現(xiàn)在支持各式各樣的Duration了,需要注意的是這里接受的是long型的參數(shù)。
Duration.ofNanos(long?nanos);
Duration.ofMillis(long?millis);
Duration.ofSeconds(long?seconds);
Duration.ofMinutes(long?minutes);
Duration.ofHours(long?hours);
Duration.ofDays(long?days);
當(dāng)然,我們還可以直接設(shè)置瀏覽器的各種全局等待時間,代碼上看觀感好了不少。
ChromeOptions?options?=?new?ChromeOptions();
options.setImplicitWaitTimeout(Duration.ofSeconds(10));
options.setScriptTimeout(Duration.ofSeconds(10));
options.setPageLoadTimeout(Duration.ofSeconds(10));
相對定位器
一些哲學(xué)流派告訴我們,世界是變化的,相對的,沒有絕對的靜,也沒有絕對的動,物體總是相對著其他物體進(jìn)行著運動。
在之前的selenium版本里,我們大部分情況下只能通過絕對定位器來定位元素,比如
- 定位一個id=xxx的元素
- 定位所有class=yyy的元素
- 定位所有的tag那么=zzz的元素
當(dāng)然,還是有例外的,我們可以通過xpath或者css來不那么絕對的定位元素。比如
- .nav > li:定位class為nav的元素下所有的直接li子元素
- #nav .item:定位id是nav下面所有的class為item的元素
這也是我推薦用css定位的原因,更靈活更簡潔,同時可以跟前端的技術(shù)棧保持相對統(tǒng)一,xpath的定位能力更強(qiáng)一些,同時也帶來了給多的復(fù)雜性和學(xué)習(xí)成本。
在selenium 4.0中,相對定位器終于千呼萬喚始出來,我們可以省去相對復(fù)雜的xpath表達(dá)式,用更加直觀的方式來定位元素了,舉個例子,下面是一個登錄頁面。
?
?
?
其html代碼如下:
<div?class="row">
????<div?class="large-6?small-12?columns">
????????<label?for="password">Password</label>
????????<input?type="password"?name="password"?id="password">
????</div>
</div>
我們試著去定位input之前的那個label,經(jīng)驗豐富的你可以想象到頁面上會有非常多l(xiāng)abel,所以用tagname的方式應(yīng)該不可??;另外這個label還沒有其他更加獨特的屬性可以利用。不過我們可以發(fā)現(xiàn),睡在他下鋪的兄弟input有id屬性,定位起來相對簡單,很自然的會想到能不能利用input來定位label呢?現(xiàn)在都2021年了,這類的相對定位方式已經(jīng)被支持了的。
WebElement?passwordArea?=?driver.findElement(By.id("password"));
WebElement?labelOfPass?=?driver.findElement(with(By.tagName("label")).above(passwordArea));
System.out.println(labelOfPass.getText());
大家可以猜一猜上面代碼的輸出是什么?
toLeftOf/toRightOf/near
除了上面所展示的above方式以外,selenium 4.0還支持below,toLeftOf/toRightOf/near等方式,舉個簡單的例子。
<tr>
????<td?class="name">itest.info</td>
????<td?class="website">itest.info</td>
????<td?class="actions">
????????<a?href="#edit">Edit</a>
????????<a?href="#delete">Delete</a>
????</td>
</tr>
如果我們要定位上面的delete按鈕,我們可以用下面的相對定位方式
WebElement?website?=?driver.findElement(By.xpath("(//td[text()='itest.info'])"));
driver.findElement(with(By.linkText("Delete")).toRightOf(website)).click();
//?or
driver.findElement(with(By.linkText("Delete")).near(website)).click();
打開新窗口或者新標(biāo)簽頁
在之前的selenium版本中,我們?nèi)绻蜷_新窗口或者是新標(biāo)簽頁的話,我們需要先實例化1個driver對象,然后使用window handler來進(jìn)行下一步的操作;在4.0以后,我們可以直接使用switchTo()方法來打開新窗口。下面是具體的例子:
WebDriver?driver?=?Driver.get();
driver.get("http://www.itest.info/");
????????
driver.switchTo().newWindow(WindowType.WINDOW);
driver.get("https://qq.com");
打開新標(biāo)簽頁也很好辦,我們只需要修改WindowType就好了。
WebDriver?driver?=?Driver.get();
driver.get("http://www.itest.info/");
????????
driver.switchTo().newWindow(WindowType.TAB);
driver.get("https://qq.com");
DevTools協(xié)議
在4.0之后我們可以直接使用chrome的開發(fā)者工具接口來獲取網(wǎng)絡(luò)情況或者是性能數(shù)據(jù)了。下面的例子展示了如何使用devtools來設(shè)置自己的地理位置,自動化打卡簽到有希望了。
WebDriver?driver?=?new?ChromeDriver();
DevTools?devTools?=?((HasDevTools)driver).getDevTools();
devTools.createSession();
devTools.send(Emulation.setGeolocationOverride(Optional.of(38.89511),
????????????????Optional.of(-77.03637),
????????????????Optional.of(1)));
driver.get("https://my-location.org/");
總結(jié)
selenium 4.0并沒有帶來特別多令人嘖嘖稱奇的特性,不過從api的設(shè)計以及語義上,元素的定位上都有了不同程度的優(yōu)化和提升,這也是selenium成熟的體現(xiàn)。作為1個從selenium rc時代就使用selenium的老用戶,對這次大的版本更新我竟然覺得有一絲絲的感動,畢竟是一個開源項目,大家都有自己的工作和生活,能十幾年如一日的維護(hù)和更新selenium本來就是一件不容易的事情,維護(hù)者們?yōu)榱藟粝牒颓閼堰€在努力,我們不妨也一起加油吧,學(xué)無止境,我獨自邁步向前,讓舉步不前的人自己卷自己吧。
?
原文鏈接
https://mp.weixin.qq.com/s/xeuKSPCg7M3-pWzv-Dl-og
本文摘自 :https://www.cnblogs.com/