Selinium: Wait function and if condition to repeat - c#

In my automation project.
Browser: Firefox
I would like add a wait function without any specific time
driver.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(7));
IWebElement query1 = driver.FindElement(By.("continue"));
How can do that?
Also to verify that if another page did not load then repeat the previous function. The reason why I am doing this is because sometimes browser does not change the page. It actually stays on that same page.
Besides this is below thing possible in Selenium
Clear Cache and Cookie for last hour
Opening URL in new tab (In already opened browser rather then opening new window)

One thing that has worked consistently for me (regarding waits) is used in the conductor framework..
Here's some pseudo-code you can attempt to recreate in C#:
while (size == 0) {
size = driver.findElements(by).size();
if (attempts == MAX_ATTEMPTS) fail(String.format("Could not find %s after %d seconds",
by.toString(),
MAX_ATTEMPTS));
attempts++;
try {
Thread.sleep(1000); // sleep for 1 second.
} catch (Exception x) {
fail("Failed due to an exception during Thread.sleep!");
x.printStackTrace();
}
}
basically this loops through the size of the selector passed, and will poll each second. Another way you can do it, is just by conditions.
Some more pseudo-code:
function waitForElement(element) {
Wait.Until(ExpectedConditions.elementIsClickable(element), 10.Seconds)
}
And to your questions -
Can Selenium...
Clear Cache and Cookie for last hour
Opening URL in new tab (In already opened browser rather then opening new window)
Opening URL in new tab (In already opened browser rather then opening new window)
If you write your tests cases correctly by making them independent of one-another and not re-using the same browser over and over, this happens automatically. When Selenium opens a new window, it starts fresh with an entirely fresh profile - meaning it has "nothing" in the cache from the start.
Selenium does not (and will never) know the difference between a tab and a window. To Selenium, it's just a handle.
Source:

Related

Selenium c# Error on switching to frame. Cannot evaluate expression because a native frame is on the top of the call stack

After login, I am switching to this frame where I am getting the following error:
"Cannot evaluate expression because a native frame is on the top of the call stack."
Here is the line of code:
Driver.SwitchTo().Frame("tabMain__ctl0_ult.org.com-Default");
The script has been executed several times and was working perfectly fine. But today all of a sudden I am getting this error. I looked into earlier posts but nothing helped. Please suggest any solutions.
Use this helper function to switch to your tab of choice. The index is determined by the order they have been created. So your your default tabIndex is 0, if you open a new tab/window it will have tabIndex 1 and so forth..
internal void SwitchToTab(int tabIndex) {
WebDriver.Instance.Wait(2);
var newTab = WebDriver.Instance.Driver().WindowHandles[tabIndex];
Instance.Driver().SwitchTo().Window(newTab);
WebDriver.Instance.Wait(2);
}
The waits are just for letting the new tab load. These waits are not good practice, so you should look for other methods for waiting for whatever element/state you are waiting for.
This is the same answer I already posted in this thread: C# Selenium - Can't Get Elements in New Tab

WebBrowser Control Loading Twice

Alrighty, guys. If you'd like to pull your hair out, the I've got a great problem for you. This problem seems very rare, but it effects my program on a few different sites that have pages that load content twice.
For instance: http://www.yelp.com/search?find_desc=donuts&find_loc=78664&ns=1#start=20
If you visit this site, you'll notice that it loads, then reloads different data. That's because there is a parameter in the URL that says start=20, so the results should start at #20 instead of #10. No matter what that is set to, Yelp loads the first 10 results. Not sure why they do this, but this is a prime example of what absolutely breaks my program. :(
Basically, whenever my program has a page that loads, it copies the source code to a string so it can display it somewhere else. It's not really important- What is important is that the string needs to actually have the last thing that is loaded in the page. Whenever a page loads, then loads again, I am not sure how to catch it and it ruins the program by exiting the while loop, and copying the source code into the string called source.
Here is a snippit of some code that I reproduced the problem with. When I attempt to use this in a new program, it will copy the source code for the first pages' results instead of what it is changed to.
GetSite = "http://www.yelp.com/search?find_desc=donuts&find_loc=78664&ns=1#start=20";
webBrowser9.Navigate(GetSite);
while (webBrowser9.ReadyState != WebBrowserReadyState.Complete)
{
p++;
if (p == 1000000)
{
MessageBox.Show("Timeout error. Click OK to skip." + Environment.NewLine + "This could crash the program, but maybe not.");
label15.Text = "Error Code: Timeout";
break;
}
Application.DoEvents();
}
mshtml.HTMLDocument objHtmlDoc = (mshtml.HTMLDocument)webBrowser9.Document.DomDocument;
Source = objHtmlDoc.documentElement.innerHTML;
Why do you wait in while loop for the browser to finish loading data?
Use DocumentCompleted event and you can remember the document's URL from there.

JavaScript window.open returns null sometimes

I am attempting maintenance on a system I did not write (and aren't we all?). It is written in C Sharp and JavaScript, with Telerik reports.
It has the following code included in JavaScript that runs when the user clicks a button to display a report in a separate window:
var oIframe = $("iframe id='idReportFrame' style='display:none' name='idReportFrame' src=''>");
oIframe.load(function() { parent.ViewReports(); });
oIframe.appendTo('body');
try
{
$('#idReportForm').attr('target', 'idReportFrame');
$('#idReportForm').submit();
}
catch (err) { // I did NOT write this
}
Then the load function:
function ViewReports()
{
var rptName = $("#ReportNameField").val();
if (rptName == '') { return false; }
var winOption = "fullscreen=no,height=" + $(window).height() + "left=0,directories=yes,titlebar=yes,toolbar=yes,location=yes,status=no,menubar=yes,scrollbars=no,resizable=no, top=0, width=" + $(window).width();
var win = window.open('#Url.Action("ReportView", "MyController")?pReportName=' + rptNameCode, 'Report', winOption);
win.focus();
return false;
}
When I execute this (in Chrome, at least), it does pop up the window and put the report in it. However, breakpoints in the c# code indicate that it is getting called 2 or 3 times. Breakpoints in the JavaScript and examination of the little log in the JavaScript debugging environment in Chrome show that the call to win.focus() fails once or twice before succeeding. It returns an undefined value, and then it appears that the first routine above is executed again.
I am inclined to think it some kind of timing issue, except that the window.open() call is supposed to be synchronous as far as I can tell, and I don't know why it would succeed sometimes and not others. There is a routine that gets executed on load of the window, perhaps that's somehow screwing up the return of the value from open().
I am not a JavaScript person much, as those of you that are can likely tell by this time. If there is something with the code I've put here that you can tell me is incorrect, that's great; what I'm more hopeful for is someone who can explain how the popup-report-in-frame is supposed to work. Hopefully I can do it without having to replace too much of the code I've got, as it is brittle and was not, shall we say, written with refactoring in mind.
From what I could find the window.open will return null when it fails to open. Something may be keeping the browser from opening additional windows a couple of times; maybe it is a popup blocker.
The actual loading of the url and creation of the window are done asynchronously.
https://developer.mozilla.org/en-US/docs/Web/API/Window.open
Popup blocking
In the past, evil sites abused popups a lot. A bad page could open
tons of popup windows with ads. So now most browsers try to block
popups and protect the user.
Most browsers block popups if they are called outside of
user-triggered event handlers like onclick.
For example:
// popup blocked
window.open('https://javascript.info');
// popup allowed
button.onclick = () => {
window.open('https://javascript.info');
};
Source: https://javascript.info/popup-windows
I just ran into this and it seems to be because I had a breakpoint on the line that calls window.open and was stepping through the code, in Chrome dev tools. This was extremely hit-and-miss and seemed to fail (return null, not open a window, whether one already existed or not) more times that it succeeded.
I read #Joshua's comment that the creation is done asynchronously, so I figured that forcing the code to 'stop' each time I step might be screwing things up somehow (though on a single line like var w = window.open(...) doesn't seem like this could happen).
So, I took out my breakpoint.. and everything started working perfectly!
I also took note of https://developer.mozilla.org/en-US/docs/Web/API/Window/open where they specify that if you are re-using a window variable and name (the second argumen to window.open) then a certain pattern of code is recommended. In my case, I am wanting to write HTML content to it, rather than give it a URL and let it async load the content over the network, and I may call the whole function repeatedly without regard for the user closing the window that pops up. So now I have something like this:
var win; // initialises to undefined
function openWindow() {
var head = '<html><head>...blahblah..</head>';
var content = '<h1>Amazing content<h1><p>Isn\'t it, though?</p>';
var footer = '</body></html>';
if (!win || win.closed) {
// window either never opened, or was open and has been closed.
win = window.open('about:blank', 'MyWindowName', 'width=100,height=100');
win.document.write(head + content + footer);
} else {
// window still exists from last time and has not been closed.
win.document.body.innerHTML = content;
}
}
I'm not convinced the write call should be given the full <html> header but this seems to work 100% for me.
[edit] I found that a Code Snippet on Stackoverflow has a some kind of security feature that prevents window.open, but this jsfiddle shows the code above working, with a tweak to show an incrementing counter to prove the content update is working as intended. https://jsfiddle.net/neekfenwick/h8em5kn6/3/
A bilt late but I think it's due to the window not beeing actually closed in js or maybe the memory pointer not being dereferenced.
I was having the same problem and I solved it by enclosing the call in a try finally block.
try {
if (!winRef || winRef.closed) {
winRef = window.open('', '', 'left=0,top=0,width=300,height=400,toolbar=0,scrollbars=0,status=0,dir=ltr');
} else {
winRef.focus();
}
winRef.document.open();
winRef.document.write(`
<html>
<head>
<link rel="stylesheet" href="/lib/bootstrap/dist/css/bootstrap.min.css">
</head>
<body>
${$(id).remove('.print-exclude').html()}
</body>
</html>
`);
winRef.document.close();
winRef.focus();
winRef.print();
} catch { }
finally {
if (winRef && !winRef.closed) winRef.close();
}

Page Load Timeout - Selenium Webdriver using C#

I am using Selenium 2.25 WebDriver
I'm having a issue with finding the elements on the page and some times my test cases able to find element and sometime the page is does not load and its due to page load and if i add this below line and it seems like working:
driver.Manage().Timeouts().SetPageLoadTimeout(TimeSpan.FromSeconds(2));
my question is, i dont want to have my code scatter with the above line of code, is there a way to make it centerlize in one place?
Any help would be greatly appreciated, thanks!
If you set the timeout once, it's set for the lifetime of the driver instance. You don't need to keep resetting it. You can set this immediately after creating the driver.
IWebDriver driver = new FirefoxDriver();
driver.Manage().Timeouts.SetPageLoadTimeout(TimeSpan.FromSeconds(2));
The only caveat for using this timeout is that not every browser may support it completely (IE does for sure, Firefox does too I think, but I don't think Chrome does).
You can try a workaround like this:
Observe the element that loads last in your page and find its id (or any other identifier). Then do something like this:
while (true)
{
try
{
IWebElement element = driver.FindElement(By.Id(...));
if (element.Displayed)
{
break;
}
}
catch (Exception)
{
continue;
}
}
This will keep looping till the element which is loaded last is displayed and breaks thereupon. The element not found exception is caught and loop is put into continuation till the element is not displayed.

How to fix "The requested resource is in use. (Exception from HRESULT: 0x800700AA)"

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

Categories