Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Phantomjs and HTML 5 fire click event and submit form fails

I'm trying to create a phantom script to automate testing of the following form:

https://travel.tescobank.com/

My script completes the required fields correctly and then clicks the button that should submit the form, unfortunately no matter what I have tried it won't submit the form and display the next page.

I've confirmed that the click on the button is firing, as without completing the mandatory fields, I see in a screenshot of the page that the validation has fired. (see screenshot attached)

I've commented below all the click/submit options that I've tried and the one that appears to trigger the form validation but doesn't submit the form and display the next page.

var page = require('webpage').create();

		
page.open("https://travel.tescobank.com/", function(status) {
				
					var currentLocation = page.evaluate(function() {
						return window.location.href;
					});
					
					// click the button for single trip
					var tripType = page.evaluate(function() {
						var trip = $("#single-trip-radio").trigger("click");
						return (trip != null);
					});	
								
					// enter value in dropdown					
					var countrySearch = page.evaluate(function() {
						var country = $("#countrySearch").val("France");
						return (country != null);
					});						

					var datePickerOne = page.evaluate(function() {
						var datePicker1 = $("#stFromdate").val("01-11-2017");
						return $("#stFromdate");
					});						
					
					var datePickerTwo = page.evaluate(function() {
						var datePicker2 = $("#stTodate").val("08-11-2017");
						return $("#stTodate").val();
					});							
					
					var numberOfTravellers = page.evaluate(function() {
						var number = $("#couple").trigger("click");
						return $("#couple").val();
					});						
					
					var firstName = page.evaluate(function() {
						var fname = $("#fName").val("Test");
						return $("#fName").val();
					});					
					
					var secondName = page.evaluate(function() {
						var sname = $("#sName").val("Test");
						return $("#sName").val();
					});	
					
					var dateOfBirth = page.evaluate(function() {
						var dob = $("#phDOB").val("11-10-1977");
						return $("#phDOB").val();
					});	
					
					var dateOfBirth2 = page.evaluate(function() {
						var dob2 = $("#ydob1").val("11-10-1977");
						return $("#ydob1").val();
					});	
					
					var postcode = page.evaluate(function() {
						var pc = $("#postcode").val("SS1 2AA");
						return $("#postcode").val();
					});							
					
					var email = page.evaluate(function() {
						var em = $("#emailaddr").val("[email protected]");
						return $("#emailaddr").val();
					});						
					
					//various attempts to submit the form
					
					//var submitForm = page.evaluate(function() {

						//does not submit
						//$("#aboutYouForm").submit();
					
						//does not submit
						//var elementPosition = $("#aboutYouSubmit").offset();
						//page.sendEvent('click', elementPosition.left + 1, elementPosition.top + 1);
						
                      //does not submit
						//return $("#aboutYouSubmit").val();
					//});	


					// this click on the button does fire the form validation but doesn’t seem to submit the form
					var submitForm = page.evaluate(function() {
						var theForm = $("#aboutYouSubmit").trigger("click");
						return (theForm != null);
					}

}

I can't see that there's any errors causing it not to submit the form correctly, it just stays on the same screen without any validation errors as far as I can see from the output. Any help appreciated.enter image description here

like image 664
78lro Avatar asked Oct 28 '22 23:10

78lro


1 Answers

I've made some modifications to your script that allowed it to successfully send the page (however the quote could not be generated at the time, probably due to all those test values?).

I'm sure things like error control and viewport size are present in your script, but for the sake of educating other readers I'll keep them in the answer.

Here's the working script with notes:

var page = require('webpage').create();
var screenshotNum = 1;

page.viewportSize = { width: 1366 , height: 768 };
page.settings.userAgent = 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.106 Safari/537.36';

page.onConsoleMessage = function(msg, lineNum, sourceId) {
  console.log('CONSOLE: ' + msg + ' (from line #' + lineNum + ' in "' + sourceId + '")');
};

// We always need to be aware of any and all errors 
// happening on the target page. Most of the time here lies the answer
page.onError = function(msg, trace) {

    var msgStack = ['ERROR: ' + msg];

    if (trace && trace.length) {
        msgStack.push('TRACE:');
        trace.forEach(function(t) {
            msgStack.push(' -> ' + t.file + ': ' + t.line + (t.function ? ' (in function "' + t.function +'")' : ''));
        });
    }

    console.error(msgStack.join('\n'));
};

// This fires every time a new page is loaded
// If a form has been sent this will show the URL of success/fail page
page.onLoadFinished = function(){

    var url = page.evaluate(function(){
        return document.location.href;
    });

    console.log(url);

    // And every time a page is loaded we'll make a screenshot
    // to make sure everything goes according to our expectations
    page.render("travel-" + screenshotNum++ + ".jpg");

    // It we've moved to another page, it means the form was sent
    // So let's exit
    if(url != 'https://travel.tescobank.com/') {
        phantom.exit();
    }

};

page.open("https://travel.tescobank.com/", function(status) {

    // Let's wait a bit before filling fields in, so that
    // any javascript on the page will have time to kick in       
    setTimeout(fillFields, 2000);

});

function fillFields()
{
    // click the button for single trip
    var tripType = page.evaluate(function() {
        var trip = $("#single-trip-radio").trigger("click");
        return (trip != null);
    }); 

    // enter value in dropdown                  
    var countrySearch = page.evaluate(function() {
        var country = $("#countrySearch").val("France");
        return (country != null);
    });                     

    var datePickerOne = page.evaluate(function() {
        var datePicker1 = $("#stFromdate").val("11-11-2017");
        return $("#stFromdate");
    });                     

    var datePickerTwo = page.evaluate(function() {
        var datePicker2 = $("#stTodate").val("18-11-2017");
        return $("#stTodate").val();
    });                         

    var numberOfTravellers = page.evaluate(function() {
        var number = $("#couple").trigger("click");
        return $("#couple").val();
    });                     

    var firstName = page.evaluate(function() {
        var fname = $("#fName").val("Robert");
        return $("#fName").val();
    });                 

    var secondName = page.evaluate(function() {
        var sname = $("#sName").val("Johnson");
        return $("#sName").val();
    }); 

    var dateOfBirth = page.evaluate(function() {
        var dob = $("#phDOB").val("11-10-1977");
        return $("#phDOB").val();
    }); 

    var dateOfBirth2 = page.evaluate(function() {
        var dob2 = $("#ydob1").val("11-10-1977");
        return $("#ydob1").val();
    }); 

    var postcode = page.evaluate(function() {
        var pc = $("#postcode").val("SS1 2AA");
        return $("#postcode").val();
    });                         

    var email = page.evaluate(function() {
        var em = $("#emailaddr").val("[email protected]");
        return $("#emailaddr").val();
    });                     

    // this click on the button does fire the form validation
    // It will submit the form if no errors are found
    var submitForm = page.evaluate(function() {
        var theForm = $("#aboutYouSubmit").trigger("click");
        return (theForm != null);
    });

    // If the page haven't been sent due to errors
    // this will count how many of them are there
    // and will make a screenshot of the page
    setTimeout(function(){
        var errorsTotal = page.evaluate(function(){
            return $(".error:visible").length;
        });
        console.log("Total errors: " + errorsTotal);
        page.render("travel-filled.jpg");
    }, 1500);
}

Why wouldn't the page submit before? On your screenshot there is an error telling the first name is not filled. Could be a typo in filling that or maybe jQuery wasn't loaded at the time of filling fields in.

like image 154
Vaviloff Avatar answered Nov 15 '22 04:11

Vaviloff