Mark T
Mark T

Reputation: 105

Issue with XPATH in Selenium and Python

I am trying to automate some components of service-now. Most everything I am doing is working with the exception of the below.

For the below snippet from the site.

    <select aria-required="true" 
                    aria-labelledby="label.cmdb_ci_netgear.u_criticality"
                    ng-non-bindable="true" name="cmdb_ci_netgear.u_criticality" 
                    id="cmdb_ci_netgear.u_criticality" 
                    onchange="onChange('cmdb_ci_netgear.u_criticality');" style="; " 
                    class="form-control" mandatory="true" aria-readonly="false">
        <option value="" role="option">-- None --</option>
        <option value="Level_1" role="option">Level 1</option>
        <option value="Level_2" role="option">Level 2</option>
        <option value="Level_3" role="option">Level 3</option>
        <option value="Level_4" role="option">Level 4</option>
        <option value="Level_5" role="option">Level 5</option>
        <option value="Level_6" role="option">Level 6</option>
        <option value="0" role="option">0</option>
        <option value="Not_Agreed" role="option">Not Agreed</option>
        <option value="level 1" role="option">level 1</option>
        <option value="1" role="option">1</option>
        <option value="3843" role="option">3843</option>
    </select>

If I inspect the HTML and copy the XPATH for the Level_(1-6) options I get the below relationship.

    code =      <option value="Level_1" role="option">Level 1</option>
    xpath =     //*[@id="cmdb_ci_netgear.u_criticality"]/option[2]      

    code =      <option value="Level_2" role="option">Level 2</option>
    xpath =     //*[@id="cmdb_ci_netgear.u_criticality"]/option[3]          

    code =      <option value="Level_3" role="option">Level 3</option>
    xpath =     //*[@id="cmdb_ci_netgear.u_criticality"]/option[4]          

    code =      <option value="Level_4" role="option">Level 4</option>
    xpath =     //*[@id="cmdb_ci_netgear.u_criticality"]/option[5]          

    code =      <option value="Level_5" role="option">Level 5</option>
    xpath =     //*[@id="cmdb_ci_netgear.u_criticality"]/option[6]          

    code =      <option value="Level_6" role="option">Level 6</option>
    xpath =     //*[@id="cmdb_ci_netgear.u_criticality"]/option[7]      

This is the code that I am running through to match the stored value from elsewhere to update the respective XPath

def CI_Create(self,ci_id,Catols):
    self.CI_field_excludes = ['install_status','u_visible_to', 'discovery_source','device_type','u_environment']
    self.ci_ids = ci_id
    self.Catol = Catols
    self.browser.get("https://rttmstest.service-now.com/cmdb_ci_netgear.do")
    sleep(5)
    for i in self.Catol:
        sleep(5)
        print('processing '+ i)
        if i == 'u_criticality':
            print('criticality text is ' + self.Catol['u_criticality'][1])
            if self.Catol[i][1] == 'Level_1':
                print('xxx - process criticality as Level_1')
                self.browser.find_element_by_xpath('//*[@id="cmdb_ci_netgear.u_criticality"]/option[2]').click()
            elif self.Catol[i][1] == 'Level_2':
                print('xxx - process criticality as Level_2')
                self.browser.find_element_by_xpath('//*[@id="cmdb_ci_netgear.u_criticality"]/option[3]').click()
            elif self.Catol[i][1] == 'Level_3':
                print('xxx - process criticality as Level_3')
                self.browser.find_element_by_xpath('//*[@id="cmdb_ci_netgear.u_criticality"]/option[4]').click()
            elif self.Catol[i][1] == 'Level_4':
                print('xxx - process criticality as Level_4')
                self.browser.find_element_by_xpath('//*[@id="cmdb_ci_netgear.u_criticality"]/option[5]').click()
            elif self.Catol[i][1] == 'Level_5':
                print('xxx - process criticality as Level_5')
                self.browser.find_element_by_xpath('//*[@id="cmdb_ci_netgear.u_criticality"]/option[6]').click()
            elif self.Catol[i][1] == 'Level_6':
                print('xxx - process criticality as Level_6')
                self.browser.find_element_by_xpath('//*[@id="cmdb_ci_netgear.u_criticality"]/option[7]').click()
            else:
                print('CRITICAL Failure to select criticality')
        if i in self.CI_field_excludes:
            print('excluding '+i)
            if i == 'discovery_source':
                print('processing lower '+i)
                self.browser.find_element_by_xpath('//*[@id="cmdb_ci_netgear.discovery_source"]/option[3]').click()
            else:
                continue
        else:
            print('processed under else '+i)
            self.browser.find_element_by_xpath(self.Catol[i][0]).send_keys(self.Catol[i][1])
    # self.browser.find_element_by_xpath(device_save_modification).click()
    sleep(5)
    return

All the prints and sleeps are me trying to gain sanity to why the selection is off. Below is a cut down version of what is being called with self.catol

    CMDB_CAT = {'name': ['//*[@id="cmdb_ci_netgear.name"]', 'somename'],
    'u_managed_b': ['//*[@id="sys_display.cmdb_ci_netgear.u_managed_by"]', 'IT'],
    'u_common_name' : ['//*[@id="cmdb_ci_netgear.u_common_name"]', 'somecommonname'],
    'u_visible_to' : ['//*[@id="cmdb_ci_netgear.u_visible_to"]', 'IT'],
    'install_status' : ['//*[@id="cmdb_ci_netgear.install_status"]', 'Active'],
    'u_criticality' : ['//*[@id="cmdb_ci_netgear.u_criticality"]', 'Level_3'],
    }

If the u_criticality is 'Level_3' it should set the '//*[@id="cmdb_ci_netgear.u_criticality"]/option[4]'.

Everything indicated this is happening, with the exception of the field showing 'Level 4' as the chosen.

Appreciate any help.

Upvotes: 0

Views: 236

Answers (1)

KunduK
KunduK

Reputation: 33384

You can use selenium select class to select the item and get the text value as well.Please check following options.See if this help.

from selenium.webdriver.support.ui import Select
select=Select(driver.find_element_by_id('cmdb_ci_netgear.u_criticality'))
select.select_by_index(3) # First item of the select index is always 0
print(select.first_selected_option.text)

OR

select=Select(driver.find_element_by_id('cmdb_ci_netgear.u_criticality'))
select.select_by_value("Level_3")
print(select.first_selected_option.text)

OR

element = driver.find_element_by_xpath("//select[@id='cmdb_ci_netgear.u_criticality']")
all_options = element.find_elements_by_tag_name("option")
for option in all_options:
    print("Value is: %s" % option.get_attribute("value"))
    option.click()

Upvotes: 1

Related Questions