# Locators 定位器

## Using Locators 使用定位器

The heart of end-to-end tests for webpages is finding DOM elements, interacting with them, and getting information about the current state of your application. This doc is an overview of how to locate and perform actions on DOM elements using Protractor.

E2E测试的核心就是找到DOM元素，和它们交互，并且得到应用目前的状态。

## Overview 概述

Protractor exports a global function element, which takes a Locator and will return an ElementFinder. This function finds a single element - if you need to manipulate multiple elements, use the element.all function.

element是protrator的 全局函数，接受一个locator,返回一个ElementFinder对象。

The ElementFinder has a set of action methods, such as click(), getText(), and sendKeys. These are the core way to interact with an element and get information back from it.

When you find elements in Protractor all actions are asynchronous. Behind the scenes, all actions are sent to the browser being controlled using the JSON Webdriver Wire Protocol. The browser then performs the action as a user natively would.

ElementFinder 有一组方法，如 click(), getText(), and sendKeys.

## locators 定位器

A locator tells Protractor how to find a certain DOM element. Protractor exports locator factories on the global by object. The most common locators are:

// find an element using a css selector
by.css('.myclass')

// find an element with the given id
by.id('myid')

// find an element with a certain ng-model
by.model('name')

// find an element bound to the given variable
by.binding('bindingname')

For a list of Protractor-specific locators, see the Protractor API: ProtractorBy.

The locators are passed to the element function, as below:

element(by.css('some-css'));
element(by.model('item.name'));
element(by.binding('item.name'));

When using CSS Selectors as a locator, you can use the shortcut ()notation:css$() notation: 当定位器是css选择器时，可以用快捷符号$()

\$('my-css');

// Is the same as

element(by.css('my-css'));

## Actions 动作

The element() function returns an ElementFinder object. The ElementFinder knows how to locate the DOM element using the locator you passed in as a parameter, but it has not actually done so yet. It will not contact the browser until an action method has been called.
The most common action methods are:

element()函数返回ElementFinder对象。但是它只有在方法被调用的时候才会联系浏览器定位DOM元素。

var el = element(locator);

// Click on the element
el.click();

// Send keys to the element (usually an input)
el.sendKeys('my text');

// Clear the text in an element (usually an input)
el.clear();

// Get the value of an attribute, for example, get the value of an input
el.getAttribute('value');

Since all actions are asynchronous, all action methods return a promise. So, to log the text of an element, you would do something like:

var el = element(locator);
el.getText().then(function(text) {
console.log(text);
});

Any action available in WebDriverJS on a WebElement is available on an ElementFinder.

## Finding Multiple Elements 寻找多个元素

To deal with multiple DOM elements, use the element.all function. This also takes a locator as its only parameter.

element.all(by.css('.selector')).then(function(elements) {
// elements is an array of ElementFinders.
});

// Number of elements.
element.all(locator).count();

// Get by index (starting at 0).
element.all(locator).get(index);

// First and last.
element.all(locator).first();
element.all(locator).last();

## Finding Sub-Elements 寻找子元素

To find sub-elements, simply chain element and element.all functions together as shown below.

Using a single locator to find:
- an element

element(by.css('some-css'));

Using chained locators to find:
- a sub-element:

element(by.css('some-css')).element(by.tagName('tag-within-css'));
• to find a list of sub-elements:
element(by.css('some-css')).all(by.tagName('tag-within-css'));

You can chain with get/first/last as well like so:

element.all(by.css('some-css')).first().element(by.tagName('tag-within-css'));
element.all(by.css('some-css')).get(index).element(by.tagName('tag-within-css'));
element.all(by.css('some-css')).first().all(by.tagName('tag-within-css'));

Written with StackEdit.