How to 'click' a radio button -> xPath needed

18,657

Solution 1

The following XPath expression will get just the input element you want:

//input[@type='radio'][following-sibling::text()[position()=1][contains(., 'Inne akcje')]]

That returns this element:

<input type="radio" ng-model="holdersModel.OperationType" value="O"
    class="prettifiedIeCheckbox ng-valid ng-dirty" name="01J" />

The key differences from your original XPath expression are:

  • Don’t use the syntax input[@type='radio']/following-sibling…; instead use //input[@type='radio'][following-sibling….

  • Don’t use following-sibling::*; instead use following-sibling::text() (because in this context * means “any element“; so if you want that text node instead, you have to explicitly indicate it by using text() instead)

  • Do use [position()=1] in following-sibling::*[position()=1] to indicate that you want the first following sibling.

Solution 2

I agree with nilesh about XPath. Here's how I would do this using CSS Selectors.

WebElement przekazanie = driver.findElement(By.cssSelector("input[value='P']"));
WebElement dekretacja = driver.findElement(By.cssSelector("input[value='D']"));
WebElement inneAkcje = driver.findElement(By.cssSelector("input[value='O']"));
// pick the one you want to click and .click() it
przekazanie.click();

Solution 3

Xpath seems to get more complicated and would be hard to maintain in long term in this case. Names seem to be unique for these radio buttons. Are they not static? If they are, then you can just use name as selector. If you really want to use xpath, then try something concise like

.//input[contains(@name, '01J') and text() = 'Inne akcje']
Share:
18,657
p__d
Author by

p__d

Updated on June 05, 2022

Comments

  • p__d
    p__d about 2 years

    I need to check one of three radio buttons. I tried this code:

    //input[@type='radio']/following-sibling::*[contains(., 'Inne akcje')]
    

    but I think it's wrong way.

    <label class="HoldersInLineLabel">Rodzaj akcji</label>
    
    <input type="radio" ng-model="holdersModel.OperationType" class="prettifiedIeCheckbox ng-valid ng-dirty" value="P" name="01H">
          "Przekazanie"
    <input type="radio" ng-model="holdersModel.OperationType" value="D" class="prettifiedIeCheckbox ng-valid ng-dirty" name="01I">
         "Dekretacja"
    <input type="radio" ng-model="holdersModel.OperationType" value="O" class="prettifiedIeCheckbox ng-valid ng-dirty" name="01J">
         "Inne akcje"
    
    <span class="k-widget k-dropdown k-header ng-pristine ng-valid" unselectable="on" role="listbox" aria-haspopup="true" aria-expanded="false"...></span>
    
  • p__d
    p__d almost 9 years
    The names are changing day after day :/
  • p__d
    p__d almost 9 years
    Ehhh, my tests don't getting it.
  • sideshowbarker
    sideshowbarker almost 9 years
    I’m not sure what you’re saying. My answer doesn’t work for you as expected? If so, and the answer from @nilesh works for you, then I suggest you try that instead. But if you really do want to locate the button based on where it occurs in relation to that Inne akcje, then my answer should be working for you. If it’s not, and you can tell me what error you get, I will be happy to help you troubleshoot it further.
  • sideshowbarker
    sideshowbarker almost 9 years
    The thing is, as you may already know, in order to get much useful work done with webdriver, you really do need to use XPath sometimes (though maybe not this time) and so you really do need to get familiar with XPath. But in this specific case, if using Selectors instead solves the problem you need to solve right now, than maybe you should just use that for now.
  • p__d
    p__d almost 9 years
    Nevermind, i just copy-past first line of your code and it works! I had to understand what means word 'sibling'. Thanks a lot @sideshowbarker!
  • nilesh
    nilesh almost 9 years
    +1 for explanation, But this xpath is very brittle. If the position of elements change this test breaks.
  • sideshowbarker
    sideshowbarker almost 9 years
    True that it’s brittle under position of elements changing, but I think the nature of the webdriver game is that it’s hard to avoid such brittleness regardless of what expression/addressing mechanism you use, and how robust you try to make it. And avoiding the brittleness often requires some knowledge of ways the page has changed in the past and may change in the future, etc., etc.