PhantomJS并单击表单按钮

时间:2014-08-13 14:05:11

标签: javascript jquery forms automated-tests phantomjs

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

我尝试了各种JavaScript技术来触发提交按钮。为了满足"只需使用JQuery"人群,我也试过了。什么都行不通。当我在测试脚本的末尾渲染表单时,我看到填充了数据的表单耐心地等待< search>按钮被点击。

以下是我尝试过的摘要:

  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. 尝试创建点击事件并从按钮对象(在下面的代码中)触发
  6. 尝试创建点击事件并从 body 对象触发,并使用相关按钮内的点坐标
  7. 以下是表格: (并且请不要对缺少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>
    

1 个答案:

答案 0 :(得分:12)

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

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

编辑 :要特别注意的一件事。对于每个页面。需要jQuery的评估(),我添加page.injectJs("jquery1-11-1min.js");行。否则我会得到&#34; $未定义&#34;作为页面错误。

&#13;
&#13;
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;
&#13;
&#13;