Selenium is telling me the ID doesn't exist - c#

When I run the following program it runs absolutely fine, until I get to filling out the form on the webclip section. Once it gets there it says the id "txtTemplateName" can't be found. I copied and pasted that name directly from Inspecting the element. It isn't that i'm not giving it enough time to load either, I've given it a full 5 seconds in the past just to make sure, and still nothing.
using OpenQA.Selenium;
using OpenQA.Selenium.Firefox;
using System.Diagnostics;
using System.Linq;
namespace Build1Evan
{
class Program
{
static void Main(string[] args)
{
IWebDriver driver1 = new FirefoxDriver();
driver1.Navigate().GoToUrl("URL");
Process.Start(#FILE"); // This is just an Auto IT Script to get me by a login window
bool loginCheck1 = driver1.FindElements(By.Id("btnLoginAgain")).Count() > 0;
if (loginCheck1 == true)
{
driver1.FindElement(By.Id("btnLoginAgain")).Click();
}
System.Threading.Thread.Sleep(500);
driver1.FindElement(By.LinkText("Configuration")).Click();
System.Threading.Thread.Sleep(500);
driver1.FindElement(By.LinkText("Payloads")).Click();
System.Threading.Thread.Sleep(500);
driver1.FindElement(By.PartialLinkText("WebClip")).Click();
// BELOW IS WHERE I ENCOUNTER THE ISSUE
System.Threading.Thread.Sleep(500);
driver1.FindElement(By.Id("txtTemplateName")).SendKeys("TESTING");
}
}
}
I also encounter the error when I try selecting any other element in the form, rather it be a button or another text field.
EDIT: PHOTO AS ASKED
EDIT 2: PHOTO 2 Also just a FYI i have had no problems using Selenium IDE, it is easily able to select the element and fill it in.

According to your screenshot, I think your app embed the form by using <object id="panelcontentobject" data="....
In case the form is really inside object tag, you have to create a WebElement of the object tag then use JavaScriptExecutor to retrieve attribute or interact with the form.
For example,
IWebElement objectTag= driver.FindElement(By.Id("panelcontentobject"));
IJavaScriptExecutor js = driver as IJavaScriptExecutor;
js.ExecuteScript("return (arguments[0].contentDocument.getElementById('txtTemplateName')).click()",objectTag);
Please see Examples from http://aksahu.blogspot.com/2015/05/dealing-with-object-tags-in-selenium-webdriver.html?m=1

The form is probably inside iframe, you need to switch to it before you can perform actions on elements inside it:
IWebElement frame = driver.FindElement(By.Id(frameId));
driver.SwitchTo().Frame(frame);
You can also use explicit wait to make sure the element you want is visible and you can interact with it:
WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10));
wait.Until(ExpectedConditions.ElementIsVisible(By.Id("txtTemplateName"))).SendKeys("TESTING");

Related

How to generate keyboard text for the active process of Firefox

I can send a text from my C# WinForm app to another application like Notepad using:
SendKeys.SendWait("Hello");
but I need to send text to an html input element in Firefox. There are several ways to select a target application. This SO Question uses code like:
Process p = Process.GetProcessesByName("notepad").FirstOrDefault();
IntPtr h = p.MainWindowHandle;
SetForegroundWindow(h);
to set the desired app to the foreground so it will receive the text. But this does not work with the app named "firefox", probably because it uses not 1 but 4 processes according to the Task Manager.
I tried another approach: right before calling SendKeys.SendWait, just switch back to the last active application just like Alt-Tab does, using code from this SO Question, which works for Notepad, and for the Chrome browser, but not for Firefox.
The purpose of this is to get data from a weight measurement device (scale), connected to the RS232 port, to the html input element in the browser. The same principle of simulating a keyboard is routinely used with USB barcode scanners.
Any idea how to do this with Firefox?
Am I perhaps on the wrong track, and are there perhaps much different methods to get text in the keyboard?
Can't you use WinForms WebBrowser? Also consider using Selenium WebDriver which is available via Nuget. I think it does exactly what you need.
That's an example from docs:
using OpenQA.Selenium;
using OpenQA.Selenium.Firefox;
// Requires reference to WebDriver.Support.dll
using OpenQA.Selenium.Support.UI;
class GoogleSuggest
{
static void Main(string[] args)
{
// Create a new instance of the Firefox driver.
// Note that it is wrapped in a using clause so that the browser is closed
// and the webdriver is disposed (even in the face of exceptions).
// Also note that the remainder of the code relies on the interface,
// not the implementation.
// Further note that other drivers (InternetExplorerDriver,
// ChromeDriver, etc.) will require further configuration
// before this example will work. See the wiki pages for the
// individual drivers at http://code.google.com/p/selenium/wiki
// for further information.
using (IWebDriver driver = new FirefoxDriver())
{
//Notice navigation is slightly different than the Java version
//This is because 'get' is a keyword in C#
driver.Navigate().GoToUrl("http://www.google.com/");
// Find the text input element by its name
IWebElement query = driver.FindElement(By.Name("q"));
// Enter something to search for
query.SendKeys("Cheese");
// Now submit the form. WebDriver will find the form for us from the element
query.Submit();
// Google's search is rendered dynamically with JavaScript.
// Wait for the page to load, timeout after 10 seconds
var wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10));
wait.Until(d => d.Title.StartsWith("cheese", StringComparison.OrdinalIgnoreCase));
// Should see: "Cheese - Google Search" (for an English locale)
Console.WriteLine("Page title is: " + driver.Title);
}
}
}

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.

Categories

Resources