Try this sample here for JS workaround - implemented as C# extension. This code works on Safari (tested on version 10.1+).
This is not the complete code, just a snippet to make it simple. You can extend it to support any functionality you like.
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Internal;
using OpenQA.Selenium.Support.UI;
namespace Gravity.Plugins.Actions.Extensions
{
public static class SelectExtensions
{
/// <summary>
/// Select the option by the index, as determined by the "index" attribute of the
/// element.
/// </summary>
/// <param name="selectElement">This <see cref="SelectElement"/>.</param>
/// <param name="index">The value of the index attribute of the option to be selected.</param>
public static void JsSelectByIndex(this SelectElement selectElement, int index)
{
// constants
var script = $"options[{index}].selected = true;";
// web element to act on
var onElement = selectElement.WrappedElement;
var onDriver = (IWrapsDriver)onElement;
// execute
((IJavaScriptExecutor)onDriver).ExecuteScript(script, onElement);
}
/// <summary>
/// Select all options by the text displayed.
/// </summary>
/// <param name="selectElement">This <see cref="SelectElement"/>.</param>
/// <param name="text">The text of the option to be selected.</param>
public static void JsSelectByText(this SelectElement selectElement, string text)
{
// constants
var script =
"var options = arguments[0].getElementsByTagName('option');" +
"" +
"for(i = 0; i < options.length; i++) {" +
$" if(options[i].innerText !== '{text}') {{" +
" continue;" +
" }" +
" options[i].selected = true;" +
" break;" +
"}";
// web element to act on
var onElement = selectElement.WrappedElement;
var onDriver = (IWrapsDriver)onElement;
// execute
((IJavaScriptExecutor)onDriver).ExecuteScript(script, onElement);
}
/// <summary>
/// Select an option by the value.
/// </summary>
/// <param name="selectElement"></param>
/// <param name="value">The value of the option to be selected.</param>
public static void JsSelectByValue(this SelectElement selectElement, string value)
{
// constants
var script =
"var options = arguments[0].getElementsByTagName('option');" +
"" +
"for(i = 0; i < options.length; i++) {" +
$" if(options[i].getAttribute('value') !== '{value}') {{" +
" continue;" +
" }" +
" options[i].selected = true;" +
" break;" +
"}";
// web element to act on
var onElement = selectElement.WrappedElement;
var onDriver = (IWrapsDriver)onElement;
// execute
((IJavaScriptExecutor)onDriver).ExecuteScript(script, onElement);
}
}
// Usage sample
public class MySeleniumClass
{
public void DoAutomation()
{
var driver = new ChromeDriver()
{
Url = "https://gravitymvctestapplication.azurewebsites.net/UiControls"
};
var element = driver.FindElement(By.Id("select_menu"));
var selectElement = new SelectElement(element);
selectElement.JsSelectByIndex(1);
selectElement.JsSelectByText("Two");
selectElement.JsSelectByValue("3");
}
}
}