What is ElementFinder in protractor

The ElementFinder is nothing but elements present on the webpage; we will get this as a result of element(by.locator("locator value"))

Anything present on the webpage such as textbox, text, button, link, table, radio button, checkbox, etc., are called as webelement. web elements in selenium-webdriver ElementFinder is a single member of an ElementArrayFinder (and is more like a convenience object). As a result, anything that can be done with an ElementFinder also can be done using an ElementArrayFinder.

ElementFinder can be used to build a chain of locators that are used to find an element.

An ElementFinder does not actually attempt to find the element until an action is called, which means they can be set up in helper files before the page is available.

Code for ElementFinder


&ltspan ng-bind="person.email" id='sampletext'>karthiq.chercher@gmail.com&lt/span>
		
// code for element finder with binding
element(by.binding('person.email"))
// code using id
element(by.id("sampletext"))

Explicit wait in Protractor

Element vs ElementFinder

Subscribe to my youtube channel :

What is ElementArrayFinder

ElementArrayFinder is nothing but a group of objects resulting from the element.all(by("id")), it can have 0(zero) to n elements

ElementArrayFinder is used for operations on an array of elements (as opposed to a single element).


										&ltspan ng-bind="person.email" id='sampletext'>karthiq.chercher@gmail.com&lt/span>
										&ltspan ng-bind="person.email" id='sampletext'>chercher.tech@gmail.com&lt/span>
												
										// code for element finder with binding
										element.all(by.binding('person.email"))
										// code using id
										element.all(by.id("sampletext"))
										


ElementArrayFinder will search all branches of the DOM to find the elements that satisfy the conditions (i.e., all, filter, get).

However, an ElementArrayFinder will not actually retrieve the elements until an action is called, which means it can be set up in helper files (i.e., page objects) before the page is available, and reused as the page changes.

You can treat an ElementArrayFinder as an array of WebElements for most purposes; in particular, you may perform actions (i.e., click, getText) on them as you would an array of WebElements.

The action will apply to every element identified by the ElementArrayFinder.

ElementArrayFinder and each result represent the result of performing the action on the element. Unlike a WebElement, an ElementArrayFinder will wait for the angular app to settle before performing finds or actions.

Ways to select the dropdown option

WebElement vs. Array of WebElement

Subscribe to my youtube channel :

What is WebElement

When we perform any action on the ElementFinder, protractor converts it into WebElement and perform the operation.

We can convert the ElementFinder into WebElement using the getWebElement() command present in the protractor. Every method calls this method internally before performing an operation on the webpage object

Similarly, we can convert ElementArrayFinder into an array of webelements using getWebElements() method in protractor


										&ltspan ng-bind="person.email" id='sampletext'>karthiq.chercher@gmail.com&lt/span>
										
										// below code convert the Element finder to WebElement before performing 
										// click operation
										element(by.id("sampletext")).getText()
										
										// getWebElement
										element(by.id("sampletext")).getWebElement()
										
										// getWebElements
										element.all(by.id("sampletext")).getWebElements()
										

Send emails in protractor.

Common methods in element & element.all

There are a few methods which are common for both element and element.all methods, with these methods we can perform some operations

Clone method in element & element.all :

The clone method creates a shallow copy of the ElementFinder.

In a simple way, we can create another variable that will hold the same information as exact as the source value.

But this variable will not have its own cell address, but it will point to the same address from where we have cloned.

In layman terms, We have created duplicate value for the original but duplicate and original both point at the same thing, and if you make any change either with duplicate or original, that change will affect both original and duplicate.

To avoid these people, make a deep copy/Clone rather than a shallow copy.


import { browser, $, by, element, $$} from 'protractor'
describe('Protractor Typescript Demo', function() {
	browser.ignoreSynchronization = true; // for non-angular websites
	browser.manage().window().maximize()
	it('Find  Operations', function() {
		// set implicit time to 30 seconds
		browser.manage().timeouts().implicitlyWait(30000);
		
		browser.get("https://google.com")
		// find the element and set value
		let originalElement = element(by.name("q"));
		let cloneElement = originalElement.clone()
		// i am passing value to original element
		originalElement.sendKeys("This is Example for clone");
		// retrieving value from clone
		cloneElement.getAttribute("value").then(function(valueFromGoogleBar){
			console.log("Retrieve value using clone *******: "+valueFromGoogleBar)
		})
	});
});			


The Output of the clone program clone-element-protractor-elementfinder

all

This method also works similar to the element.all but the difference is, all method is present inside the ElementFinder.

all method finds all the matching elements present inside an element. For example, consider the dropdown, the upper-level select tag will have all the options inside.

This function returns a new ElementArrayFinder, which would contain the children elements found (and could also be empty).


&ltdiv id='id1' class="parent">
  &ltul>
    &ltli class="foo" id="child1">1a&lt/li>
    &ltli class="baz" id="child2">1b&lt/li>
  &lt/ul>
&lt/div>			


In the above HTML code, we have a div element as a parent and what ever present inside till </div> are child elements

Once we find the parent, we can check other elements inside the parent using all method.


// finds parent and gets all child elements which has class as child1
let foo = element.all(by.css('.parent')).all(by.css('.child1'));
expect(foo.getText()).toEqual(['1a']);	
// finds parent and gets all child elements which has tagname as li
let foo = element.all(by.css('.parent')).all(by.tagname('.li'));
expect(foo.getText()).toEqual(['1a', '1b']);		

element.all().locator :

element.all().locator method tries to return the most relevant CSS value of the target value from the given Jquery value


// returns by.css('#ID1')
$('#ID1').locator();
// returns by.css('#ID2') as #ID2 is target element
$('#ID1').$('#ID2').locator();			

Package.json with Protractor

Methods of element.all

With the help of the element.all we can find all the matching elements present on the webpage; once we receive an array of web elements, we can use methods that are provided by elements.all which are similar to an array method, but it has few methods from protractor.

element.all().get() :

get method returns an element present in the specific position of the array of elements.

When we handle an array of elements, this method will be useful for iteration with for loop. Use below HTML code for all the methods in the element.all


&ltul class="items">
  &ltli>First&lt/li>
  &ltli>Second&lt/li>
  &ltli>Third&lt/li>
&lt/ul>			

let list = element.all(by.css('.items li'));
expect(list.get(0).getText()).toBe('First');
expect(list.get(1).getText()).toBe('Second');
for(let i=0; i&ltlist.length; i++){
	expect(list.get(i)).not.toBe("", "element has no value")
}	

first() & last()

first() method return the first element of the array and the last method returns the last element of the array


let first = element.all(by.css('.items li')).first();
expect(first.getText()).toBe('First');
let last = element.all(by.css('.items li')).last();
expect(last.getText()).toBe('Third');			

count() :

count() method in protractor returns a number of elements present in the given ElementArrayFinder.


let list = element.all(by.css('.items li'));
// we checking whether three elements are there in array
expect(list.count()).toBe(3);			

each :

each() method iterates over the elements present in the given array of elements in protractor Below code will fetch the position of the element and the element itself


element.all(by.css('.items li')).each(function(element, index) {
  // Will print 0 First, 1 Second, 2 Third.
  element.getText().then(function (text) {
    console.log(index, text);
  });
});			

map()

map() method will create a map using the ElementArrayFinder with user-given attributes Use same HTML code as above, create a map based on index, text, class as given by the user


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'}
]);		

mouseMove / hover in Protractor

Different Ways to find the WebElement

We can find the elements on the webpage using few ways in protractor.

Element :

    • element
    • $()
    • browser.findElement
    • browser.driver.findElement

Array of Elements :

  • element.all
  • $$()
  • browser.findElements
  • browser.driver.findElements

Protractor project folder structure

element :

We can find the element on the web page using element() method in the protractor, element() method will return only single element.

If there are more elements are matching, then element() method will return only the first match.

In the below example, we will be setting a value into the google search field.


import { browser, element, by, ElementFinder, ProtractorBrowser, protractor} from 'protractor'
import {} from "../specs/loge"
import { CutomLogger } from './t';
describe('Protractor Typescript Demo', function() {
	browser.ignoreSynchronization = true; // for non-angular websites
	browser.manage().window().maximize()
	it('Find  Operations', function() {
		// set implicit time to 30 seconds
		browser.manage().timeouts().implicitlyWait(30000);
		
		browser.get("https://google.com")
		// finds th element
		element(by.name("q")).sendKeys("hello")
	});
});			

$ :

$ method works only based on the CSS value; we have to provide the right CSS value to find the elements, the first match will be returned if there are more than one match is present


import { browser, $} from 'protractor'
describe('Protractor Typescript Demo', function() {
	browser.ignoreSynchronization = true; // for non-angular websites
	browser.manage().window().maximize()
	it('Find  Operations', function() {
		// set implicit time to 30 seconds
		browser.manage().timeouts().implicitlyWait(30000);
		
		browser.get("https://google.com")
		// finds the element
		$("input[name='q']").sendKeys("dollar method")
	});
});	

Dynamic Table | Custom WebElement

browser.findElement :

browser.findElement method will find the element based on the given locator. browser.findElement will fall back to webdriver methods, and then only it finds the element.

This is more of a Webdriver method than a protractor method, but it works well with protractor as well.


import { browser, $, by} from 'protractor'
describe('Protractor Typescript Demo', function() {
	browser.ignoreSynchronization = true; // for non-angular websites
	browser.manage().window().maximize()
	it('Find  Operations', function() {
		// set implicit time to 30 seconds
		browser.manage().timeouts().implicitlyWait(30000);
		
		browser.get("https://google.com")
		// find the element and set value
		browser.findElement(by.name("q")).sendKeys("find elements method")
	});
});

browser.driver.findEement :

browser.driver.findEement method is directly from webdriver; in this method, we are not even falling back; we are directly accessing the findElement method in webdriver.


import { browser, $, by} from 'protractor'
describe('Protractor Typescript Demo', function() {
	browser.ignoreSynchronization = true; // for non-angular websites
	browser.manage().window().maximize()
	it('Find  Operations', function() {
		// set implicit time to 30 seconds
		browser.manage().timeouts().implicitlyWait(30000);
		
		browser.get("https://google.com")
		// find the element and set value
		browser.driver.findElement(by.name("q")).sendKeys("base find element way")
	});
});


Above four methods will find the single element but we can user other four methods to get the first element or make them work as the above four methods

Protractor Interview Questions

Array of Elements

element.all method works like element() method but element.all method returns all the elements which are matching with a given locator, so as a result, we would be getting an array of elements.

I hope you remember that which match the element() method returns, exactly you are right, the first match, the array index starts with 0 (zero), so our required element will be at 0th position.

This way, we can achieve the function of the element() through the element.all() method, if we don't know the position of the element when there are more matches, then you cannot use this way.


import { browser, $, by, element} from 'protractor'
describe('Protractor Typescript Demo', function() {
	browser.ignoreSynchronization = true; // for non-angular websites
	browser.manage().window().maximize()
	it('Find  Operations', function() {
		// set implicit time to 30 seconds
		browser.manage().timeouts().implicitlyWait(30000);
		
		browser.get("https://google.com")
		// find the element and set value
		element.all(by.name("q")).get(0).sendKeys("elements all method")
	});
});			


I guess you are confident about how the remaining three methods work to find a single element. $$ method :


$$("input[name='q']").get(0).sendKeys("double dollar method")			


browser.findElements:


browser.findElements(by.name('q')).then(function(elements){
	elements[0].sendKeys("find elements method")
})			


browser.driver.findElements :


browser.driver.findElements(by.name('q')).then(function(elements){
	elements[0].sendKeys("find elements method")
})			


We have a huge usage of the element.all other than finding a single element.

Protractor Interview Questions

Comment / Suggestion Section
Point our Mistakes and Post Your Suggestions
  • Deva
    It would be helpful if you could provide next and previous buttons at end of every page , 
    Reply
    • Author
      Most of the people cannot come till half, it is great you reached till bottom. I will add those very soon (not really by march 2019)
      Reply