Select radio button using Selenium with value that changes

Viewed 898

I need to select the radio button below with value="QMBT-0029104.xlsx;SYPFJPC2MQHC-5-688478#QHBTW"

HTML:

<form name="ViewQueryForm" method="post" action="/equery/getAttachments.do">

<div class="txt_align_left innerdvcont" id="tabmenu1" style="display:">

<div class="clear"></div>

<div class="txt_align_left innerdvcont" id="tabmenu011" name="tabmenu011">

        <table width="100%" border="0" cellspacing="0" cellpadding="0">
            <thead>
             <tr>
            <th width="10%" style="text-align: left"></th>
                    <th width="60%" style="text-align: left">Attachment </th>
                    <th width="30%" style="text-align: left">Date </th>
                    
            </tr>
                </thead>
        
                <tbody>
                <tr>
                <td align="center" valign="top">
                <input type="radio" name="getAttachmentValue" id="getAttachmentValue" value="Dispute_1466718.xlsx;SYPFJPC2MQHC-5-687433#QHBTW"> </td>
                    <td style="padding:5px 4px">Dispute_1466718.xlsx</td>
                    <td style="padding:5px 4px">2021-02-16T10:34:08.617</td>
                    
                        </tr>
                        
                </tbody><tbody>
                <tr>
                <td align="center" valign="top">
                <input type="radio" name="getAttachmentValue" id="getAttachmentValue" value="QMBT-0029104.xlsx;SYPFJPC2MQHC-5-688478#QHBTW">    </td>
                    <td style="padding:5px 4px">QMBT-0029104.xlsx</td>
                    <td style="padding:5px 4px">2021-03-27T08:08:46.09</td>
                    
                        </tr>
                        
                
            </tbody>    
            </table>    
</div>  

So far I have been able to click on it using the code below:

radiobutton2 = driver.find_element_by_xpath("//input[@value='QMBT-0029104.xlsx;SYPFJPC2MQHC-5-688478#QHBTW']");
radiobutton2.click()

However, the value changes every time which means that it's not something that I can use when running the code. Is there any way to select the second radio button by default for example. Alternatively, I will know the QMBT-00000 reference, so is there a way to select the radio button by searching for that text?

I have tried:

radiobutton2 = driver.find_element_by_xpath('//*[contains(text(), "QMBT-0029104") and @id="getAttachmentValue"]');
radiobutton2.click()

However, that gives me an error:

Unable to locate element

3 Answers

Great first question.

If the radio button you need to select will always be the second option, you can select it by the index (below is in C#, but should be similar for Python):

 // get all elements where id = "getAttachmentValue" 
var radioButtons = driver.FindElements(By.Id("getAttachmentValue"));

 // click second element 
radioButtons[1].Click();

Edit (Python):

from selenium.webdriver.common.by import By

radioButtons = driver.find_elements(By.ID, 'getAttachmentValue')

radioButtons[1].click()

I added your HTML to a simple HTML file and was able to select the second radio button using the above example (using C#):

enter image description here

You can select the second radio button by xpath using array index notation. Instead of targeting the value attribute, use the name attribute instead. The value of the name attribute seems to be consistent:

xpath = "(//input[@type = 'radio' and @name = 'getAttachmentValue'])[2]"
radio_button = driver.find_element_by_xpath(xpath)
radio_button.click()

You probably should not use the id attribute in your locator. The Id attribute value must be unique for the entire web page, but the Id attribute value is repeated for each radio button. This is invalid HTML. It is best to avoid using attributes in locators where the values of those attributes violate the HTML spec. You never fully know how the browser is going to treat it.

For your use case, the name attribute would work best. It is perfectly valid HTML to have repeated name attribute values, and the value of the name attribute appears to be stable for each page view.

If you have only two same ids, the answer is simple. Try this.

driver.find_element_by_css_selector("#getAttachmentValue:nth-of-type(2)")

If there are more - the solution may be more complicated. How may IDs are there?

Related