Node JS driver.findElements(by.className('classname').getText() throws an error - javascript

I am trying to get a feedback from Selenium tests and closest I've come to solution was with:
driver.findElement(By.className('classname')).getText();
But to make it effective I have to find all Elements with same classname, so I tried changing it to:
driver.findElements(By.className('classname')).getText();
but I get an error:
TypeError: driver.findElements(...).getText is not a function
Any suggestions how to fix it or ideas for code with equivalent function?

The problem is that .findElements() returns a collection and .getText() doesn't work on a collection, only a single element. If you want the text from each element, you will need to loop through the collection and get text on each element inside the loop.
See this reference if you need more info on looping through a collection.

Since findElements returns a collection, you can use the map method to loop through the collection and get the text for all the elements.
let array_of_elements = driver.findElements(By.className('some_classname'));
//get the text from the elements in an another array
let text_of_elements = array_of_elements.map((array_of_text,index,array_of_elements)=>{
return array_of_text.getText();
});
Read about the map method here.

You can get Text Collection Using:
List<WebElement> findData = driver.findElements("******");
for (WebElement webElement : findData) {
String getValueofString = webElement.getText();
}

Related

How to check if an html element with a specific class exists in JavaScript?

I am trying to use javaScript to determine if an element with a specific class name exists on an html page. The element in question is only sometimes loaded on the page.
When I use document.getElementsByClassName('element-in-question').innerHTML = "Hello"
It will work when the element exists, but when it doesn't exist, it will return as "cannot set property of innerHTML of undefined and the rest of the code will not run.
Is there a way to check if an element exists, and only modify it when it does without breaking the rest of the code?
Thanks for the help
You can also use document.querySelector which will return the first element within the document if it exists, if not, it returns null.
const targetElement = document.querySelector('.element-in-question');
if (targetElement) {
targetElement.innerText = 'Hi there!';
}
<div class="element-in-question"></div>
Tip: If you're just adding text consider using innerText instead of innerHTML.
Just wrap you code with if statement :
const elemts = document.getElementsByClassName('element-in-question');
if(elemts.length) {
// this actually need to be elemts[0].innerHTML
elemts.innerHTML = "Hello"
}
Note: document.getElementsByClassName will return array/collection of elements so if you really know that there is no other elements keep using it otherwise switch to getElementById.
as per documentation:
The getElementsByClassName() method returns a collection of all
elements in the document with the specified class name, as an
HTMLCollection object.
It's very simple with the condition IF
If you want to get elements by class, the function will return an array (a collection of all elements in the document with the specified class name), so you will check as following :
if (document.getElementsByClassName('class-in-question').length > 0) {
// Existed
}
If you want to get an element by specified id, the function will return an objet HTML with that id, so you will check as following :
if (document.getElementById('id-in-question')) {
// Existed
}

Correct jQuery Syntax for accessing text of array in one line

I am trying to access the text of the first "th" element of the first element of "rows" with jQuery and would like to do so in one line
var currentStation = $(rows[0]).find("th")[0].text();
What would be the correct syntax to do so?
I am able to get the "th" element, but as soon as I try to access the text I get error messages.
I already tried numerous variations of different brackets combinations, but each one threw me errors.
The issue is that your [0] on find("th") takes the HTML element out of the jQuery object. The easiest way to do this is to either use innerText instead of text:
var currentStation = $(rows[0]).find("th")[0].innerText;
Or don't use [0], rather first:
var currentStation = $(rows[0]).find("th:first").text();
(Or another first):
var currentStation = $(rows[0]).find("th").first().text();
text() is a method on jQuery objects.
You are extracting the DOM element object from the jQuery object and then trying to call text() on the DOM element object.
Use the :first selector instead (note this is a jQuery selector and not a CSS selector)
const $firstRow = $(rows[0]);
const $firstTh = $firstRow.find("th:first");
var currentStation = $firstTh.text();

Protractor - get child element of an element?

I am trying to access child element of an ng-repeat element but I am having troubles doing that.
I have searched around about the problem and the solutions that I have found did not work for me. One of those solutions was to do something like this:
var parent = element(by.repeater(''));
var child = parent.element(by.....);
When I try the child line I cant see the element function on the parent element..
http://prikachi.com/images/11/8338011u.png
If you see the screenshot above you will see the structure of the code of the page that I am trying to test.
I need to access the alt attribute of the image of the avatar and get its value (thats the Username of the User).
One thing that came to my mind is to use .getInnerHTML() on the ng-repeat row which will return a string with all that code. From there I can find the alt attribute and its value with string manipulation but this seems too brute and I am sure that there has to be a better way.
Simply I want to be able to get row 4 from the repeater and get the Username of the user at row 4, that's all I wanna do actually.
Try this,
var parent = element(by.repeater('f in feed'));
var child = parent.all(by.xpath('//img[#alt="Pundeep"]')).first()
(or)
var parent = element(by.repeater('f in feed'));
var child = parent.all(by.xpath('//img[#alt="Pundeep"]')).get(0)
You can get it directly using element.all() and get() locator in protractor. Here's how -
var child = element.all(by.repeater('parent_locator')).get(3); //gets 4th element in repeater. Its a 0 based index.
child.getAttribute('alt').then(function(user){
var username = user; //username contains the alt text
});
Hope this helps.
In Protractor element documentation it gives an example like this to find child elements, which is same as chaining element find:
// Chain 2 element calls.
let child = element(by.css('.parent')).
$('.child');
expect(child.getText()).toBe('Child text\n555-123-4567');
// Chain 3 element calls.
let triple = element(by.css('.parent')).
$('.child').
element(by.binding('person.phone'));
expect(triple.getText()).toBe('555-123-4567');
// Or using the shortcut $() notation instead of element(by.css()):
// Chain 2 element calls.
let child = $('.parent').$('.child');
expect(child.getText()).toBe('Child text\n555-123-4567');
// Chain 3 element calls.
let triple = $('.parent').$('.child').
element(by.binding('person.phone'));
expect(triple.getText()).toBe('555-123-4567');
https://www.protractortest.org/#/api?view=ElementFinder.prototype.$
this example could help :
return element(by.css('select.custom-select:nth-child(1) option[value="12"]'));
you can use nth-child() selector to access to a child element.
In my example i used a plugin with 2 select with same classes and i wanted to click on a defined option in the select 1, and a second in the select 2.

Google Chrome not letting me use setAttribute for ID's

I've got some JS code here. Basically, I am trying to change the ID of an element to some value from a previous variable.
Here's what I got so far;
function() {
var colorarray = [ "RANDOMCOLOR_0", "RANDOMCOLOR_1", "RANDOMCOLOR_2" ];
var RANcolorarray = colorarray[Math.rsound(Math.random() * (colorarray.length - 1))];
document.getElementsByClassName('RANDOMCOLOR').setAttribute('id', RANcolorarray);
}
This code throws an error in Chrome for line 4: Uncaught TypeError: undefined is not a function which is weird because JsLint finds no errors.
I also tried using the other way to setting id's;
document.getElementsByClassName('RANDOMCOLOR').id = RANcolorarray;
However, although this method does not throw an error on chrome or jslint - it does not work at all after inspecting the element.. :/
Any ideas?
document.getElementsByClassName('RANDOMCOLOR') returns a list of DOM nodes (even if there's only one match) so you can't just call .setAttribute() on the list as the list doesn't have that method.
You can either get the first item out of the list and call .setAttribute() on that one or use a for loop to iterate through the list and call it on all of them. Of course, since you're setting the id, you should not be setting multiple elements to the same id, so I'll assume you just want one element:
document.getElementsByClassName('RANDOMCOLOR')[0].id = RANcolorarray;
Or, a little more safe:
var elems = document.getElementsByClassName('RANDOMCOLOR');
if (elems && elems.length) {
elems[0].id = RANcolorarray;
}

jQuery find() Issue

I have the following Code
var page = '<h1>Hello!</h1><p>FOO</p><span class="username">this is ur name</span><p>sample text</p>';
when I alert $(page).html() i get Hello! and when I wrap the contents of the page in a div and alert $(page).html() I get the whole html contents.
What I am trying to accomplish here is I have a page string with html template and I am trying to find a class username in it and i am getting null.
I am confused with this happens
Here is a small fiddle of the issue
http://jsfiddle.net/6TSuq/1/
When you call $(page) you construct a jQuery object which contains 4 elements; for each of the HTMLElements that aren't nested in your string.
console.log($(page).map(function () {
return this.nodeName;
}).toArray());
// ["H1", "P", "SPAN", "P"]
​
html() returns the innerHTML of the first element in this jQuery object; which is why you only see "Hello!".
To find the .username you should use the filter() method, which searches within the jQuery object for elements which match the given selector.
alert($(page).filter('.username').text()); // "this is ur name", kthx.
See your updated fiddle here; http://jsfiddle.net/6TSuq/15/
Bare in mind that in future, you might have nested elements such as this;
var page = "<h1><span class='username'>Foo</span></h1>";
In this circumstance, filter()ing for .username will yeild no results; as the jQuery object $(page) does not contain the .username element; it contains a h1, which has a descendant which is a .username. Therefore here you'd need to use;
alert($(page).find('.username').text());
For reference, see find(), filter() and map()
A very simple way to do this is:
var elem = $('<h1>Hello!</h1><p>FOO</p><span class="username">this is ur name</span><p>sample text</p>').filter('.username').get(0);
console.log($(elem).html()); // returns this is ur name
​jsFiddle example
You need to convert your string to a jQuery object first in order to use any jQuery method on it.

Categories

Resources