Angularjs E2E Testing with Angular-UI Select2 Element

I have a partial select2 element using Angular UI http://angular-ui.imtqy.com/

The problem I encountered is that the element is required, and although I successfully set the field through the following code, the required attribute is not deleted, since the Angular model should not be updated due to an external change, and I'm not sure how either provide $ scope.apply (), or use another Angular function to continue the test.

First allow the launch of direct jQuery functions: (taken from How to execute jQuery from Angular e2e test area? )

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)); }); }; }); 

Then, to change the value of the field:

 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'); 

Note that not all of these functions are needed to reflect the changes in ui, just everything I used to try to get this to work ...

+6
source share
5 answers

I was not able to get this to work in the Karma test runner cassette, however it became much easier in the protractor testing kit.

To accomplish this in the transporter test suite, I used the following to select the first select2 flag on the page and select the first option in this field:

 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(); }); 

The next select2 on the page has the identifier s2id_autogen3

+2
source

To make this work, I consulted with Brian's answer and with my wife, but he still failed in my case for two reasons:

  • clicking on 'div # s2id_autogen1' does not open select2 input for me, the selector I used was 'div # s2id_autogen1 a'
  • Getting the select2 element, I would get an ElementNotVisibleError, possibly because my select2 is in the bootstrap module, so I explicitly wait for the element to be visible before clicking on it (you can read the original hint I read to use it here ) .

Final code:

 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(); }); } 

Hope this helps.

+5
source

I'm the second that @Brian said, if you use a protractor and new karma, this worked for me:

 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(); }; 

use it like:

if the value of the element you want to select is β€œQ3 2013”, you can provide it with a selector model and the exact or partial match of the text of the element you want to select.

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

or

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

they will work

+2
source

I did work under karma with the following changes.

Add the following DSL to the top of the e2e test file:

 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)); }); }; }); 

Then to change the select2 value in your script use

 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); }); 
0
source

Sometimes select2 can take a load time, especially when working with data loaded by ajax. Therefore, when using the protractor and extending Brian's answer, here is a method that I found reliable:

 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(); } 

This takes advantage of the fact that driver.wait can promise the result .

0
source

Source: https://habr.com/ru/post/952134/


All Articles