In the previous article, we have discussed browser API commands. To perform any action on the web element needs to be uniquely recognized in a DOM tree. There are various ways to find the element in protractor lets discuss alias function element() which returns ElementFinder in Protractor. Throughout the article, we discuss about
- What is a Web element in the Webpage?
- What is ElementFinder in Protractor?
- Import elementFinder and element to test script
- Finding Sub Elements in Protractor
- GetWebElement() function in Protractor
- Using locator() function in protractor ElementFinder
- Using evaluate() function in protractor ElementFinder
- Cloning web element in Protractor
- Equals function in Protractor
What is a Web element in the Webpage?
Each and individual component in the webpage is considered an element. For example, at ToolsQA home page, there are components like ToolsQA logo, menu items, footer content, etc. ToolsQA logo is one individual web element, each menu item is an individual web element. With the help of protractor and selenium, these elements are uniquely identified. Each web element is associated with the property such as class, tags, id or attributes which uniquely identifies that element.
What is ElementFinder in Protractor?
In protractor, the single web element belongs to type ElementFinder. The ElementFinder can be treated as a WebElement for most purposes, in particular, you may perform actions (i.e. click, getText) on them as you would a WebElement. Once an action is performed on an ElementFinder, the latest result from the chain can be accessed using the then method. Unlike a WebElement, an ElementFinder will wait for angular to settle before performing finds or actions.
The global alias function element() is used for finding the element in protractor. It is as equal to findElement in Selenium. This function accepts one argument that is of type Locator(will be discussed in the next article). Returns ElementFinder which is used to uniquely locate the element in the webpage.
In order to use the ElementFinder in the test script, we need to import element and ElementFinder.
Import elementFinder and element to test script
import { element, ElementFinder} from 'protractor'
Protractor ElementFinder
Purpose: The element() function in protractor is used to locate the element in a web page.
Syntax: element(locator):ElementFinder
Parameters: This function accepts one parameter of type Locator. The locator can be found using multiple ways which will be covered in the next article.
Returns: This function returns value of type ElementFinder. One can perform various actions using the ElementFinder instance.
Code Example
//spec.ts
import { browser, by, element, ElementFinder } from 'protractor'
import { Driver } from 'selenium-webdriver/edge';
describe('Protractor ElementFinder Demo', function () {
it('Uses ElementFinder', () => {
browser.get("https://material.angularjs.org/latest/demo/autocomplete")
let sampleElement: ElementFinder = element(by.css('ul#docs-menu-Demos>li:nth-child(1) a')); //ElementFinder function used here
sampleElement.getAttribute('innerText').then((text) => {
console.log(text);
});
});
});
Note: There are various ways to locate the element in protractor which will be discussed in coming articles.
In the above example,
- let sampleElement:ElementFinder = element(by.css('ul#docs-menu-Demos>li:nth-child(1) a'));: We have created sampleElement as variable. The let keyword is used to create a local variable in typescript. The type of varaible is mentioned after : (colon).In the above example type is ElementFinder.
Syntax to create a local variable in Typescript:
let variable_name : data_type
- element(by.css('ul#docs-menu-Demos>li:nth-child(1) a')); : element is a function / method which is used to find the webelement
- by.css('ul#docs-menu-Demos>li:nth-child(1) a') : This is the locator passed as parameter to element()
- sampleElement.getAttribute('innerText'): This is used to get the attribute value in protractor. We will cover in detail upcoming articles.
- .then((text) => { console.log(text): As explained in Promise article, the getAttribute('innerText') returns promise that will be resolved to string. When we use then the value of the promise will be resolved and passed to function inside the then as parameter ex: in the above example local variable text. The text is the value of getAttribute('innerText') statement when this function is chained with then, the value will be will be automatically passed as a parameter to the input function of then.
Finding Sub Elements in Protractor
ElementFinder can be used to build a chain of locators that are used to find the sub-element. An ElementFinder does not actually attempt to find the element until an action is called.
Syntax: element(locators).element(subLocator):ElementFinder;
Code Example
//spec.ts
import { browser, by, element, ElementFinder} from 'protractor'
describe('Protractor ElementFinder Demo', ()=> {
it('Should find sub elements', ()=> {
browser.get("https://material.angularjs.org/latest/demo/autocomplete")
let sampleElement:ElementFinder=element(by.id('docs-menu-Demos')) // Element Finder
.element(by.repeater('page in section.pages')) //ElementFinder chained
.element(by.className('ng-isolate-scope')) //ElementFinder Chained
.element(by.tagName('a')); //ElementFinder Chained
sampleElement.getText()
.then((text)=>(console.log(text)));
});
});
In the above example,
- let sampleElement:ElementFinder=element(by.id('docs-menu-Demos')): Gets the element from the webpage, this can be considered as the parent element
- .element(by.repeater('page in section.pages')) : In this line, we are getting child element by chaining with parent, this child can even have few more child elements
- element(by.tagName('a')) : At last, we try to drill into the child that is in need.
Instead of constructing typical XPath, one can just traverse element one by one to find the subelement in protractor. This improves the readability of the code and easy to understand.
Note: ElementFinder can be chained with element array finder which will be covered in the next article.
GetWebElement() function in Protractor
Purpose: The element() returns value type of ElementFinder. However, if required we can use the getWebElement() function to get the element of type WebElement.
Syntax: element(locator).getWebElement(): WebElementPromise;
Returns: This function returns the value of type WebElementPromise
Code Example:
//spec.ts
import {browser,by,element,ElementFinder, WebElementPromise} from 'protractor'
import { WebdriverWebElement } from 'protractor/built/element';
describe('Protractor ElementFinder Demo', function () {
it('Get webelement example', () => {
browser.get("https://material.angularjs.org/latest/demo/autocomplete")
let sampleElement: WebElementPromise = element(by.css('#docs-menu-Demos > li:nth-child(2) > menu-link > a')).getWebElement(); //getWebElement() function used here
browser.executeScript("arguments[0].click();", sampleElement); // Javscript click action by passing pure selenium element
browser.sleep(4000);
});
});
What is the difference between Element(locator) and GetWebElement()?
When we use element(locator)) the protractor returns element of type ElementFinder, as discussed earlier ElementFinder is a protractor wrapper. There might be some instance where one may need pure or raw web element which selenium returns. For example, if one needs to execute javascript actions which accept only selenium web element of type WebElement, in that case, one can use getWebElement() function to get the pure base Selenium WebElement.
Using locator() function in protractor ElementFinder
Purpose: The function locator() returns most relevant locator. This is one of the less used functions in protractor and mostly used in error reporting.
Syntax: element(locator).locator();
Returns: This function returns the value of type Any, Any is advanced datatype in typescript which accepts all types
Code Example:
//spec.ts
import { browser, by, element, ElementFinder, } from 'protractor'
describe('Protractor ElementFinder Demo', function () {
it('Get webelement example', () => {
browser.get("https://material.angularjs.org/latest/demo/autocomplete")
browser.sleep(4000);
let sampleElement: ElementFinder = element(by.css('#docs-menu-Demos'));
expect(sampleElement.isPresent()).toBeFalsy('Expected element ' + sampleElement.locator() + ' Should be present and Visible'); //locator() is used here
});
});
The locator() function in protractor returns the most relevant locator. In the above example sampleElement.locator() is used inside the .toBeFalsy() function, Upon failing the expect statement this statement prints the locator. Ex: Expected true toBeFalsy 'Expected element By(css selector, #docs-menu-Demos) Should be present and Visible'. Instead of explicitly specifying a locator name one can dynamically get the locator using a locator() function.
Using evaluate() function in protractor ElementFinder
Purpose: The evaluate() function is rarely used, but has a unique purpose - it gives you access to the scope of the current element you are working with. This is usually needed when a value you are looking for is not exposed in the HTML as an attribute or element's text.
Syntax: evaluate(expression: string): ElementFinder
Parameter: This function accepts one parameter which is of type string.
Returns: This function evaluates the expression and returns element of type ElementFinder
Code Example:
let value = element(by.id('foo')).evaluate('letiableInScope');
Cloning web element in Protractor ElementFinder
Purpose: The clone() function is helpful if one needs to do a shallow copy of ElementFinder. basically, this method creates an exact copy of the source. clone() is rarely used function.
Syntax: element(locator).clone(): ElementFinder
Returns: This function returns element of type ElementFinder
Code Example:
let originalWebElement = element(by.className("toolsqa")); //Original Web Element
let clonedWebElement = originalElement.clone(); //Cloned Web Element
In the above example variables originalWebElement and clonedWebElement having the exact same value.
Equals function in Protractor ElementFinder
Purpose: The equals() method is used to compare two elements.
Syntax:element(element:ElementFinder|WebElement).equals(element:ElementFinder|WebElement):Promise<boolean>
;
Parameter: This function accepts a parameter which is another element to compare
Returns: This function returns a promise that will be resolved to type bolean.
Code Example:
//spec.ts
import { browser, by, element, ElementFinder } from 'protractor'
describe('Protractor ElementFinder Demo', function () {
it('Example of equals function in protractor', function () {
browser.get("https://material.angularjs.org/latest/demo/autocomplete")
let sampleElement: ElementFinder = element(by.id('docs-menu-Demos'))
.element(by.repeater('page in section.pages')); //Create a sample element
let clonedSampleElement = sampleElement.clone(); // Create a copy using clone function
sampleElement.equals(clonedSampleElement) //Equals function used here
.then((isEqual)=>(console.log('Euqality Check :'+isEqual))) // Value of euquals function displayed in console log
});
});
Note: Points to remember
- The alias function element() is used to find the element in protractor
- The getWebElement() can be used to get the plain element of type WebElement
- The element() can be chained to find the sub-element