Javascript PhantomJS并单击表单按钮
我有一个非常简单的HTML表单,我正试图用各种数据测试它。我使用IE对象在MS Access/VBA中编写了一个原型概念验证。它工作得很好,但最终的测试产品必须使用PhantomJS。我已经有了页面界面的工作和形式是填充刚刚好。我被卡住的地方是让提交按钮启动。我仔细检查了S.O.并尝试了所有建议,但没有任何效果。我使用的是PhantomJS1.9.7和直接的JavaScript测试脚本 我尝试了各种JavaScript技术来启动提交按钮。为了满足“只使用JQuery”的人群,我也尝试了。什么都没用。当我在测试脚本末尾呈现表单时,我看到表单中填充了数据,耐心地等待按钮被单击 以下是我尝试的总结:Javascript PhantomJS并单击表单按钮,javascript,jquery,forms,automated-tests,phantomjs,Javascript,Jquery,Forms,Automated Tests,Phantomjs,我有一个非常简单的HTML表单,我正试图用各种数据测试它。我使用IE对象在MS Access/VBA中编写了一个原型概念验证。它工作得很好,但最终的测试产品必须使用PhantomJS。我已经有了页面界面的工作和形式是填充刚刚好。我被卡住的地方是让提交按钮启动。我仔细检查了S.O.并尝试了所有建议,但没有任何效果。我使用的是PhantomJS1.9.7和直接的JavaScript测试脚本 我尝试了各种JavaScript技术来启动提交按钮。为了满足“只使用JQuery”的人群,我也尝试了。什么都没
document.getElementById('btnSearch')。单击()代码>
$(“btnSearch”)。单击()代码>
var el=document.getElementById('btnSearch');//获取搜索按钮对象
$(el).单击()代码>
document.getElementById('Form1').submit()代码>
嗯。我想我明白了。我将PhantomJS和我的脚本引导到一个可以监视后端数据的网站。令我惊讶的是,按钮被点击了。我就是看不到结果 幸好,这个问题似乎更多地与页面处理程序和排序有关。在PhantomJS中处理页面转换的最佳方法似乎是启动页面循环(单击提交按钮、链接等)并退出JS评估功能。在检查PhantomJS以确保页面已完全加载且稳定后,请调用另一个页面。评估并查找浏览器返回提交结果时您希望找到的内容。以下是我从文杰的帖子中复制/修改的代码: 编辑:需要特别注意的一件事。对于需要jQuery的每个page.Evaluates(),我将添加
page.injectJs(“jquery1-11-1min.js”)代码>行。否则我会将“$未定义”作为页面错误
var page=require('webpage').create();
var loadInProgress=错误;
var-testindex=0;
//将“console.log()”调用从页面上下文中路由到主虚拟上下文(即当前“this”)
page.onConsolleMessage=函数(msg){
控制台日志(msg);
};
page.onAlert=函数(msg){
console.log('alert!!>'+msg);
};
page.onLoadStarted=函数(){
loadInProgress=true;
log(“加载已启动”);
};
page.onLoadFinished=功能(状态){
loadInProgress=false;
如果(状态!=“成功”){
console.log('无法访问网络');
phantom.exit();
}否则{
控制台日志(“加载完成”);
}
};
变量步骤=[
函数(){
第页打开('http://www.MadeUpURL.com');
},
函数(){
第页注入js(“jquery1-11-1min.js”);
page.evaluate(函数(){
document.getElementById('Address')。value='302 E Buchtel Avenue';//如果您想知道
document.getElementById('City')。value='Akron';
document.getElementById('State')。selectedIndex=36;
document.getElementById('ZipCode')。值='44325';
log('JQ:'+$().jquery);
$('#btnSearch')。单击();
console.log('Clicked');
});
},
函数(){
console.log('Answers:');
第页注入js(“jquery1-11-1min.js”);
page.render('AnswerPage.png');
page.evaluate(函数(){
console.log('TheAnswer:'+document.getElementById('TheAnswer').innerHTML);
$(“#按钮无应答页”)。单击();//除非您需要更深入地导航,否则实际上不需要这样做
log('单击子按钮');
});
},
函数(){
console.log('More Answers:');//此函数用于导航到比第一级表单提交更深的位置
page.render('moreswerspage.png');
page.evaluate(函数(){
log('More Stuff:'+document.body.innerHTML);
});
},
函数(){
console.log('Exiting');
}
];
间隔=设置间隔(函数(){
如果(!loadInProgress&&typeof步骤[testindex]=“函数”){
console.log(“步骤”+(testindex+1));
步骤[testindex]();
testindex++;
}
if(步骤类型[testindex]!=“函数”){
log(“测试完成!”);
phantom.exit();
}
}, 50);
我知道我知道,不是你的,但是:在xhtml中表示strict元素X未定义:xhtml中的大写标记(在xhtml中,属性和元素必须都是小写)
如果手动提交,则是否document.getElementById('TheAnswer')代码>是否存在于(下一页)?@Artjom:捕捉得好-我将“到达这里”改为“时间之前”,将“和这里”改为“时间之后”。我将进行适当的编辑…@Birdspider:当你说“手动提交”时”“什么意思?如果我在适当的浏览器中加载该网页,并在其中输入地址,然后单击搜索按钮,则该网页将加载各种数据,包括“答案”。这就是我在这里的原因。我无法让PhantomJS通过单击按钮或直接提交表单来提交表单代码>在文件中方便的位置。然后启动phantomjs——远程调试器端口=8889.js
。在localhost:8889
-clic上打开chrome
<!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>
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();
});
});
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>