Handling Select2 with Selenium webdriver

I used the below code to select the desired option and it worked. This must also be faster than performing multiple clicks.

String script = "$('select#yearSelector').trigger($.Event('change',{val:'" + year + "'}))";
((JavascriptExecutor) driver).executeScript(script);

And, in Python, if this one-liner doesn't work, try splitting it into it's components:

 value = ['a', 'b', 'c']
 script = "var elem = $('select#tradingMarketSelect'); "
 script += "elem.val(%s); " % value
 script += "elem.change();"
 self.driver.execute_script(script)

I've spent some time to get it working in FF, Chrome and IE8-11.

  1. Click the drop arrow
  2. Click the required li

Here is my simplified code:

[FindsBy(How = How.ClassName, Using = "select2-arrow")]
private IWebElement Selector { get; set; }

private void selectItem(string itemText)
{
    Selector.Click();  // open the drop
    var drop = Driver.FindElement(By.Id("select2-drop"));    // exists when open only
    var item = drop.FindElement(By.XPath(String.Format("//li[contains(translate(., '{0}', '{1}'), '{1}')]", itemText.ToUpper(), itemText.ToLower())));
    item.Click();
}

Here's my code(Getting/Displaying):

Getting select2 available elements(Results):

public List<WebElement> getDataFromSelect2(String elementXpath)
{       
    WebElement select2Element = driver.findElement(By.xpath(elementXpath));
    select2Element.click();     

    WebDriverWait webDriverWait = new WebDriverWait(driver, 90);
    webDriverWait.until(ExpectedConditions.presenceOfElementLocated(By.xpath("//ul[@class='select2-results']//div")));

    WebElement select2ElementResults=driver.findElement(By.xpath("//div[@id='select2-drop']/ul[@class='select2-results']"));
    List<WebElement> selectResultsAsListCollection = select2ElementResults.findElements(By.tagName("div"));

    return selectResultsAsListCollection; 
}

Displaying select2 available elements(Results)

Using select2 with id(attribute) of: s2id_autogen1:

List<WebElement> select2Results = getDataFromSelect2("//input[@id='s2id_autogen1']");

for(WebElement item: select2Results)
{
    System.out.println(item.getText());
}

Could you please show us the locators as well? Here is what I tested without any issues.

Note

  1. To open select box, use css selector #s2id_e1 .select2-choice, or equivalent XPath.
  2. Make sure #select2-drop is the visible one, by css selector #select2-drop:not([style*='display: none']), or equivalent XPath.
  3. Make sure to click the selectable item using subContainerClass + .select2-results li.select2-result-selectable, or equivalent XPath.
var driver = new FirefoxDriver();
driver.Url = "http://ivaynberg.github.io/select2/";

var select2Product = driver.FindElement(By.CssSelector("#s2id_e1 .select2-choice"));
select2Product.Click();

string subContainerClass = "#select2-drop:not([style*='display: none'])";
var searchBox = driver.FindElement(By.CssSelector(subContainerClass + " .select2-input"));
searchBox.SendKeys("Ohio");

var selectedItem = driver.FindElements(By.CssSelector(subContainerClass + " .select2-results li.select2-result-selectable")).First();
selectedItem.Click();