How to use findElements for img class? - selenium

On inspect element I can see number of records is 15 but when I tried using findelements it does not show all records.
Below is the tag:
<img class="md-user-avatar" ng-src="/../../resources/image_thumb.png" src="/../../resources/image4_thumb.png">
And I am using as below:
java.util.List<WebElement> elements = driver.findElements(By.xpath("//img[#class='md-user-avatar']"));
System.out.println("Number of elements:" +elements.size());
for (int i=0; i<elements.size();i++){
System.out.println("Radio button text:" + elements.get(i).getAttribute("value"));
}
But it returns me size as 1. And when I fire //img[#class='md-user-avatar'] in inspect elements it shows me 15 records.

try adding some implicit wait or Thread.sleep before doing findElementsand see if it works. If it does, then you will have to use explicit waits to make sure all images have loaded.
And if it doesn't, then in that case you will have to see that how all 15 images are visible manually.

Related

Selenium: Checking if several elements are not visible takes too much time

In one of my testcases, im checking if some elements are NOT visible.
Its very simple:
Login
Check if 5 buttons inside the left menu bar are not visible (As the user has no rights)
End test
This shouldnt take more than 10 seconds to test.
But as im using implicit wait, it does always wait 5 seconds for each button, which causes the test to take way too much time to finish. Currently it takes more than 30 seconds just to test if 5 buttons are not visible.
Im using this method:
var elements = _webDriver.FindElements(By.XPath(selector));
if (elements.Count > 0)
{
throw new Exception(selector + " still displayed");
}
Are there any other ways how to make this work?
Use a explicit wait to check for the first element and then just check the other elements directly (with implicitly_wait = 0).
something like:
try:
element = WebDriverWait(driver, 5).until(
EC.presence_of_element_located((By.XPATH, selector))
)
except TimeoutException:
# no element found
if element:
# check the presence of the other elements with find_element
documentation:
https://selenium-python.readthedocs.io/waits.html

Can't select option: element is found but invisible

I'm trying to automate a website which is not under my control, so I can't change its HTML and CSS. I need to select an option from a combo box.
I can successfully find a "select ../>" element but when I try to select an option via SelectByText, ByValue, ByIndex it results in the ElementNotVisibleException. The html is pretty complex on that page and I believe that developers assigned "display:none" by a css-style. I can navigate to the "div" which contains that combo box and click on it via Actions but it doesn't help to select an option after that. After such a click I see for a second the options on the screen and then the combo box collapses.
Is it possible at all to overcome such a problem?
Since Selenium API tries to be "user-centric" it will not allow interaction with non-visible elements. There are two approaches you can try:
1) Click on the select element, then perform an explicit wait for the option to become visible. This is useful if the page is using JavaScript to display the select options which can cause slight delay.
By bySelect = By.id("id_of_select_element");
By byOption = new ByChained(bySelect, By.xpath(".//option[contains(text(), 'text_of_option')]");
WebElement select = driver.findElement(bySelect);
select.click();
try {
// wait at-most 5 seconds for element to become visible
WebElement option = new WebDriverWait(driver, 5)
.until(ExpectedConditions.visibilityOfElementLocated(byOption)));
} catch(TimeoutException t) {
System.err.println("Timed out while waiting for dropdown to become visible: " + byOption.toString());
}
2) If the above doesn't work, you can be a little more invasive and execute some JavaScript to force the option to be selected. This is only recommended as a last resort.
public void selectDropdownByText(WebDriver driver, WebElement select, String text) {
((JavascriptExecutor) driver).executeScript(
"var select = arguments[0]; for(var i = 0; i < select.options.length; i++) {if(select.options[i].text == arguments[1]) {select.options[i].selected = true; }}", select, text);
}
ok, Element is not visible exception is thrown because of "user-centric" behavior of selenium,
In my working experience i found out that,
Selenium is not able to select element which are not visible to clients.
I mean can't select those who not appears on UI Window,
Still those are you can inspect on HTML DOM but cant access through selenium.
When those are visible on screen you can very well select those elements.
solution is before finding out select tag you must click on it to get visible full options tags.
Clicking makes all options that needs to be selected are now visible to clients.
Then you find that select element and then select options under select tag. when those List of options are completely visible on screen.

wait.Until(ExpectedConditions.VisibilityOfAllElementsLocatedBy(By.ClassName(className)) doesn't return any element

I need to find IReadOnlyCollection<IWebElement> using WebDriverWait to make sure that elements had been rendered on page.
This is my code
WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(timeout));
return wait.Until(ExpectedConditions.VisibilityOfAllElementsLocatedBy(By.ClassName("TextInput")));
This code failing on timeout.
Meaning that could not find any elements on page with given class name.
I added this line of code BEFORE my original code just to make sure that elements are present
var allInputs1 = container.FindElements(By.ClassName("textInput"));
And that line returns elements as expected.
So my conclustion is that
wait.Until(ExpectedConditions.VisibilityOfAllElementsLocatedBy(By.ClassName("TextInput")))
doesn't work as expected since that couldn't find elements that are for sure present on page.
What is the best way to find array of elements using WebDriverWait?
Your conclusion is wrong. With FindElements you just make sure that elements are present.
The API documentation for VisibilityOfAllElementsLocatedBy states:
An expectation for checking that all elements present on the web page
that match the locator are visible. Visibility means that the elements
are not only displayed but also have a height and width that is
greater than 0.
And obviously present is not visible.
I think you should try ExpectedConditions.PresenceOfAllElementsLocatedBy

selenium cssSelector vs. tagName

I have a use case that I need to find all iframe and object tags from the page.
Currently I'm using cssSelector() method. I have noticed that there is also tagName() method.
What is the difference between these 2 methods with the above use case ?
findElement(By.tagName("a_tag")) will find elements by html tags such as <iframe> , <div>. But you can only provide it with html tags, not css classes, etc ...
With findElement(By.cssSelector("a_tag")) you can find elements with html tags but you can also give a css class for example findElement(By.cssSelector("div.myClass"))
For your case you can use :
List<WebElement> iframes = driver.findElements(By.tagName("iframe"))
List<WebElement> objects = driver.findElements(By.tagName("object"))
And then perform a for loop to do your tests
It's recommended to use cssSelector/id/xpath/etc ... By since it will wait for the "needed element" displayed if the element is not present on the page initially.
Because By.cssSelector is more specific, selenium will continue checking if the element exists until the implicit wait (x seconds) times out.
By.Tag is not specific at all. Using By.tagName, selenium will not wait for the element. On findElements(By.tagName("table"), Selenium will return an array of all the tables that are present immediately after the page loads. As the "needed" element is not present yet, it will not be in the array.

Selenium WebDriver access a sub element

I have a div with a unique ID. Under that div are a bunch of span elements that have className=foo. There are several span elements with className=foo but they are unique to each div (if that's clear). So my Selenium code first gets the unique div as a web element then tries to take that element and get by class name the span like so
element = sDriver.findElement(By.id("c_"+cID));
String sTest = element.findElement(By.className("actions")).getText();
On the second line it throws an exception every time
org.openqa.selenium.StaleElementReferenceException: Element not found in the cache - perhaps the page has changed since it was looked up
Command duration or timeout: 22 milliseconds
Do I misunderstand how to get that span from under a unique div?
Nope you'right accessing the span but the problem is that the Dom has changed since StaleReferenceException is about (see StaleReferenceException )
This may be caused because the page isn't loaded completely when the code starts or changes when the code is executed. You can either try to wait a little longer for the element or catch the StaleReferenceException and try again finding the div and the span.
My solution is not fancy but it works like a Swiss watch (in my situation of course). So my code is calling the parent element in a loop looking for different child elements in it. Nothing got changed at all - just simple querying and the exception began to occur. So! I've added the Thread.Sleep(2000) command before every search of parent element and it solver the problem. Not elegant but works every time with minimum code to debug afterwards.