Casperjs:测试jquery自动完成

Casperjs:测试jquery自动完成,jquery,jquery-autocomplete,casperjs,browser-automation,browser-testing,Jquery,Jquery Autocomplete,Casperjs,Browser Automation,Browser Testing,我在使用casperjs与jquery自动完成输入框交互时遇到问题。我尝试了许多不同的方法,但当选项列表弹出时,我似乎无法选择自动完成选项 我的代码如下: casper.thenEvaluate(function() { $('#myInput').val('cars'); // fill in the text box $('#myInput').blur(); // should trigger the autocomplete ajax call $('.ui-autoco

我在使用casperjs与jquery自动完成输入框交互时遇到问题。我尝试了许多不同的方法,但当选项列表弹出时,我似乎无法选择自动完成选项

我的代码如下:

casper.thenEvaluate(function() {
  $('#myInput').val('cars');  // fill in the text box
  $('#myInput').blur();  // should trigger the autocomplete ajax call
  $('.ui-autocomplete li.ui-menu-item:nth-of-type(1)').click(); // should click the first item in the list
});

// take a picture to make sure it worked
casper.then(function() {
  this.captureSelector('pics/test1.png', '#theForm');
});
这根本不起作用,尽管它看起来应该起作用。通过使用它,我发现触发向下箭头键几次会触发自动完成显示,所以这里有一个更接近工作的版本。这在浏览器中有效,但在casper.thenEvaluate块中不起作用

$('#myInput').val('cars');  // fill in the text box
var e = jQuery.Event("keydown");
e.which = 40; // press down arrow a few times, not sure why this works
$("#myInput").trigger(e);
$("#myInput").trigger(e);
$('.ui-autocomplete li.ui-menu-item:nth-of-type(1)').click();

这不是基于jqueryui的autocomplete,而是基于与引导相关的Typeahead,但机制应该是相同的

我在以下方面取得了成功:

casper.sendKeys("#field_departure_airport", 'a', {keepFocus: true});
casper.waitUntilVisible(".typeahead", function() {
    casper.click(".typeahead>li:nth-child(1)>a");
    test.assertField("departure_airport", "A. L. Mangham Jr. Regional Airport(Nacogdoches, Texas, United States) [OCH]"); 
});
这在一个
casper.then()函数中运行,
sendKeys
根据ID选择一个字段并将“a”传递给它。
keepFocus
很重要,否则它将在插入文本后取消选择输入

等待出现
.typeahead
,等待对服务器的AJAX调用,然后单击typeahead中的第一个
元素


最后测试字段的值。请注意,字段选择器是它的名称,而不是CSS3选择器。

我尝试了很多不同的解决方案,但都不起作用,或者不总是这样。我终于找到了一个看起来很健壮的:

/*
 * You have to specify the input selector, the text you want to write in (which activates the auto-completion), and the text on which you want to click
 */
casper.fillAutoCompletion = function (inputSelector, text, autoCompleteText) {
    //keepfocus : true to keep the auto-completion opened
    this.sendKeys(inputSelector, text, {keepFocus: true});
    //wait for the auto-complete block to appear
    this.waitUntilVisible("[class*='ui-autocomplete']", function() {
        var x = require('casper').selectXPath
            ,xpath = "//*[contains(text(),'" + autoCompleteText + "')]"
            ;
    //move on the wanted element and click
    this.mouse.move(x(xpath));
    this.click(x(xpath));
    });
};
或者,如果您不喜欢扩展js函数:

var fillAutoCompletion = function (inputSelector, text, autoCompleteText) {
    //keepfocus : true to keep the auto-completion opened
    casper.sendKeys(inputSelector, text, {keepFocus: true});
    //wait for the auto-complete block to appear
    casper.waitUntilVisible("[class*='ui-autocomplete']", function() {
        var x = require('casper').selectXPath
            ,xpath = "//*[contains(text(),'" + autoCompleteText + "')]"
            ;
    //move on the wanted element and click
    casper.mouse.move(x(xpath));
    casper.click(x(xpath));
    });
};
叫它:

.thenOpen("yourUrl", function(){
    this.fillAutoCompletion(".jODMainSearch","Ren", "Rennes");//extending
    fillAutoCompletion(".jODMainSearch","Par", "Paris");//js
})

(对我来说)诀窍是在点击想要的元素之前使用mouse.move()来激活它的选择,否则它就不起作用了。

我的实现不同,但这提供了我需要的线索。你试过你的
  • 的第二个孩子了吗?->:第N个孩子(2),因为我有一个类似的问题,无论我做什么,它总是需要我的第一个李。。。因此,只有自动完成的第一个li元素。我建议将
    sendKeys
    嵌套在
    then
    块中,因为在使用前面的步骤完成一些导航之后调用
    fillAutoCompletion
    可能会在目标页面甚至可见之前执行
    sendKeys
    。更改后,您可以将
    fillAutoCompletion
    移出
    thenOpen
    块,并在其后面移动。您无处不在:p,您的意思是这样使用它:
    .thenOpen().fillAutoCompletion().then().wait()它不工作。我已经养成了将自定义函数嵌套在单个步骤函数中的习惯,因为我不是唯一一个阅读测试的人,这样他们就知道它何时是本机函数。但我同意;要在闭包中执行自定义函数,最好用step函数嵌套它。纯属运气:)是的,我的意思是(几乎)这样:
    casper.thenOpen;fillAutoCompletion();casper.then()。嵌套是可以的,只要你知道你不能在
    之后再打开
    ,因为它们也必须嵌套。好吧,我明白了,但我更喜欢链接指令,它也一样,但我发现这样更轻:p,显然casper不喜欢我们链接自定义函数。另外,thenOpen()在执行第一条指令之前等待加载DOM和执行js函数,因此对我来说,thenOpen()中的fillAutoCompletion()没有问题-也许对你也是,我可能误解了你的最后一句话-。但是我们同意一个
    this.click()
    -如果它影响我们的输入-
    +这个.fillAutoCompletion()
    必须在不嵌套的情况下进行监控:p