Selenium - Force click on non-visible element - c#

I'm using C# Selenium.WebDriver.2.44.0
On some 3rd party site I'm trying to press an element and get this:
var myWebElement = Driver.FindElement(By.XPath("//a[.=' some value']
myWebElement.Click();
I get the element and on click I get this:
{"element not visible\n (Session info: chrome=39.0.2171.95)\n (Driver info: chromedriver=2.9.248315,platform=Windows NT 6.1 SP1 x86_64)"}
The item is within some sub menu revealing after I successfully press the parent menu. Also put 5 seconds sleep to be safe that the accordion is well seen (and it is well seen in my eyes).
Question - on 3rd party site how can I force the click on this item?

You could try bringing it to the top by changing the z-index with driver.execute_script().

You could use the inbuilt functions and WebDriver waits
var myWebElement = Driver.FindElement(By.XPath("//a[.=' some value']
WebDriverWait wait = new WebDriverWait(Driver.FindElement, TimeSpan.FromSeconds(10));
var element = wait.Until(ExpectedConditions.ElementIsVisible(myWebElement));
Actions action = new Actions(Driver.FindElement);
action.MoveToElement(element).Perform();
myWebElement.Click();

The problem is that Selenium executes actions one after another, but something like "show a sub menu" is lost between actions.
You're likely going to have to use an Actions chain for this:
Actions action = new Actions(Driver);
action.MoveToElement(Driver.FindElement(By(ParentElementSelector)))
.click()
.MoveToElement(Driver.FindElement(By.XPath("//a[.=' some value'])))
.click()
.Build()
.Perform();
This will move to the parent element, click, then move to the element you wish to find, then click. It will perform all of these as one action, which should be able to click the sub menu element.

When an element is not visible u can try this...It works for me
IWebElement WEHiddenID = driver.FindElement(By.Id(""));
WEHiddenID.SendKeys(OpenQA.Selenium.Keys.Enter);

Related

Selenium - Wait for OutOfBound element C#

I use Selenium C# binding and I want to click over the addToCart button.
First, I'm waiting the button appears on the page with ExpectedConditions.ToBeClickable.
Then, I need to scroll down the page to be able to click over the button. I used the Selenium.Interactions class but it work as well with js executor.
private By addToCartBy = By.XPath("/html/body/div[2]/div/div/div[1]/div/div[3]/div[2]/div/section[1]/div[2]/aside/div/div[2]/div/div[2]/div/button");
WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(5));
IWebElement addToCart = wait.Until(ExpectedConditions.ElementToBeClickable(addToCartBy));
Actions action = new Actions(driver);
action.MoveToElement(addToCart);
action.Perform();
addToCart.Click();
When I perform this test with Chrome driver, the page loads and the navigator scroll down to the element addToCart and click it but I'm unable to get the button working properly.
When I use Firefox driver, it raise this exception:
OpenQA.Selenium.WebDriverException : '(1435, 998) is out of bounds of viewport width (1920) and height (966)'and I'm unable to click over the button
Most of the time, the click will be performed but no action will follow from this. If I want the button to work properly (go the the cart), I need to put a System.Threading.Thread.Sleep(2000) to be effective or a Console.ReadLine(). Even if I disable the automation click and I do it manually, the button don't always proceed.
How can I make sure my element addToCart is displayed after I moved to Element? in a way to click it when he's ready.
Thank you, Eelke Johnson
For some of the scenarios, you can use not
IWebElement.Click();
but
IWebElement.SendKeys(Keys.Enter);
I had some scenarios, where just Click() didn't work for me.Maybe this will help in your situation.
You need to consider a couple of things.
To invoke MoveToElement(), ExpectedConditions as ElementToBeClickable() is overkill. Instead you can do away with ElementIsVisible().
While invoking Click() as per best practices you need to invoke WebDriverWait inconjunction with ExpectedConditions as ElementToBeClickable().
So effectively, your code block will be:
Actions action = new Actions(driver);
action.MoveToElement(new WebDriverWait(driver, TimeSpan.FromSeconds(10)).Until(ExpectedConditions.ElementIsVisible(By.XPath("/html/body/div[2]/div/div/div[1]/div/div[3]/div[2]/div/section[1]/div[2]/aside/div/div[2]/div/div[2]/div/button")))).Perform();
new WebDriverWait(driver, TimeSpan.FromSeconds(10)).Until(ExpectedConditions.ElementToBeClickable(By.XPath("/html/body/div[2]/div/div/div[1]/div/div[3]/div[2]/div/section[1]/div[2]/aside/div/div[2]/div/div[2]/div/button"))).Click();

selenium locate element with xpath

Firebug gives me this for an element inputfiled I want to fill in:
<label for="form:composite:tabView:ssn">Fødselsnummer</label>
Tried this in my selenium script:
WebElement velger = driver.findElement(By.xpath("//input[#id='form:composite:tabView:ssn']"));
Next I do this:
velger.sendKeys(new String[]{"27017833176"});
And then:
WebElement sokknapp = driver.findElement(By.xpath("//*[#id=\"form:composite:tabView:searchSSN\"]"));
sokknapp.click();
To click the serach button.
However when looking at the browser during replay I can se that the "sendkeys" does not work but the button click does work (the inputfield gets red because I press the button for searching without content in the inputfield).
Is there something wrong with this:
velger.sendKeys(new String[]{"27017833176"});
Unable to locate element might means that you need some time to wait before handle element:
var wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10));
var velger = wait.Until(ExpectedConditions.ElementIsVisible(By.Id("form:composite:ta‌​b‌​‌​View:ssn")));
Also I'm not sure about correctness of velger.sendKeys(new String[]{"27017833176"});. Try to send simple string:
velger.sendKeys("27017833176");
The problem (or solution) was that I missed i clear() function before sendkeys.
velger.clear();
velger.sendKeys("27017833176");

Menu and SubMenu in different frames

I have a little problem clicking on submenu, the reason is that the menu tag in one frame and the submenu in other so when i switch to other frame the submenu is invisible
My code:
driver.SwitchTo().DefaultContent().SwitchTo().Frame("top");
Actions actions = new Actions(driver);
IWebElement menuHoverLink = driver.FindElement(By.PartialLinkText("Cons"));
actions.MoveToElement(menuHoverLink);
actions.Build().Perform();
driver.SwitchTo().DefaultContent().SwitchTo().Frame("content").FindElement(By.Id("elem3")).Click();
Exception
Unexpected error. Element is not currently visible and so may not be
interacted with
does anyone have an idea what can i do in that case?
Thanks.
Try to use explicit wait
driver.SwitchTo().Frame("content");
WebDriverWaitwait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10));
wait.Until(ExpectedConditions.ElementIsVisible(By.Id("elem3"))).Click();
Or to use send keys
actions.MoveToElement(menuHoverLink).Build().Perform();
menuHoverLink.SendKeys(OpenQA.Selenium.Keys.ArrowDown);
menuHoverLink.SendKeys(OpenQA.Selenium.Keys.Enter);
I found solution but it's not always will work
i just redirect to the url that comes after clicking the option.
string urlAfterClick = "..."
driver.Navigate().GoToUrl(urlAfterClick);

Selenium click link multiple times

I'm automating tests for our webapp in Selenium WebDriver for C#. One of our test scenarios identified an issue with clicking the save button multiple times resulting in multiple identical records.
The standard IWebElement.Click() causes Selenium to block until the page is fully loaded. That means by the time our second click comes around to executing, the postback has been performed and we're not on the form page anymore.
Does anyone know a means of 'manually' clicking an element that won't cause Selenium to block?
You could either wait for a predetermined amount of time for the page to load:
driver.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(10));
...or to be more dynamic and wait for your button to appear:
var driver = new WebDriver();
var wait = new WebDriverWait(driver, TimeSpan(0, 1, 0));
wait.Until(d => d.FindElement(By.Id("button"));
Source: https://stackoverflow.com/a/7811812/2006048
Selenium also has source code that is similar to the second method: http://selenium.googlecode.com/svn/trunk/dotnet/src/WebDriver.Support/UI/ExpectedConditions.cs
Let me know if it works out for you. I personally use these options with WatiN:
browser.WaitForComplete();
...or:
browser.WaitUntilContainsText("Text");
It's a shame Selenium does not have the first one.
If we use JavaScript to send our click events, Selenium will not be blocked and we can click multiple times. However, because our click triggers a page load, we cannot reference the element directly. Instead, we need to specify the location to click and then fire our click events.
Because our WebApp uses JQuery, I was able to use the code specified here:
How to simulate a click by using x,y coordinates in JavaScript?
So in the end our C# logic looks something like this:
IWebElement element = driver.findElement(By.id("foobar"));
Point point = element.Location;
IJavascriptExecutor jscript = (IJavascriptExecutor)driver;
jscript.executeScript("$(document.elementFromPoint(arguments[0], arguments[0])).click();", point.X, point.Y);
Although this sends the click event I'm not 100% sure that the element receives it; I'll run some experiments and see.
What you need to do is click via javascript. In java this is done like this:
IJavascriptExecutor executor = (JavascriptExecutor)driver;
executor.executeScript("arguments[0].click();", driver.findElement(By.id("gbqfd")));
executor.executeScript("arguments[0].click();", driver.findElement(By.id("gbqfd")));
I actually imagine it is very similar, this will not block selenium and you should be able to chain a few on before the page comes back.
if this newer approach is too slow you might be quicker doing it all in js, e.g.
IJavascriptExecutor executor = (JavascriptExecutor)driver;
executor.executeScript("document.getElementById(id).click();");
executor.executeScript("document.getElementById(id).click();");

Selenium WebDriver SubMenu click not working

I am not able to Click on SubMenu item using selenium webdriver using c#.
I am using IE9 and FireFox 13.
I have tried Action Builder but it does not work.
It gives an error saying element cannot be clicked.
WebDriverWait Wait = new WebDriverWait(webDriver, TimeSpan.FromSeconds(5));
IWebElement menu = Wait.Until((d) => webDriver.FindElement(By.Id("id1")));
IWebElement menuOption = Wait.Until((d)=>webDriver.FindElement(By.Id("ID2")));
Actions builder = new Actions(webDriver);
builder.MoveToElement(menu).Build().Perform();
Thread.Sleep(5);
//then click when menu option is visible
menuOption.Click();
I have used even javascript :
js.ExecuteScript("return $(\"a:contains('ID1')\").mouseover();"); // Mouse hove to main menu
webDriver.FindElement(By.Id("ID2")).Click();
Please give some solution to click on hidden elements
You could use Expected Conditions to wait for element being clickable after hovering above it (Thread.sleep() is almost always the bad choice. And 5 ms won't be enough.).
The docs for this class (ExpectedConditions in OpenQA.Selenium.Support.UI namespace) are broken as I can see them now, but if you can follow the Java code in the link above, here are the Expected conditions for Java - it's really almost the same in C#, too.
Instead of using the statement Thread.sleep(). You can try to click on the element after making sure that it is displayed.
After you get the WebElement you want to click on , check if it is displayed by using the isDisplayed() method within the ExpectedContition statement about which #Slanec is talking about in the above post.
By this you can make sure you will click on the element only after Wait.Until() returns true. i.e the menuOption is displayed.
I'm writing the code in java as I do not know C#. But I guess you can figure out what I'm trying to say -
new WebDriverWait(driver, 60).until(new ExpectedCondition<Boolean>() {
public Boolean apply(WebDriver driver ) {
return driver.findElement(By.Id("ID2")).isDisplayed();
}
});
I hope that this helps you.

Categories