How to use findElements method with implicit waiting? - selenium

In the method document it's written:
When implicitly waiting, this method will return as soon as there are more than 0 items in the found collection, or will return an empty list if the timeout is reached
As i see (please fix me if i'm wrong), when the method find one element it returns it without searching the others.
So what is the advantage of using this method upon using findElement method?

findElements method returns a list of web elements matching the passed locator while findElement method will always return a single web element.
Also in many cases you are applying findElement and findElements methods on already fully loaded page. In this case findElements will return you a list of All the web elements matching the passed locator.
However in order to get all the matching elements in loading page you can't effectively use findElements with implicit wait.
Expected conditions implementing explicit wait should be used instead.
In case you know the exact amount of elements matching the passed locator presented on that page you can use this method:
wait.until(ExpectedConditions.numberOfElementsToBe(element, expectedElementsAmount))
And in case you know that it should be at least some known amount of elements you can use this method:
wait.until(ExpectedConditions.numberOfElementsToBeMoreThan(element, expectedElementsAmount))

Rather individually, you need to read the line in it's entire context.
findElements():
Find all elements within the current page using the given mechanism.
This method is affected by the 'implicit wait' times in force at the
time of execution. When implicitly waiting, this method will return as
soon as there are more than 0 items in the found collection, or will
return an empty list if the timeout is reached.
Here, more than 0 items implies greater then 0 i.e. n > 0 but definitely find all elements within the current page till the timeout is reached.

Related

Why does 'indexOf' not find the specified arrayOfLong?

I have an ArrayList of LongArrays, each of size 2. I am trying to use the built-in 'indexOf' method to find the index of a specific array of longs, and I can't figure out why the code says the array of longs I'm searching for isn't found. See the below screen shot of a debugging session where try to evaluate finding 'longArrayOf(0L,5L)' in the ArrayList. In my mind, longArrayOf(0L,5L) is clearly the first element in the cardHierarchy array. Can the 'indexOf' function not be used for finding arrays? Can anyone suggest an alternate method?
indexOf uses Object.equals() when you pass arrays, which compares by reference address which is different for the LongArray passed to indexOf and the one present in cardHierarchy.
Change it to
cardHierarchy.indexOfFirst { it.contentEquals(longArrayOf(0L, 5L)) }

For the W3C WebDriver "Find Element From Element" command, how does one format the element ID in request URL?

I'm learning how a WebDriver works, and I don't understand how to format the request URL for Find Element From Element.
The element ID of Find Element will return something like this:
{"element-6066-11e4-a52e-4f735466cecf": "e72b0320-5d61-4886-b903-5b2e4bb43d88"}
As I understand it, the above {key: value} format IS the element ID. If that is the case, how does one user that as the {element id} in "POST /session/{session id}/element/{element id}/element"? If {key: value} IS NOT the element ID, what is? And what would a properly formatted request URL look like?
Thanks!
In the above example, the element ID is "e72b0320-5d61-4886-b903-5b2e4bb43d88". It's a bit confusing because rather than creating an object that looks like this:
{"ELEMENT": "e72b0320-5d61-4886-b903-5b2e4bb43d88"}
We have the very odd:
{"element-6066-11e4-a52e-4f735466cecf": "e72b0320-5d61-4886-b903-5b2e4bb43d88"}
What's going on here? It has been deemed from on high that the key which in a JSON object indicates that we are dealing with an element ID is the arbitrary and constant string "element-6066-11e4-a52e-4f735466cecf". The reason is that any non-arbitrary key might end up being a return value of some unrelated JavaScript code. Consider this JavaScript code:
return document.getElementById('foo');
This could be used in ExecuteScript as follows (for example in Python):
driver.execute_script("return document.getElementById('foo');");
What should be returned here? Well we are dealing with an actual HTML element, which can't be converted into JSON and sent back over the wire to the Python client. So instead, WebDriver stores a reference to that element as an ID, and sends that back. But it can't just send back the ID as a string, because there's no way for driver.execute_script to know in advance what sort of thing might be returned. Maybe it's not an element ID--maybe it's some other string related to your application. In the past, the standard format for a JSON WebElement was as I noted above (with the ELEMENT key).
At some point, however, someone must have written some JavaScript code which resulted in a JS object which contained the word ELEMENT as key somewhere inside. This object had nothing to do with WebElements, but when it was returned via a call to driver.execute_script, the client converted it into a WebElement object!
Whether or not this scenario ever actually happened is beside the point; the point is that a simple short word like ELEMENT is ripe for name clashes. The spec authors wanted a way to unambiguously denote that we are dealing with a WebElement even if we encounter it in a serialized JSON format, and in a way that is not likely to clash with other things web developers or testers are doing.
So the most direct answer to your question is, your POST request should look like:
POST /session/{session id}/element/e72b0320-5d61-4886-b903-5b2e4bb43d88/element

In Selenium how exactly are the sendKeys() and setValue() methods different?

I've used both
WebElement.sendKeys('')
and
WebElement.setValue('')
In order to input text into fields. The vast majority of the time they seem to act the same, but I've found a few cases where setValue() works but sendKeys() does not.
All I can find in the Selenium docs is that sendKeys() 'more accurately imitates user input' then setValue(). Does anyone know what is actually happening under the hood?
sendKeys()
sendKeys() is the Java method from WebElement to simulate typing into an element, which may set its value.
Defination:
void sendKeys(java.lang.CharSequence... keysToSend)
Use this method to simulate typing into an element, which may set its value.
Parameters:
keysToSend - character sequence to send to the element
Throws:
java.lang.IllegalArgumentException - if keysToSend is null
Usage:
driver.findElement(By.id("identifierId")).sendKeys("C.Peck#stackoverflow.com");
However there is no setValue() method in Java and the closest match seems to be setAttribute() JavaScript method.
setAttribute()
setAttribute() is the JavaScript method which sets the value of an attribute on the specified element. If the attribute already exists, the value is updated; otherwise a new attribute is added with the specified name and value.
Syntax:
Element.setAttribute(name, value);
Example:
HTML:
<button>Hello World</button>
JavaScript:
var b = document.querySelector("button");
b.setAttribute("name", "helloButton");
b.setAttribute("disabled", "");
Implementation through Java executeScript():
((JavascriptExecutor)driver).executeScript("document.getElementById('elementID').setAttribute('attribute_name', 'new_value_for_element')");

evaljs returns nil even though it shouldn't?

The following code ...
splash:evaljs('document.querySelectorAll("iframe.iframe-container.js-oddset-game-iframe")[0].contentDocument.querySelectorAll("td.leftText a.eventLink").length')
... returns 8 - i.e. there are 8 nodes in the array.
However, when I then try to return the nodeList (array) directly, the result is nil? Obviously a table should be returned since an array is returned from the javascript code.
Is this a bug in Splash? Can't Splash handle access to elements in iframes? I have the --js-cross-domain-access option on too.
It is not a bug. iframes are only available when you use the render.json endpoint with the iframes=1 parameter. When you use that you cannot run a custom Lua script.
Refer to the documentation: https://splash.readthedocs.io/en/stable/api.html#render-json
And this answer: https://stackoverflow.com/a/44682917/4082726

WebDriver isDisplayed() returns true even if the element is hidden

The element I am looking for is as below
I want to call isDisplayed() on the highlighted span web element, and as it is hidden it should return exception. But it is returning true and continuing to the next statement.
Your question lacks a lot of information.
maybe you are looking for some of these:
ispresent()
isvisible()
textpresent()
isDisplayable()
don't know how your code looks but it should be
boolean visible=driver.findElement(By.id("yourverylongid")).isDisplayed();
or using xpath
But I am not sure if it will work because I didn't use is Displayed()