I am trying to click an accept terms checkbox while signing up for an account in selenium. My code seems to work, but it only works on some of my customers computers. On those who it doesn't work, it throws a staleelementexception. I have looked online to find a way to handle it such as
bool result = false;
int attempts = 0;
Thread.Sleep(500);
while (attempts < 100)
{
Thread.Sleep(700);
try
{
driver.Navigate().Refresh();
IJavaScriptExecutor javascriptExecutor = (IJavaScriptExecutor)driver;
Actions action = new Actions(driver);
IWebElement db = driver.FindElement(By.XPath("/html/body/div[1]/div/div[2]/form/div[1]/label/span[2]"));
action.MoveToElement(db).Build().Perform();
javascriptExecutor.ExecuteScript("arguments[0].click();", db);
result = true;
break;
}
catch (WebDriverException ee)
{}
attempts++;
}
nextPage(driver, wait);
I have also tried just clicking on it with the driver and clicking with actions, but nothing seems to be working for certain users. I am at the point of not knowing the solution or not knowing what else I can do.
UPDATE 1:
While I mentioned this in the comments, I still do receive a stale element, but I seem to of found the cause. When using specific country proxies, it seems that this is thrown. Now the element is still there, but why would the proxies cause this to happen?
A stale element usually means the DOM changed from the moment you found the element. There are a few things you can try:
Inspect the page and try to determine what is changing for those users. Maybe MoveToElement triggers a tooltip or some classes to change. If you can identify such change you can wait for it to be done and then get the element
Try using fluent waits as explained here
Try clicking the element as soon as it is identified driver.findElement(by.xpath(xpath)).click();
Note: The JavaScript click that you are using in the snippet works well for CLickIntercepted exceptions, not so much for StaleElements. The element will be stale regardless on how you click it
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:
I have a test case that is uploading a file and I am guessing I need a while loop to determine when the upload is complete.
There is an xpath //div[#class='media-upload-progress finished'] that appears when the file is finished or //div[#class='media-upload-progress uploading'] when the file is uploading.
I thought I could do something with a while loop and a SeleniumDriver.IsElementPresent but I have not been able to figure it out.
Any ideas?
Thanks for the help!
I would suggest you you give DefaultWait a try. PollingInterval would really help you since the finished element won't present unless the file is completely uploaded. The following code should poll the dom in every 100 ms and look for the intended element.
By bySelector = By.XPath("//div[#class='media-upload-progress finished']");
DefaultWait<IWebDriver> wait = new DefaultWait<IWebDriver>(driver);
wait.Timeout = TimeSpan.FromSeconds(1); // increase the timeout as needed
wait.PollingInterval = TimeSpan.FromMilliseconds(100);
wait.IgnoreExceptionTypes(typeof(NoSuchElementException));
//Add more typrof() exceptions as needed
IWebElement element = wait.Until<IWebElement>((d) =>
{
return d.FindElement(bySelector );
});
Disclaimer: I have never personally implemented this. So this code is entirely untested from my side. But, theoretically this should solve the issue you are having
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.
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();
}