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('[email protected]');
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);