14
<div>
   <a href='...'>LINK</a>
   <img class='image' />
</div>
<div>
   ...
</div>

I want to get a protractor element for the img tag with image class. I already know the link text 'LINK'. In other words, "How do I locate a sibling of a given element?".

The first line of the code could look like this:

browser.findElement(by.linkText('LINK'))

Any ideas?

Thanks & Cheers

Waseem
  • 8,232
  • 9
  • 43
  • 54
user1879408
  • 1,948
  • 3
  • 17
  • 27
  • 1
    Could you catch the parent? because elementFinder can be chained to find within a known parent: https://github.com/angular/protractor/blob/master/docs/api.md#elementfinderelement but it seems to me that this feature is missing and you can ask on Protractor Github if there's a workaround or suggest a pull request ;) – glepretre May 19 '14 at 16:40

3 Answers3

24

Thanks for the inspiration. Here's my solution, not the one I was hoping for, but it works:

element(by.css('???')).element(by.xpath('..')).element(by.css('???')).click();

The chaining and the by.xpath, which allows to get back to the parent are the keys of the solution.

alecxe
  • 462,703
  • 120
  • 1,088
  • 1,195
user1879408
  • 1,948
  • 3
  • 17
  • 27
  • In case other people reach this page: [Protractor style guide](https://www.protractortest.org/#/style-guide) asks to never use XPath. But in our case, to find a sibling, it seems that there is currently no better solution. – ThCollignon Sep 28 '18 at 06:47
1

This is what I actually implement on a Page Object:

  this.widgets['select-status'] = this.ids['select-status']
      .element(by.xpath('following-sibling::div[1]'));
  this.widgets['select-status.dropdown'] = element(by.css('.btn-group.bootstrap-select.open'));

The page is based on Bootstrap along with Bootstrap Select. Anyways, we traverse the DOM along the following-sibling axis. Refer to XPATH specification for yourself.

Jason Aller
  • 3,541
  • 28
  • 38
  • 38
Khanh Hua
  • 1,086
  • 1
  • 14
  • 22
  • it worked for me as well. i.e. `var result = cols.all(by.cssContainingText('span', 'MY TEXT')); var sibElem = result.all(by.xpath("following-sibling::div[1]")).first();` – bob.mazzo Feb 02 '17 at 15:02
0

Using Xpath selectors is not a better choice as it slows down the element finding mechanism.

I have designed a plugin to address this specific issues: protractor-css-booster

The plugin provides some handly locators to find out siblings in a better way and most importantly with CSS selector.

using this plugin, you can directly use:

var elem = await element(by.cssContainingText('a','link text')).nextSibling();

elem.click(); //proceed with your work

or, use this as by-locator

var elem = element(by.cssContainingText('a','link text')).element(by.followingSibling('img'));

You can always checkout the other handy methods available here...

Now, you can find web elements such as:

  1. Finding Grand Parent Element
  2. Finding Parent Element
  3. Finding Next Sibling
  4. Finding Previous Sibling
  5. Finding any Following Sibling
  6. Finding First Child Element
  7. Finding Last Child Element

And, guess what, everything you can find using CSS Selectors

Hope, it will help you...