如何在机器人框架中选择动态列表元素(kendoUI)

时间:2018-07-20 18:03:51

标签: selenium dynamic frameworks robotframework dropdown

我正在尝试使用Robot Framework(Selenium)测试UI。我有一个下拉列表,它是动态填充的,我必须选择其中的一个文本。我可以单击下拉元素,然后将列表显示为弹出窗口。但是无法选择任何元素。当我尝试使用从列表中选择来访问下拉列表时,它返回一条错误,指出其不是列表。由于其动态ID并非恒定不变。

*<kendo-dropdownlist name="sel" style="width: 400px;" ng-reflect-data="[object Object],[object Object" ng-reflect-text-field="Name" ng-reflect-value-field="Id" ng-reflect-default-item="[object Object]" ng-reflect-value-primitive="true" ng-reflect-name="sel" class="k-widget k-dropdown k-header ng-valid ng-touched ng-dirty" ng-reflect-model="-9999">
 <span role="listbox" unselectable="on" class="k-dropdown-wrap k-state-default k-state-focused" ng-reflect-ng-class="[object Object]" id="5c2a0848-f6fa-433f-a927-8b645ac4047b" dir="ltr" readonly="false" tabindex="0" aria-disabled="false" aria-readonly="false" aria-haspopup="true" aria-expanded="false" aria-owns="c7cb9422-f181-4b66-905e-eaa05305a0e9" aria-activedescendant="b0f86e8c-1fea-4bee-9367-39a207fa4859-undefined">
<span unselectable="on" class="k-input" ng-reflect-ng-class="[object Object]">
<span unselectable="on" class="k-select" ng-reflect-ng-class="[object Object]">
</span>
</kendo-dropdownlist>*


*<kendo-popup class="ng-tns-c7-14 k-animation-container ng-star-inserted k-animation-container-shown" dir="ltr" style="left: 189.6px; top: 338.2px; min-width: 400px; width: 400px;">
<div class="k-popup ng-trigger ng-trigger-toggle k-list-container k-reset" ng-reflect-klass="k-popup" ng-reflect-ng-class="k-list-container,k-reset">
<div kendodropdownsselectable="" class="k-state-focused k-state-selected ng-star-inserted k-list-optionlabel" ng-reflect-ng-class="[object Object]" ng-reflect-index="-1" aria-selected="true" style="">Please Select</div>
<kendo-list ng-reflect-data="[object Object],[object Object" ng-reflect-text-field="Name" ng-reflect-value-field="Id" ng-reflect-height="200" ng-reflect-show="true" ng-reflect-id="c7cb9422-f181-4b66-905e-eaa053" ng-reflect-option-prefix="b0f86e8c-1fea-4bee-9367-39a207" class="ng-star-inserted" style="">
<div unselectable="on" class="k-list-scroller" ng-reflect-ng-class="[object Object]" style="max-height: 200px;">
<ul role="listbox" class="k-list k-reset" ng-reflect-ng-class="[object Object]" id="c7cb9422-f181-4b66-905e-eaa05305a0e9" aria-hidden="false">
<li kendodropdownsselectable="" role="option" class="k-item ng-star-inserted" ng-reflect-ng-class="[object Object]" ng-reflect-index="0" ng-reflect-multiple-selection="false" id="b0f86e8c-1fea-4bee-9367-39a207fa4859-5560" tabindex="-1">
................
................
<li kendodropdownsselectable="" role="option" class="k-item ng-star-inserted" ng-reflect-ng-class="[object Object]" ng-reflect-index="10" ng-reflect-multiple-selection="false" id="b0f86e8c-1fea-4bee-9367-39a207fa4859-5360" tabindex="-1">
</ul>
</div>
</kendo-list>
</div>
</kendo-popup>*

任何帮助或指针将不胜感激。谢谢。

1 个答案:

答案 0 :(得分:0)

最简单的选择是调用一些JavaScript。这是一个示例:

Custom Select From List by Label
    [Arguments]    ${locator}    ${label}    ${timeout}=${global_timeout}
    ${tempId} =    Generate Random String    8
    Wait Until Page Contains Element    locator=${locator}    timeout=${timeout}
    ${origId} =    Get Element Attribute    ${locator}    attribute=id
    Run Keyword If    "${origId}"=="${EMPTY}"    Assign Id To Element    locator=${locator}    id=${tempId}
    ${elementId} =    Set Variable If    "${origId}"=="${EMPTY}"    ${tempId}    ${origId}
    Execute Javascript    var dropdownlist = $find("${elementId}"); var itemByText = dropdownlist.findItemByText("${label}"); itemByText.select();

要添加的一件事:更好的方法是用Python(作为一个简单的关键字)来实现。这是我已经在项目中计划的,并且也在我们的路线图上。基本上,每条记录的行的机械手性能都会下降,如果您有2k +包,则可以轻松注意到差异。因此,我开始执行以下操作:

def select_checkbox(locator):
    seleniumlib = BuiltIn().get_library_instance('SeleniumLibrary')
    seleniumlib.wait_until_page_contains_element(locator)
    checkbox = seleniumlib.find_element(locator)
    elementId = seleniumlib.get_element_attribute(locator,"id")
    if elementId=='':
        elementId = uuid.uuid4()
        seleniumlib.assign_id_to_element(locator, elementId)
    seleniumlib.execute_javascript('$("#' + elementId + ':not(:checked)").click();')

它执行相同的工作,但速度更快。然后,您可以使用以下命令将自定义关键字设置为在原始SeleniumLibrary之前:

Set Library Search Order    MyCustomSeleniumLibrary    SeleniumLibary