【问题标题】:mimic jQuery autocomplete with Selenium WebDriver ExecuteScript command使用 Selenium WebDriver ExecuteScript 命令模仿 jQuery 自动完成功能
【发布时间】:2012-02-14 23:27:52
【问题描述】:

注意:

要回答这个问题,您不必了解 Selenium 或 WebDriver,只需了解 jQuery 知识即可。这就是我没有足够知识的地方——这正是我问这个问题的原因。 :-) 如果您还没有听说过 Selenium WebDriver,它只是一种通过代码自动化您的网站或 Web 应用程序的方法(我在示例中使用的是 C# 客户端驱动程序)。

另请注意,我的 FirefoxDriver 对象已打开本机事件

环境:

下面是 HTML 和 JavaScript 的 sn-p,用于在您开始输入时自动完成您在输入字段中输入的文本。当您选择一个值时,它会设置一个隐藏字段,其中包含根据输入字段中输入的记录名称选择的值的 id。我的目标是通过调用 ExecuteScript 方法来调用一些 jQuery 代码来模仿 WebDriver 中的这种自动完成行为。但由于我知道我们试图在 WebDriver 中匹配的确切值,所以我想模仿最终用户使用该值在字段中键入的内容。如何才能做到这一点?

如果我不能让它工作,我的答案是直接用 id 设置隐藏字段。但我宁愿将文本传递给它,这样我就可以真正模仿最终用户正在做的事情。 WebDriver 脚本将只输入部分或全部文本(在 ac_variation_id 中设置值),并且不会通过 AJAX 检索记录 id(在variation_id 隐藏字段中设置值)。下面,我设置了这两个值。但是,我只想要一个获取 id 并设置 id 的 jQuery 脚本,或者模拟在输入中键入值。

所以我必须通过以下两种方法之一来解决它:
- 让 WebDriver 模拟自动完成 100%
- 让 WebDriver 调用一个 JavaScript 脚本(jQuery AJAX 调用),该脚本执行页面除了键入值之外的所有操作,以便使用为所选选项返回的 id 设置隐藏字段

我也不知道该怎么做。

示例 jQuery 脚本设置带有 id 的隐藏字段和带有文本的输入字段:

Element.SetValueById(driver, "variation_id", discount.Variation);  // set input field with text
Element.SetValueById(driver, "ac_variation_id", "123");  // set hidden field with id

        public static void SetValueById(IWebDriver driver, string tagId, string newValue)
        {
            IJavaScriptExecutor js = driver as IJavaScriptExecutor;
            js.ExecuteScript("$('#" + tagId + "').val('" + newValue + "')");
        }

用于自动完成功能的 HTML 代码和 JavaScript 代码:

<link rel="stylesheet" href="http://localhost/admin/css/vanilla/jquery.ui.autocomplete.css" media="screen" type="text/css" />

<script type='text/javascript' src="http://localhost/admin/js/vanilla/jquery-ui-1.7.1.custom.min.js"></script>
<script type="text/javascript" src="http://localhost/admin/js/vanilla/jquery.ui.autocomplete.ext.js"></script>
<script type="text/javascript" src="http://localhost/admin/js/vanilla/jquery.ui.autocomplete.js"></script>

<input type="text"  name="ac_variation_id" id="ac_variation_id" value="" class="autocomplete" autocomplete="off" />
<button type="button" value="clear" name="cl_variation_id" id="cl_variation_id"  onclick="$('#variation_id').val('');$('#ac_variation_id').val('');"  >clear</button>
<input type="hidden" name="variation_id" id="variation_id" value="" />

<script>
    $('#ac_variation_id').autocomplete({ 
        ajax: 'http://localhost/admin/discount/ajax-auto-complete/variation',
        match: function(typed) { 
                return this.name;//.match(new RegExp("^"+typed, "i")); had to comment that out to be able to type integration_id and display name 
        },
        insertText: function(entity) { 
                return entity.name +' '+ (( entity.integration_id == undefined ) ? '' : entity.integration_id);
        }
    }).bind("activate.autocomplete",function(e, entity){

        var id = '#'+($(this).attr('id').substring(3));//remove ac_ prefix
        $(id).val( entity.id );
    });
</script>

在输入字段中输入文本后自动完成查找值的屏幕截图:

【问题讨论】:

    标签: c# jquery webdriver jquery-autocomplete selenium-webdriver


    【解决方案1】:

    使用自动完成小部件需要测试两件事:1) 在文本字段中输入内容,以及 2) 从自动完成列表中选择一个项目。

    这些答案在 ruby​​ 中,但我怀疑有相应的 C# 版本

    在文本字段中输入

    search_term = "stackoverflow.com"
    
    input = find('#q')
    input.click
    
    # this is the same as input.set(search_term[0..5]) I believe
    search_term[0..5].chars.each do |key|
        input.native.send_key(key)
    end
    

    从自动完成列表中选择一个项目(通过项目的文本)

    search_term = "stackoverflow.com"
    selector = ".ui-menu-item a:contains(\"#{@search_term}\")"
    page.execute_script " $('#{selector}').trigger(\"mouseenter\").click();"
    
    # I have 4 auto completes on my page, so I just wait until they all gone
    wait_until do
        autocompletes = all(:css, '.ui-autocomplete')
        autocompletes.inject(true) { |x,autocomplete| x && !autocomplete.visible? }
    end
    

    【讨论】:

      【解决方案2】:

      我无法模仿自动完成并选择选项,所以我调用 JSON GET 请求来获取隐藏字段的 id,并将隐藏字段设置为它找到的第一个匹配项(如果有多个)。

      Element.SetHiddenFieldIdViaAutoCompleteJSON(driver, "/admin/discount/ajax-auto-complete/variation", "val", discount.Variation, "id", "variation_id");
      
      public static void SetHiddenFieldIdViaAutoCompleteJSON(IWebDriver driver, string requestPage, string queryParam, string queryParamValue, string jsonObjectProperty, string hiddenFieldId)
      {
          IJavaScriptExecutor js = driver as IJavaScriptExecutor;
          js.ExecuteScript("$.ajax({ url: '" + Config.SITE_URL + requestPage + "',data:{'" + queryParam + "':'" + queryParamValue + "'},dataType:'json',type: 'GET',contentType: 'application/json',success: function(jsonObject) { $('#" + hiddenFieldId + "').val(jsonObject[0]." + jsonObjectProperty + "); } });");
      }
      

      【讨论】:

        【解决方案3】:

        使用 Selenuim IDE 并导出为 Java 代码,我将结果调整为以下函数,以便我可以选择要更改的自动完成组合框。 (这也在我所有的 PageObjets 扩展的“基础”类中。

        public BasicPage selectComboBox(int buttonIndex, String selection) {
          driver.findElement(By.xpath("(//button[@type='button'])[" + buttonIndex + "]")).click();
          driver.findElement(By.xpath("//html/body/ul/li/a[. = \"" + selection + "\"]")).click();
        
          // delay till the selected element is visible
          WebElement duh = (new WebDriverWait(driver, 10)).until( visibilityOfElementLocated(By.xpath("(//button[@type='button'])[" + buttonIndex +"]" )) ) ;     
        
          return this;
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2012-03-01
          • 1970-01-01
          • 2011-09-10
          • 2015-06-20
          • 1970-01-01
          • 1970-01-01
          • 2022-08-15
          • 1970-01-01
          相关资源
          最近更新 更多