Protractor - 核心 API(續…)
在本章中,讓我們學習更多 Protractor 的核心 API。
元素 API
Element 是 Protractor 公開的全域性函式之一。此函式接受一個定位器並返回以下內容:
- ElementFinder,根據定位器查詢單個元素。
- ElementArrayFinder,根據定位器查詢元素陣列。
以上兩者都支援如下所述的鏈式方法。
ElementArrayFinder 的鏈式函式及其描述
以下是 ElementArrayFinder 的函式:
element.all(locator).clone
顧名思義,此函式將建立元素陣列(即 ElementArrayFinder)的淺複製。
element.all(locator).all(locator)
此函式基本上返回一個新的 ElementArrayFinder,它可能為空或包含子元素。它可用於如下選擇多個元素作為陣列
示例
element.all(locator).all(locator) elementArr.all(by.css(‘.childselector’)); // it will return another ElementFindArray as child element based on child locator.
element.all(locator).filter(filterFn)
顧名思義,在將過濾器函式應用於 ElementArrayFinder 中的每個元素後,它將返回一個新的 ElementArrayFinder,其中包含透過過濾器函式的所有元素。它基本上有兩個引數,第一個是 ElementFinder,第二個是索引。它也可用於頁面物件。
示例
檢視
<ul class = "items"> <li class = "one">First</li> <li class = "two">Second</li> <li class = "three">Third</li> </ul>
程式碼
element.all(by.css('.items li')).filter(function(elem, index) {
return elem.getText().then(function(text) {
return text === 'Third';
});
}).first().click();
element.all(locator).get(index)
藉助此功能,我們可以透過索引獲取 ElementArrayFinder 中的元素。請注意,索引從 0 開始,負索引會被包裝。
示例
檢視
<ul class = "items"> <li>First</li> <li>Second</li> <li>Third</li> </ul>
程式碼
let list = element.all(by.css('.items li'));
expect(list.get(0).getText()).toBe('First');
expect(list.get(1).getText()).toBe('Second');
element.all(locator).first()
顧名思義,這將獲取 ElementArrayFinder 的第一個元素。它不會檢索底層元素。
示例
檢視
<ul class = "items"> <li>First</li> <li>Second</li> <li>Third</li> </ul>
程式碼
let first = element.all(by.css('.items li')).first();
expect(first.getText()).toBe('First');
element.all(locator).last()
顧名思義,這將獲取 ElementArrayFinder 的最後一個元素。它不會檢索底層元素。
示例
檢視
<ul class = "items"> <li>First</li> <li>Second</li> <li>Third</li> </ul>
程式碼
let first = element.all(by.css('.items li')).last();
expect(last.getText()).toBe('Third');
element.all(locator).all(selector)
當可以連結對 $$ 的呼叫時,用於在父級中查詢元素陣列。
示例
檢視
<div class = "parent">
<ul>
<li class = "one">First</li>
<li class = "two">Second</li>
<li class = "three">Third</li>
</ul>
</div>
程式碼
let items = element(by.css('.parent')).$$('li');
element.all(locator).count()
顧名思義,這將計算 ElementArrayFinder 表示的元素數量。它不會檢索底層元素。
示例
檢視
<ul class = "items"> <li>First</li> <li>Second</li> <li>Third</li> </ul>
程式碼
let list = element.all(by.css('.items li'));
expect(list.count()).toBe(3);
element.all(locator).isPresent()
它將元素與查詢器匹配。它可以返回 true 或 false。如果存在任何與查詢器匹配的元素,則為 true,否則為 false。
示例
expect($('.item').isPresent()).toBeTruthy();
element.all(locator).locator
顧名思義,它將返回最相關的定位器。
示例
$('#ID1').locator();
// returns by.css('#ID1')
$('#ID1').$('#ID2').locator();
// returns by.css('#ID2')
$$('#ID1').filter(filterFn).get(0).click().locator();
// returns by.css('#ID1')
element.all(locator).then(thenFunction)
它將檢索 ElementArrayFinder 表示的元素。
示例
檢視
<ul class = "items"> <li>First</li> <li>Second</li> <li>Third</li> </ul>
程式碼
element.all(by.css('.items li')).then(function(arr) {
expect(arr.length).toEqual(3);
});
element.all(locator).each(eachFunction)
顧名思義,它將對 ElementArrayFinder 表示的每個 ElementFinder 呼叫輸入函式。
示例
檢視
<ul class = "items"> <li>First</li> <li>Second</li> <li>Third</li> </ul>
程式碼
element.all(by.css('.items li')).each(function(element, index) {
// It will print First 0, Second 1 and Third 2.
element.getText().then(function (text) {
console.log(index, text);
});
});
element.all(locator).map(mapFunction)
顧名思義,它將對 ElementArrayFinder 中的每個元素應用對映函式。它有兩個引數。第一個是 ElementFinder,第二個是索引。
示例
檢視
<ul class = "items"> <li>First</li> <li>Second</li> <li>Third</li> </ul>
程式碼
let items = element.all(by.css('.items li')).map(function(elm, index) {
return {
index: index,
text: elm.getText(),
class: elm.getAttribute('class')
};
});
expect(items).toEqual([
{index: 0, text: 'First', class: 'one'},
{index: 1, text: 'Second', class: 'two'},
{index: 2, text: 'Third', class: 'three'}
]);
element.all(locator).reduce(reduceFn)
顧名思義,它將對累加器和使用定位器找到的每個元素應用歸約函式。此函式將每個元素歸約為單個值。
示例
檢視
<ul class = "items"> <li>First</li> <li>Second</li> <li>Third</li> </ul>
程式碼
let value = element.all(by.css('.items li')).reduce(function(acc, elem) {
return elem.getText().then(function(text) {
return acc + text + ' ';
});
}, '');
expect(value).toEqual('First Second Third ');
element.all(locator).evaluate
顧名思義,它將評估輸入是否在當前底層元素的範圍內。
示例
檢視
<span class = "foo">{{letiableInScope}}</span>
程式碼
let value =
element.all(by.css('.foo')).evaluate('letiableInScope');
element.all(locator).allowAnimations
顧名思義,它將確定當前底層元素是否允許動畫。
示例
element(by.css('body')).allowAnimations(false);
ElementFinder 的鏈式函式及其描述
ElementFinder 的鏈式函式及其描述:
element(locator).clone
顧名思義,此函式將建立 ElementFinder 的淺複製。
element(locator).getWebElement()
它將返回此 ElementFinder 表示的 WebElement,如果元素不存在,則會丟擲 WebDriver 錯誤。
示例
檢視
<div class="parent"> some text </div>
程式碼
// All the four following expressions are equivalent.
$('.parent').getWebElement();
element(by.css('.parent')).getWebElement();
browser.driver.findElement(by.css('.parent'));
browser.findElement(by.css('.parent'));
element(locator).all(locator)
它將在父級中查詢元素陣列。
示例
檢視
<div class = "parent">
<ul>
<li class = "one">First</li>
<li class = "two">Second</li>
<li class = "three">Third</li>
</ul>
</div>
程式碼
let items = element(by.css('.parent')).all(by.tagName('li'));
element(locator).element(locator)
它將在父級中查詢元素。
示例
檢視
<div class = "parent">
<div class = "child">
Child text
<div>{{person.phone}}</div>
</div>
</div>
程式碼
// Calls Chain 2 element.
let child = element(by.css('.parent')).
element(by.css('.child'));
expect(child.getText()).toBe('Child text\n981-000-568');
// Calls Chain 3 element.
let triple = element(by.css('.parent')).
element(by.css('.child')).
element(by.binding('person.phone'));
expect(triple.getText()).toBe('981-000-568');
element(locator).all(selector)
當可以連結對 $$ 的呼叫時,用於在父級中查詢元素陣列。
示例
檢視
<div class = "parent">
<ul>
<li class = "one">First</li>
<li class = "two">Second</li>
<li class = "three">Third</li>
</ul>
</div>
程式碼
let items = element(by.css('.parent')).$$('li'));
element(locator).$(locator)
當可以連結對 $ 的呼叫時,它將在父級中查詢元素。
示例
檢視
<div class = "parent">
<div class = "child">
Child text
<div>{{person.phone}}</div>
</div>
</div>
程式碼
// Calls Chain 2 element.
let child = element(by.css('.parent')).
$('.child'));
expect(child.getText()).toBe('Child text\n981-000-568');
// Calls Chain 3 element.
let triple = element(by.css('.parent')).
$('.child')).
element(by.binding('person.phone'));
expect(triple.getText()).toBe('981-000-568');
element(locator).isPresent()
它將確定元素是否顯示在頁面上。
示例
檢視
<span>{{person.name}}</span>
程式碼
expect(element(by.binding('person.name')).isPresent()).toBe(true);
// will check for the existence of element
expect(element(by.binding('notPresent')).isPresent()).toBe(false);
// will check for the non-existence of element
element(locator).isElementPresent()
它與 element(locator).isPresent() 相同。唯一的區別在於它將檢查由子定位器標識的元素是否存在,而不是當前元素查詢器。
element.all(locator).evaluate
顧名思義,它將評估輸入是否在當前底層元素的範圍內。
示例
檢視
<span id = "foo">{{letiableInScope}}</span>
程式碼
let value = element(by.id('.foo')).evaluate('letiableInScope');
element(locator).allowAnimations
顧名思義,它將確定當前底層元素是否允許動畫。
示例
element(by.css('body')).allowAnimations(false);
element(locator).equals
顧名思義,它將比較元素是否相等。
定位器 (by) API
它基本上是元素定位器策略的集合,提供了透過繫結、模型等在 Angular 應用程式中查詢元素的方法。
函式及其描述
ProtractorLocators API 的函式如下:
by.addLocator(locatorName,fuctionOrScript)
它將定位器新增到此 ProtrcatorBy 例項,然後可與 element(by.locatorName(args)) 一起使用。
示例
檢視
<button ng-click = "doAddition()">Go!</button>
程式碼
// Adding the custom locator.
by.addLocator('buttonTextSimple', function(buttonText, opt_parentElement, opt_rootSelector) {
var using = opt_parentElement || document,
buttons = using.querySelectorAll('button');
return Array.prototype.filter.call(buttons, function(button) {
return button.textContent === buttonText;
});
});
element(by.buttonTextSimple('Go!')).click();// Using the custom locator.
by.binding
顧名思義,它將透過文字繫結查詢元素。將進行部分匹配,以便返回繫結到包含輸入字串的變數的任何元素。
示例
檢視
<span>{{person.name}}</span>
<span ng-bind = "person.email"></span>
程式碼
var span1 = element(by.binding('person.name'));
expect(span1.getText()).toBe('Foo');
var span2 = element(by.binding('person.email'));
expect(span2.getText()).toBe('foo@bar.com');
by.exactbinding
顧名思義,它將透過精確繫結查詢元素。
示例
檢視
<spangt;{{ person.name }}</spangt;
<span ng-bind = "person-email"gt;</spangt;
<spangt;{{person_phone|uppercase}}</span>
程式碼
expect(element(by.exactBinding('person.name')).isPresent()).toBe(true);
expect(element(by.exactBinding('person-email')).isPresent()).toBe(true);
expect(element(by.exactBinding('person')).isPresent()).toBe(false);
expect(element(by.exactBinding('person_phone')).isPresent()).toBe(true);
expect(element(by.exactBinding('person_phone|uppercase')).isPresent()).toBe(true);
expect(element(by.exactBinding('phone')).isPresent()).toBe(false);
by.model(modelName)
顧名思義,它將透過 ng-model 表示式查詢元素。
示例
檢視
<input type = "text" ng-model = "person.name">
程式碼
var input = element(by.model('person.name'));
input.sendKeys('123');
expect(input.getAttribute('value')).toBe('Foo123');
by.buttonText
顧名思義,它將透過文字查詢按鈕。
示例
檢視
<button>Save</button>
程式碼
element(by.buttonText('Save'));
by.partialButtonText
顧名思義,它將透過部分文字查詢按鈕。
示例
檢視
<button>Save my file</button>
程式碼
element(by.partialButtonText('Save'));
by.repeater
顧名思義,它將在 ng-repeat 內查詢元素。
示例
檢視
<div ng-repeat = "cat in pets">
<span>{{cat.name}}</span>
<span>{{cat.age}}</span>
<</div>
<div class = "book-img" ng-repeat-start="book in library">
<span>{{$index}}</span>
</div>
<div class = "book-info" ng-repeat-end>
<h4>{{book.name}}</h4>
<p>{{book.blurb}}</p>
</div>
程式碼
var secondCat = element(by.repeater('cat in
pets').row(1)); // It will return the DIV for the second cat.
var firstCatName = element(by.repeater('cat in pets').
row(0).column('cat.name')); // It will return the SPAN for the first cat's name.
by.exactRepeater
顧名思義,它將透過精確重複查詢元素。
示例
檢視
<li ng-repeat = "person in peopleWithRedHair"></li> <li ng-repeat = "car in cars | orderBy:year"></li>
程式碼
expect(element(by.exactRepeater('person in
peopleWithRedHair')).isPresent())
.toBe(true);
expect(element(by.exactRepeater('person in
people')).isPresent()).toBe(false);
expect(element(by.exactRepeater('car in cars')).isPresent()).toBe(true);
by.cssContainingText
顧名思義,它將透過 CSS 查詢包含精確字串的元素
示例
檢視
<ul> <li class = "pet">Dog</li> <li class = "pet">Cat</li> </ul>
程式碼
var dog = element(by.cssContainingText('.pet', 'Dog'));
// It will return the li for the dog, but not for the cat.
by.options(optionsDescriptor)
顧名思義,它將透過 ng-options 表示式查詢元素。
示例
檢視
<select ng-model = "color" ng-options = "c for c in colors"> <option value = "0" selected = "selected">red</option> <option value = "1">green</option> </select>
程式碼
var allOptions = element.all(by.options('c for c in colors'));
expect(allOptions.count()).toEqual(2);
var firstOption = allOptions.first();
expect(firstOption.getText()).toEqual('red');
by.deepCSS(selector)
顧名思義,它將透過 CSS 選擇器在 Shadow DOM 中查詢元素。
示例
檢視
<div>
<span id = "outerspan">
<"shadow tree">
<span id = "span1"></span>
<"shadow tree">
<span id = "span2"></span>
</>
</>
</div>
程式碼
var spans = element.all(by.deepCss('span'));
expect(spans.count()).toEqual(3);