Sourav
Sourav

Reputation: 91

How to select multiple options from multi select list using Selenium-Python?

I am trying to select P0_ENGLISH, P1_ENGLISH, P5_ENGLISH from multiple select which has 10 options. I want to select only these 3 options.

HTML CODE:

<select multiple="" class="gwt-ListBox" style="height: 80px; width: 205px;">
    <option title="Generic_Eng" value="Generic_Eng">Generic_Eng</option>
    <option title="Generic_Hindi" value="Generic_Hindi">Generic_Hindi</option>
    <option title="P0_English" value="P0_English">P0_English</option>
    <option title="P0_Hindi" value="P0_Hindi">P0_Hindi</option>
    <option title="P1_English" value="P1_English">P1_English</option>
    <option title="P1_Hindi" value="P1_Hindi">P1_Hindi</option>
    <option title="P4_English" value="P4_English">P4_English</option>
    <option title="P4_Hindi" value="P4_Hindi">P4_Hindi</option>
    <option title="P5_English" value="P5_English">P5_English</option>
    <option title="P5_Hindi" value="P5_Hindi">P5_Hindi</option>
</select>

SELENIUM-PYTHON CODE:

queues = Select(driver.find_element_by_css_selector(".rowStyle1:nth-child(6) .gwt-ListBox"))
queues.select_by_visible_text("P0_English")
time.sleep(3)
queues.select_by_visible_text("P1_English")
time.sleep(3)
queues.select_by_visible_text("P5_English"

I've tried using this code. With this code, I am able to select the first option i.e. "P0_ENGLISH". However, after selecting the first option I get an error:

selenium.common.exceptions.StaleElementReferenceException: Message: stale element reference: element is not attached to the page document

Upvotes: 5

Views: 14883

Answers (4)

ishaj
ishaj

Reputation: 101

For me:

Multi-select option present on Techlistic form site worked by below code when I used CSS Selector-

https://www.techlistic.com/p/selenium-practice-form.html

act=ActionChains(self.drv)
WE_cmd= self.drv.find_element(By.CSS_SELECTOR,'#selenium_commands > option:nth-child(2)' )
opt=Select(self.drv.find_element(By.ID,"selenium_commands"))
opt.select_by_visible_text("Browser Commands")
act.key_down ( Keys.CONTROL ).click ( WE_cmd).key_up ( Keys.CONTROL ).perform ()

Upvotes: 0

supputuri
supputuri

Reputation: 14135

The OP is to select part of items in the multi select list, but if you want to select all the items in the list then here are the options.

JavaScript:

elements = driver.find_elements_by_css_selector(".gwt-ListBox option")
driver.execute_script("arguments[0].forEach(function(ele){ele.selected=true;});",elements)

Pyhton

elements = driver.find_elements_by_css_selector(".gwt-ListBox option")
for ele in elements:
    # select the item here

Upvotes: 0

undetected Selenium
undetected Selenium

Reputation: 193088

To select multiple options from a Multi Select element you can use ActionChains to mock Control Click as follows:

from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.common.keys import Keys

myElemA = driver.find_element_by_css_selector(".rowStyle1:nth-child(6) .gwt-ListBox option[value='P0_English']")
myElemB = driver.find_element_by_css_selector(".rowStyle1:nth-child(6) .gwt-ListBox option[value='P1_English']")
myElemC = driver.find_element_by_css_selector(".rowStyle1:nth-child(6) .gwt-ListBox option[value='P5_English']")
ActionChains(driver).key_down(Keys.CONTROL).click(myElemA).key_up(Keys.CONTROL).perform()
ActionChains(driver).key_down(Keys.CONTROL).click(myElemB).key_up(Keys.CONTROL).perform()
ActionChains(driver).key_down(Keys.CONTROL).click(myElemC).key_up(Keys.CONTROL).perform()

Upvotes: 5

adq
adq

Reputation: 184

In the context of Selenium, a reference is stale when the reference is invalid, because the referenced element has been deleted, or outdated as the element has been detached and then attached by a client-side script. Without knowing the precise mechanics of the client script, there may be different solutions. The easiest is to attempt to reference the element again, i.e.

queues = Select(driver.find_element_by_css_selector(".rowStyle1:nth-child(6).gwtListBox"))
queues.select_by_visible_text("P0_English")
time.sleep(3)
queues = Select(driver.find_element_by_css_selector(".rowStyle1:nth-child(6).gwtListBox"))
queues.select_by_visible_text("P1_English")
time.sleep(3)
queues = Select(driver.find_element_by_css_selector(".rowStyle1:nth-child(6).gwtListBox"))
queues.select_by_visible_text("P5_English")

This assumes that the CSS selector stays the same after the selection list is reattached. There is also a possibility that the selector becomes invalid because the element has been either removed or its location has been changed. In the first case, you'd want to throw an exception and handle it appropriately and, in the second, find out what its new selector is going to be either empirically or by client-side script code analysis. More on the StaleElementReferenceException here.

Upvotes: 2

Related Questions