Hi I am new to Selenium Webdriver. I can successfully open a webpage and find elements on it.
In one case I have noted that there is a link on a page that becomes clickable after a while. In Firebug on the Script tab, I can see the code for the javascript that does the timer function.
But using Selenium Webdriver if I issue:
driver.PageSource
I cannot see the source code for the Javascript. Delaying for 30 seconds before requesting the source makes no difference. I have tried finding it with various By options using:
driver.FindElement
and so on, but it isnt there.
How does firebug manage to find and show the Javascript source code? Is there a way that I can coerce Selenium Webdriver to return all code referenced by the page?
Or is there a better approach?
Thanks for any advice!
EDIT---------------------
I tried the following in Firefox:
Dim Driver2 As IWebDriver = New Chrome.ChromeDriver
Driver2.Url = "http://mypage"
Dim js As IJavaScriptExecutor = TryCast(Driver2, IJavaScriptExecutor)
Dim title As String = DirectCast(js.ExecuteScript("return JSON.stringify(window)"), String)
and I got
Permission denied to access property 'toJSON'
I read that this wont work in firefox so I tried in Chrome, and got
Blocked a frame with origin "http://mypage" from accessing a
cross-origin frame
and from there no solutions because according to this its a security restriction, apparently you can't access an with Javascript
I'm starting to think Im a bit out of my depth here.
PageSource probably doesn't return an exact snapshot of the DOM & etc.
You can instead inspect javascript using driver.executeScript() but the burden of analyzing the return object may be discouraging.
Regardless - Here's a contrived example:
Object result = driver.executeScript("return JSON.stringify(window)");
System.out.println(result.toString());
Related
I wrote in Python a script which uses Selenium to auto-complete a form. It works with no issues.
I am very new to C# but I thought I would try and port it over so I can build a Windows executable to share it with a couple of non tech-savvy family members.
However, when I try what appears to be the same code, I get a timeout in C#.
As an example, I am trying to click a radio button:
HTML of radio button:
<input data-v-7af3e24c="" type="radio" id="condition-2" name="condition" class="govuk-radios__input" value="false">
Python (this works):
WebDriverWait(driver, max_wait).until(EC.presence_of_element_located(
(By.CSS_SELECTOR, '[id$=condition-2]'))).click()
However, when I try what I think is the same request in C#:
int elementLoadTime = 5; // Max 5 seconds for element to load
var wait = new WebDriverWait(driver, new TimeSpan(0, 0, elementLoadTime));
wait.Until(SeleniumExtras.WaitHelpers.ExpectedConditions.ElementToBeClickable(By.CssSelector("[id$=condition-2]"))).Click();
This produces:
Exception thrown: 'OpenQA.Selenium.WebDriverTimeoutException' in WebDriver.dll
The strange thing is, I am able to select the element in C# using the full XPath, so the element is clearly loading, and it strongly suggests the problem is with my CSS selector query.
// This works
wait.Until(SeleniumExtras.WaitHelpers.ExpectedConditions.ElementToBeClickable(By.XPath("/html/body/div[1]/div[2]/main/div/div/form/fieldset/div[2]/div/div/div[2]/label"))).Click();
However, obviously that is a very brittle way of writing the code which will break the moment the site changes slightly.
I have also tried "[id$='condition-2']" and "[id$=\"condition-2\"]", to no avail.
Can anyone shed any light on what I am doing wrong?
Instead of using:
By.CssSelector("[id$=condition-2]")
Just use:
By.Id("condition-2")
If you want to use Xpath instead, do two things. First, forget that there's an option in your browser to 'Copy Xpath' - just purge it from your mind. Second, use this Xpath instead:
By.Xpath("//input[#id=\"condition-2\"]")
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.
I'm sorry if this question has allready been answered , but I litterally spent more than two weeks searching the Internet for a solution to my issue.
Now , I definitly do not perform the best google searches , and it might seem that my question has several effective answers on the Internet. but I really tried every single solution that I found , without any positive results.
What i'm trying to do is simple , and I did it successfully on many websites :
Navigating to a website using WebBrowser (1).
Waiting for everything to load properly (document completed event).
Download the page using DocumentText property (1).
(1) : I also use WebClient from time to time.
And there it is , I get the html page , and I can exploit it anyway I like. The issue is with a particular website that I cannot obtain the full content inspite of using all the different solutions that I found. I suspected the fact that this page might need to load several scripts before getting the full content. Yet again, I read that WebBrowser does run all the necessarry scripts before triggering the " completed " event, so , apparently , that's not the issue. The page that i'm inquiring about is : http://www.coolmod#com/tarjetas-graficas-nvidia-pci-express
I tried , after that the WebBrowser loads the entire page , looking for random elements using GetElementByID property and checking if I get a null result. It appears that when I try getting an element that does not belong to the products list , i'm successful. But , whenever I try to get an element that belongs to the list it self , I always get a null. Which means , the list it self does not load. and I really don't know why. By the way , I do not prevent the WebBrowser. Navigate () from delivering multiple responses , I allow it to give as many feedbacks as possible , and still , the product list does not load , even when I pass the cookies. I Even tried copying all the content of the document and pasting it through the clipboard. Here is a simple example of what I try to do :
private void catalogueDownload()
{
System.Windows.Forms.WebBrowser wb = new System.Windows.Forms.WebBrowser();
wb.ScriptErrorsSuppressed = true;
wb.DocumentCompleted += new WebBrowserDocumentCompletedEventHandler(Catalogue_DocumentCompleted);
wb.Navigate("http://www.coolmod.com/tarjetas-graficas-nvidia-pci-express");
}
public void Catalogue_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
var wb = sender as System.Windows.Forms.WebBrowser;
string output = wb.DocumentText;
File.WriteAllText("testing.html", output);
}
Thanks for giving up your time to read all this.
System.Windows.Forms.WebBrowser is a bit outdated, If I were you, I would consider using an external library for that, Selenium would be my 1st choice, given it has all the necessary integrations with .NET Framework (and a lot of other languages)
I am trying to use watin to mimic login to live.com using c#. code is below.
IE myIE = new IE("http://login.live.com/");
myIE.TextField(Find.ByName("login")).TypeText("abc#abc.com");
myIE.TextField(Find.ByName("passwd")).TypeText("1234");
myIE.Button(Find.ByValue("Sign in")).Click();
However it always failed to find the textfield:
WatiN.Core.Exceptions.ElementNotFoundException: Could not find INPUT (hidden) or INPUT (password) or INPUT (text) or INPUT (textarea) or TEXTAREA element tag matching criteria: Attribute 'name' equals 'login' at http://login.live.com/
The sample code in home page of http://watin.org/ works fine for www.google.com.
Did I miss something or is there anything special on http://login.live.com that prevents watin to work?
PS: I am running windows 7 64bit. VS 2008 with .net 3.5
You're hitting issues because the email field you're trying to type in is an HTML5 element.
Create the TextFieldExtended class as defined in this SO question: WatiN support for HTML5 tags
Then your code will be like the below:
ie.GoTo("http://login.live.com/");
ie.ElementOfType<TextFieldExtended>(Find.ByName("login")).TypeText("thisismyusername#here.com");
ie.TextField(Find.ByName("passwd")).TypeText("thisismypassword");
ie.Button(Find.ByValue("Sign in")).Click();
Tested on Watin2.1, IE9, Win7-64.
You may want to try this: I got it to work on my end:
ie.Div(Find.ByCustom("innertext","someone#example.com")).Click();
ie.TextField(Find.ById("i0116")).TypeText("hello");
ie.TextField(Find.ById("i0118")).Click();
ie.TextField(Find.ById("i0118")).TypeText("Hello!");
I recommend using this test Recorder. It will give you the elemnt names to use in your source:
http://www.codeproject.com/Articles/19180/WatiN-Test-Recorder
Edit:
I was also able to get this to work when finding by divID.
ie.Element(Find.ById("idDiv_PWD_UsernameExample")).Click()
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.