I am writing integration tests in c# and when I use the click() method on certain elements inside a dialog box nothing happens and I get no errors. It will click some of the elements inside the dialog but not others. I thought if it wasn't selecting them properly then it would throw and exception but it runs smooth and says test passed even though it never actually clicked the button. The dialog box is an iframe.
I thought maybe it was trying to click a button that wasn't display yet or enabled so I added this before the click() call:
_driver.SwitchTo().Frame(_frameElement);
_wait.Until(d =>
{
var shippingInfoButton = d.FindElement(By.CssSelector("input[title ='Info']"));
return shippingInfoButton.Displayed && shippingInfoButton.Enabled;
});
var infoButton = _driver.FindElement(By.CssSelector("input[title ='Info']"));
ScrollToElement(infoButton);
infoButton.Click();
again this runs with no thrown exceptions so I'm assuming it has found the element and it is both displayed and enabled.
Let me know if you need any more info. Thanks
I can't explain why the selenium driver .click() method won't fire on some elements in the page but not others, but I did find a solution.
Using IJavaScriptExecutor you can click the element using javascript instead and in my case it worked.
Here is the code to run the IJavaScriptExecutor and below is my whole method.
//IJavaScriptExecutor
IJavaScriptExecutor js = _driver as IJavaScriptExecutor;
js.ExecuteScript("arguments[0].click();", infoButton);
//my whole method for clicking the button and returning the page object
public ShippingMethodDetailsPageObject SelectShippingMethodInfo()
{
_driver.SwitchTo().Frame(_frameElement);
_wait.Until(d =>
{
var shippingInfoButton = d.FindElement(By.CssSelector("input[title='Info']"));
return shippingInfoButton.Displayed && shippingInfoButton.Enabled;
});
var infoButton = _driver.FindElement(By.CssSelector("input[title ='Info']"));
IJavaScriptExecutor js = _driver as IJavaScriptExecutor;
js.ExecuteScript("arguments[0].click();", infoButton);
_driver.SwitchTo().DefaultContent();
return new ShippingMethodDetailsPageObject(_driver, false);
}
I ran into a similar problem. If it's the same problem there's a fault in the ChromeDriver it can't click certain elements because of surrounding divs etc. Bit lame really.
A simple fix is to send the Enter key e.g. element.SendKeys(Keys.Enter). Seems to work across all browsers.
I have some tests that works in Firefox all the times, and in Chrome it drove me mad, because sometimes it passed successfully, and sometimes the ".click" didn't work and it would fail the test.
Took a long time to notice it, but the reason was: I used to sometimes minimize the browser to 80% to be able to see the browser along side my IDE. it appears that the ".click" doesn't work when I did it.
At least for me this was the issue
Related
Why C# + Selenium can't locate to any element from this URL only
I want to try to filling data to textbox programmatically using c# + selenium.
I had tried for some sites and it worked, but only that site it doesn't work. This is my code.
class Program
{
static void Main(string[] args)
{
Test test = new Test();
test.testDriver();
Console.WriteLine(Environment.NewLine + "Done!");
Console.ReadLine();
}
}
public class Test
{
public void testDriver()
{
IWebDriver driver = new FirefoxDriver();
driver.Navigate().GoToUrl(#"http://atrium.xsis.co.id/#!/");
IWebElement login = driver.FindElement(By.Name("email")); //Unable to locate element
//IWebElement login = driver.FindElement(By.Id("email")); //Unable to locate element
//IWebElement login = driver.FindElement(By.Name("password")); //Unable to locate element
//IWebElement login = driver.FindElement(By.Id("password")); //Unable to locate element
//IWebElement login = driver.FindElement(By.XPath("//input[#id='password']")); //Unable to locate element
//IWebElement login = driver.FindElement(By.XPath("//input[#id='email']")); //Unable to locate element
//IWebElement login = driver.FindElement(By.XPath("//input[#name='password']")); //Unable to locate element
//IWebElement login = driver.FindElement(By.XPath("//input[#name='email']")); //Unable to locate element
login.SendKeys("MyName");
login.Submit();
//------------------------------Some sites, i have tried
/* --It Worked
driver.Navigate().GoToUrl(#"https://accounts.google.com/");
IWebElement login = driver.FindElement(By.Name("identifier"));
login.SendKeys("MyName");
login.Submit();
*/
/* --It Worked
driver.Navigate().GoToUrl(#"https://web.facebook.com/");
IWebElement login = driver.FindElement(By.Name("email"));
login.SendKeys("MyName");
login.Submit();
*/
/* --It Worked
driver.Navigate().GoToUrl(#"https://stackoverflow.com/");
IWebElement login = driver.FindElement(By.Name("display-name"));
login.SendKeys("MyName");
login.Submit();
*/
/* --It Worked
driver.Navigate().GoToUrl(#"https://github.com/login?");
IWebElement login = driver.FindElement(By.Name("login"));
login.SendKeys("MyName");
login.Submit();
*/
}
}
I think that is simple code, just locate specific element. Or use other method if the web using IFrame, but there is no frame.
I am using vs 2013 community edition, WebDriver.dll version 3.4.0.0, RunTime version v4.0.30319., and Firefox 54.0.1 (32-bit).
There's something which is kind of cool and annoying at sometime in Selenium, it literally try to work exactly as if the user where using the browser. Hence you gotta be sure that the element exposed on your screen and the user can click on it, otherwise you must scrool until it.
Another important thing is the bootstrap, which sometimes change the visibility of its elements and replace to others.
Scrool to elements on page's bottom.
Guarantee the element is literally visible.
Check whether there's something over the element.
I can't comment yet and I'd prefer that this be a comment, but here goes anyway.
I tried browsing to the site you reference and can't get there. Not sure if it's live or not or just blocked by my company's firewall. I really wanted to look at the code for the site because I've seen issues like this before. Typically when I've seen this it's either a locater issue or an iframe issue. If you could post the html from the site that would help diagnose your issue. Oh, and the code you have written looks correct, but that doesn't help if Selenium is looking in the wrong frame.
So, here's what I would try.
First, I'd use FireFox's developer version and inspect the element. Make sure it's not inside of a frame that you haven't noticed.
Second, I'd try to locate by CSSSelector. I know that it should work by Id or XPath, but sometimes it doesn't and I don't know why. However, I have had luck with locating by CSSSelector when the others fail. You can copy the CSS Selector directly out of the inspection window in FireFox's developer version.
Third, if none of that works, I'd pass a SwitchTo the Default Content Frame, just in case the entire page is in a frame that is buried inside a div that you're missing. The code for that is:
driver.SwitchTo().DefaultContent();
Finally, the last thing I would try is adding some explicit waits just in case there is an element loading after you are trying to access it. Unfortunately this happens more than I'd like.
This would be my final, kitchen sink, approach.
Thread.Sleep(2000);
driver.SwitchTo().DefaultContent();
Thread.Sleep(2000);
By emailLocator = By.CSSSelector("insert CSS Selector Here");
IWebElement email = driver.FindElement(emailLocator);
email.SendKeys("email address");
If that still doesn't work, please post the html for the page you're trying to access and we'll see if we can figure out why it's failing to locate the element.
Your code looks good... something simple like your first attempt, By.Id("email"), should have worked. When it doesn't you want to look first to see if the desired element is in an IFRAME. In this case, it isn't.
The next thing you should try is an explicit wait, WebDriverWait.
IWebElement email = new WebDriverWait(Driver, TimeSpan.FromSeconds(3)).Until(ExpectedConditions.ElementIsVisible(By.Id("email")));
email.SendKeys("MyName");
email.Submit();
The wait.Until() returns the element waited for so you can capture that by assigning the return to a variable and then using it, as I did above.
Have you tried using Xpath?
driver.findElement(By.xpath("//input[#name='email']"))
I find that sometimes Selenium is finicky and you need to try other approaches to find elements.
I'm going to explain this the best I can.
I run tests using the 3 major browsers, firefox, chrome and IE.
I have line where I select data from a drop down menu. Here is an example of what I use.
new SelectElement(CPC_Main.driver.FindElement(By.XPath("//select[#id='orgVdc']"))).SelectByText("Selenium_vDC");
This will select my element orgVdc and select the text value by Selenium_vDC. This will work perfectly for Firefox however it hangs and timesout for Chrome.
From what I can tell the issue is related to the default value of that element.
For example if default value of the element is "Test_vDC" selenium will successfully change it "Selenum_vDC" for all browsers.
However if the default value was "Selenium_vDC" already then Chrome will hang on trying to select that same value.
I hope that explains this enough, in a nut shell Chrome does not like matching default values.
I had encountered issue like this in the past. I used to get exceptions like "The element is no longer attached to the DOM". The issues(stale reference exceptions) like these needs a solid exception handling to make sure Automation execution is not affected.
You can try the below code. You can modify the below code as per your code set up.
public void SetDropDownValue(string Xpath, string value)
{
var element = FindElement(By.Xpath("Xpath"));
var selectElement = new SelectElement(element);
//check whether the option is selectable or not
var wait = new WebDriverWait(this.driver, this.testCaseConfiguration.WaitTime);
wait.Until(ExpectedConditions.TextToBePresentInElement(selectElement , option));
try
{
selectElement.SelectByText(value);
}
catch (StaleElementReferenceException)
{
element = FindElement(By.Xpath("Xpath"));
selectElement = new SelectElement(element);
selectElement.SelectByText(value);
}
}
I have an issue when switching from ChromeDriver to PhantomJSWebDriver, that I need a workaround for.
Using the ChromeDriver I perform a .Click on a visible element, with another visible element next to it. the .Click makes the web page place a 'popup' over these elements. I then perform a .Click on an element within this 'popup' and it then goes away, and I am able to perform a .Click on the second of the original elements and it all works fine.
However, when I switch to using the PhantomJSDriver it complains that the second element is NOT visible after the 'popup' has been removed, and so wont do the .Click.
Is this a known issue with the PhantomJS driver, or is there some way to get it to 're-evaluate' what is visible? I have tried using a DriverWait looking for the element and waiting for it to be 'Displayed' but that doesn't work
WebDriverWait waitforpopdown = new WebDriverWait(driver, TimeSpan.FromSeconds(15));
waitforpopdown.Until(d => {
var elpd = driver.FindElement(By.ClassName(trid));
return elpd.Displayed;
});
I'm using PhantomJS 2.1.1 and Selenium 2.52.0.0 and using C#
I had the same problem with PhantomJSDriver. It hasn't the same javascript engine than Chrome, FF and IE.
I "fixed" my problem by installing a selenium server that is running chrome on a docker. If you have the ability to do that, I would recommend to work that way. It's an actual chrome browser that is running, so you don't have any difference between your different types of chromes.
You can find information about it on the following page : https://github.com/peroumal1/docker-chrome-selenium
EDIT : You have to declare your driver like this (note that it's java Syntax, but I'm sure you'll be able to find the C# syntax) :
return new RemoteWebDriver(new URL("http://myurl.url:8888"), DesiredCapabilities.chrome());
I'm working on a Product automation(Web CMS), where element.Click() shows the inconsistent behaviour. Basically we are using,
Selenium + Nunit GUI(unit testing framework) - To run the test cases from local on a particular environment
Selenium + Asp.net web application - Multiple user's can run the test cases on different environment
Here environment I mean different levels(Dev, SIT, QA, Production).
My Concern
In one of my test cases, I want to Click a button. So for that, I have tried few code. But all are inconsistent behaviour. Here Inconsistent I mean, the code whatever I wrote for clicking a button are only working in my local or server and viceversa.
1st attempt:-
I tried all the element locator's
IWebElement element = driver.FindElement(By.Id("element id goes here"))
Working fine at my local, but not in server
Result - Failed
2nd attempt:-
driver.FindElement(By.XPath("Element XPath goes here")).SendKeys(Keys.Enter);
Working fine at server, but not in local
Result - Failed
3rd attempt:-
IWebElement element = driver.findElement(By.id("something"));
IJavaScriptExecutor executor = (IJavaScriptExecutor)driver;
executor.ExecuteScript("arguments[0].click()", element);
Not working in both(local and server)
Result - Failed
At last, I tried waiting for the element to be visible and performing action
4th attempt:-
WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(60));
return wait.Until(ExpectedConditions.ElementIsVisible(By.XPath("element xpath goes here")));
After webdriver wait performing action on that element (element.click())
Working fine at local but not in server
Result - Failed
I'm looking for a solution, where Clicking the button should not be an inconsistent behaviour. Basically it should work fine in both (Local and Server). Your help would be greatly appreciated..Thanks in advance
FYI - I'm testing in Mozilla Firefox browser 38.5.2
I'm using Selenium in C# locally on Win7 and remotely on Win10 and MacOS with the Firefox browser and also noticed that Firefox sometimes requires special treatment for IWebElement.Click(). So I wrote myself an extension method, which works fine for me, no matter by what locator the element was found:
public static void Click(this IWebElement element, TestTarget target)
{
if (target.IsFirefox)
{
var actions = new Actions(target.Driver);
actions.MoveToElement(element);
// special workaround for the FirefoxDriver
// otherwise sometimes Exception: "Cannot press more then one button or an already pressed button"
target.Driver.Manage().Timeouts().ImplicitlyWait(TimeSpan.Zero);
// temporarily disable implicit wait
actions.Release().Build().Perform();
target.Driver.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(MyDefaultTimeoutInSeconds));
Thread.Sleep(500);
actions.MoveToElement(element);
actions.Click().Build().Perform();
}
else
{
element.Click();
}
}
If you want more stable behavior for your test cases, I would recommend using ChromeDriver. It never needs any special treatment at all, and it's also much faster than the FirefoxDriver.
So within my selenium regression tests, I've been trying to double click on a calendar to make a new appt. I have attempted to use the doubleClick(); method within the advanceduserinteractions library, but there is an issue; the two clicks aren't fast enough/close enough together to fire an actual double-click! Has anybody found a way to deal with this in their testing?
This code works for me!
Actions action = new Actions(driver);
action.doubleClick(myElemment);
action.perform();
Here is the Java equivalent. This code will blindly open the first event. You could add some logic to open a specific event etc. This code works! (tested with 2.12)
List<WebElement> events = driver.findElements(By.cssSelector("div.dv-appointment"));
for(WebElement event:events){
WebElement body = event.findElement(By.cssSelector("div.body"));
if(!body.getText().isEmpty()) //or open a known event
{
System.out.println(body.getText()); //open the first event
Actions builder = new Actions(driver);
Action doubleClick = builder.doubleClick(event)
.build();
doubleClick.perform();
break;
}
}
Do not forget "using"
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;
using OpenQA.Selenium.Interactions.Internal;
using OpenQA.Selenium.Support.UI;
//create Actions object
Actions builder = new Actions(driver);
//create a chain of actions
builder.DoubleClick().Build().Perform();
http://selenium-interview-questions.blogspot.ru/2014/03/how-to-double-click-on-web-element.html
I too had the problem where Selenium's doubleclick event works in Firefox but has no effect in Chrome. Upgrading to Selenium didn't help; I already have the latest version. (My environment is Ubuntu 14.04, Python 2.7.6, Selenium 2.44.0, Firefox 35.0, Chrome 40.0.2214.91.)
I'm not sure why CBRRacer's answer was downvoted. I successfully worked around the problem by using two click events. This works in both Firefox and Chrome. There are two ways do to it, and both worked for me.
The first way:
elem = driver.find_element_by_css_selector('#myElement')
elem.click()
elem.click()
The second way:
elem = driver.find_element_by_css_selector('#myElement')
actions = webdriver.ActionChains(driver)
actions.click(elem).click(elem).perform()
I quite like the approach used here, particularly queuing the actions first, then performing, since that allows repeated application of the actionchain.
http://selenium-python.readthedocs.org/en/latest/api.html#selenium.webdriver.common.action_chains.ActionChains
From the documentation example linked:
menu = driver.find_element_by_css_selector(".nav")
hidden_submenu = driver.find_element_by_css_selector(".nav #submenu1")
actions = ActionChains(driver)
actions.move_to_element(menu)
actions.click(hidden_submenu)
actions.perform()
have you tried catching the IWebElement and then clicking it twice?
IWebElement element = driver.FindElement(By.Id("yourID"));
element.Click();
element.Click();
I don't know if this would give you the desird functionality or not but I know that when I execute a click event like the one above it runs as close as a double click from an actual user.
The other option is to reference the ThoughtWorks.Selenium.Core, however the only downside of this is that I'm not sure it plays well with the current IWebDriver I think it needs it's own instantiation of the IWebDriver.