Protractor Chained Elements by Using Variables?

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP



Protractor Chained Elements by Using Variables?



I am trying to keep my pageObjects in Protractor as clean as possible, but have run up against some behavior in selecting sub-elements.



This works:


var parent = element(by.css('.parent-class'));

parent.element(by.css('.child-class')).getText();



However this does not:


var parent = element(by.css('.parent-class'));
var child = element(by.css('.child-class'));

parent.child.getText();



Is there someway to do something like the second example? I'd rather not have the element locators spread throughout the methods on my pageObjects, but it seems thats the only way to locate subelements?



In actual application I have a long list of cards, from which I filter down to just the one I am looking for. I then want to do things with subelements of the card.





I have found something that looks to allow me to separate the locator info from the pageObject methods: var parent = element(by.css('.parent-class')); var child = by.css('.child-class'); parent.element(child).getText();
–  mollons
May 18 '15 at 17:53



var parent = element(by.css('.parent-class')); var child = by.css('.child-class'); parent.element(child).getText();




3 Answers
3



You could use the locator() function to get the locator of the child element and use it to find a child of the parent. This is similar to the solution you provided in your comment, but allows you to define all properties on your page object as web elements instead of a mix of elements and locators:


locator()


var parent = element(by.css('.parent-class'));
var child = element(by.css('.child-class'));

parent.element(child.locator()).getText();





awesome. Just what I was looking for!
–  mollons
May 21 '15 at 15:03



I have a lot of the following code:


var parent = element(by.css('.parent-class'));
var child = parent.element(by.css('.child-class'));

child.getText();



But as far as I understood you have a lot of children and you don't want to list all the variants.



Additionally to Nathan Thompson answer you can have a helper function in page object to find subelement:


function getCard(parent, child) // Or getChild()
return element(by.css(parent)).element(by.css(child));


function getCardText(parent, child) // Or getChildText
return getCard(parent, child).getText();



So then you can just write in spec:


expect(cardPage.getCardText('.parent-class', '.child-class')).toBe('...');



I wanted to mention that using 5.2.2 version this implementation is bit different.
To get actual selector value you must use following code


let selector = child.locator().value



This is because locator returns an object which contains selector and other properties, but in this case, you only need selector.
here is what is returned by method locator()


name(name)
return By.css('*[name="' + escapeCss(name) + '"]');

using: 'css selector', value: '.child-class'



Here is how it should be implemented now.


var parent = element(by.css('.parent-class'));
var child = element(by.css('.child-class'));
parent.element(child.locator().value).getText();

//short hand
var parent = $('.parent-class');
var child = $('.child-class')

parent.$(child.locator().value).getText();






By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Popular posts from this blog

Firebase Auth - with Email and Password - Check user already registered

Dynamically update html content plain JS

How to determine optimal route across keyboard