Alert Problem
jiangjiangzhouzhou opened this issue · 23 comments
Driving a desktop Windows Chrome browser, when an "OK / Cancel" alert box is popped up,
the alert flashes, disappears, and the browser test script immediately fails with an exception:
Unhandled alert: alert must be confirmed or dismissed before test can continue.
I am using hsac-fitnesse-fixtures.version: 5.2.12.
Thanks!
JavaScript alerts are a bit special, they block all interactions with the browser. So you must handle them in your test explicitly. Optionally you can check the text they display but then you must indicate whether the test should choose ok or cancel. You do that by either confirm alert
or dismiss alert
. Are you doing that?
See also: HsacAcceptanceTests.SlimTests.BrowserTest.AlertHandlingTest
I am doing that. The test stops because of the Unhandled alert. It doesn't run any code after the click action.
The test click a button, then an "OK / Cancel" alert box is popped up.
And what is on the line after the click? The test must do a dismiss/confirm before it ends...
Can you share you test page, and maybe a sample HTML page to reproduce the problem? The acceptance test seems to show that alert handling in general is working...
Aha a custom subclass...
I believe there is some custom handling for alerts via an 'interceptor', maybe that is what is causing you problems. I don't have the code open right now but maybe this pointer can already help you debug it yourself?
Otherwise can you share some HTML and the custom code to see whether it can be reproduced outside your environment?
Unfortunately, it is unlikely to reproduce the issue outside of my environment. Thanks for your help. Would you mind explaining a little more about the "interceptor"? Thanks again!
I'm sorry I was wrong there is no 'interceptor' dealing with the alerts. I haven't looked at that part of the code for a long time and I thought it was there but now I can't find it. (I now believe I got mixed up with some interceptors I once wrote that had to check for alerts before they tried to do their thing, because they wouldn't work if an alert was present)
Only in exception handling (#handleException()
) do I see some the special handling of alerts, that is the code producing the message you see. Maybe you can place a breakpoint there and see what exactly is throwing/causing the exception you see?
Looking at your wiki and code I get the impression either the alert is triggered by something in your #shouldOperationBeSkipped()
method or by the page itself immediately after 'Submit' becomes visible. It doesn't look like the 'Submit' is clicked and then the alert is shown. What happens if you move 'confirm alert' one line up?
(In general the 'wait for 2 seconds' line should not be needed, 'wait for visible' already waits, a configured amount of time and even 'click' itself also waits if no element with the text 'Submit' can be found. Is you app really that slow that the explicit waits are needed? in that case I recommend you just configure a longer generic wait time. Or is 'Submit' already on the screen before the 2 second wait and you really must wait at least 2 seconds? A 'wait for visible' should really only be needed if what you wait for is different than what you interact with in the next line, given that 'click' also already waits.)
I confirmed that the alert will only be shown after the button is clicked. I tried to remove click the button, it then showed a NullPointerException, like the photo. And I tried to create a new method to click the button and then confirm alert. I tried to catch the exception while the button is clicked. But somehow element.click() triggered the exception without getting caught by try catch.
The method i created is below:
@WaitUntil(TimeoutPolicy.RETURN_FALSE)
public boolean confirm(String place) {
boolean result = false;
place = cleanupValue(place);
try {
WebElement element = getElementToClick(place, null);
element.click();
Alert alert = super.getAlert();
if (alert != null) {
alert.accept();
onAlertHandled(true);
result = true;
}
} catch (WebDriverException e) {
if (!clickExceptionIsAboutHiddenByOtherElement(e) && !(e instanceof UnhandledAlertException)) {
//throw e;
}
}
return result;
}
So the screenshot is from the situation where you removed the line with element.click()
from the code above? Or from exactly the code above?
Which line is line 1344 that is reported in the stack trace?
1344 is the confirm method above. The screen shot is where I remove click Submit, not element.click().
What does the rest of the method look like? To me it looks like the last }
in your comment closes the catch
block not the method.
The only thing I can think of is that you for some reason return null
from the method that should then be 'autoboxed' to become a boolean
, but null
cannot be made a boolean
so the error is thrown...
That is all of the method. I missed a } in the comment. That is not the reason it throws an error.
Then the exception must be from the element.click();
line, which would happen since you are looking for an element named 'alert' in the line above and I assume that does not exist. I would have expected its line number in the stack trace. Strange.
What happens when you remove the element.click()
from your method (or just change the row in your table to |confirm alert|
instead of |confirm|alert|
)?
The method is supposed to do click the button and then confirm the alert. If I remove the element.click(), then Submit button won't be clicked and no alert pop up. But I need to click the button to save the changes I make in previous steps.
But then the wiki should have |confirm|Submit|
, right (if the button's text is 'Submit')?
I see that your method only returns true
if the alert is present. Could it be that:
- the method is called, 'Submit' is clicked
- the alert does not show immediately (some Javascript is processing and the alert is shown when it is done) so the call to 'super.getAlert()
returns
null` - the
confirm
method completes and returnsfalse
- my fixtures see that
false
is returned and do a retry (because of the@WaitUntil
annotation) - the method is called but now the alert is shown on the page and therefore
getElementToClick()
orelement.click()
throw the exception
What happens if you remove the WaitUntil
annotation, or make the method return true
when element
is not null
, or start the method with a getAlert()
and if that returns an alert immediately confirm it?
You're right. I'm just struggling to see whether I can help see whether the issue comes from.
Does changing the catch
from WebDriverException
to Exception
and logging the stack trace shed any new light?
I would expect you would be able to see what is going on by stepping through the code with a debugger. I assume you tried that, but it didn't help?
I don't think I can help you much further without a way to reproduce the problem in my environment...
I will keep trying. thank you very much. Changing exception type of catch doesn't really make a difference. Somehow, the exception can't be caught by the try catch.
I have tried debugged it. I set the break point at Alert alert = super.getAlert(), then it didn't throw any exception. And the test passed. Do you have any idea about this situation?
I added waitSeconds(2) before Alert alert = super.getAlert(), it doesn't throw any exception anymore.