【问题标题】:how to handle combo boxes of ExtJS in selenium webdriver如何在 selenium webdriver 中处理 ExtJS 的组合框
【发布时间】:2013-04-30 09:26:31
【问题描述】:

您好,我有一个基于 ExtJS 的用户界面。我知道在 ExtJS 中,组合框不是真正的组合框,而是输入文本字段、下拉框图像和列表的组合。现在我能够识别控件,但我坚持从列表中选择值。在 HTML 源代码中,我看到该列表显示为单独的 div,并在我们单击下拉列表时附加在源代码的末尾。在下拉控件的 HTML 源代码下方找到。 {

<div id="ext-gen678" class="x-form-field-wrap x-form-btn-plugin-wrap" style="width: 556px;">
<div id="ext-gen676" class="x-form-field-wrap x-form-field-trigger-wrap x-trigger-wrap-focus" style="width: 521px;">
<input id="ext-gen677" type="hidden" name="GHVOg:#concat#~inputFld~ISGP_UNIV:ft_t_isgp.prnt_iss_grp_oid:0" value="">
<input id="GHVOg:Mixh8:0" class="x-form-text x-form-field gs_dropDown_input gs_req x-form-invalid x-form-focus" type="text" autocomplete="off" size="24" style="width: 504px;">
<img id="trigger-GHVOg:Mixh8:0" class="x-form-trigger x-form-arrow-trigger" alt="" src="../../ext/resources/images/default/s.gif">

}

在下拉列表的 HTML 源代码下方找到:

<div id="ext-gen726" class="x-layer x-combo-list x-resizable-pinned" style="position: absolute; z-index: 12007; visibility: visible; left: 294px; top: 370px; width: 554px; height: 123px; font-size: 11px;">
<div id="ext-gen727" class="x-combo-list-inner" style="width: 554px; margin-bottom: 8px; height: 114px;">
<div class="x-combo-list-item"></div>
<div class="x-combo-list-item">12h Universe</div>
<div class="x-combo-list-item">1h Universe</div>
<div class="x-combo-list-item">24h Universe</div>
<div class="x-combo-list-item">2h Universe</div>
<div class="x-combo-list-item x-combo-selected">4h Universe</div>

现在我从列表中选择值时遇到问题,因为列表的 div 元素未附加到控件。 另请参阅屏幕截图,其中我有多个类似的控件 [命名为“向宇宙添加安全性”]

在屏幕截图中,您可以看到突出显示的多个下拉菜单 [向 Universe 添加安全性],并且所有下拉菜单在列表中都具有相同的值。那么我如何从下拉列表中识别这些值。 我想知道 ExtJS 如何维护下拉 div 元素与组合框小部件的映射,以便我可以使用相同的逻辑来识别列表。谁能告诉我如何在 selenium webdriver 中做这件事?

【问题讨论】:

    标签: extjs selenium-webdriver


    【解决方案1】:

    您是否注意到页面上只有一个可见的x-combo-list? (让我知道你是否可以同时打开两个组合列表)

    因此你只需要关心可见的x-combo-list

    CSS 选择器:.x-combo-list[style*='visibility: visible;'] .x-combo-list-item

    Xpath://*[contains(@class, 'x-combo-list') and contains(@style, 'visibility: visible;')]//*[contains(@class, 'x-combo-list-item')]

    // untested java code, just for the logic
    public void clickComboItem(WebElement input, String target) {
        input.click(); // click input to pop up the combo list
        List<WebElement> comboItems = driver.findElements(By.cssSelector(".x-combo-list[style*='visibility: visible;'] .x-combo-list-item"));
        for (int i = 0; i <= comboItems.size(); i++) {
            WebElement item = comboItems.get(i);
            if (item.getText().eqauls(target)) {
                item.click();
                break;
            }
        }
    }
    
    // compilable C# version
    public void ClickComboItem(IWebElement input, string target) {
        input.Click();
        IList<IWebElement> comboItems = driver.findElements(By.CssSelector(".x-combo-list[style*='visibility: visible;'] .x-combo-list-item"));
        comboItems.First(item => item.Text.Trim() == target).Click();
    }
    

    【讨论】:

    • 谢谢!我玩了几个小时,这解决了我的问题。
    【解决方案2】:

    我可以建议的是:

    您可以捕获所有输入,例如:

    List<WebElement> inputList = driver.findElements(By.cssSelector("input cssSelector")); // you must complete this cssSelector
    WebElement input = inputList.get(0); // get the 1st input
    input.click(); //click on the first input and the option list appears.
    

    你抓住了所有的“选项”,比如:

    List<WebElement> optionList = driver.findElements(By.cssSelector(".x-combo-list-item")); // get all options
    WebElement option = optionList.get(1);
    option.click();
    input.sendKeys(option.getText()); //getText() get the html inner value
    

    这只是 Java 中的一个示例,如果您想为所有 inputs 自动填充此循环,您实际上可以使用循环 foreach

    【讨论】:

    • 嗨@e1che 我的问题是下拉控件与它显示的列表的链接。假设我希望为第三个组合框下拉列表选择一个值,那么如果我尝试通过文本搜索值,即出现在列表中,我将如何在 HTML 源代码中执行此操作,我将获得多个这样的控件。而且这也是非常危险的,因为相同的值也可能出现在其他一些下拉列表中。举个例子,现在有 2 个组合框在其列表中存储了整数,我如何在这两个组合框中选择值?
    【解决方案3】:

    我使用 JavaScriptExecutor,我的 SelectRandomOption 看起来像这样:

    public void SelectRandomOption()
    {
        String randomOptionIndex = "Math.floor(Math.random()*Ext.getCmp('" + ExtJSIdOfComboBox + "').getStore().getCount()-1)";
        String randomOptionValue = "Ext.getCmp('" + ExtJSIdOfComboBox + "').getStore().getAt(" + randomOptionIndex + ").getData()['model']";
        String jsScript = "Ext.getCmp('" + ExtJSIdOfComboBox + "').setValue(" + randomOptionValue + ");";
        js.ExecuteScript(jsScript);
    }
    

    【讨论】:

    • 我同意。但在这种情况下,我还是更喜欢 JavaScriptExecutor。仅仅是因为在 ExtJS 中经常有 'onselect'、'onclick' 和其他侦听器,这些侦听器可能很难(甚至不可能)用纯 selenium 驱动程序实现。
    【解决方案4】:

    我基本上使用了上面标记的答案,但是它需要一点适应 Ext Js 4.1。

    这本质上是相同的方法,但你需要寻找一个标有“x-boundlist”类的可见div

    我使用了 xpath 并使用了看起来像这样的查询:

    .//div[@class[contains(.,'x-boundlist')]]
    

    然后检索并单击与所需条目匹配的 li:

    .//li[normalize-space(text())='combobox entry text']
    

    我已经把 normalize-space 放在那里,因为如果你不修剪字符串,xpath 似乎有真正的问题。该方法进行左+右修剪并删除重复的空格,例如 ' blah blah ' 将更改为 'blah blah'

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-04-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-11-13
      • 1970-01-01
      • 1970-01-01
      • 2019-11-13
      相关资源
      最近更新 更多