Find div element by multiple class names?

前端 未结 3 1877
孤城傲影
孤城傲影 2020-11-28 21:18

I\'d like to identify that web element. It only has this two classes defined. I cannot do the following as className
相关标签:
3条回答
  • 2020-11-28 21:27

    I don't think barak manos's answer has fully explained it.

    Imagine we have few elements as the followings:

    1. <div class="value test"></div>
    2. <div class="value test "></div>
    3. <div class="first value test last"></div>
    4. <div class="test value"></div>

    How XPath matches

    • Match only 1 (exact match), barak's answer

      driver.findElement(By.xpath("//div[@class='value test']"));
      
    • Match 1, 2 and 3 (match class contains value test, class order matters)

      driver.findElement(By.xpath("//div[contains(@class, 'value test')]"));
      
    • Match 1, 2, 3 and 4 (as long as elements have class value and test)

      driver.findElement(By.xpath("//div[contains(@class, 'value') and contains(@class, 'test')]"));
      

    Also, in cases like this, Css Selector is always in favor of XPath (fast, concise, native).

    • Match 1

      driver.findElement(By.cssSelector("div[class='value test']"));
      
    • Match 1, 2 and 3

      driver.findElement(By.cssSelector("div[class*='value test']"));
      
    • Match 1, 2, 3 and 4

      driver.findElement(By.cssSelector("div.value.test"));
      
    0 讨论(0)
  • 2020-11-28 21:42

    Try this:

    test = driver.findElement(By.xpath("//div[@class='value test']"));
    
    0 讨论(0)
  • 2020-11-28 21:42

    Class By.ByClassName

    Class By.ByClassName is defined in By.java as follows:

    /**
     * Find elements based on the value of the "class" attribute. If an element has multiple classes, then
     * this will match against each of them. For example, if the value is "one two onone", then the
     * class names "one" and "two" will match.
     *
     * @param className The value of the "class" attribute to search for.
     * @return A By which locates elements by the value of the "class" attribute.
     */
    public static By className(String className) {
      return new ByClassName(className);
    }
    

    This usecase

    So as per the defination you can't pass multiple classes i.e. value and test as arguments to @FindBy(className = "..."). Sending multiple classes will raise an error as:

    invalid selector: Compound class names not permitted
    

    Solution

    There are multiple approaches to solve this usecase as follows:

    • If the element is uniquely identified only through the classname value you can use:

      @FindBy(className = "value")
      @CacheLookup
      private WebElement test;
      
    • If the element is uniquely identified only through the classname test you can use:

      @FindBy(className = "test")
      @CacheLookup
      private WebElement test;
      
    • If both the classnames, value and test are mandatory to identify the element, you can use css-selectors as follows:

      @FindBy(css  = ".value.test")
      @CacheLookup
      private WebElement test;
      
    • As an alternative you can also use xpath as follows:

      @FindBy(xpath   = "//*[@class='value test']")
      @CacheLookup
      private WebElement test;
      

    tl; dr

    Invalid selector: Compound class names not permitted error using Selenium

    0 讨论(0)
提交回复
热议问题