I am automating some tests for a webapp written in ASP.NET MVC5 that also uses jQuery. I've been looking around for options on handling an alert confirmation box while using Selenium in IE.
I need to confirm the message on the box, but I do not need to click anything on the dialog. Here is what I have now:
public bool IsAlertPresentAndCorrect(string Message)
{
try
{
WebDriverWait Wait = new WebDriverWait(Driver, System.TimeSpan.FromSeconds(10));
Wait.Until(ExpectedConditions.AlertIsPresent());
ReadOnlyCollection<string> Handles = Driver.WindowHandles;
string ToUse = "";
foreach (string Handle in Handles)
{
if (!Driver.CurrentWindowHandle.Equals(Handle))
{
ToUse = Handle;
}
}
IAlert Alert = (IAlert) Driver.SwitchTo().Window(ToUse);
return Alert.Text.Equals(Message);
}
catch (NoAlertPresentException)
{
return false;
}
finally
{
_driver.SwitchTo().DefaultContent();
}
}
I have also tried IAlert Alert = Driver.SwitchTo().Alert() and IAlert Alert = Driver.SwitchTo().ActiveElement() in place of getting the window handle but they are not working either.
The problem has been the exact same no matter what code I use: OpenQA.Selenium.UnhandledAlertException: Modal dialog present.
Any help would be greatly appreciated
Alert in Chrome:
Alert in IE:
In case of alert you don't necessarily have to switch back to the window handle. You can simply switch to alert, perform necessary operation, close the alert.
I modified your code a bit to fetch the alert text in a variable, close the alert pop-up then compare the alert text with the message passed in parameter and return bool value.
public bool IsAlertPresentAndCorrect(string Message)
{
try
{
WebDriverWait Wait = new WebDriverWait(Driver, System.TimeSpan.FromSeconds(10));
Wait.Until(ExpectedConditions.AlertIsPresent());
string alertText = Driver.SwitchTo().Alert().Text;
Driver.SwitchTo().Alert().Accept();
return alertText.Equals(Message);
}
catch (NoAlertPresentException)
{
return false;
}
}
Related
I'm developing an automation testing project on http://the-internet.herokuapp.com/ website using C# and NUnit.
While testing the presence of the below alert on the page http://the-internet.herokuapp.com/basic_auth, the web driver is not able to detect the alert on the page though it is present. It is continuously giving NoAlertPresentException.
I'm using the code given below to detect the alert
Internal WebDriver wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10));
internal void WaitUntilAlertIsVisible()
{
try
{
wait.Until(SeleniumExtras.WaitHelpers.ExpectedConditions.AlertIsPresent());
}
catch(WebDriverTimeoutException)
{}
}
internal bool IsAlertPresent()
{
try
{
WaitUntilAlertIsVisible();
driver.SwitchTo().Alert();
return true;
}
catch(NoAlertPresentException)
{
return false;
}
}
Please help!
So the application I'm making needs to handle authentication request sent by the webpage in order to log in and use that page. To achieve this, I found after some research that I should implement the IRequestHandler interface of CefSharp and use it method called "GetAuthCredentials" to open a dialog and request the username and password from here.
This all seems to work fine and I am able to login to the page with the correct credentials. However when I try to close my entire application after logging into a website via this method, the application freezes and refuses to close after that. It does seem to close the browser control on the form but not the form itself.
I can close the application normally without any issues when I do not have to use the log in, but whenever I do the scenario above happens and I'm unable to close it except for ending the task within Taskmanager.
I suspect the "GetAuthCredentials" is never truly handled or it keeps requesting the dialog over and over again, resulting in an infinite loop that keeps my application from closing. However I have not been able to find the root of this problem.
The Requesthandler implementation with "GetAuthCredentials":
class RequestEventHandler : IRequestHandler
{
bool IRequestHandler.GetAuthCredentials(IWebBrowser browserControl, IBrowser browser, IFrame frame, bool isProxy, string host, int port, string realm, string scheme, IAuthCallback callback)
{
bool handled = false;
AuthenticationDialog dlg = new AuthenticationDialog(host);
dlg.ShowDialog();
if (dlg.DialogResult == System.Windows.Forms.DialogResult.OK)
{
callback.Continue(dlg.UserName, dlg.Password);
handled = true;
}
return handled;
}
The Dialogform it opens:
public partial class AuthenticationDialog : Form
{
internal string UserName { get; set; }
internal string Password { get; set; }
public AuthenticationDialog(string Hostname)
{
InitializeComponent();
Lbl_WebUrl.Text = Hostname;
}
private void Btn_SignIn_Click(object sender, EventArgs e)
{
if(Tbx_Username.TextLength > 0 && Tbx_Password.TextLength > 0)
{
UserName = Tbx_Username.Text;
Password = Tbx_Password.Text;
}
else if (Tbx_Username.TextLength == 0 && Tbx_Password.TextLength > 0)
{
Lbl_Error.Text = SetError(1);
}
else if (Tbx_Username.TextLength > 0 && Tbx_Password.TextLength == 0)
{
Lbl_Error.Text = SetError(2);
}
else
{
Lbl_Error.Text = SetError(0);
}
}
The sign-in button here has it's Dialog_Result property set to Dialogresult.OK
The Method that closes the application: (Located in the mainform that contains the browser)
private void btn_ApplicationClose_Click(object sender, EventArgs e)
{
browser.Dispose();
Cef.Shutdown();
Application.Exit();
}
Any suggestion or fix for this problem would be much appreciated, this problem has been grinding my gears for a couple of days now.
Update:
With the advice of #amaitland I've opened the dialog on the UI thread using the code below:
bool IRequestHandler.GetAuthCredentials(IWebBrowser browserControl, IBrowser browser, IFrame frame, bool isProxy, string host, int port, string realm, string scheme, IAuthCallback callback)
{
bool handled = false;
ChromiumWebBrowser b = browserControl as ChromiumWebBrowser;
b.BeginInvoke((MethodInvoker)delegate
{
AuthenticationDialog dlg = new AuthenticationDialog(host);
dlg.ShowDialog();
if (dlg.DialogResult == System.Windows.Forms.DialogResult.OK)
{
callback.Continue(dlg.UserName, dlg.Password);
handled = true;
}
});
return handled;
This seems to work and let's my application close when it has used a log-in, however now it seems to be unable to process the login information. When logging in, it closes the dialog and doesn't seem to do anything with the credentials I've given it.
Did I miss something or is my implementation wrong?
So with some helpfull suggestions of #amaitland, I've been able to fix my issue, resulting in the code below for the GetAuthCredentials method of the RequestHandler.
bool IRequestHandler.GetAuthCredentials(IWebBrowser browserControl, IBrowser browser, IFrame frame, bool isProxy, string host, int port, string realm, string scheme, IAuthCallback callback)
{
ChromiumWebBrowser b = browserControl as ChromiumWebBrowser; //casts the given browsercontrol as chromiumwebbrowser, to acces the .beginInvoke method
b.BeginInvoke((MethodInvoker)delegate
{
//creates an instance of the authentication dialog to get the user credentials
AuthenticationDialog dlg = new AuthenticationDialog(host);
dlg.ShowDialog();
if (dlg.DialogResult == System.Windows.Forms.DialogResult.OK) //if the sign-in button is clicked
{
callback.Continue(dlg.UserName, dlg.Password);
}
else // if the close or cancel button on field is clicked
{
callback.Cancel();
}
});
return true;
}
Here I opened the dialog on the UI thread instead of the main thread with .BeginInvoke() and made sure the request would pas as handled when used
This fixes all of the issues I had with it, and it might give an example to implement your own RequestHandler for GetAuthCredentials.
I am new to Selenium, and I am trying to verify that if user has successfully landed on the Home page or not. Here is the snippet:
LoginPage.GoTo();//Goes Well
LoginPage.LoginAs("UserName").WithPassword("Password").Login();//goes Well
Assert.IsTrue(HomePage.IsAt, "Failed to login");//Below is the implementation of HomePAge.IsAt
public static bool IsAt
{
get
{
var wait = new WebDriverWait(Driver.Instance, TimeSpan.FromSeconds(5));
wait.Until(x => x.SwitchTo().ActiveElement().GetAttribute("id") == "IDHere");//Here the exception is occuring.
}
var homePage = Driver().Instance.FindElement(By.Id("IDHere"));
// return true or False;
Can someone please help?
When an alert is present on your browser, it prevents you from actually doing ANYTHING else.
FYI, when I try to run my application, a window authentication pop up
comes and after that Page loads.
Well, yeah. That's the alert part from "Unhandled Alert Exception". The unhandled part, is because you didn't use any line of code to show your program how to handle the alert. Selenium goes to login page. Then tries to run this line x.SwitchTo().ActiveElement().GetAttribute("id") == "IDHere", but there is an alert on your page that prevents you from doing anything.
You have to actually try to handle it (close it or accept the message) and THEN do anything else.
It might be considered a good practice to wait for your alert to appear (since it might not appear instantly), and then, after (e.g.) 5 seconds, if there is no alert, run your code.
Try the code below to see if it resolves your problem:
public static boid WaitForAlert(bool accept)
{
//Initialize your wait.
WebDriverWait wait = new WebDriverWait(Driver.Instance, TimeSpan.FromSeconds(5));
//Wait for alert
try
{
wait.Until(ExpectedConditions.AlertIsPresent());
if (accept)
{
Driver().Instance.SwitchTo().Alert().Accept();
}
else
{
Driver().Instance.SwitchTo().Alert().Dismiss();
}
}
catch (WebDriverTimeoutException) { /*Alert did not appear, do nothing*/ }
}
And then do:
LoginPage.GoTo();
LoginPage.LoginAs("UserName").WithPassword("Password").Login();
LoginPage.WaitForAlert(true); //True to accept the alert
Assert.IsTrue(HomePage.IsAt, "Failed to login");
I am really sorry if this question has already been asked/answered. but I could not find it.
Please excuse my ignorance as I am new to WebDriver.
When the page is initially loads, it displays a LOADING DIV untill all the data is loaded. How can I wait until this div is hidden before I proceed with other actions on page elements?
I am trying to know as follows:
public static void waitForPageLoad(string ID, IWebDriver driver)
{
WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10));
IWebElement myDynamicElement = wait.Until<IWebElement>((d) =>
{
return d.FindElement(By.Id(ID));
});
}
I pass the Id of SOME OTHER ELEMENT to this function which I will use when the LOADING DIV disappears. It returns the wrong result as the element by ID is actually present/loaded but is behind the grey DIV that shows "Loading... Please wait" message. So this does not work. I would like to know when that LOADING div disappears.
Any help is greatly appreciated.
By waiting on a bool value instead of IWebElement, the .NET WebDriverWait class will wait until a value of true is returned. Given that, how about trying something like the following:
public static void WaitForElementToNotExist(string ID, IWebDriver driver)
{
WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10));
wait.Until<bool>((d) =>
{
try
{
// If the find succeeds, the element exists, and
// we want the element to *not* exist, so we want
// to return true when the find throws an exception.
IWebElement element = d.FindElement(By.Id(ID));
return false;
}
catch (NoSuchElementException)
{
return true;
}
});
}
Note that this is the appropriate pattern if the element you're looking for is actually removed from the DOM. If, on the other hand, the "waiting" element is always present in the DOM, but just made visible/invisible as required by the JavaScript framework your app is using, then the code is a little simpler, and looks something like this:
public static void WaitForElementInvisible(string ID, IWebDriver driver)
{
WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10));
wait.Until<bool>((d) =>
{
try
{
IWebElement element = d.FindElement(By.Id(ID));
return !element.Displayed;
}
catch (NoSuchElementException)
{
// If the find fails, the element exists, and
// by definition, cannot then be visible.
return true;
}
});
}
I have written an nUnit test using selenium in c#.
All was going well until I have to confirm a JS confirm box.
here is the code I am using:
this.driver.FindElement(By.Id("submitButton")).Click();
this.driver.SwitchTo().Alert().Accept();
The confirm box appears after the submit button. The confirm appears and then disappears immediately but the form does not submit. The behaviour is the same regardless of the accept() line above.
I am using Firefox v15.0.1 and selenium v2.24
I have tried putting a Thread.Sleep between the submit click and the confirm accept.
Everything I have read has said that the selenium driver will automatically send a confirm OK, but something else seems to be happening.
in this issue i would try to verify confirm box presence.
it be something like:
this.driver.FindElement(By.Id("submitButton")).Click();
boolean presentFlag = false;
try {
// Check the presence of alert
Alert alert = driver.switchTo().alert();
// Alert present; set the flag
presentFlag = true;
// if present consume the alert
alert.accept();
} catch (NoAlertPresentException ex) {
// Alert not present
ex.printStackTrace();
}
return presentFlag;
}
then if doen't work. try to debug step by step.
some additional info concerning alert ( confirm boxes) handle in selenium here
hope this somehow helps you
You just need:
IAlert alert = driver.SwitchTo().Alert();
alert.Accept();
The end point I am testing does not have reliable response times and the only way I could get it to always work with webdriver selenium-dotnet-2.33.0 (.NET4) using Firefox was by doing the following:
private void acceptAlert(){
string alertText = "";
IAlert alert = null;
while (alertText.Equals("")){
if (alert == null)
{
try{
alert = driver.SwitchTo().Alert();
}
catch{
System.Threading.Thread.Sleep(50); }
}
else{
try{
alert.Accept();
alertText = alert.Text;
}
catch (Exception ex){
if (ex.Message.Equals("No alert is present")) alertText = "Already Accepted";
else System.Threading.Thread.Sleep(50);
}
}
}
}