【发布时间】:2014-10-06 22:32:54
【问题描述】:
我有一个非常简单的 HTML 表单,我正在尝试使用各种数据进行测试。我使用 IE 对象在 MS Access/VBA 中编写了一个原型概念验证。它运行良好,但完成的测试产品必须使用 PhantomJS。我已经让页面接口工作并且表单填充得很好。我被卡住的地方是让提交按钮触发。我已经梳理了 S.O.并尝试了所有建议,但没有任何效果。我正在使用 PhantomJS 1.9.7 并使用直接的 JavaScript 测试脚本。
我尝试了各种 JavaScript 技术来触发提交按钮。为了满足“只使用 JQuery”的人群,我也尝试过。没有任何工作。当我在测试脚本结束时呈现表单时,我看到表单中填充了数据,耐心等待点击
以下是我尝试过的总结:
-
document.getElementById('btnSearch').click(); -
$("btnSearch").click(); -
var el = document.getElementById('btnSearch'); // Get search button object$(el).click(); document.getElementById('Form1').submit();- 尝试创建一个点击事件并从按钮对象触发它(在下面的代码中)
- 尝试创建一个点击事件并从 body 对象触发它,并使用相关按钮内的某个点的坐标
表格如下: (请不要就缺乏 CSS、表格的使用等进行 cmets/辩论。我对创建该网站的人没有发言权或影响力。)
<!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>
【问题讨论】:
-
我知道我知道,不是你的但是:validator.w3.org/check 在 xhtml 中严格说
element X undefined: upper-case tags in XHTML (in XHTML attributes and elements must be all lower-case) -
如果您手动提交,
document.getElementById('TheAnswer');是否存在于(下一页)页面上? -
@Artjom:很好——我将“到达这里”改为“之前”和“这里”改为“之后”。我会进行适当的编辑...
-
@Birdspider:当你说“手动提交”时,你是什么意思?如果我在适当的浏览器中加载网页并输入地址并单击“搜索”按钮,则该页面会加载各种数据,包括“TheAnswer”。这就是我在这里的坚持。我无法让 PhantomJS 通过单击按钮或直接 form.submit() 提交表单
-
试试这个:在文件中方便的地方添加
debugger;。然后开始phantomjs --remote-debugger-port=8889 <file>.js。在localhost:8889上打开 chrome - 单击链接,转到控制台并执行__run()- 您现在应该能够逐步执行脚本 - 以debugger开始一行;
标签: javascript jquery forms automated-tests phantomjs