Selenium: Why does click() not behave like it does in firefox? - java

I have a link with an id:
<a href="#" onclick="return false();" id="lol">
In my test:
selenium.click("lol"); //when running the test, the click will just end up selecting the item, not firing off the frameworks javascript
This does not register the click the same! There is javascript that is part of a complex framework which will cause a div to popup. This works in firefox.
But this does work as a fix:
selenium.click("lol"); //when running the test, the click will just end up selecting the item, not firing off the frameworks javascript
selenium.keyPress("lol", "\\13"); //press enter key, since the click ended up selecting it
The fix does work. However, what is going on here? It seems that selenium.click() != [actual browser click event]. Can anyone help shed some light on these inner workings?

Selenium sometimes does not simulate click on javascript hrefs exactly. Maybe its the same issue here. A quick fix is to use a combination of selenium's mousedown and mouseup events. You can also consider using selenium.fireEvent("lol","click");. Revert back when you have tried these.

It is possible to click a link in a browser before the javascript is loaded. See this other question. One solution would be to wait for some element to be visible on the page that is put there by javascript.

Related

Element could not be scrolled into view (even though it is right there) Selenium

I am using Selenium to run tests on a page with multiple drop-down menus (specifically a pop-up page which allows you to select some options then close it). I am able to click on some of these menus totally fine; however, some of them throw an ElementNotInteractable exception with the message "element could not be scrolled into view", even though the menus are right beside each other. I am very confused as to why one menu works and the other does not even though they appear to be the same. The three things I have tried in order to click on the menu are:
a) Regular Selenium clicking :
driver.findElement(By.xpath("//select[#foo='bar']").click();
This is what works with the other menus, except I navigate directly to the "option" tag and click on it (don't need to click the drop down first)
b)Javascript executor
JavascriptExecutor executor = (JavascriptExecutor)driver;
executor.executeScript("arguments[0].click();", element);
When I use this, no exceptions are thrown; however, the menu remains empty, which leads me to believe it is not being clicked on.
c)Actions
Actions builder = new Actions(driver);
builder.moveToElement(menu).click(menu);
builder.perform();
For some reason when I use this, the whole pop-up window with the drop down menus on it closes. :/ (I have double checked that it is not the close button being clicked)
I'm not sure if this is relevant, but Selenium has no problem finding the elements, it is just when I try to click them that it complains.
To summarise, my questions are:
1) What could make the menus different such that one is clickable and one is not?
2) How can I click on the second menu and choose an option?
Edit: I tried the solution found in the similar problem; unfortunately it does not work. The solution was to add an explicit wait since the element may not have completely loaded, this only leads to a timeout.
Using JavascriptExecutor is a workaround to interact with non interactable elements. I think it should never be used in selenium tests because it makes the test do things a real user wouldn't be able to do in a real life scenario.
The most plausible cause is that you are interacting with the wrong element, try to debug to identify the element returned by the used selector.
You can use chrome dev tools in debug mode :
1- Put a breakpoint at the exception line,
2- Use $x("//select[#foo='bar']") in the chrome console to get the element.
To select a value, you can use the org.openqa.selenium.support.ui.Select object :
new Select(element).selectByValue(value);

Selenium iFrame input text

I am using Selenium to build a test automation where the html is in an iFrame, I was able to find online the lines of code to activate the iFrame, click on a link, and press a button and they are working fine -see following lines:
driver.SwitchTo().Frame("06634000000BVL6");
driver.FindElement(By.LinkText("Loan Details R1")).Click();
driver.FindElement(By.XPath("//button[contains(.,'Edit')]")).Click();
I needed to input a text within a textBox in that iFrame, but I couldn't handle the ID or the Class, below is the HTML for the input:
Any thoughts ?
Thanks for your help
I can't comment yet, so this will be part answer, part comment.
Based on what you have posted, it looks like you may not be in the correct iframe and we don't have enough of the code from the webpage to tell if there is an additional iframe.
I'd also like to see the code you are using to write text to the field, you may have an issue there.
If you don't and the only issue you have is the selector then try the following. Go get the developer version of firefox. Navigate to your webpage in firefox. Inspect the element where you want to write text to. Once you are in the inspection screen, there is a path bar that can scroll left and right at the bottom of the screen. Check that to confirm that there is only the one iframe you mentioned and that you are in the correct iframe. If that is the issue, you should be good to go, you're code above works for switching between frames. If you are in the right iframe, then try a different method of finding the element for the text box. I have had the most success with hard to find elements by using the cssselector. To get the cssselector for the element right click on it, navigate to copy and then cssselector. From there your code should look like this (using c#):
driver.FindElement(By.CssSelector("INSERT CSS SELECTOR HERE")).SendKeys("Text");

Inspect font/text of a pop-up bubble displayed when a required field is missing value - using Selenium WebDriver

Using Selenium-Java 2.47.1, I see this pop-up bubble/balloon that gets displayed whenever the 'submit' button is clicked and a required field is missing a value. I'm unable to inspect the bubble with firebug or DevTools. I need to be able to get the text and font.
Here is a link to an image of the bubble, it's very simple, I just can't seem to figure this out. Any help is appreciated, thanks!
In Firebug you can select Break On Mutate in the HTML tab (The pause button with brackets). Click the submit button, and Firebug will tell you what element is being added.

Selenium Webdriver (Java) , Need to send "Space" keypress to the website as whole

My problem is as follows.
I am attempting to automate part of a test suite for a website I work in, and while most of it went well, I'm at the point where the developers added a lightbox to confirm the next action.
Using firebug I found out an xpath I could use to click the button I need to proceed, but sadly it isn't working.
After some manual attempts, I figured that pressing the "Space" key, I can proceed.
The problem is that any sort of try using "driver.findElement" be it by xpath, or link text, fails with a "No such element" error in console.
So I'm trying to just send the keypress of Space , without using find element.
To be clear, I want to emulate someone just pressing space without clicking or selecting anything beforehand.
I tried with driver.Keyboard... but "Keyboard" isn't recognized, so I'm at a loss of how to send this keypress without using driver.findElement.
The piece of code giving me problems is:
driver.findElement(By.xpath("//div[4]/div[3]/div/button")).click();
Any help would be appreciated.
Thank you and have a great day!
If you receive NoSuchElementException, but you know that the element is there, then it seems that the element get loaded into the DOM later (with ajax?), than the page get loaded.
In this case you should use Implicit or Explicit Wait to wait until an element present, or an element is visible, etc...
If it still doesn't work, and you want to try the Space Key thing, then you can perform it on any element, for example on the <body> tag:
WebElement body = driver.findElement(By.tagName("body"));
body.sendKeys(Keys.SPACE);
Hope it helps.
try this:
Actions action = new Actions(Driver);
action.SendKeys(Keys.Space).Build().Perform();

Selenium: Clicking on toaster issues

I'm trying to click on an element on a page; the element is clearly visible on screen. There is a toaster that might pop up, so I'm trying to write a defense: if the toaster is on screen, close the toaster first, then continue clicking through to the next page. I am using PageFactory, so I have an element to contain the toaster and one for the close button for the toaster. My "deal with toaster" method is as follows:
if (driver.findElements(By.cssSelector("#toaster")).size() > 0
&& toaster.isDisplayed()) {
toasterClose.click();
}
When I do this in chrome, however, I'm getting org.openqa.selenium.WebDriverException: unknown error: Element is not clickable at point (994, 758)
Pausing the test execution, I cannot see the toaster on the screen. I figure the devs must be hiding it by making it render in a far away, unscrollable location. So as a stopgap measure, I added a condition that if the x coordinate was greater than 800, don't click. With that in place, I get:
org.openqa.selenium.WebDriverException: unknown error: Element is not clickable at point (547, 725). Other element would receive the click: <div id="toaster">...</div>
What's going on? How can the toaster not be clickable but would somehow receive the click anyway? Firefox can handle the test just fine, with or without the 800 pixel workaround; it's only Chrome having this issue.
For Clarification: The goal of the test is NOT to click the toaster. The goal is to click another element on the page. The test reported that a toaster was in the way, so I attempted to write a step to close the toaster if it is displayed. I have not seen this toaster, so I'm not exactly sure what it is, but chrome keeps reporting that it's in the way. All our toasters site-wide use a basic template that includes a close button so the user can close the toaster, which is what I'm trying to click. Firefox never has this issue and does not report the existence of any toasters.
I'm calling it a toaster because that's what our site calls it, because that's what it's called in whatever framework we got it from (jQuery UI? Backbone?). If I pause execution, I cannot see any toasters at this point in the test, but jQuery tells me it exists and is visible. However, the element found with jQuery has just the default pieces of our toaster setup: a div, an empty div where the message should be, and the close button. Clearly it's not meant to be rendered at this time, but Chrome thinks it's in the way.
I'm assuming by "toaster" you mean some sort of javascript modal popup with a close button.
Identifying the correct problem
You're testing the existence and visibility of the #toaster element, but not the toasterClose element that you're clicking. There's no guarantee that just because one element exists and is displayed, another is as well. From the error, it appears that the #toaster element overlaps the toasterClose element, making it unclickable.
Troubleshooting clickability
Once you've properly selected toasterClose, manually use devtools and inspect to see why it's unclickable. Is it visible and unobstructed? Is the toasterClose element something of zero height/width? Is there dynamic JavaScript modifying the page post-load? Is it actually positioned in view of the page? (I've had elements render visibly at the edge of the window only to be obstructed by the browser's scroll bars.1)
Alternative
You should also see if you really need to use this toasterClose element. How does would a human close this popup? Would they press Escape? Would they click outside the popup window, on the overlay element? Do they do something else that triggers some sort of closeModal() javascript function? You can also do any of these things using Selenium.
Last Resort
One thing you can always do to remove such a popup is to run your own javascript to modify the DOM and remove the offending element(s) altogether:
driver.execute_script(<<-javascript)
var toaster = document.getElementById("toaster");
toaster.parentNode.removeChild(toaster);
var overlay = document.getElementById("modal_overlay");
overlay.parentNode.removeChild(overlay);
javascript
Future/Additional
If this is a regular issue for you, I would suggest wrapping this code in try/catches and a retry mechanism to make it resilient to javascript dynamically loaded elements.
1 Update
Just to elaborate on the scrollbar issue I had, because it turned out that it was a very similar problem to yours.
Here, the "I'm Feeling Lucky" button is out of view. If Selenium tries to click on it, first it will attempt to scroll it into view.
Here's an example of what Selenium would attempt to do. Notice how the button is now "in view".
However, Chrome on OSX is styled in such a way that the scrollbars are normally hidden. The moment that Selenium issues the scroll command, the scrollbars appear and the following click command fails to reach the button.
The solution was to use javascript to scroll the window manually:
page.execute_script(<<-javascript)
document.getElementById("gbqfsb").scrollIntoView(true);
// or if that doesn't work:
window.scrollTo(0, document.getElementById("gbqfsb").getBoundingClientRect().top);
javascript
Try the following code. Should work:
if (driver.findElements(By.cssSelector("#toaster")).size() > 0
&& toaster.isDisplayed()) {
Actions builder = new Actions(driver);
builder.moveToElement(toasterClose).moveByOffset(2,2).click().build().perform();
}
Can you close toaster using escape key from keyboard manually.
If you can than use following:
Actions action = new Actions(driver);
action.sendKeys(Keys.ESCAPE).build().perform();
It seems the toaster was partially rendered and fixed to the DOM just below the bottom edge of the screen, using position:fixed to stop it from showing up until it's ready to be populated with data and animated onto the screen. When chrome tried to click on links that were below the bottom edge of the screen, it predicted that it'd hit the toaster and didn't actually bother scrolling.
After some googling, I added the following utility function:
public static void ScrollElementIntoView(WebDriver driver, WebElement element) {
((JavascriptExecutor) driver).executeScript("arguments[0].scrollIntoView(true);", element);
}
Then I call this method before clicking any link on that page, and voila, no more toaster problems!

Categories

Resources