HTMLUnit HandleAlert and Javascript - javascript

I'm attempting to log on to a web page that I cannot guarantee has previously been logged out of.
If the prior logoff was not successful then a javascript alert pops up which needs to be acknowledged, then logging back on will work.
1: Initial Logon
2: Acknowledge javascript alert
3: Second Logon
I can verify that this works using a web browser. I can also verify that my handleAlert function works. However... upon attempting my second logon the javascript alert opens back up.
I'm not much of a javascript or web expert. I've tried clearing the cache, reloading the page, emptying the form and re-setting the credentials, and I cannot get around this issue.
Are there any suggestions for what I'm either doing wrong or what I can do to troubleshoot?
import com.gargoylesoftware.htmlunit.BrowserVersion
import com.gargoylesoftware.htmlunit.*
isError = 0
def login() {
cancelPage = cancelButton.click()
form = cancelPage.getFormByName("loginForm");
userField = form.getInputByName('j_username');
passwordField = form.getInputByName('j_password');
submitButton = page.getElementById("loginBtnId");
cancelButton = page.getElementById("cancelBtnId");
userField.setValueAttribute(username);
passwordField.setValueAttribute(password);
submitButton = page.getElementById("loginBtnId")
submitButton.click()
}
try
{
if (!url.startsWith("https"))
{
url = "https://" + url;
}
conn = new WebClient(javaScriptTimeout:10000)
conn.waitForBackgroundJavaScript(10000)
conn.waitForBackgroundJavaScriptStartingBefore(3000)
conn.getOptions().setJavaScriptEnabled(true);
conn.getOptions().setCssEnabled(false);
conn.setAlertHandler(new AlertHandler() {
void handleAlert(Page page,String errorMessage) {
println "\nIn handleAlert routine"
isError = isError + 1
if (isError == 1) {
login()
}
}
});
//get page
page = conn.getPage(url)
form = page.getFormByName("loginForm");
//get username and password form input fields and submit button
userField = form.getInputByName('j_username');
passwordField = form.getInputByName('j_password');
submitButton = page.getElementById("loginBtnId");
cancelButton = page.getElementById("cancelBtnId");
submitButton.click()
}
catch (Exception e)
{
println "\nFAIL - Unexpected exception: " + e.getMessage();
for (trace in e.getStackTrace())
{
println "\n\t" + trace;
}
}

The alert handler is only for the alert dialog - to get you informed that there is an alert. Do not call you login code from the alert handler, you have to place this code directly after the click call that opens the alert.
Some more hints:
Maybe this is not a alert box maybe it is a confirm box and you need a confirm handler.
Have a look at the javadoc of the handler classes.
Make yourself familiar with the page your are driving, many modern js libs do not use alert/confirm at all. They use some js/css magic to show something that looks like an dialog but is part of the page dom tree. This has to be handled with the usual HtmlUnit API.

Related

Contents of reports getting overwritten . Need to refresh parent page?

Please find the summary of my query:-
Lets say I start off at my homepage :- https://example.com//homepage
At the homepage I have links to certain documents .Once I click on one of the links it takes me to a page where I am asked to fill information and I can finally submit it.
I fill the information ,click on submit it takes me to final signature page where it asks me to enter my credentials so that it can post a timestamp saying that I have authored this document at this particular time.
Now I close this window and return to the homepage and click on another document link ,WITHOUT REFRESHING THE HOMEPAGE and follow the same steps. For some some odd reason when I complete this document I see that details mentioned in the first report have been leaked\merged\overwritten into this document.BIZZARE!!
So I did a bit of research(soul searching if you may say) and I found the reason could be because the session is still having the old data from the old document ?Basically what I tried was when I manually refreshed the homepage ,this issue didn't occur. So what I am trying to do now is ,every time I SIGN off the document, i.e reach the final signature page and click no 'SUBMIT' button , I want the homepage ,viz https://example.com/homepage to refresh.
Below is the snippet of JSCRIPT that is being called when I click on 'SUBMIT' button on the signature page:-(this is basically the onclick function for that 'SUBMIT' HTML function )
function completeForm(aForm)
{
var foundError = false;
if(validateRequiredInput(aForm.loginID) &
validateRequiredInput(aForm.password) )
{
document.getElementById("submitBtn").disabled = true;
// Modified to get the newWindow request Parameter by Nidhi Prakash Srivastava for clinSIGHT release 2.0.6
var newWindow = "";
if(aForm.getNewWindow != null)
{
newWindow=aForm.getNewWindow.value;
}
// Modified to get the newEPCWindow request Parameter by Nidhi Prakash Srivastava for clinSIGHT release 2.0.10
var newEPCWindow = "";
var newQCWindow = "";
if(aForm.getNewEPCWindow != null && aForm.action.indexOf("?") < 0)
{
newEPCWindow=aForm.getNewEPCWindow.value;
aForm.action = aForm.action+"?op=complete&newWindow="+newWindow+"&newEPCWindow="+newEPCWindow;
}else if(aForm.getNewQCWindow != null && aForm.action.indexOf("?") < 0){
newQCWindow=aForm.getNewQCWindow.value;
aForm.action = aForm.action+"?op=complete&newWindow="+newWindow+"&newQCWindow="+newQCWindow;
}else if(aForm.action.indexOf("?") < 0)
{
aForm.action = aForm.action+"?op=complete&newWindow="+newWindow;
}
onsubmitFormHandler();
aForm.submit();
}
How do I go about achieveing the refresh of the homepage from here? Is this even the right approach ? Any suggestions on the same ?

Groovy, HTMLUNIT and Javascript popup window

I am using htmlunit and groovy to perform a lot of web automation. I'm stuck when attempting to press the "OK" button on a javascript popup alert window (not a normal browser window). I've set up ConfirmHandler - I think correctly - but the button still is not being pressed.
This is what I have currently:
conn = new WebClient(javaScriptTimeout:1000)
conn.waitForBackgroundJavaScript(1000)
conn.getOptions().setJavaScriptEnabled(true);
conn.getOptions().setCssEnabled(false);
ConfirmHandler okayHandler = new ConfirmHandler() {
boolean handleConfirm(Page page,String message) {
return true
}
}
def page = conn.getPage(url)
def form = page.getFormByName("loginForm");
// code to login here - won't bore you with it
if (login failed) { // <-- this isn't the actual if statement, but need to remove for security purposes
println "\n\nNeed to hit the okayHandler here"
okayResult = conn.setConfirmHandler(okayHandler)
println "\n\nOkay Result: ${okayResult}"
}
The things I notice:
The okayHandler method seems to be run
The value of "okayResult" is null
I can verify manually that the actual button has not been pressed
So, either my ConfirmHandler is incorrect, I'm calling it incorrectly, or my understanding of the javascript alert window is off. My questions are:
What am I doing wrong with ConfirmHander?
Is there a better way to handle the javascript alert window? All I need to do is acknowledge it by pressing "ok".
==============
Here is my browser setup
public void setupBrowser() {
conn = new WebClient(javaScriptTimeout:1000)
conn.waitForBackgroundJavaScript(1000)
conn.getOptions().setJavaScriptEnabled(true);
conn.getOptions().setCssEnabled(false);
AlertHandler myAlertHandler = new AlertHandler() {
void handleAlert(Page page,String message) {
println "\n\nClosing login alert message"
}
}
}
Here is how I am attempting to handle the alert:
conn.myAlertHandler(handleAlert(resultPage,errorMessage))
And here is the error message:
FAIL - Unexpected exception: No signature of method: Groovy_charterLogin_Test.handleAlert() is applicable for argument types: (com.gargoylesoftware.htmlunit.html.HtmlPage, java.lang.String) values: [HtmlPage('pagestuffhere'),passedErrorMesageHere]
You have to set the confirm handler before the alert opens; in your case you can do this directly after the construction and make sure with the real browser you are facing a confirm dialog (window.confirm(....)).

Why Page is not redirected using javascript on using window.location and window.location.href

I am using a login system for my website.
What I am doing is that when the user clicks the submit button an ajax request is being executed to target php script which logs in the user and if user is logged in successfully then echo's back the message "login_successful" to the ajax request. By using if statement I check whether the message is "login_successful" else display the error.
If the message is "login_successful" the script redirect the user to the new page 'user.php' by using window.location = 'user.php';
//I have also tried this.
window.location.href = 'user.php';
But it doesn't work It simply stays on the login page and nothing happens.
but when i check the page source after logging in but no redirection takes place then i got a surprise that the source of the page is for user.php instead of login.php. Somehow window.location hasn't redirected the page but bring the source of user.php to login.php. It's all messed up and I couldn't solve the problem.
Here is the login function which performs the ajax request and then redirect the user-
function login()
{
var e = _("email").value;// Grab the email input by the user.
var p = _("password").value;// Grab the password input by the user.
if(e === "" || p === "")// Check if they are empty.
{
_("status").innerHTML = "Fill out all the form data";//Display error message if fields are empty.
}
else
{
_("loginbtn").style.display = "none";// Hide the login button
_("status").innerHTML = 'please wait ...';//Tell the user to wait while the script works.
// Below id another function which is defined in other js file.
var ajax = ajaxObj("POST", "login.php"); //start the ajax request.
ajax.onreadystatechange = function()// Wait for the request to be complete
{
if(ajaxReturn(ajax) === true) // Ensures if the response is recieved
{
var response = ajax.responseText;// Put the response in a variable
if(response === 'login_successful')// Check if user is logged in succesfully.
{
window.location = 'user.php';//Redirect the user to the new page.(Not working)
}
else
{
_('status').innerHTML = response;// Display the response
_("loginbtn").style.display = "block";// Display the login button
}
}
};
ajax.send("e="+e+"&p="+p);
}
}
I am using the latest version of chrome on a 64 bit windows machine.
Update
OK guys I have verified that the response via php script is 'login_successful' and it doesn't contains any line so that we can trim on it.
check the result by alert in between response condition & use
window.location.href='correctfilepath.php';
correct path of file to be redirected. Check your user.php also as it will not print anything if it will have some error in code
if you use location i prefer to use a absolute path. Maybe this is your problem and a redirect will be working with this. For example:
location.href = '/user.php';
If you want to redirect to a url do it like this:
location.href = '//www.google.com';
(it will automatically use http or https based on the current scheme.
Try setting the full URL for redirection
window.location = window.location.protocol + "//" + window.location.host + "/user.php"
instead of window.location = 'user.php';
Edited:
window.location = "//" + window.location.host + "/user.php"
Javascript redirection works without the protocol (http or https) also.
if(response === 'login_successful')// Check if user is logged in succesfully.
{
window.location = 'user.php';//Redirect the user to the new page.(Not working)
}
else
{
_('status').innerHTML = response;// Display the response
_("loginbtn").style.display = "block";// Display the login button
}
In the else block you had given _('status').innerHTML = response; check that block is executing or not if its is executing then try to change the (=== as == )in the if condition hope it may work.

ReportViewer Web Form causes page to hang

I was asked to take a look at what should be a simple problem with one of our web pages for a small dashboard web app. This app just shows some basic state info for underlying backend apps which I work heavily on. The issues is as follows:
On a page where a user can input parameters and request to view a report with the given user input, a button invokes a JS function which opens a new page in the browser to show the rendered report. The code looks like this:
$('#btnShowReport').click(function () {
document.getElementById("Error").innerHTML = "";
var exists = CheckSession();
if (exists) {
window.open('<%=Url.Content("~/Reports/Launch.aspx?Report=Short&Area=1") %>');
}
});
The page that is then opened has the following code which is called from Page_Load:
rptViewer.ProcessingMode = ProcessingMode.Remote
rptViewer.AsyncRendering = True
rptViewer.ServerReport.Timeout = CInt(WebConfigurationManager.AppSettings("ReportTimeout")) * 60000
rptViewer.ServerReport.ReportServerUrl = New Uri(My.Settings.ReportURL)
rptViewer.ServerReport.ReportPath = "/" & My.Settings.ReportPath & "/" & Request("Report")
'Set the report to use the credentials from web.config
rptViewer.ServerReport.ReportServerCredentials = New SQLReportCredentials(My.Settings.ReportServerUser, My.Settings.ReportServerPassword, My.Settings.ReportServerDomain)
Dim myCredentials As New Microsoft.Reporting.WebForms.DataSourceCredentials
myCredentials.Name = My.Settings.ReportDataSource
myCredentials.UserId = My.Settings.DatabaseUser
myCredentials.Password = My.Settings.DatabasePassword
rptViewer.ServerReport.SetDataSourceCredentials(New Microsoft.Reporting.WebForms.DataSourceCredentials(0) {myCredentials})
rptViewer.ServerReport.SetParameters(parameters)
rptViewer.ServerReport.Refresh()
I have omitted some code which builds up the parameters for the report, but I doubt any of that is relevant.
The problem is that, when the user clicks the show report button, and this new page opens up, depending on the types of parameters they use the report could take quite some time to render, and in the mean time, the original page becomes completely unresponsive. The moment the report page actually renders, the main page begins functioning again. Where should I start (google keywords, ReportViewer properties, etc) if I want to fix this behavior such that the other page can load asynchronously without affecting the main page?
Edit -
I tried doing the follow, which was in a linked answer in a comment here:
$.ajax({
context: document.body,
async: true, //NOTE THIS
success: function () {
window.open(Address);
}
});
this replaced the window.open call. This seems to work, but when I check out the documentation, trying to understand what this is doing I found this:
The .context property was deprecated in jQuery 1.10 and is only maintained to the extent needed for supporting .live() in the jQuery Migrate plugin. It may be removed without notice in a future version.
I removed the context property entirely and it didnt seem to affect the code at all... Is it ok to use this ajax call in this way to open up the other window, or is there a better approach?
Using a timeout should open the window without blocking your main page
$('#btnShowReport').click(function () {
document.getElementById("Error").innerHTML = "";
var exists = CheckSession();
if (exists) {
setTimeout(function() {
window.open('<%=Url.Content("~/Reports/Launch.aspx?Report=Short&Area=1") %>');
}, 0);
}
});
This is a long shot, but have you tried opening the window with a blank URL first, and subsequently changing the location?
$("#btnShowReport").click(function(){
If (CheckSession()) {
var pop = window.open ('', 'showReport');
pop = window.open ('<%=Url.Content("~/Reports/Launch.aspx?Report=Short&Area=1") %>', 'showReport');
}
})
use
`$('#btnShowReport').click(function () {
document.getElementById("Error").innerHTML = "";
var exists = CheckSession();
if (exists) {
window.location.href='<%=Url.Content("~/Reports/Launch.aspx?Report=Short&Area=1") %>';
}
});`
it will work.

Intercept page exit event

When editing a page within my system, a user might decide to navigate to another website and in doing so could lose all the edits they have not saved.
I would like to intercept any attempt to go to another page and prompt the user to be sure they want this to happen since they could potentially lose their current work.
Gmail does this in a very similar way. For example, compose a new email, start typing into the message body and enter a new location in the address bar (say twitter.com or something). It will prompt asking "Are you sure?"
Ideas how to replicate this? I'm targeting IE8, but would like to be compatible with Firefox and Chrome also.
Similar to Ghommey's answer, but this also supports old versions of IE and Firefox.
window.onbeforeunload = function (e) {
var message = "Your confirmation message goes here.",
e = e || window.event;
// For IE and Firefox
if (e) {
e.returnValue = message;
}
// For Safari
return message;
};
See this article.
The feature you are looking for is the onbeforeunload
sample code:
<script language="JavaScript">
window.onbeforeunload = confirmExit;
function confirmExit()
{
return "You have attempted to leave this page. If you have made any changes to the fields without clicking the Save button, your changes will be lost. Are you sure you want to exit this page?";
}
</script>
Instead of an annoying confirmation popup, it would be nice to delay leaving just a bit (matter of milliseconds) to manage successfully posting the unsaved data to the server, which I managed for my site using writing dummy text to the console like this:
window.onbeforeunload=function(e){
// only take action (iterate) if my SCHEDULED_REQUEST object contains data
for (var key in SCHEDULED_REQUEST){
postRequest(SCHEDULED_REQUEST); // post and empty SCHEDULED_REQUEST object
for (var i=0;i<1000;i++){
// do something unnoticable but time consuming like writing a lot to console
console.log('buying some time to finish saving data');
};
break;
};
}; // no return string --> user will leave as normal but data is send to server
Edit:
See also Synchronous_AJAX and how to do that with jquery
I have users who have not been completing all required data.
<cfset unloadCheck=0>//a ColdFusion precheck in my page generation to see if unload check is needed
var erMsg="";
$(document).ready(function(){
<cfif q.myData eq "">
<cfset unloadCheck=1>
$("#myInput").change(function(){
verify(); //function elsewhere that checks all fields and populates erMsg with error messages for any fail(s)
if(erMsg=="") window.onbeforeunload = null; //all OK so let them pass
else window.onbeforeunload = confirmExit(); //borrowed from Jantimon above;
});
});
<cfif unloadCheck><!--- if any are outstanding, set the error message and the unload alert --->
verify();
window.onbeforeunload = confirmExit;
function confirmExit() {return "Data is incomplete for this Case:"+erMsg;}
</cfif>

Categories

Resources