使用Selenium网络驱动程序处理Select2
本文关键字:处理 Select2 驱动程序 网络 Selenium 使用 | 更新日期: 2023-09-27 18:23:55
我一直在用selenium网络驱动程序从启用ajax的select2选择列表中选择一个选项。我已经设法让它与IE网络驱动程序一起工作,但没有与firefox一起工作。这是我的IE 破解解决方案
public static void SetSelect2Option(this IWebDriver driver, By locator, string subContainerClass, string searchTerm, TimeSpan? ajaxWaitTimeSpan = null)
{
var select2Product = driver.FindElement(locator);
select2Product.Click();
var searchBox = driver.FindElement(By.CssSelector(subContainerClass + " .select2-input"));
searchBox.SendKeys(searchTerm);
if (ajaxWaitTimeSpan != null)
{
driver.Manage().Timeouts().ImplicitlyWait(ajaxWaitTimeSpan.Value);
}
var selectedItem = driver.FindElements(By.CssSelector(subContainerClass + " .select2-results li")).First();
selectedItem.Click();
selectedItem.SendKeys(Keys.Enter);
}
在Firefox中,这个解决方案一直工作到SendKeys调用的点,它只是挂起并进入下一步,而不实际触发select2的事件来填充所选项目。
我也厌倦了使用http://code.google.com/p/selenium/wiki/AdvancedUserInteractions具有类似结果的api。
以前有人遇到过类似的问题吗?
你能给我们看看定位器吗?以下是我在没有任何问题的情况下测试的内容。
注意
- 若要打开选择框,请使用css选择器
#s2id_e1 .select2-choice
或等效的XPath - 通过css选择器
#select2-drop:not([style*='display: none'])
或等效的XPath,确保#select2-drop
是可见的 - 请确保使用
subContainerClass
+.select2-results li.select2-result-selectable
或等效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();
我花了一些时间让它在FF、Chrome和IE8-11中工作。
- 单击下拉箭头
- 单击所需的li
这是我的简化代码:
[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();
}
我使用下面的代码来选择所需的选项,它成功了。这也必须比执行多次单击更快。
String script = "$('select#yearSelector').trigger($.Event('change',{val:'" + year + "'}))";
((JavascriptExecutor) driver).executeScript(script);
而且,在Python中,如果这一行不起作用,请尝试将其拆分为组件:
value = ['a', 'b', 'c']
script = "var elem = $('select#tradingMarketSelect'); "
script += "elem.val(%s); " % value
script += "elem.change();"
self.driver.execute_script(script)
这是我的代码(获取/显示):
获取select2
可用元素(结果):
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;
}
显示select2
可用元素(结果)
使用id(属性)为:s2id_autogen1
:的select2
List<WebElement> select2Results = getDataFromSelect2("//input[@id='s2id_autogen1']");
for(WebElement item: select2Results)
{
System.out.println(item.getText());
}
这里有一个可靠的、可重复使用的解决方案,它可以处理与一个页面上的多个select2下拉菜单交互的额外问题。
出于某种原因,网络驱动程序没有考虑将搜索值发送到的元素是可见的,即使你可以在屏幕上看到它,并且光标就在其中。这就是"如果显示"测试所检查的。然后它使用不同的选择器。
这是一个功能,你可以发送你想与之交互的字段的ID(减去标准的s2id_)和要选择的值(或者至少足够的值来进行选择)
额外的thread.sleep()只是为了帮我看。我不认为它们会影响结果。
public void SelectDropDownOption(string dropDownID, string option)
{
for (int second = 0; ; second++)
{
if (second >= 60) Assert.Fail("timeout");
try
{
if (driver.FindElement(By.CssSelector("div[ID^=s2id_" + dropDownID + "]>a.select2-choice")).Displayed) break;
}
catch (Exception)
{ }
Thread.Sleep(1000);
}
driver.FindElement(By.CssSelector("div[ID^=s2id_" + dropDownID + "]>a.select2-choice")).Click();
Thread.Sleep(1000);
if (driver.FindElement(By.CssSelector("input.select2-input.select2-focused")).Displayed == true)
{
driver.FindElement(By.CssSelector("input.select2-input.select2-focused")).SendKeys(option);
Thread.Sleep(500);
driver.FindElement(By.CssSelector("input.select2-input.select2-focused")).SendKeys(Keys.Enter);
Thread.Sleep(500);
}
else
{
driver.FindElement(By.CssSelector("input.select2-focusser.select2-offscreen")).SendKeys(option);
Thread.Sleep(500);
driver.FindElement(By.CssSelector("input.select2-focusser.select2-offscreen")).SendKeys(Keys.Enter);
Thread.Sleep(500);
}
}
protected void SelectOptionForSelect2(IWebDriver driver, string id, string text)
{
var element = driver.FindElement(By.Id(id)).FindElement(By.XPath("following-sibling::*[1]"));
element.Click();
element = driver.FindElement(By.CssSelector("input[type=search]"));
element.SendKeys(text);
Thread.Sleep(1000);
element.SendKeys(Keys.Enter);
}
尝试选择执行webdriver javascript。下面是一个方便的C#方法。
// usings
using System;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
// method
public static void SetSelect2Option_JSExample(this IWebDriver driver, string select2Id, string value)
{
IJavaScriptExecutor jsExecutor = (IJavaScriptExecutor)driver;
string js = "$('#" + select2Id + "').val('" + value + "').trigger('change');";
string jsOutput = (string)jsExecutor.ExecuteScript(js);
}
对于2022年的读者。。。使用SelectElement类与select2交互:(csharp)
IWebElement select2Element = _webDriver.FindElement(By.Id("select2"));
var select2 = new SelectElement(select2Element);
select2.SelectByText("foo");
//example of getting an item from the list
var selectOptions= select2.Options.Select(x => x.Text).ToList();