PhantomJS并单击表单按钮

我有一个非常简单的HTML表单,我试图用各种数据进行测试。 我使用IE对象在MS Access / VBA中编写了一个原型概念validation。 它工作正常,但完成的测试产品必须使用PhantomJS。 我有页面连接工作,表单填充得很好。 我被困的地方是让提交按钮开火。 我已经梳理了SO并尝试了所有建议,但没有任何工作。 我正在使用PhantomJS 1.9.7并使用直接的JavaScript测试脚本。

我尝试了各种JavaScript技术来触发提交按钮。 为了满足“Just use JQuery”的用户群,我也试过了。 没有什么工作。 当我在测试脚本的末尾渲染表单时,我看到填充了数据的表单耐心地等待点击按钮。

以下是我尝试过的摘要:

  1. document.getElementById('btnSearch').click();
  2. $("btnSearch").click();
  3. var el = document.getElementById('btnSearch'); // Get search button object
    $(el).click();
  4. document.getElementById('Form1').submit();
  5. 尝试创建一个click事件并从按钮对象中触发它(在下面的代码中)
  6. 尝试创建一个click事件并使用相关按钮内部点的坐标从body对象中触发它

以下是表格:(并且请不要对缺乏CSS,使用表格等进行评论/辩论。我对创建网站的人没有任何发言权或影响力。)

    Da Site   
Street Address:
City:
State: AL - Alabama AK - Alaska [The rest of the other states] WI - Wisconsin WY - Wyoming PR - Puerto Rico
Zip Code:

这是驱动表单的JavaScript:

 var maxtimeOutMillis = 3000; var start; var finish; var page = require('webpage').create(); // Route "console.log()" calls from within the Page context to the main Phantom context (ie current "this") page.onConsoleMessage = function(msg) { console.log(msg); }; page.open('http://www.MadeUpURL.com/', function(status) { page.includeJs("http://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js", function() { if (status !== 'success') { console.log('Unable to access network'); } else { page.render('before.png'); // Renders the blank form page.evaluate( function () { // page.render('Sample.png'); document.getElementById('Address').value = '123 Somewhere Drive'; document.getElementById('City').value = 'Somewhere'; document.getElementById('State').selectedIndex = 36; document.getElementById('ZipCode').value = '12345'; // I've done a page.render() here and it shows the form fully and correctly populated // Now let's submit the form... var el = document.getElementById('btnSearch'); // Get the "search" button object // Tried the usual suspects document.getElementById('btnSearch').click(); $("btnSearch").click(); $(el).click(); document.getElementById('Form1').submit(); // Tried creating a click event and firing it from the button object var ev = document.createEvent("MouseEvent"); ev.initMouseEvent("click", true /* bubble */, true /* cancelable */, window, null, 0, 0, 0, 0, /* coordinates */ false, false, false, false, /* modifier keys */ 0 /*left click*/, null); el.dispatchEvent(ev); // Tried calculating the location of the button itself (which works) and fire the click event from the  object var obj = document.getElementById('btnSearch'); var x = obj.offsetLeft; var y = obj.offsetTop; while (obj.offsetParent) { x = x + obj.offsetParent.offsetLeft; y = y + obj.offsetParent.offsetTop; if (obj == document.getElementsByTagName("body")[0]) { break; } else { obj = obj.offsetParent; } } x = x + 5; // Tried with and without this +5 delta y = y + 5; // Tried with and without this +5 delta console.log('X = ' + x); console.log('Y = ' + y); var ev = document.createEvent("MouseEvent"); ev.initMouseEvent("click", true /* bubble */, true /* cancelable */, window, null, 0, 0, x, y, /* coordinates */ false, false, false, false, /* modifier keys */ 0 /*left click*/, null); document.body.dispatchEvent(ev); }); start = new Date().getTime(); finish = new Date().getTime(); console.log('Time before: ' + start); // Check to see if results are defined (or times out) while ( (finish - start < maxtimeOutMillis) && !( page.evaluate( function() {return document.getElementById('TheAnswer');}))) { finish = new Date().getTime(); } console.log('Time after: ' + finish); if ( page.evaluate( function() {return document.getElementById('TheAnswer');})) { console.log(page.evaluate( function() {return document.getElementById('TheAnswer').textContent;})); } else { console.log('Element not defined'); } } page.render('after.png'); phantom.exit(); }); }); 

我希望这是你忘记分号的东西之一,但我只是没有看到它。 任何帮助将非常感谢!

编辑#1:添加脚本输出以供参考。

 C:\Temp\WebAutomation\PhantomJS\scripts>phantomjs interact.js X = 151 Y = 442 Time before: 1407875912197 [edit #2 - change before/after labels to match code] Time after: 1407875915197 Element not defined C:\Temp\WebAutomation\PhantomJS\scripts> 

好。 我想我想通了。 我将PhantomJS和我的脚本导向了一个可以监控后端数据的网站。 令我惊讶的 ,按下了按钮。 我只是看不到结果。

感谢Vinjay Boyapati这篇文章 ,问题似乎与页面处理程序和排序有关。 似乎在PhantomJS中处理页面转换的最佳方法是启动页面循环(单击提交按钮,链接等)并退出该JS评估函数。 在检查PhantomJS以确保页面已完全加载并且稳定后,请调用另一个页面。评估并查找浏览器获取提交结果时您希望找到的内容。 这是我从Vinjay的post中复制/修改的代码:

编辑 :要特别注意的一件事。 对于每个page.Evaluates(),其中需要jQuery,我正在添加page.injectJs("jquery1-11-1min.js"); 线。 否则我会得到“$ is undefined”作为页面错误。

 var page = require('webpage').create(); var loadInProgress = false; var testindex = 0; // Route "console.log()" calls from within the Page context to the main Phantom context (ie current "this") page.onConsoleMessage = function(msg) { console.log(msg); }; page.onAlert = function(msg) { console.log('alert!!> ' + msg); }; page.onLoadStarted = function() { loadInProgress = true; console.log("load started"); }; page.onLoadFinished = function(status) { loadInProgress = false; if (status !== 'success') { console.log('Unable to access network'); phantom.exit(); } else { console.log("load finished"); } }; var steps = [ function() { page.open('http://www.MadeUpURL.com'); }, function() { page.injectJs("jquery1-11-1min.js"); page.evaluate(function() { document.getElementById('Address').value = '302 E Buchtel Avenue'; //University of Akron if you're wondering document.getElementById('City').value = 'Akron'; document.getElementById('State').selectedIndex = 36; document.getElementById('ZipCode').value = '44325'; console.log('JQ: ' + $().jquery); $('#btnSearch').click(); console.log('Clicked'); }); }, function() { console.log('Answers:'); page.injectJs("jquery1-11-1min.js"); page.render('AnswerPage.png'); page.evaluate(function() { console.log('The Answer: ' + document.getElementById('TheAnswer').innerHTML); $('#buttonOnAnswerPage').click(); // This isn't really necessary unless you need to navigate deeper console.log('Sub button clicked'); }); }, function() { console.log('More Answers:'); // This function is for navigating deeper than the first-level form submission page.render('MoreAnswersPage.png'); page.evaluate(function() { console.log('More Stuff: ' + document.body.innerHTML); }); }, function() { console.log('Exiting'); } ]; interval = setInterval(function() { if (!loadInProgress && typeof steps[testindex] == "function") { console.log("step " + (testindex + 1)); steps[testindex](); testindex++; } if (typeof steps[testindex] != "function") { console.log("test complete!"); phantom.exit(); } }, 50);