5

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("test@test.com");
      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

78lro
  • 1,790
  • 7
  • 37
  • 63
  • Whats is your PhantomJS version? – Vaviloff Nov 01 '17 at 16:40
  • 2.1.1 - I went to the very latest version in an attempt to solve this issue :) – 78lro Nov 01 '17 at 16:46
  • Would there be some additional event processing that needs to be fired? I don’t see any errors, if I debug it using the PhantomJS proxy it completes cleanly, so there’s nothing to suggest it hasn’t submitted the form as it would if a user clicked the button. – 78lro Nov 01 '17 at 20:15
  • Do you use any console/error logging? It's not there in the script. – Vaviloff Nov 02 '17 at 04:57
  • I do but had removed it from the script posted here, I was also debugging it with chrome and the phantomjs proxy. It completes cleanly with a success message but doesn't fire the submit form event. Can you suggest any logging/console output that would help to check if the button/event has fired? I tried checking the object etc but not sure what else could be checked, apart from viewing the screenshot output? thanks – 78lro Nov 02 '17 at 11:35
  • Try to bluntly send the form without any validation: `$("#aboutYouForm")[0].submit()` – Vaviloff Nov 02 '17 at 12:21
  • Unfortunately that doesn't work, even the validation doesn't fire if I try that. I have even tried the suggestion here as I thought it might be a similar issue - https://stackoverflow.com/questions/20928915/jquery-triggerclick-not-working but it doesn't help, fires the validation but does not submit the form (bangs head on table) – 78lro Nov 03 '17 at 11:38

1 Answers1

2

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("test@test.com");
        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.

Vaviloff
  • 16,282
  • 6
  • 48
  • 56
  • Thanks, the screenshot was demonstrating what happened without all the fields completed i.e. the form submit was firing and triggering the validation but then failing to send. I think your point about waiting for jquery to load before completing the form fields might be important. I’ll try the script and see, I’ve sinced used headless chrome and this submits without any issue at all. – 78lro Nov 07 '17 at 16:06
  • Your screenshot also shows *why* it was failing ot send — not all fields had been filled. – Vaviloff Nov 07 '17 at 20:11
  • 1
    I ensured all fields were filled in a later test but still the filled result page remained, without moving on to the results. I think the main issues were timing, I needed a delay before filling the fields as you mentioned and also a delay before taking the next screenshot on the results page. – 78lro Nov 07 '17 at 22:18