使用protractor操作頁面元素

無敵西瓜發表於2015-05-04

Protractor是為Angular JS應用量身打造的端到端測試框架。它可以真實的驅動瀏覽器,自動完成對web應用的測試。Protractor驅動瀏覽器使用的是WebDriver標準,所以使用起來與其他語言實現的WebDriver庫大體相同。當然,我說大體相同那肯定還是有不同的地方。一旦不注意這些不同的地方就會坑到你(我就被成功坑過,所以才有了這篇文章)。

Protractor編寫測試的核心是查詢DOM元素,與其互動,然後檢視互動後的狀態與你的期望是否一致。所以查詢DOM元素並與之互動顯的非常重要。Protractor提供了一個全域性函式element,其接受一個Locator物件並返回一個ElementFinder物件。該函式會返回單個元素。如果你想返回多個元素,可以使用element.all函式,其接受一個Locator物件並返回ElementArrayFinder物件。ElementFinder物件有一組方法,用於元素互動,比如click(),getText(),sendKeys等。

Locator物件的建立主要使用全域性的by物件,其提供一些API來生成Locator物件以供element或element.all函式使用。

比如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
//根據class名來查詢元素
by.css(myclass`)

//根據id來查詢元素
by.id(‘myid`)

//根據ng-model名來查詢元素
by.model(name`)

//查詢繫結了指定名的元素
by.binding(‘bindingname`)

//查詢指定repeater中的元素
by.repeater(myrepeater`)

可以看出前兩個Locator的建立方法與其他語言實現的WebDriver的用法基本一樣,而後幾個則專為AngularJS應用設計的,方便在基於AngualrJS框架下寫的web應用中查詢頁面元素。這是第一處不同。

另一處不同其他語言實現的WebDriver庫使用Locator找到的元素型別是WebElement,而Protractor則返回的是ElementFinder物件。兩者不同之處是在於ElementFinder物件不會立即與瀏覽器互動,根據指定的Locator來查詢到頁面上的元素;而只有當你呼叫了ElementFinder物件的方法時,它才會真正的與瀏覽器進行互動。一些常用的方法有以下所示。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
//這時不會與瀏覽器互動獲取元素資訊
var el = element(by.css(mycss));

//點選元素
el.click();

//給該元素輸入內容
el.sendKeys(text);

//清空元素內內容
el.clear();

//獲取指定屬性的值
el.getAttribute(value);

//獲取元素的文字值
el.getText();

請注意這些方法都是非同步的。所有的方法返回的是一個promise(我就吃過這個虧,以為返回的是值)。所以比如你想輸出一個元素的值,應該這麼寫:

1
2
3
element(by.css(myclass)).getText().then(function(text) {
     console.log(text);
}):

如果你使用expect方法來驗證元素的值時,expect方法會幫你取出promise中值,所以你只用這麼寫:

1
expect(element(by.css(myclass)).getText()).toEqual(`確定’);

還有不同的地方在於Protractor支援對元素查詢時進行鏈式呼叫。這樣的功能相當實用。你可以組合element和element.all兩個函式來定位元素。並且Protractor還提供了幾個輔助方法來更方便你的使用。

1
2
3
element.all(locator1).first().element(locator2);
element(locator1).all(locator2);
element.all(locator1).get(index).all(locator2);

element.all函式提供的輔助方法有:

  • filter: 提供一個過濾器過濾其中的元素。

1
2
3
4
5
element.all(by.css(myclass)).filter(function(ele, index) {
return ele.getText().then(function(text) {
     return text == ‘確定`;
});
});
  • get: 根據索引獲取指定元素。如 element.all(by.css(‘myclass’)).get(0);

  • first: 獲取第一個元素。 element.all(by.css(’myclass’)).first();

  • last: 獲取最後一個元素,用法同上。

  • count:獲取元素個數。

此外還提供了each,map,reduce等方法對列表進行各種操作。

element函式提供的輔助方法有:

  • locator: 返回locator物件。

  • getWebElement: 返回該ElementFinder包裹的WebElement物件。

  • all: 查詢其一組子元素。

  • element: 查詢其子元素。

  • isPresent: 元素是否在頁面上展示。

總結起來,Protractor與其它的WebDriver語言實現的區別如下:

  1. Protractor專為AngualrJS應用定製,其自身包含了很多wait操作,保證AngularJS指令碼執行完畢後才進行下一步操作,保證了測試的穩定性與健壯性。

  2. Protractor設計的By物件針對AngularJS應用提供了很多實用方法,在定義AngularJS應用頁面時更加輕鬆。

  3. element函式返回的是ElementFinder物件,其不會立即與瀏覽器互動,除非呼叫ElementFinder物件的方法。

  4. 呼叫ElementFinder物件的方法返回的是一個promise。(這點很重要)

  5. Protractor在定位元素時支援鏈式呼叫。


相關文章