Protractor - 核心 API(续)

在本章中,让我们学习 Protractor 的更多核心 API。

Elements 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'));
// 它将根据子定位器返回另一个 ElementFindArray 作为子元素。

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)

顾名思义,它将对累加器和使用定位器找到的每个元素应用一个 Reduce 函数。该函数将每个元素简化为一个值。

示例

查看

<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>

代码

// 以下所有四个表达式都是等效的。
$('.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
981-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
981-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);
// 将检查元素是否存在

expect(element(by.binding('notPresent')).isPresent()).toBe(false);
// 将检查元素是否存在

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

顾名思义,它将比较元素是否相等。

Locators(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)); // 它将返回第二只猫的 DIV。
var firstCatName = element(by.repeater('cat in pets').
row(0).column('cat.name')); // 它将返回第一只猫名字的 SPAN。

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'));
// 它将返回狗的 li,但不返回猫的 li。

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 选择器在影子 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);