2013-07-19 37 views
19

Tôi đã đập đầu vào tường cố gắng chọn một tùy chọn từ ajax cho phép select2 chọn danh sách với trình điều khiển web selenium. Tôi đã quản lý để làm cho nó làm việc với trình duyệt web IE nhưng không phải firefox. Đây là giải pháp hacky tôi cho IEXử lý Select2 với trình điều khiển web Selenium

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); 
    } 

Trong Firefox, giải pháp này làm việc cho đến khi điểm của SendKeys gọi nơi nó chỉ bị treo và di chuyển sang bước tiếp theo mà không thực sự bắn kiện Select2 để cư mục đã chọn.

Tôi cũng đã mệt mỏi khi sử dụng số http://code.google.com/p/selenium/wiki/AdvancedUserInteractions api với kết quả tương tự.

Có ai gặp phải vấn đề tương tự trước đây không?

Trả lời

24

Bạn có thể vui lòng cho chúng tôi biết người định vị không? Đây là những gì tôi thử nghiệm mà không có bất kỳ vấn đề.

Note

  1. Để mở hộp chọn, sử dụng css selector #s2id_e1 .select2-choice, hoặc XPath tương đương.
  2. Đảm bảo #select2-drop là hình ảnh hiển thị, bằng công cụ chọn css #select2-drop:not([style*='display: none']) hoặc XPath tương đương.
  3. Đảm bảo nhấp vào mục có thể chọn bằng cách sử dụng subContainerClass + .select2-results li.select2-result-selectable hoặc XPath tương đương.
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(); 
+2

FWIW, tôi đã phải sử dụng 'ClickAt' 5,5 thay vì nhấp chuột để làm việc này. – Daniel

+0

@Daniel: Nhiều khả năng bạn có các yếu tố khác chồng lên nhau. Phiên bản nào? Trình duyệt nào? –

+0

Đây là trong Selenium 2.4.0 trong FF. Tôi đang sử dụng IDE, nhưng sẽ mong đợi hành vi tương tự. Tôi mới sử dụng Selenium, nhưng không thể tưởng tượng điều gì sẽ gây ra nhấp chuột không hoạt động, khi clickAt thực hiện. Hành vi với nhấp chuột là menu thả xuống select2 không xuất hiện. Câu trả lời của bạn rất hữu ích trong việc đưa tôi đến các phần tử phù hợp ... – Daniel

2

Dưới đây là một giải pháp tái sử dụng rắn để xử lý các vấn đề bổ sung tương tác với nhiều Dropdowns Select2 trên một trang.

Vì lý do nào đó, trình quản trị web không xem xét yếu tố để gửi giá trị tìm kiếm đến mức hiển thị, mặc dù bạn có thể nhìn thấy nó trên màn hình và con trỏ ở trong đó. Đó là những gì kiểm tra 'nếu được hiển thị' kiểm tra. Sau đó, nó sử dụng một bộ chọn khác.

nó một chức năng mà bạn có thể gửi ID của lĩnh vực bạn muốn tương tác với (ít s2id_ tiêu chuẩn) và giá trị để chọn (hoặc ít nhất đủ của nó để làm cho sự lựa chọn.)

Các thêm thread.sleep() s chỉ để giúp tôi xem nó. Tôi không nghĩ chúng ảnh hưởng đến kết quả.

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); 
     } 

    } 
+0

Đây là một ví dụ tốt về thực hành mã hóa thực sự kém. –

+2

@HappyBird, Chúng ta đều ở đây để học hỏi. Bạn có thể đề xuất cải tiến không? Giải pháp của tôi có thể không hoàn hảo nhưng tôi cảm thấy nó cung cấp rất nhiều thông tin hữu ích. – KyleK

+0

Xin lỗi, tôi không cần phải thô lỗ. Ý tôi là 'Thread.Sleep()' nên tránh càng nhiều càng tốt. –

5

Tôi đã dành chút thời gian để làm việc trong FF, Chrome và IE8-11.

  1. Nhấp vào thả mũi tên
  2. Nhấp vào li cần

Dưới đây là mã đơn giản của tôi:

[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(); 
} 
3

Dưới đây là mã của tôi (Bắt/Hiển thị):

Bắt select2 các yếu tố có sẵn (Kết quả):

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; 
} 

Hiển thị select2 yếu tố có sẵn (Kết quả)

Sử dụng select2 với id (thuộc tính) của: s2id_autogen1:

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

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

tôi đã sử dụng mã dưới đây để chọn tùy chọn mong muốn và nó làm việc. Điều này cũng phải nhanh hơn so với thực hiện nhiều lần nhấp.

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

Và, trong Python, nếu điều này là một-liner không hoạt động, hãy thử tách nó thành các thành phần của nó:

value = ['a', 'b', 'c'] 
script = "var elem = $('select#tradingMarketSelect'); " 
script += "elem.val(%s); " % value 
script += "elem.change();" 
self.driver.execute_script(script) 
1
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); 
} 
Các vấn đề liên quan