我有一个非常简单的HTML表单,我尝试使用各种数据进行测试。我使用IE对象在MS Access / VBA中编写了一个原型概念验证。它工作正常,但完成的测试产品必须使用PhantomJS。我已经有了页面连接工作,表格填充得很好。我被困的地方是要点击提交按钮。我已经梳理了S.O.并尝试了所有的建议,没有任何工作。我正在使用PhantomJS 1.9.7并使用直接的JavaScript测试脚本。
我尝试了各种JavaScript技术来触发提交按钮。为了满足"只需使用JQuery"人群,我也试过了。什么都行不通。当我在测试脚本的末尾渲染表单时,我看到填充了数据的表单耐心地等待< search>按钮被点击。
以下是我尝试过的摘要:
document.getElementById('btnSearch').click();
$("btnSearch").click();
var el = document.getElementById('btnSearch'); // Get search button object
$(el).click();
document.getElementById('Form1').submit();
以下是表格: (并且请不要对缺少CSS,使用表格等进行评论/辩论。我对创建该网站的人没有任何发言权或影响力。)
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<HTML>
<HEAD>
<title>Da Site</title>
</HEAD>
<body>
<form name="Form1" method="post" action="Default.aspx" id="Form1">
<TABLE id="Table2" cellSpacing="2" cellPadding="1" border="0">
<TR>
<TD>Street Address:</TD>
<TD><input name="Address" type="text" maxlength="100" id="Address" /></TD>
</TR>
<TR>
<TD>City:</TD>
<TD><input name="City" type="text" maxlength="100" id="City" style="width:232px;"/></TD>
</TR>
<TR>
<TD>State:</TD>
<TD><select name="State" id="State">
<option value=""></option>
<option value="AL">AL - Alabama</option>
<option value="AK">AK - Alaska</option>
[The rest of the other states]
<option value="WI">WI - Wisconsin</option>
<option value="WY">WY - Wyoming</option>
<option value="PR">PR - Puerto Rico</option>
</select>
</TD>
</TR>
<TR>
<TD>Zip Code:</TD>
<TD><input name="ZipCode" type="text" maxlength="5" id="ZipCode" /></TD>
</TR>
<tr>
<td><input type="submit" name="btnSearch" value="Search" id="btnSearch" />
<input type="submit" name="btnReset" value="Reset" id="btnReset" />
</td>
</tr>
</TABLE>
</form>
</body>
</HTML>
这是用于驱动表单的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 (i.e. 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 <Body> 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>
答案 0 :(得分:12)
确定。我想我明白了。我将PhantomJS和我的脚本导向了一个可以监控后端数据的网站。令我惊讶的是,点击了按钮 。我只是看不到结果。
由this post from Vinjay Boyapati提供,问题似乎与页面处理程序和排序有关。似乎在PhantomJS中处理页面转换的最佳方法是启动页面循环(单击提交按钮,链接等)并退出该JS评估函数。在检查PhantomJS以确保页面已完全加载并且稳定后,请调用另一个页面。评估并查找浏览器取回提交结果时您希望找到的内容。这是我从Vinjay的帖子中复制/修改的代码:
编辑 :要特别注意的一件事。对于每个页面。需要jQuery的评估(),我添加page.injectJs("jquery1-11-1min.js");
行。否则我会得到&#34; $未定义&#34;作为页面错误。
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 (i.e. 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);
&#13;