Can't right-click, Java Selenium WebDriver java.lang.UnsupportedOperationException: contextMenu - java

This is driving me crazy, I just need WebDriver to right-click on an element and the rest of my selenium will work.
I'm using Eclipse, all my .jar imports and libraries are set up correctly.
WebDriver driver = new FirefoxDriver();
String baseUrl = "http://............/";
selenium = new WebDriverBackedSelenium(driver, baseUrl);
Much later in my code, I left-click inside the javascript portlet row I want to execute a right-click on without any problems.
selenium.click("//tr[#id[contains(.,'Equipment')]]");
That works just fine, the row that gets clicked is highlighted, as it is supposed to do.
Now I just need to right-click on it, but I can't! Trying:
selenium.contextMenu("//tr[#id[contains(.,'Equipment')]]");
fails to right-click, and returns me the error: java.lang.UnsupportedOperationException: contextMenu.
There is an element that is not considered 'visible' until that row is right-clicked. It is being detected as existing, but selenium will not run it unless I manually right-click it myself mid-run in WebDriver to make it visible. Otherwise, it just gives me this:
com.thoughtworks.selenium.SeleniumException:Element is not currently visible and so may not be interacted with.
Right-clicking on that row is what makes the element 'visible', which is why I need to have selenium right-click so badly. I have tested to make sure the not visible element is being detected as existing, it is.
boolean exists = selenium.isElementPresent("//a[#id[contains(.,'faction')]]");
boolean visible = selenium.isVisible("//a[#id[contains(.,'faction')]]");
System.out.println("Exists: " + exists);
System.out.print("Visible: " + visible);
Gives me
Exists: true
Visible: false
In other words, it's not a problem with my xpath. It's there. It's just not 'visible'. I've tried sending Shift+F10 as a replacement for right-clicking as well, no good.
This all works fine in Selenium IDE, but I need it working with WebDriver so I can mess with it in Java. Please help me out.
EDIT: Thanks to Slanec's advice and more messing around with the actions builder, I found that it's a problem with my selenium webdriver not being up to date for Firefox 14. It's odd, considering I thought I had downloaded the most recent one just last Thursday. Either way, apparently native event support for Firefox 14 was not added until webdriver 2.25.0, and I am using 2.24.1.

Unfortunately, when looking at the source code, the contaxtMenu() method has not been added to WebDriver emulation. It's not even present at the org.openqa.selenium.internal.seleniumemulation package where all the other methods (disguised classes via the Command-pattern) sit. It was, most likely, not backported to WebDriverBackedSelenium when it was introduced (Selenium RC is deprecated and not in active development, remember?).
Things you could try:
Get rid of Selenium RC, if you still can. The WebDriver API is much more clean, powerful, and actively developed :). To do it with WebDriver, you'd do
WebElement elem = driver.findElement(By.xpath("//tr[#id[contains(.,'Equipment')]]"));
new Actions(driver).contextClick(elem).perform();
Try to do just this task with the WebDriver object you created and then fall back to using Selenium again. The two lines of code above should possibly work when just thrown in between the Selenium code.
Implement it yourself. It's not that hard. Just look at the org.openqa.selenium.internal.seleniumemulation package and the WebDriverCommandProcessor class, add contextMenu() method as described above. This will mean to make your own Selenium builds from the edited source code, but hey, why not.
Last resort - figure out what action exactly the hidden element is waiting for and simulate the event via fireEvent() method. Doing the following should do the trick (if not, it's just waiting for a different event):
fireEvent("//tr[#id[contains(.,'Equipment')]]", "contextmenu")
As a side note, instead of the long
"//tr[#id[contains(.,'Equipment')]]"
or a little bit better
"//tr[contains(#id,'Equipment')]"
you could just write this:
"css=tr[id*='Equipment']"
Isn't it a little bit nicer and more readable? I'm really comfortable with XPath, too, but learning some basic CSS Selectors (which can do most, but definitely not all XPaths can do) isn't that scary...

May be you can try selenium.contextMenuAt

Related

Selenium - Java - ChromeDriver: Opens blank "data;" on some cases before opening another chrome window that runs actual test? [duplicate]

This question already has an answer here:
data:, shown in the chrome url bar when I execute the following Selenium ChromeWebdrive Script
(1 answer)
Closed 4 years ago.
So I'm an intern who was tasked with developing various test cases with Selenium. For the most part what I've developed works, however:
For some of my test cases a blank "data;" window opens up and then it'll open another window with my actual test case running. It doesn't really impede on my test case from functioning, but gets annoying from all the extra windows it's opening.
I've searched stackoverflow as well as other forums thoroughly and some people found solutions from updating the chromedriver (which I did and didn't work) and the questions others have posted here are in regards to their actual test case window being a blank data; instead of the issue I'm having.
Relevant Information:
I'm using JUnit and in my #Before annotation I instantiate the chrome
driver object as I close the driver after every case (to be able to
run each case independently even if they're in the same test class).
This extra blank data; window seemed to only come up after I did the above point.
I do a driver.get(URL) within each test case at the beginning
If someone has a solution can they please post and perhaps explain why it's behaving this way as I don't just want the solution, but want to understand the underlying cause behind it.
Thanks a bunch in advance!
New blank "data" window opens when new ChromeDriver() is created. So if you see two windows, that means new ChromeDriver() was executed twice.
You might have left some driver = new ChromeDriver(); in the code somewhere, before you created your #Before method.
So when you are running your test, you have this code (driver = new ChromeDriver();) executed twice. Once in #Before method, and then again somewhere else in code.
Try using search in your IDE to find all occurrences of new ChromeDriver().
Or if not, maybe somehow your #Before method executes twice. New blank "data" window opens when new ChromeDriver() is created. So if you see two windows, that means new ChromeDriver() was executed twice.
Try verbose logging to at least see if it's the same instance of chromedriver opening up two windows.
System.setProperty("webdriver.chrome.verboseLogging", "true");
If it's separate chromedriver instances, you'll see, on Windows, in Task Manager two instances of chromedriver.exe, on Mac in Activity Monitor, two instances in chromedriver. Then you can narrow it down to maybe one of your test cases doesn't actually run, or immediately fails.

Selenium InternetExplorerDriver doesn't get focus on the window

My project includes Selenium webdriver, JAVA, Maven, TestNG, Jenkins, Allure (reports). I have a few suites of tests with 100+ test cases, and I iterate them through 3 different browsers (the tests run in parallel using TestNG).
There is one test that can't pass unless I am actually watching the window and see the test run.
I will explain: what am I trying to test? our JS developers created a feature that only if the user has focus on the window, then a image slideshow will start to move and change images.
On Firefox and Chrome it pass great- I don't need to see the test. The focus can be on other tabs or browsers, and the driver will emulate everything. On IEdriver its not like that!!
I have tried to add many capabilities to the driver and still nothing (some of them solved me some other issues):
}else if (browser.equalsIgnoreCase("ie")) {
String exeServiceIEdriver = Consts.ieDriverPath;
System.setProperty("webdriver.ie.driver", exeServiceIEdriver);
DesiredCapabilities ieCapabilities = DesiredCapabilities.internetExplorer();
ieCapabilities.setCapability("nativeEvents", false);
ieCapabilities.setCapability("unexpectedAlertBehaviour", "accept");
ieCapabilities.setCapability("ignoreProtectedModeSettings", true);
ieCapabilities.setCapability("disable-popup-blocking", true);
ieCapabilities.setCapability("enablePersistentHover", true);
ieCapabilities.setCapability("ignoreZoomSetting", true);
//ieCapabilities.setCapability("version", "12"); does it work?? don't think so..
ieCapabilities.setCapability("requireWindowFocus", true);
//ieCapabilities.setCapability("browser_version", "9.0"); // Does NOT work. need user agent
ieCapabilities.setCapability("IE_ENSURE_CLEAN_SESSION", true); // Does NOT work. need user agent
ieCapabilities.setCapability("browserAttachTimeout",5000);
ieCapabilities.setCapability(CapabilityType.ACCEPT_INSECURE_CERTS,true);
ieCapabilities.setCapability(CapabilityType.ACCEPT_SSL_CERTS,true);
ieCapabilities.setCapability(CapabilityType.SUPPORTS_APPLICATION_CACHE,false);
driver = new InternetExplorerDriver(ieCapabilities);
Log.info("\n*** Starting IE Browser ***");
Seems you have opted to add all the InternetExplorerDriver related capabilities.
Browser Focus
The challenge is that IE itself appears to not fully respect the Windows messages we send to the IE browser window (WM_MOUSEDOWN and WM_MOUSEUP) if the window doesn't have the focus. Specifically, the element being clicked on will receive a focus window around it, but the click will not be processed by the element. Arguably, we shouldn't be sending messages at all; rather, we should be using the SendInput() API, but that API explicitly requires the window to have the focus. We have two conflicting goals with the WebDriver project.
So first, we strive to emulate the user as closely as possible. This means using native events rather than simulating the events using JavaScript.
Second, we want to not require focus of the browser window being automated. This means that just forcing the browser window to the foreground is sub-optimal.
An additional consideration is the possibility of multiple IE instances running under multiple WebDriver instances, which means any such bring the window to the foreground solution will have to be wrapped in some sort of synchronizing construct (probhably a mutex) within the IE driver's C++ code. Even so, this code will still be subject to race conditions, if, for example, the user brings another window to the foreground between the driver bringing IE to the foreground and executing the native event.
The discussion around the requirements of the driver and how to prioritize these two conflicting goals is ongoing. The current prevailing wisdom is to prioritize the former over the latter, and document that your machine will be unavailable for other tasks when using the IE driver. However, that decision is far from finalized, and the code to implement it is likely to be rather complicated.
Solution
As an interim solution you can add the capability:
ieCapabilities.setCapability("requireWindowFocus", false);

Java Selenium - Waiting on slow websites

Im testing on a site that sometimes doenst really have a good connection.
Everything works great until it decides to not work properly.
I am seperating every element with a wait.until, everything works normally until the connection gets slow and it believes the element is present and decides to use it.
public static WebElement login_btn(WebDriver driver, WebDriverWait wait) {
wait.until(ExpectedConditions.refreshed(ExpectedConditions.presenceOfElementLocated(By.id("btnEntrar"))));
wait.until(ExpectedConditions.refreshed(ExpectedConditions.elementToBeClickable(By.id("btnEntrar"))));
element = driver.findElement(By.id("btnEntrar"));
return element;
}
I cannot find a way to simulate this until the website becomes terribly slow and I get to see if it works or not. After months of trying I am unable to find out a way to completely wait for the element to be present and not receive a staleElementReferenceException or the site actually going into an error page due to me using an element. Using the site manually without these tests cannot simulate what is happening with the webdriver. Are there any hints or suggests on what I could do?
There are a few good answers you can try in this question and this question. One is to use Chrome dev tools to throttle adjust the download speed, https://stackoverflow.com/a/34728002/2386774. Another is Charles Web Debugging Proxy.
To solve this issue more simply, my suggestion is to specifically wait for the page to load completely then scrape the page. This will allow you to wait once and then you won't have to add waits everywhere. You would need to add additional waits if your page is dynamic, e.g. you click a button and it updates part of the page. In that case, add a wait when the button is clicked and you're good again. No need to add waits everywhere.

Selenium Webdriver.load.strategy unstable

I'm having problems loading my page with webdriver. My current (problematic) solution involves using the unstable load with firefox, but I'm open to other solutions.
The Core Problem
The root of all my problems comes from the fact my page will never fully load when I call it normally with webdriver, and thus will never preform the 2nd step, it's just always loading. It loads fine when you just go to the site with a normal browser. I've tried out a few work arounds that work intermittently, including opening the driver to google, and then going to the page which sometimes makes it load, and with
IJavaScriptExecutor js = (IJavaScriptExecutor)Driver;
js.ExecuteScript("return window.stop");
as suggested by this question, which sometimes makes it continue without loading. But neither of those work consistently at all (probably <50% of the time)
The best I've got so far is using the unstable load strategy. However that has its own different problems, all of which only happen sometimes.
1) Sometimes it doesn't wait for the page to load at all, and I get an "Unable to locate element:" exception within milliseconds of loading the page, despite the fact that I have a wait set up:
new WebDriverWait(cdriver, 30).until(ExpectedConditions.visibilityOf(cdriver.findElement(By.id(myId))));
Thread.sleep(3000); solves that problem, but I've read that is a sloppy way to do things.
2) If I get passed that step, my test should click one link, then click another and continue on with the test. However, it often gets stuck after that first click. So if my code is like this:
Thread.sleep(3000);
element1.click();
System.out.println("clicked!");
element2.click();
The first click (which doesn't load a new page, by the way, just a pop up on the same page) will work, but then the system will never print out "clicked!", it's stuck in the same way would be loading the page initially (without the unstable load thing). If/when it makes it over that hurdle, I think the rest of the test is fine.
Any ideas 1) why it works sometimes but not others. 2) how to fix it 3) how to just get my page to load in the first place
Thank you!
Try the following approach:
Don't wait for visibility of element on the page - in your case By.id(myId).
The element can become visible much earlier than the page is fully loaded, before all java scripts are loaded and fired etc.
Wait for some element on the page to be clickeable instead. For example you can wait until link becomes clickeable in this way:
By locatorOfLink1 = By.xpath(....); // By.id, By.name, By.linkText etc.
wait.until(ExpectedConditions.elementToBeClickable(locatorOfLink1));
If the above will not help for problem #2 (the webdriver gets stuck after the click), then send ENTER key to the link instead of the click:
element1.sendKeys(Keys.ENTER);

Selenium exception when attempting to click ID of a button

I'm attempting to use the Java Selenium client with JBehave to interact with a simple web page as a demonstration of BDD techniques.
When running the test, i'm trying to do a simple
selenium.click("joinButton");
but i'm getting a
(com.thoughtworks.selenium.SeleniumException: joinButton is not defined)
exception thrown.
I've tried qualifying the ID as a dom ID using id=joinButton, as a css selector and even as xpath but to no avail.
The element is definitely rendered in the page. I'm clearly doing something daft here.
Any pointers?
Thanks
Did you call waitForPageToLoad() after navigating to the page in Selenium? I'm betting your DOM hasn't loaded yet when your click is called.
Please confirm that while verifying with xpath and css you used selenium.click("//[#id=joinButton]") and selenium.click("css=#joinButton") respectively.
You can also keep selenium.isElementPresent("joinButton") in a loop until some timeout (30/60 sec) and the moment selenium finds this element, it would come out of this loop and execute click command.
I realised what the issue was here. The Selenium class was being extended, and the click method overridden to only accept CSS selectors. With this cruft now removed, the operation works as expected.
Thanks for your help folks.

Categories