New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Scoping with `element` doesn't match element text selector #1354

Closed
gregtyler opened this Issue May 30, 2016 · 3 comments

Comments

Projects
None yet
2 participants
@gregtyler

gregtyler commented May 30, 2016

The problem

If you have two identical elements on the page, then I understand you can use the "element" method to scope the next selector. However, this doesn't seem to work when using a selector that matches text against a specific element.

That is, with two identical elements on the same page, but one inside the scope, it will select the inside button with .btn, =publish or *=publish but not a=publish or a*=publish.

Environment

Details

I've provided some code below which demonstrates the issue (running against a JS Bin that I've created). Notice that both buttons in the JS Bin have the same text (publish) and the same class (btn).

I want to click the button inside the container and, because they are otherwise identical, I have to use the element method. In the example I've provided, the obvious solution is to just use =publish, but in my real life situation I'm using a button element so would have to use button=publish. I'm only using a link in the example to demonstrate the limitations.

However, the webdriver code clicks the outside button when using text matching.

Link to Selenium/WebdriverIO logs

I've provided logs for the three cases below.

Code To Reproduce Issue

Doesn't work

client
  .init()
  .url('http://jsbin.com/finogu/27')
  .element('#container')
    .click('a=publish')
  .getText('#log').then(console.log)
  .end();

Works

client
  .init()
  .url('http://jsbin.com/finogu/27')
  .element('#container')
    .click('=publish')
  .getText('#log').then(console.log)
  .end();

Works

client
  .init()
  .url('http://jsbin.com/finogu/27')
  .element('#container')
    .click('.btn')
  .getText('#log').then(console.log)
  .end();
@gregtyler

This comment has been minimized.

gregtyler commented May 30, 2016

I've been looking into this a bit further, and think I've figured it out. Selectors of the type button=publish are converted into XPath using findElementStrategy (e.g. //a[normalize-space() = "publish"])

But, in lib/protocol/element.js, findStrategy is called without the "relative" parameter and after the selector is formatted between global and relative.

There are two potential solutions:

  1. Add a "relative" parameter to the findStrategy call when suitable.
  2. Call findStrategy before the XPath selector formatting, and format found.value instead.

The first one seems more "proper", so I'm going to implement that and create a pull request. But if one of the maintainers would rather use a different method then that's fine.

@gregtyler

This comment has been minimized.

gregtyler commented May 30, 2016

I'm afraid I've failed to implement this fix. It worked fine when I manually edited the files in my node_modules, but doing it in the repository trunk against test criteria is proving troublesome.

If somebody who already has the repository working fine would like to fix, I think it's just a case of adding let relative = false; to line 23 of /lib/protocol/element.js and then setting relative = true inside the if statement of the same file.

@christian-bromann

This comment has been minimized.

Member

christian-bromann commented Jun 1, 2016

Thanks for posting. Fixed issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment