I'm trying to run some tests with C# and InternetExplorerDriver.
This code is executed on Windows Server 2012, 64 bit.
Right after navigation to a new URL, I'm calling a function that waits until a page loads\20 seconds timeout.
private bool waitForPageToLoad()
{
try
{
int timeout = int.Parse(ConfigurationManager.AppSettings["TimeoutForCustomExpression"]);
IWait<IWebDriver> wait = new OpenQA.Selenium.Support.UI.WebDriverWait(m_driver, TimeSpan.FromSeconds(timeout));
wait.Until(driver1 => ((IJavaScriptExecutor)m_driver).ExecuteScript("return document.readyState").Equals("complete"));
}
catch//(Exception e) //timeout
{
log(e.Message + e.StackTrace);
return false;
}
return true;
}
The function works great for every browser other than IE.
On IE, I the following error in my log:
JavaScript error (UnexpectedJavaScriptError) at
OpenQA.Selenium.Support.UI.DefaultWait1.PropagateExceptionIfNotIgnored(Exception
e) in
c:\Projects\WebDriver\trunk\dotnet\src\WebDriver.Support\UI\DefaultWait.cs:line
222 at OpenQA.Selenium.Support.UI.DefaultWait1.Until[TResult](Func`2
condition) in
c:\Projects\WebDriver\trunk\dotnet\src\WebDriver.Support\UI\DefaultWait.cs:line
180 at MainClass.waitForPageToLoad()
I have no idea why it happens.
Could somebody help me out here?
Sincerely,
Adam.
Without seeing all that extra information that Arran requested, it's hard to help you understand the error.
However if you're just looking for a quick fix that works in all browsers, I always just use
Thread.sleep(int milliseconds);
for my Selenium tests in C# that need to wait for a page to load or a certain element to render before continuing.
Related
I have a problem that my phantomjs loads one site too slow, always at least 60 seconds though on other sites like google.com it takes less than 1 second.
PhantomJSDriverService service = PhantomJSDriverService.CreateDefaultService();
service.IgnoreSslErrors = true;
service.LoadImages = false;
service.ProxyType = "none";
service.HideCommandPromptWindow = true;
using (IWebDriver driver = new PhantomJSDriver(service ))
{
driver.Navigate().GoToUrl("http://abc.xyz"); //blocks too long
...
}
Is there any way to force it finish loading after reaching some point so the script will continue?
I see what you are asking now. You have a long loading page that you want to stop after the relevant stuff loads. I run into this same issue with some of the sites that we have at work but I have not tried a programmatic solution. Sorry, I don't know phantomjs but I found some links that I think would be helpful.
The way I would approach it is to wait for the DOMContentLoaded event to fire and then send an ESC to the page. At least that's what I do manually to stop the long loading files that I don't care about so that the execution can continue.
I found this question How can I wait for the page to be ready in PhantomJS? Here's the relevant part:
var page = require('webpage').create();
var system = require('system');
page.onInitialized = function() {
page.onCallback = function(data) {
console.log('Main page is loaded and ready');
//Do whatever here
};
page.evaluate(function() {
document.addEventListener('DOMContentLoaded', function() {
window.callPhantom();
}, false);
console.log("Added listener to wait for page ready");
});
};
page.open('https://www.google.com', function(status) {});
Once you detect DOMContentLoaded, use sendkeys() to send the ESC key. I honestly don't know if this will work but it's where I would start. Hopefully it will get you started.
I've just found out the reasons why the phantomjs load so slow because the target web has too many extensions, ads... so I switch to chrome and use adblock like Running Selenium WebDriver using Python with extensions (.crx files)
This issue began when I switched from testing on the www website to my localhost version of it. Working in VS 2012, I will begin debugging so the localhost is active, detach the process so I can test on it, then run any test I like. For a very basic example:
[Test]
public void CanGoToHomePage()
{
Pages.HomePage.Goto();
Assert.IsTrue(Pages.HomePage.IsAt());
}
And the functions it references are here:
public class HomePage
{
const string Url = "http://localhost:3738";
const string HomepageTitle = "FunnelFire - Home Page";
public void Goto()
{
Browser.Goto(Url);
}
public bool IsAt()
{
return Browser.Title == HomepageTitle;
}
}
And the actual selenium code here:
public static class Browser
{
static IWebDriver webDriver = new FirefoxDriver();
public static void Goto(string url)
{
webDriver.Manage().Window.Maximize();
webDriver.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(10));
webDriver.Url = url;
}
}
Now the issue. The 10 second implicit wait that I added in Browser does successfully wait at most 10 seconds after loading a page to see if it can locate whatever information I want it to find, that is not the problem.
As I said earlier, after I switched to testing on localhost, suddenly I ran into a strange issue where a page would begin to load (i.e. screen still totally white, nothing finished) or even sometimes the next page would JUST barely finish loading and suddenly the test would just up and fail, pointing to the Assert of IsAt returning false even though the page it was loading was the correct one. I could run that test immediately once more and it would pass without a problem. Run it a third time and it could randomly fail again. I'm honestly not sure what is causing the issue and any help would be appreciated!
Implicit waits work only for finding elements. For waiting on the title of the page to be a certain value, you'll want to use an explicit wait. You can write your own version of this pattern, but in the .NET bindings, the WebDriver.Support.dll assembly has a WebDriverWait class to help with this. Its use would look something like this:
// WARNING! Untested code written from memory below. It has not
// been tested or even compiled in an IDE, so may be syntactically
// incorrect. The concept, however, should still be valid.
public void WaitForTitle(IWebDriver driver, string title, TimeSpan timeout)
{
WebDriverWait wait = new WebDriverWait(driver, timeout);
wait.Until((d) => { return d.Title == title; });
}
You could even modify your IsAt method to use this pattern, catching the WebDriverTimeoutException and returning false if the wait function times out.
I'm having a problem with SignalR and so far can not understand why.
I've wrote a hub for long order processing operation and noticed, that it updates progress ok within FireFox, but has a problem with Chrome.
So, I've wrote simple test hub to check what is going on:
public class SimpleHub: Hub
{
public void LongProcess()
{
System.Threading.Thread.Sleep(2000);
Clients.Caller.AddProgress("Step 1 of 5 has completed.");
System.Threading.Thread.Sleep(2000);
Clients.Caller.AddProgress("Step 2 of 5 has completed.");
System.Threading.Thread.Sleep(3000);
Clients.Caller.AddProgress("Step 3 of 5 has completed.");
System.Threading.Thread.Sleep(1000);
Clients.Caller.AddProgress("Step 4 of 5 has completed.");
System.Threading.Thread.Sleep(4000);
Clients.Caller.AddProgress("Step 5 of 5 has completed.", true);
}
}
What it does, it adds progress every several seconds. It works as supposed in clean project in both browsers - every couple seconds appears new progress message in browser.
But when I try it on real project, with Firefox it works ok, but in Chrome it looks like it completely blocks UI(doesn't even repaint Chrome console) and only when LongProcess finishes, it adds all progress messages.
So question is, what could be cause of this - may be some jQuery setting? Any ideas what to check?
Btw, I've tried longPolling and serverSendEvents (this was chosen auto by signalR in Chrome), same result on both.
Update: added client code:
var hub = $.connection.SimpleHub;
hub.client.AddProgress = function (progress) {
$("#placeOrderProgress").append('<li><span>' + progress + '</span><i></i></li>');
};
$.connection.hub
.start()
.done(function () {
hub.server.longProcess($('#checkoutForm').toJSON());
});
Found the answer.
We had in couple places where jQuery remote validation is used this piece of code (to avoid racing conditions):
$.ajaxSetup({ async : false });
So when I removed it, SignalR started working fine on Chrome. Interestingly enough, on FireFox it does not have any influence - it works with or without this line of code.
I have a web application that, under some conditions, pop up JavaScript alert()s that I need to react to in a WatiN test. Google pointed me at Handling alerts in WATIN from way back in 2007 that seemed promising, and I adapted the example code in that post into the following (anonymized):
private void MyAssert(IE browser, WatinHelper helper)
{
AlertDialogHandler alertDialogHandler = new AlertDialogHandler();
using (new UseDialogOnce(browser.DialogWatcher, alertDialogHandler))
{
// DoWrong() causes a JavaScript alert(); false means use nowait.
DoWrong(helper, false);
alertDialogHandler.WaitUntilExists(10 /*seconds*/);
if (!alertDialogHandler.Exists())
{
Assert.Fail("No JavaScript alert when it should have been there");
}
alertDialogHandler.OKButton.Click();
}
SecondAssert(browser);
}
However, while the alert is displayed virtually instantaneously (as it is supposed to) when DoWrong() is called, the call to alertDialogHandler.WaitUntilExists() eventually fails with a WatiNException: Dialog not available within 10 seconds... The only problem was that I could see that the dialog most definitely was up on the screen.
I'm probably missing something simple; can someone point me in the right direction please?
I have also tried the following two variants, and some variations of them, with no luck; I keep getting the same error.
AlertDialogHandler alertDialogHandler = new AlertDialogHandler();
DoWrong(helper, false);
System.Diagnostics.Stopwatch stopwatch = new System.Diagnostics.Stopwatch();
stopwatch.Start();
do
{
}
while (!alertDialogHandler.Exists() && stopwatch.Elapsed.TotalMilliseconds < 3000);
Assert.IsTrue(alertDialogHandler.Exists(), "No JavaScript alert when it should have been there");
alertDialogHandler.OKButton.Click();
SecondAssert(browser);
and
AlertDialogHandler alertDialogHandler = new AlertDialogHandler();
browser.DialogWatcher.Add(alertDialogHandler);
DoWrong(helper, false);
alertDialogHandler.WaitUntilExists();
alertDialogHandler.OKButton.Click();
browser.WaitForComplete();
Assert.IsFalse(alertDialogHandler.Exists());
SecondAssert(browser);
Yes, I know that code is getting a bit ugly, but right now I'm mostly trying to get it to work at all. If it sits for a few seconds cooking the CPU at 100% utilization because of the tight loop in my second attempt, but only does what I need it to (plain and simple, dismiss that alert()), it's OK.
This is an issue with WatiN and IE8 and the way IE8 changed the way it creates popups. The issue is fixed in the current code available at the Sourceforge SVN repository for the project. Get it, compile it and your problem is solved.
A new release of WatiN will be available before the end of this year.
HTH,
Jeroen
How can I solve this error?
"The requested resource is in use. (Exception from HRESULT: 0x800700AA)".
This appears while navigating to a different website using the WebBrowser control in C# .NET. Why?
The WebBrowser control is considered "in use" if either a navigation action is currently being processed, or any blocking dialog from the control is currently open (including context menu, Javascript alerts, NTLM login dialog, etc.). You can use the WebBrowser.IsBusy property to detect these states.
If due to a currently incomplete navigation action, you could try to stop the current navigation (if you indeed want to stop when the page is not completed loaded) or add the new navigation to a request queue and use a timer to wait until WebBrowser.IsBusy returns false.
If instead the busy state is due to one or more open blocking dialogs, you could do the same wait technique and perhaps Messagebox.Show() the user a message that pending navigation is delayed due to an open dialog window.
I had this same issue. Calling WebBrowser.Stop() did not help, and WebBrowser.IsBusy never became false.
It turns out that if the page creates any sort of dialog (alert() popups, javascript errors, NTLM login popups etc.) you can't navigate away from the page until the dialog is closed.
My solution was to prevent the dialogs from showing in the first place. Apparently preventing all of these popups is simple; just set
webBrowser.ScriptErrorsSuppressed = true;
bool go = false;
string SiteContent1 = string.Empty;
string SiteContent2 = string.Empty;
int index = 0;
WebBrowser wb = new WebBrowser();
void wb_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
try
{
if (go)
{
SiteContent2 = wb.DocumentText;
// Code to compare to contents of the webbrowser
index++;
go = false;
steps = 1;
}
if (!go)
{
if (index >= TotalSiteCount)
{
Stop();
}
else if (steps == 1)
{
wb.Navigate(UrltocompareList[index].Url1);
}
else if (steps == 2)
{
SiteContent1 = wb.DocumentText;
wb.Navigate(UrltocompareList[index].Url2);
go = true;
}
steps++;
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
UrltocompareList is a collection of 2 sites to compare.
TotalSiteCount is the number of items in UrltocompareList.
The form for this inherit IOleClientSite to remove media such as images, videos and no active X download to have a faster rendering time in webbrowser control.
I use this method instead of system.net.webclient to get the html of a webpage then compare them.
I got this error when it hits the wb.Navigate method.
An issue I ran into when running specflow tests with watin in windows 10 is that win10 by default uses MS Edge, so I had never opened IE, and when watin started it IE was stuck on the prompt for using default settings. Selecting options, closing browser and running tests again worked for me.
Just something to watch
This can be solved pretty easily.
This error occurs when the browser commits an action while he's already performing an action.
For example, you are navigating to some website while you rightclick in the web browser.
To solve this, I did the follow:
//if my webbrowser isn't performing any actions
if(!myWebBrowser.IsBusy)
{
//Navigate
myWebBrowser.Navigate("http://www.google.com");
}
First Try
1- Please Check Navigate URL's (if you check, please check again compiled folder)
2- Delete WebBrowser Control and Add New
Me forget copy original file App.Path + "\error.html" and see this problem.
Guarantee Method
I Fix This Error in VB6
Add WebBrowserControl wb(0) (Name wb , Index=0)
And Before Ever Navigate
For i = 1 To wb.UBound
Unload wb(i)
Next
Load wb(1)
wb(0).Visible = False
wb(1).Visible = true
wb(1).Navigate URL