代码之家  ›  专栏  ›  技术社区  ›  Jack Miller

Selenium取消选择所有不适用于具有多个属性的HTML选择

  •  1
  • Jack Miller  · 技术社区  · 7 年前

    我正在使用 this HTML code :

    <select name="cars" multiple>
      <option value="volvo">Volvo</option>
      <option value="saab">Saab</option>
      <option value="opel">Opel</option>
      <option value="audi">Audi</option>
    </select>
    

    手动选择一些项目。然后我想取消选择所有这些选项(我使用的是C,但这并不重要):

    var carsElement = BrowserDriver.FindElementByName("cars");
    var carsSelect = new SelectElement(carsElement);
    carsSelect.DeselectAll();
    

    会发生什么:第一个选择的选项保持选中状态,其他选项则不被选中。

    看看代码这就是 必须 发生,因为 DeselectAll() 电话 Click() 对于所有选定的选项。您可以在浏览器中尝试。这永远不会取消选择 全部的 选项(除非单击时按住ctrl,但硒代码不执行此操作)。所以正确的方法是改变 DeselectAll 单击时按Ctrl键,如所示 How to perform Control key down in selenium webdriver?

    总之,我知道如何解决这个问题;我的问题是:我遗漏了什么吗?有更简单的方法吗?是 SelectElement 不是从HTML中选择多个?

    4 回复  |  直到 7 年前
        1
  •  0
  •   Guy    7 年前

    Select 类可以处理多选项下拉列表。它甚至在使用时检查下拉列表是否是多项选择 DeselectAll() . 从 github

    public void DeselectAll()
    {
        if (!this.IsMultiple)
        {
            throw new InvalidOperationException("You may only deselect all options if multi-select is supported");
        }
    
        foreach (IWebElement option in this.Options)
        {
            SetSelected(option, false);
        }
    }
    
    private static void SetSelected(IWebElement option, bool select)
    {
        bool isSelected = option.Selected;
        if ((!isSelected && select) || (isSelected && !select))
        {
             option.Click();
        }
    }
    

    当您在不按控制键的情况下单击第一个选择选项时,此选项将保持选中状态,但所有其他选项将被取消选中,因此实际上不会对其余选项执行单击,因为这两个选项都是 isSelected select false 在里面 SetSelected .

    解决方案要么是实现您自己的 取消选择() 如问题中建议的那样,或从下拉列表中选择第一个选项(将自动取消选择所有其他选项),然后使用控件取消选择此选项。

        2
  •  2
  •   pguardiario    7 年前

    您可以用

    browser.execute_script("[...document.querySelectorAll('[name=cars] option')].map(o => o.selected = false)")
    
        3
  •  0
  •   Jack Miller    7 年前

    即使我没有要求代码如何设置选择状态,我还是会为遇到相同问题的任何人发布它。这是C代码。你需要新的包裹 Selenium.WebDriver Selenium.Support . BrowserDriver 是包含此方法的帮助程序类的成员变量。

    /// <summary>
    /// Sets the selection state of <paramref name="selectElement"/>. All options specified  by <paramref name="selectedOptions"/>
    /// are select, all others are unselected.
    /// </summary>
    /// <param name="selectElement">HTML select element</param>
    /// <param name="selectedOptions">options to be selected</param>
    internal void SelectStateByText(OpenQA.Selenium.Support.UI.SelectElement selectElement, params string[] selectedOptions)
    {
        Assert.IsNotNull(selectElement);
        Assert.IsNotNull(selectedOptions);
        CollectionAssert.IsSubsetOf(selectedOptions, selectElement.Options.Select(o => o.Text).ToArray());
        if (!selectElement.IsMultiple)
        {
            Assert.AreEqual(1, selectedOptions.Length);
            selectElement.SelectByText(selectedOptions[0]);
        }
        else
        {
            var actions = new OpenQA.Selenium.Interactions.Actions(BrowserDriver);
            actions.KeyDown(Keys.LeftControl);
            foreach (var option in selectElement.Options)
            {
                if (selectedOptions.Contains(option.Text) && !option.Selected)
                {
                    actions.Click(option);
                }
                else if (option.Selected)
                {
                    actions.Click(option);
                }
            }
            actions.KeyUp(Keys.LeftControl).Build().Perform();
        }
    }
    
        4
  •  -1
  •   undetected Selenium    7 年前

    我已经验证了您使用 deselect_all() method through the Selenium python client的 usecase->em>

    取消选择_all()。

    deselect_all(). >a>method clears all selected entries.只有当选择支持多个选择时,此选项才有效。如果选择不支持多个选择,则引发NotImplementedError。


    插图

    注意 :正如您在问题中提到的,我还模拟了所有项目的选择 manually

    • 代码块:

      从Selenium导入WebDriver 来自selenium.webdriver.common.by import by 从Selenium.webDriver.support.ui导入webDriverWait 来自selenium.webdriver.support导入预期的欧盟条件 从Selenium.webDriver.support.ui导入选择 导入时间 选项=webdriver.chromeoptions() 选项。添加参数(“开始最大化”)。 选项。添加参数(‘disable-infobars’) driver=webdriver.chrome(chrome_options=options,executable_path=r'c:\utility\browserdrivers\chrome driver.exe') driver.get(“https://www.w3schools.com/tags/tryit.asp?”)文件名=tryhtml_select_multiple') webdriverwait(driver,10).until(EC.frame_to_be_available_and_switch_to_it((by.id,“iframesult”)) 选择“cars=select”(driver.find_element_by_css_selector(“select[name='cars']”))) time.sleep(5)手动选择所有项目的时间范围 选择“汽车”。取消选择“全部”()
      
                   
    • 浏览器快照:

    女士工作 完美的 .

    取消选择()

    deselect_all() 方法清除所有选定的项。只有当选择支持多个选择时,此选项才有效。如果选择不支持多个选择,则引发NotImplementedError。


    插图

    注意 :正如您在问题中提到的,我还模拟了所有项目的选择。 手动

    • 代码块:

      from selenium import webdriver
      from selenium.webdriver.common.by import By
      from selenium.webdriver.support.ui import WebDriverWait 
      from selenium.webdriver.support import expected_conditions as EC
      from selenium.webdriver.support.ui import Select
      import time
      
      options = webdriver.ChromeOptions() 
      options.add_argument("start-maximized")
      options.add_argument('disable-infobars')
      driver=webdriver.Chrome(chrome_options=options, executable_path=r'C:\Utility\BrowserDrivers\chromedriver.exe')
      driver.get('https://www.w3schools.com/tags/tryit.asp?filename=tryhtml_select_multiple')
      WebDriverWait(driver, 10).until(EC.frame_to_be_available_and_switch_to_it((By.ID,"iframeResult")))
      select_cars = Select(driver.find_element_by_css_selector("select[name='cars']"))
      time.sleep(5) # Timeframe to Manually select all the items
      select_cars.deselect_all()
      
    • 浏览器快照:

    deselect_all.gif

    推荐文章