使用Angularjs E2E测试AngularUI Select2元素

使用Angularjs E2E测试AngularUI Select2元素,angularjs,angular-ui,angularjs-e2e,ui-select2,Angularjs,Angular Ui,Angularjs E2e,Ui Select2,我有一个带有select2元素的部分用户界面 我遇到的问题是元素是必需的,尽管我通过以下代码成功地设置了字段,但必需的属性没有被删除,因为Angular的模型不能由于外部更改而更新,我不确定如何提供$scope.apply()或利用另一个角度函数继续测试 首先允许直接jQuery函数运行:(取自) 然后,要更改字段值,请执行以下操作: jQueryFunction('#s2id_autogen1', 'select2', 'open'); jQueryFunction('#s2id_au

我有一个带有select2元素的部分用户界面

我遇到的问题是元素是必需的,尽管我通过以下代码成功地设置了字段,但必需的属性没有被删除,因为Angular的模型不能由于外部更改而更新,我不确定如何提供$scope.apply()或利用另一个角度函数继续测试

首先允许直接jQuery函数运行:(取自)

然后,要更改字段值,请执行以下操作:

jQueryFunction('#s2id_autogen1', 'select2', 'open');
    jQueryFunction('#s2id_autogen1', 'select2', "val", "US");
    jQueryFunction('#s2id_autogen1', 'select2', 'data', {id: "US", text: "United States"});
    jQueryFunction('.select2-results li:eq(3)', 'click');
    jQueryFunction('#s2id_autogen1', 'trigger', 'change');
    jQueryFunction('#s2id_autogen1', 'select2', 'close');
    input('request._countrySelection').enter('US');

请注意,并非所有这些功能都需要反映对ui的更改,而仅仅是我用来尝试使其工作的所有功能…

我无法在Karma test runner中使其工作,但是在量角器测试套件中,这变得非常容易

为了在量角器测试套件中实现这一点,我使用以下方法选择页面上的第一个select2框,并选择该框中的第一个选项:

var select2 = element(by.css('div#s2id_autogen1'));
select2.click();
var lis = element.all(by.css('li.select2-results-dept-0'));
lis.then(function(li) {
    li[0].click();
});

页面上的下一个select2的id为s2id_autogen3

我让它在Karma下工作,并进行了以下更改

将以下DSL添加到e2e测试文件的顶部:

angular.scenario.dsl('jQueryFunction', function() {
  return function(selector, functionName /*, args */) {
    var args = Array.prototype.slice.call(arguments, 2);
    return this.addFutureAction(functionName, function($window, $document, done) {
      var $ = $window.$; // jQuery inside the iframe
      var elem = $(selector);
      if (!elem.length) {
        return done('Selector ' + selector + ' did not match any elements.');
      }
      done(null, elem[functionName].apply(elem, args));
    });
  };
});
然后要更改场景中的select2值,请使用

it('should narrow down organizations by likeness of name entered', function() {
  jQueryFunction('#s2id_physicianOrganization', 'select2', 'open');
  jQueryFunction('#s2id_physicianOrganization', 'select2', 'search', 'usa');
  expect(element('div.select2-result-label').count()).toBe(2);
});

有时候,select2可能需要一些时间来加载,尤其是在处理ajax加载的数据时。因此,当使用量角器,并扩展布赖恩的答案时,我发现有一种方法是可靠的:

function select2ClickFirstItem(select2Id) {
    var select2 = element(by.css('div#s2id_' + select2Id));
    select2.click();
    var items = element.all(by.css('.select2-results-dept-0'));
    browser.driver.wait(function () {
        return items.count().then(function (count) {
            return 0 < count;
        })
    });
    items.get(0).click();
}
函数select2ClickFirstItem(select2Id){
var select2=element(by.css('div#s2id"+select2Id));
选择2.单击();
var items=element.all(by.css('.select2-results-dept-0');
browser.driver.wait(函数(){
返回items.count().then(函数(count){
返回0

这使用了driver.wait.

这一事实来实现这一点,我参考了Brian的答案和sinelaw,但在我的案例中,它仍然失败,原因有两个:

  • 单击“div#s2id_autogen1”不会为我打开select2输入,我使用的选择器是“div#s2id_autogen1 a”
  • 获取select2元素我会得到ElementNotVisibleError,可能是因为我的select2在引导模式中,所以我显式地等待元素可见,然后单击它(您可以阅读我阅读的原始提示来使用它)
  • 生成的代码是:

    function select2ClickFirstItem(select2Id) {
            var select2Input;
    
            // Wait for select2 element to be visible
            browser.driver.wait(function() {
                select2Input =  element(by.css('#s2id_' + select2Id + ' a'));
                return select2Input;
            }).then(function() {
                select2Input.click();
    
                var items = element.all(by.css('.select2-results-dept-0'));
                browser.driver.wait(function () {
                    return items.count().then(function (count) {
                        return 0 < count;
                    });
                });
                items.get(0).click();
            });
        }
    
    函数select2ClickFirstItem(select2Id){
    var选择2输入;
    //等待select2元素可见
    browser.driver.wait(函数(){
    select2Input=element(by.css('#s2id'+select2Id+'a');
    返回select2Input;
    }).然后(函数(){
    选择2输入。单击();
    var items=element.all(by.css('.select2-results-dept-0');
    browser.driver.wait(函数(){
    返回items.count().then(函数(count){
    返回0

    希望能有所帮助。

    如果你使用量角器和新的业力,我会支持@Brian所说的话,这对我起了作用:

    function uiSelect(model, hasText) {
        var selector = element(by.model('query.cohort')),
            toggle = selector.element(by.css('.ui-select-toggle'));
    
        toggle.click();
    
        browser.driver.wait(function(){
            return selector.all(by.css('.ui-select-choices-row')).count().then(function(count){
                return count > 0;
            });
        }, 2000);
    
        var choice = selector.element(by.cssContainingText('.ui-select-choices-row',hasText));
        choice.click();
    };
    
    像这样使用它:

    如果要选择的项目的值为“2013年第3季度”,则可以为其提供选择器的型号以及要选择的项目的精确或部分文本匹配

    uiSelect('query.cohort','Q3 2013');
    


    如果元素具有id属性,则select2创建的div将是s2id_
    uiSelect('query.cohort','Q3 2013');
    
    uiSelect('query.cohort','Q3');