3

I am new to CSS and am trying to avoid using xpath in my Protractor AngularJS test automations. I am trying to get a specific element in the list, which Im getting, however Protractor tells me there are more than one element found for locator. In the future I want to avoid this as I'm not always going to want first on the list. I am slightly confused about CSS and exactly how to get where I'm going and the documentation I have found has been vague. I am trying to grab Marketing Venue element but will also need to grab the other elements beneath as well at some point. The top code is AngularJS and how I am currently grabbing the text. Thanks in advance.

var iPlanLevel=element(by.css("div:nth-of-type(2) > div:nth-of-type(2) > div > div:nth-of-type(1) > span")).getText().then(function (text) {
  console.log(text);
}
);

<!-- begin snippet: js hide: false -->
<div class="home-info">

  <span class="web-developer-id-class-details"></span>
  <div class="home-top home-section"></div>
  <span class="web-developer-id-class-details"></span>
  <div class="home-bottom home-section">
    <h3></h3>
    <span class="web-developer-id-class-details"></span>
    <div class="home-box">
      <span class="web-developer-id-class-details"></span>
      <span class="home-name"></span>
      <br></br>


      Lindemannstrasse 88

      <br></br>


      Dortmund 44137

      <br></br>
      <br></br>
      <span class="web-developer-id-class-details"></span>
      <div class="property-group meduim">
        <div></div>
        <span>

                    MarketingVenue

                </span>
      </div>
      <span class="web-developer-id-class-details">

                .property-group.meduim

            </span>
      <div class="property-group meduim">
        <div></div>
        <span>

                    December 31, 2016

                </span>
      </div>
      <span class="web-developer-id-class-details"></span>
      <div class="property-group meduim"></div>
      <div></div>
      <br></br>
    </div>
    <span class="web-developer-id-class-details"></span>
    <div class="home-box"></div>
  </div>

</div>

2
  • Tell me this please: what is your input and the desired result? In other words, what do you know beforehand and can rely on, MarketingVenue text? Thanks. Commented Jul 28, 2015 at 13:52
  • @Alecxe I am getting this Subscription (MarketingVenue) and then checking to see if the subscription level has all of its apps available to it. For example: A user has MarketingVenue subscription access so it has Apps: bookings, media, search. Subscription levels change, and so doesn't other elements like Dortmund which is the name of the hotel per user subscription level. There are seven different subscription levels. Commented Jul 28, 2015 at 15:40

1 Answer 1

3

Are you able to edit the HTML you are testing? If so, it would be very useful to add a tag into the Marketing Venue span. Say you add name="marketingVenue", then you could do something like this:

// Element by css selector shorthand($ = by.css())
var marketingVenue = $('[name="marketingVenue"]');

// Child selector using css selector shorthand
var marketingChild = marketingVenue.$('[name="childBeneathMarketingVenue]');

// Child selector using a variable and element(el.locator())
var marketingChildSelector = $('[name="childBeneathMarketingVenue"]');
var marketingChild = marketingVenue.element(marketingChildSelector.locator());

If you cannot edit the HTML, you can still use the code above, but with a longer, more fragile css selector.

For clearing the warning of multiple elements, youve got to get all of the elements are select .first or .get(x) a specific one in the array.

// Get all elements with a tag using shorthand $$ element.all(by.css(x))
var marketingVenues = $$('[name="marketingVenues"]');
var firstMarketingVenue = marketingVenues.first();
var specificMarketingVenue = marketingVenues.get(12); // Get the 13th element from the array

You can also use this function to grab ONLY the visible element(s), assuming your html has some hidden and some visible.

// Pass a string css selector to get the first visible element of that selector
function getVisibleElements(selector){
    var allElementsOfSelector = element.all(by.css(selector));
    var displayedElement = allElementsOfSelector .filter(function(elem) {
        return elem.isDisplayed('cannot find' + ' ' + selector);
    }) // Add '.first();' here if you want just the first visible
    return displayedElement ;
}

var visibleMarketingVenues = getVisibleElements('[name="marketingVenues"]');
var marketingVenue = visibleMarketingVenues.first();
var fifthMarketingVenue = visibleMarketingVenues.get(4);

For your specific selector, if you do not have access to edit the html, you are probably looking at changing the selector if the page itself has any changes, as div selectors are really fragile. Your selector right now may be something like:

var marketingVenue = $$('.property-group').get(0).$('span');
Sign up to request clarification or add additional context in comments.

3 Comments

I just need to grab the element in which the text MarketingVenue is located. What you are looking at is a subscription level and it is changed when different users with different subscription levels login. After I get the subscription level (MarketingVenue) I then check to see what is included with there subscription using expects.
Editing HTML to support tests should generally be discouraged. Separation of concerns for the win, right?
Whatever works, I just prefer for my tests to not fail every time a new span is added!

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.