Phantomjs 和 HTML 5 触发点击事件并提交表单失败

Phantomjs and HTML 5 fire click event and submit form fails

我正在尝试创建一个虚拟脚本来自动测试以下形式:

https://travel.tescobank.com/

我的脚本正确地完成了必填字段,然后单击应该提交表单的按钮,不幸的是,无论我尝试了什么,它都不会提交表单并显示下一页。

我已确认按钮上的点击已触发,因为在未完成必填字段的情况下,我在页面的屏幕截图中看到已触发验证。 (见附件截图)

我在下面评论了我尝试过的所有 click/submit 选项,以及似乎触发表单验证但未提交表单并显示下一页的选项。

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);
     }

}

我看不出有任何错误导致它无法正确提交表单,它只是停留在同一屏幕上而没有任何验证错误,据我从输出中可以看出。感谢任何帮助。

我对您的脚本进行了一些修改,使其能够成功发送页面(但是引用 could not be generated at the time,可能是由于所有这些 test 值? ).

我确定您的脚本中存在诸如错误控制和视口大小之类的内容,但为了教育其他读者,我会将它们保留在答案中。

这是带注释的工作脚本:

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);
}

为什么之前的页面没有提交?在您的屏幕截图上,有一个错误提示未填写名字。可能是填写时的打字错误,或者 jQuery 在填写字段时未加载。