1

this is my first post so please go easy one me. :)

I'am new to protractor therefore I would like to ask for your help. I've been asked to write a test for the folowing code:

<div class="content ps-container ps-active-y expand" ng-class={hide:items.length === 2}" ng-transclude="" csf-product-navigator-content="" csf-scrollbar="" style="">
 <div class="product-wrp prod-active" ng-class="{'prod-active' : active, 'odd' : (odd === true && !active), 'even' : (odd !== true && !active)}" ng-repeat="product in accounts" csf-product-navigator-item="">
  <div class="product-wrp odd" ng-class="{'prod-active' : active, 'odd' : (odd === true && !active), 'even' : (odd !== true && !active)}" ng-repeat="product in accounts" csf-product-navigator-item="">
   <div class="product-item animate-hide" ng-click="onDropdowmItemClick()" ng-transclude="" csf-product-navigator-anim-item="">
    <div class="ng-scope" ng-repeat="product in accounts" csf-product-navigator-item="">
     <div class="navigator-view ng-hide" ng-show="active">
      <div class="" ng-hide="active">
       <div class="product-choice ng-scope" ng-if="product.type !== 'SM'">
        <section class="product-name">
         <header class="ng-scope" ng-if="product.name">
          <p class="product-details" ng-show="product.type">
           <span class="ng-binding" ng-bind="product.no">PL84 9101 0003 2001 0006 1883 0004</span>
          </p>
        </section>
        <section class="product-amount">
       </div>
      </div>
     </div>
    </div>
   </div>
  <div class="product-wrp even" ng-class="{'prod-active' : active, 'odd' : (odd === true && !active), 'even' : (odd !== true && !active)}" ng-repeat="product in accounts" csf-product-navigator-item="">
  <div class="product-wrp even" ng-class="{'prod-active' : active, 'odd' : (odd === true && !active), 'even' : (odd !== true && !active)}" ng-repeat="product in accounts" csf-product-navigator-item="">
  <div class="product-wrp odd" ng-class="{'prod-active' : active, 'odd' : (odd === true && !active), 'even' : (odd !== true && !active)}" ng-repeat="product in accounts" csf-product-navigator-item="">
  <div class="product-wrp even" ng-class="{'prod-active' : active, 'odd' : (odd === true && !active), 'even' : (odd !== true && !active)}" ng-repeat="product in accounts" csf-product-navigator-item="">

Goal is to get the number of the products on the dropdown list.

So I figured i should get all elements in the container and then use function to go through them.

This is my code:

features(iOwe):

var iOwe = function () {
  this.accNo = element(by.className('content ps-container ps-active-y expand')).all(by.className('product-item animate-hide'))
}

Spec(iOwe):

it('should display accounts numbers on dropdown list', function () {
  expect(iOwe.accNo.count()).not.toBe(0);
  iOwe.accNo.each(function(elem) {
    elem.element(by.className('product-details')).getText()
    .then
    (function (text){
        console.log(text);
    });
  });

The problem is that each time I run tests I get diffrent output in console. Getting only first 3/4 strings (should be 7) and rest is empty.

Thanks for help

EDIT: I checked what exactly happens during test by adding browser.sleep(5000); each time console prints string and suprisingly I found out that I have to actually see (in browser) the following account to allow test to read it.

3 Answers 3

2

Goal is to get the number of the products on the dropdown list.

The most logical way to approach that is to use the by.repeater() locator:

var products = element.all(by.repeater("product in accounts"));
expect(products.count()).toEqual(7);

Or, with a CSS selector:

var products = $$("p.product-details");
expect(products.count()).toEqual(7);

If this is a timing issue, you may specifically wait for count of elements matching a locator:

function waitForCount(elements, expectedCount) {
    return elements.count().then(actualCount) {
        return actualCount >= expectedCount;
    });
}

browser.wait(waitForCount($$("p.product-details"), 7), 5000);
Sign up to request clarification or add additional context in comments.

3 Comments

Ok so i tested both of them and unfortunately first one is too general(it returns account name/ammount). Second one works like charm but it still returns only 3/4 numbers. But... I checked what exactly happens during test by adding browser.sleep(5000); each time console prints string and suprisingly i found out that I have to actually see (in browser) the following account to allow test to read it.
@krzygol alright, does it mean that your issue is now resolved? Thanks.
Yes I found an anwser and tommorow I will post whole code with the changes and explanation. Thanks for help.
1

I got an anwser to my question,it was not a matter of selectors/matchers.

As I found out according to this Article in order to .getText() u have to actually see the element in browser otherwise it will return empty string.

I decided to find another way to get the text and I used

.getAttribute()

to get the string.

Basically i changed :

elem.element(by.css('span.ng-binding')).getText()

to

elem.element(by.css('span.ng-binding')).getAttribute('outerHTML')

And it returned string with accnumber.

But... This is not what I wanted. I wanted to check if the element is actually visible in browser and folowing solution wont work.

Then i found this Question,it shows how to scroll down to element in your browser You want to check.

So i edited my code:

it('should display accounts numbers on dropdown list', function () {
  expect(iOwe.accNo.count()).not.toBe(0);
  iOwe.accNo.each(function(elem) {
    browser.executeScript('arguments[0].scrollIntoView()', elem.getWebElement()) //Scroll down to element
    .then
    elem.element(by.className('product-details')).getText()
    .then
    (function (text){
      console.log(text);
    });
});

And this is an anwser to my question.

Thanks for help!

Comments

0

You could try something like this-

it('should display accounts numbers on dropdown list', function () {
expect(iOwe.accNo.count()).not.toBe(0);
iOwe.accNo.each(function(elem) {
expect(elem.element(by.css('p.product-details')).isDisplayed()).toBe(true);
elem.element(by.css('span.ng-binding')).getText()
.then
(function (text){
    console.log(text);
});
});

1 Comment

updated my answer, you could put a extra check whether the product details are displayed and then use the normal chaining elements!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.