Consider the following <select> from an internal Selenium test page:
<select id="invisi_select" style="opacity:0;">
<option selected value="apples">Apples</option>
<option value="oranges">Oranges</option>
</select>
It is used to simulate an invisible element as the id suggests, which is done by setting opacity to 0.
Although the element is not visible, a user can actually interact with it. If I open the page in a browser and click on the element's position, the select menu opens. I believe this is also why WebElement#isDisplayed() returns true for this element, which is also what these old Selenium issues suggest:
https://github.com/seleniumhq/selenium-google-code-issue-archive/issues/1610
https://github.com/seleniumhq/selenium-google-code-issue-archive/issues/1941
To execute actions such as clicks, we recently switched to the Java interactions API for several reasons, e.g., to prevent ElementClickInterceptedExceptions. (Please note that this is not about refactoring a bunch of Selenium tests, this happens in the context of a generic action executor that operates on top of the Selenium API.) However, if I do something like:
WebElement applesOption = /* get apples option */
new Actions(webDriver).moveToElement(applesOption)
.click()
.perform();
Moving to the element throws the following exception:
org.openqa.selenium.JavascriptException: javascript error: Failed to execute 'elementsFromPoint' on 'Document': The provided double value is non-finite.
I guess this is because elementsFromPoint() via the WebDriver Actions API seems to return a "non-finite" double for transparent elements like this?
Is there a way to prevent this from happening when using Actions? Maybe, in addition to checking if the element is clickable (ExpectedConditions#elementToBeClickable(...)), I would have to parse—which sounds horrible—attributes such as opacity?
I just tried your sample file locally and the code below is working with no exceptions.
WebElement e = driver.findElement(By.id("invisi_select"));
Select select = new Select(e);
select.selectByValue("apples");
System.out.println(select.getFirstSelectedOption().getText());
select.selectByValue("oranges");
System.out.println(select.getFirstSelectedOption().getText());
It prints
Apples
Oranges
This error message...
org.openqa.selenium.JavascriptException: javascript error: Failed to execute 'elementsFromPoint' on 'Document': The provided double value is non-finite.
...implies that the WebDriver instance was unable to focus on the element for one or other reasons:
The element havn't loaded properly when you tried to interact with it.
The element haven't got the focus.
Solution
Instead of using the Java interactions API you can use the Select Class and you can use either of the following Locator Strategies:
Using cssSelector and selectByValue():
Select s = new Select(driver.findElement(By.cssSelector("select#invisi_select")));
s.selectByValue("apples");
Using xpath and selectByVisibleText():
Select s = new Select(driver.findElement(By.xpath("//select[#id='invisi_select']")));
s.selectByVisibleText("Apples");
References
You can find a couple of relevant detailed discussions in:
javascript error: Failed to execute 'elementsFromPoint' on 'Document': The provided double value is non-finite
Related
I learn Selenium in Java and I'm struggling with little problem.
I'm working on handling dropdowns and to resolve my probelm I have to use Select class.
I wrote a selector:
#FindBy(css="#speed")
WebElement selectSpeed;
Then I wrote a method :
public SelectMenuPage selectRandomSpeed(){
getWaitForTheElement().untilElementIsPresentCss("#speed");
//webDriverWait.until(ExpectedConditions.presenceOfElementLocated(By.cssSelector(locator)));
Select select = new Select(selectSpeed);
select.selectByIndex(0);
return this;
}
The problem is that when I use Select class the code simply does not work and I receive:
org.openqa.selenium.ElementNotInteractableException: element not interactable:
Element is not currently visible and may not be manipulated
It works very well when, instead of using Select, I just put the selectors of all the wanted elements and just simply interact with them. Unfortunately, I have to use Select class.
Here is my DOM
As per the HTML, the html-select tag is having the style attribute set as display: none;.
Unless the element is visible within the HTML DOM Select() may not work properly.
I tried a lot to locate elements on this page with this link
ALL I want to do is to select "1 queen bed" or "1 double large bed" and then select amount from the drop down list then press, I'll reserve button.
But I totally failed trying all of these:-
using Action --> moveToElement --> perform()
using JS Execution --> scrollToView, scrollBy(0,100) for example to make the page scroll down
using all types of locators (ID, xPaths, cssSelectors, names) but always an error message that Expected condition failed: waiting for visibility of element located by By.xpath- By.id .. etc.
tried to search for an iFrame but I didn't find but I think there are some but not related to the locators I want
Thread.sleep() to wait for a time if the element is not loaded on the web page.
I am using Selenium JAVA TestNG
so in the page I write this function:-
Page class I write this function :-
private By btnBed = By.xpath("(//i[#class='bicon bicon-double'])[1]");
public void clickBed(){
// JavascriptExecutor exe = (JavascriptExecutor)driver;
// exe.executeScript("window.scrollBy(0,1000)");
click(btnBed);
}
In my Test I write this:-
hotelPage.clickBed();
Error message:-
Expected condition failed: waiting for visibility of element located by By.xpath
The problem was that this page was opened in a new tab so the code can't locate any elements on the screen.
So I just switch tabs, the code works fine.
ALL I want to do is to select "1 queen bed" or "1 double large bed"
I inspecting the DOM on the link you provided, I see that it is radio button that you might want to select. Try locate the radio element button something like this
<input type="radio" value="1" name="bedPreference_78883120" data-bed-type="">
Locate by name
By.name("bedPreference_78883120")
then perform the click.
I have a div with a class attribute with the value textLayer. I'm trying to get that div.
Here is my code:
WebElement jsiFrame = driver.findElement(By.tagName("iframe"));
driver.switchTo().frame(jsiFrame);
WebElement docViewerElement = driver.find(By.classname("textLayer")
(note: this isn't exactly the code but it's more or less the functions I call)
I also have a timeout where I wait 5 seconds while requesting each element so it's not a matter of the element not existing when I query it). Selenium fails to find it, even though it's very plainly there. What's more, it only fails on Chrome, Firefox finds it without any problems.
Try dynamic xpath with explicit wait.
You can achieve it in this way
driver.switchTo().frame(0)
WebElement docViewerElement = driver.find(By.classname("textLayer")
I'm trying to use Selenium (Java) to automate some searches.
When I go to the page and click Inspect Element on the search bar, I see that it has the id searchBox and name q, both of which are potentially useful. Nevertheless, these properties are nowhere to be found in the HTML when I go to View Source.
When I try to use
WebElement search = driver.findElement(By.id("searchBox"));
or
WebElement search = driver.findElement(By.name("q"));
both come back as unable to be found.
How do I proceed with populating the search field then hitting submit (the submit button also is missing in the source page) if I can't find either of these elements?
EDIT:
As requested, here's a more detailed picture of what's wrong:
The URL of the page accessed by WebDriver is http://www.ycharts.com using the line
driver.get("http://www.ycharts.com/login");
If you go to this page with your actual web browser, right click on the search bar and choose Inspect Element, you'll see that its ID is "searchBox" and its name is "q". However, if you go to view the same page's source, you'll see that there's no such element in the HTML. Clearly, this is why WebDriver can't find it.
driver was initiated as follows:
WebDriver driver = new HtmlUnitDriver();
When I try something like
WebElement search = driver.findElement(By.id("searchBox"));`
The exception returned is:
Exception in thread "main" org.openqa.selenium.NoSuchElementException: Unable to locate element with ID: searchBox
So, back to the original question: clearly, the element is there, but it's not in the HTML – how do you interact with it?
The problem is being caused by the fact that the search box is added to the html post page load by javascript.
The HTML returned by http://ycharts.com/ does not contain the searchbox, therefore when Selenium thinks the page has finished loading (i.e DOM ready state), there is no search box.
In order to interact with the search box, you need to tell Selenium to wait until the box appears in the DOM.
The easiest way to achieve this is with WebDriverWait;
WebDriverWait wait = new WebDriverWait(webDriver, timeoutInSeconds);
wait.until(ExpectedConditions.visibilityOfElementLocated(By.id<locator>));
How to get the property value of a CSS class using selnium RC
I tried it using webdriver but can't get what is required
You can use the getEval(String script) command to evaluate javascript to fetch the property.
Selenium can be pretty limited in this sense
EDIT:
this.style.someAttribute will give you the value of someAttribute css style for the given Selenium node.
Also, if you want to run JavaScript on elements within the document body, such as document.getElementById .., you need to preceed your JavaScript string with "this.browserbot.getCurrentWindow()". For example, if I wanted to get the innerHTML of the element with id 'page_title', I would call
String title = getEval("this.browserbot.getCurrentWindow().document.getElementById('page_title').innerHTML");
This will evaluate the JavaScript in the context of the window you are testing. Failure to include this will execute JavaScript within the context of the Selenium frame. See this documentation on the Selenium API.