Selenium C# RemoteWebDriver not finding XPath Elements - c#

I'm using Selenium 2.25.1 API, and I'm trying to be able to find the elements using RemoteWebDriver(). Except when I try, it just fails to find the element. I've tried several different combinations with no luck and have been looking this up for a few days now.
WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10));
IWebElement WaitForPage = wait.Until<IWebElement>((d) =>
{
return driver.FindElement(By.XPath((String)data));
});
Is my code where it fails. Basically the data variable is an object grabbed from my database. I converted it, and going though the code it comes out perfectly fine. How the difference is, when I used just the browser (i.e. firefox, IE) it works just fine with no errors. But when I use it with RemoteWebDriver(), it throws InvalidOperationException and throws a popup saying it was unable to find the element. (Server did not provide any stacktrace information).
This is usually what I use
IWebDriver driver = new RemoteWebDriver(new Uri("http://localhost:4444/wd/hub"), IEcapa);
When that is used, it just fails everytime.
Any ideas? I am completely puzzled. Anything is welcome and thanks in advance!

I would suggest using an implicit wait instead of an WebDriverWait statement.
WebDriver driver = new FirefoxDriver();
driver.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(10));
IWebElement WaitForPage = driver.FindElement(By.XPath((String)data));
And make sure that the xpath you are getting from the data variable is valid. If possible post an some xpath you get from the database.

Related

Headless Browser C# and Alternatives

currently I have the following code using selenium and phantomjs in c#:
public class Driver
{
static void Main()
{
using (var driver = new PhantomJSDriver())
{
driver.Navigate().GoToUrl("https://www.website.com/");
driver.Navigate().GoToUrl("https://www.website.com/productpage/");
driver.ExecuteScript("document.getElementById('pdp_selectedSize').value = '10.0'"); //FindElementById("pdp_selectedSize").SendKeys("10.0");
driver.ExecuteScript("document.getElementById('product_form').submit()");
driver.Navigate().GoToUrl("http://www.website/cart/");
Screenshot sh = driver.GetScreenshot();
sh.SaveAsFile(#"C:\temp\test.jpg", ImageFormat.Png);
}
}
}
My objective is to be able to add a product to my cart and then checkout automatically. The screenshot is just included to test whether the code was successfully working. My first issue is that I often get an error that it cannot find the element with product id "pdp_selectedSize". I'm assuming this is because the the webdriver hasn't loaded the page yet, so I'm looking for a way to keep checking until it finds it without having to set a specific timeout.
I'm also looking for faster alternatives to use instead of a headless browser. I used a headless browser instead of http requests because I need certain cookies to be able to checkout on the page, and these cookies are set through javascript within the page. If anyone has a reccommendation for a faster method, it would be greatly appreciated, thanks!
For your first question, it would behoove you to look into using ExpectedConditions' which is part of theWebDriverWaitclass inSelenium`. The following code sample was taken from here and only serves as a reference point.
using (IWebDriver driver = new FirefoxDriver())
{
driver.Url = "http://somedomain/url_that_delays_loading";
WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10));
IWebElement myDynamicElement = wait.Until<IWebElement>(d =>
d.FindElement(By.Id("someDynamicElement")));
}
More on WebDriverWaits here.
As to your second question, that is a really subjective thing, in my opinion. Headless Browsers aren't necessarily any faster or slower than a real browser. See this article.

Selenium C# Webdriver: I am getting error: 'iWebDriver' does not contain definition for 'WaitforElement'

I am new to Selenium and C#... I am in middle of a selenium application development using C#. I have a drop down menu on a webpage. I want selenium to click on the exact name after clicking the drop down menu. So I did something like this:
C#/NUnit code:
driver.FindElement(By.LinkText("z")).Click;
driver.WaitForElement(By.LinkText("xxxxx"));
driver.FindElement(By.LinkText("xxxxx")).Click();
but when I build my code I get the following error:
'iWebDriver' does not contain definition for 'WaitforElement'
Okay, I can offer you an example, but I don't know c#, But I can give you the example from Ruby Selenium Binding.
driver.manage.timeouts.implicit_wait=20
driver.find_element(:link_text,"z").click;
driver.find_element(:link_text,"xxxxx").click
Since I have given the implicit wait 20, whenever it finds the element via find_element function, it waits for 20 minutes, So your external wait statement is not necessary .
The C# code might be(I don't know C#, I took it from the net and placing it here)
driver.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(10));
driver.FindElement(By.LinkText("z")).Click;
driver.FindElement(By.LinkText("xxxxx")).Click();
It doesn't work the way you shown.
The next code is an example how you should write it:
WebDriverWait watiDriver = new WebDriverWait(Driver, TimeSpan.FromSeconds(10));
IWebElement element = watiDriver.Until(x => Driver.FindElement(By.CssSelector("")));
Where Driver is your instance of a webdriver.
If you want to use it as you shown then you need to add an extension method to the webdriver class. To do this, just create a new static class (with any name) and insert the next code into it:
public static IWebElement WaitForElement(this IWebDriver driver, By how)
{
webDriverWait watiDriver = new WebDriverWait(Driver, TimeSpan.FromSeconds(10));
return watiDriver.Until(x => Driver.FindElement(FindElement(how));
}

Ocasional InvalidElementStateException or ElementNotVisibleException when calling SendKeys on input

I have this code:
IWebDriver driver = new FirefoxDriver();
driver.Manage().Window.Maximize();
driver.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(30));
//Go to the powerbi site
driver.Navigate().GoToUrl("https://powerbi.microsoft.com/en-us/");
//Go to the page with login form
driver.FindElement(By.XPath("html/body/div[2]/header/nav/div/ul[3]/li[1]/a")).Click();
//Fill in email field
driver.FindElement(By.XPath("//*[#id='cred_userid_inputtext']")).SendKeys("example#gmail.com");
When I launch this code on my computer everything works fine without errors. But when I launch this code on my boss's computer, sometimes it works and sometimes it doesn't.
When an error occurs, it's always on the last line of code. I don't remember exactly which error it is: InvalidElementStateException (when the target element is not enabled) or ElementNotVisibleException (when the target element is not visible).
I suppose the whole thing lies on the Click() method. The documentation says:
Click this element. If the click causes a new page to load, the Click() method will attempt to block until the page has loaded.
I don't quite understand how it attempts to block.
Seems like your input isn't always ready immediately after you click the button.
You should wait for it before sending the keys:
Try this instead of your last line:
WebDriverWait wait = new WebDriverWait(driver, new TimeSpan(0,0,5));
var input = wait.Until(ElementIsClickable(By.XPath("//*[#id='cred_userid_inputtext']")));
input.SendKeys("example#gmail.com");
In order to do that check, you should create a ElementIsClickable function, which returns a delegate, just as this answer shows:
public static Func<IWebDriver, IWebElement> ElementIsClickable(By locator)
{
return driver =>
{
var element = driver.FindElement(locator);
return (element != null && element.Displayed && element.Enabled) ? element : null;
};
}
Also, keep in mind that for using the WebDriverWait class you might need to import the Selenium.WebDriver and Selenium.Support packages into your project, just as this answer suggests.
It's coming occasional because sometimes it takes time to load element from DOM and which cause exception like InvalidElementStateException or ElementNotVisibleException.
I ran your snippets code.
It runs fine, try to separate action and find element.
WebElement element = driver.findElement(By.xpath(".//xyz"/);
element.sendkeys("data");
This could work.

Selenium - C# - Webdriver - Unable to find element

Using selenium in C# I am trying to open a browser, navigate to Google and find the text search field.
I try the below
IWebDriver driver = new InternetExplorerDriver(#"C:\");
driver.Navigate().GoToUrl("www.google.com");
driver.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(5));
IWebElement password = driver.FindElement(By.Id("gbqfq"));
but get the following error -
Unable to find element with id == gbqfq
This looks like a copy of this question that has already been answered.
I can show you what I've done, which seems to work well for me:
public static IWebElement WaitForElementToAppear(IWebDriver driver, int waitTime, By waitingElement)
{
IWebElement wait = new WebDriverWait(driver, TimeSpan.FromSeconds(waitTime)).Until(ExpectedConditions.ElementExists(waitingElement));
return wait;
}
This should wait waitTime amount of time until either the element is found or not. I've run into a lot of issues with dynamic pages not loading the elements I need right away and the WebDriver trying to find the elements faster than the page can load them, and this is my solution to it. Hope it helps!
You can try using a spin wait
int timeout =0;
while (driver.FindElements(By.id("gbqfq")).Count == 0 && timeout <500){
Thread.sleep(1);
timeout++;
}
IWebElement password = driver.FindElement(By.Id("gbqfq"));
this should help make sure that the element has actually had time to appear.
also note, the "gbqfq" id is kinda a smell. I might try something more meaningful to match on than that id.

Selenium Error when using JavaScript or getting elements

Using Seleneium 2.25, I've had a lot of issues arise.
I'm trying to use Selenium Remote Driver on a remote machine (Server) from my computer (local / client). However, when I try to use DesiresCapabilities.Htmlunit() It will locate the elements, but it says they are not visible. I'm completely stumped by this. I'm not sure why it can be found but then not visible.
So then I tried to use some JavaScript in order force it. It comes back and throws an error saying that the webpage can not execute javascript before the page is loaded. How is this possible when I did an implicate wait, and it found the element it was waiting for?
DesiredCapabilities iecapa = DesiredCapabilities.HtmlUnit();
iecapa.IsJavaScriptEnabled = true;
driver = new RemoteWebDriver(new Uri("http://<IP of server>:4444/wd/hub"), iecapa);
IJavaScriptExecutor jQuery = ((IJavaScriptExecutor)(driver));
addressElement = (IWebElement)jQuery.ExecuteScript("return document.GetElementByName('searchAddress')");
So if anyone would like to help me, it would be greatly appreciated! Thank you!
http://imageshack.us/photo/my-images/163/seleniumhtmluniterror.jpg/
that is the error. StackOverflow wont let me post it here. =(
Try this:
WebDriverWait wait = new WebDriverWait(driver, new TimeSpan(0, 0, 0, 30));
wait.Until(p => driver.FindElement(By.Name("searchAddress")));
IJavaScriptExecutor jQuery = ((IJavaScriptExecutor)(driver));
addressElement = (IWebElement)jQuery.ExecuteScript("return document.GetElementByName('searchAddress')");
Also you can add check in JavaScript:
if (document.readyState.toLowerCase()=="complete")
return document.GetElementByName('searchAddress');
return 'Error';

Categories

Resources