简体   繁体   English

悬停元素列表-Selenium Java WebDriver

[英]Hover list of elements - Selenium Java WebDriver

Below is the scenario I am trying to test using Selenium WebDriver (2.53.1) and Java. 以下是我尝试使用Selenium WebDriver(2.53.1)和Java进行测试的方案。

On a webpage, I have a list of stars. 在网页上,我有一个星星列表。 I want to hover over each of them, the stars get highlighted as we do a mouse hover. 我想将鼠标悬停在它们上面,当我们进行鼠标悬停时,星星会突出显示。 Then click on one of the stars. 然后单击星星之一。 The css changes when each of the stars are hovered. 当每个星星都悬停时,css会发生变化。

Before hover 悬停前

  <div class="wh-rating-choices" style="display: none;">
        <div class="wh-rating-choices-holder">
                                <a href="#">1</a>
                                <a href="#">2</a>
                                <a href="#">3</a>
                                <a href="#">4</a>
                                <a href="#">5</a>
                            <em>Your Rating: <span></span></em>
        </div>
    </div>

After hover 悬停后

   <div class="wh-rating-choices" style="display: none;">
        <div class="wh-rating-choices-holder">
                                <a href="#" class="hover">1</a>
                                <a href="#" class="hover">2</a>
                                <a href="#" class="hover">3</a>
                                <a href="#" class="hover">4</a>
                                <a href="#" class="hover">5</a>
                            <em>Your Rating: <span>Excellent</span></em>
        </div>
    </div>

So basically, on successful hover, the class 'hover' gets added in the html/css. 因此,基本上,在成功悬停时,会在html / css中添加“悬停”类。

Code I have tried is as below. 我尝试过的代码如下。

List<WebElement> allStars = driver.findElements(By.xpath("//a[@class='hover']"));
System.out.println("<<<<<<<<<<<<------List of all stars, size------------>>>>>>>>>>"+allStars.size());
for (WebElement e : allStars) {
    Actions act = new Actions(driver);
    act.moveToElement(e).build().perform();
    Thread.sleep(5000);
}

As before hover, the class 'hover' is not added, the list of WebElements is always zero. 与悬停之前一样,未添加类“悬停”,WebElement的列表始终为零。 Tried some of the options suggested on some selenium sites, but did not work. 尝试了一些硒站点上建议的某些选项,但是没有用。 Please help, how to proceed on this one. 请帮助,如何进行这一步骤。

I've just tested a solution, but it is very crude. 我刚刚测试了一个解决方案,但是它很粗糙。 It works, however. 但是,它可以工作。

Note: navigating directly to the fifth star (the element with text "5") didn't work for me. 注意:直接导航至第五颗星(文字为“ 5”的元素)对我不起作用。 It seems you need to hover such that the rating holder box opens, and then hover to the fifth star so that you get all of them as class="hover". 似乎您需要将鼠标悬停以打开“评级持有人”框,然后将鼠标悬停在第五颗星上,以便将它们全部都作为class =“ hover”。

This is what I did: 这是我所做的:

-- navigate to the element above ("Write a review") with Actions -使用操作导航到上方的元素(“撰写评论”)

-- move down (positive "y") in increments of 1 pixel -以1像素为增量向下移动(正“ y”)

-- after every increment, test if the element with class "wh-rating-choices" contains string "block" -每次增加之后,测试“ wh-rating-choices”类的元素是否包含字符串“ block”

-- if it does, move to element with text "5" contained under the element with class "wh-rating-choices-holder" -如果是的话,请移至元素为“ wh-rating-choices-holder”的元素下包含文本为“ 5”的元素

I tested it in python, but here is what should work in Java: 我在python中进行了测试,但这是在Java中应该起作用的内容:

Actions action = new Actions(driver);
int inc = 0;
while (inc < 100) {
    WebElement top = driver.findElement(By.xpath("//*[contains(text(), 'Write a Review')]"));
    action.moveToElement(top, 0, inc).contextClick().perform();
    Thread.sleep(200);
    a = driver.findElement(By.xpath("//*[contains(@class, 'wh-rating-choices')]"));
    if (a.getAttribute("style").contains("block") {
        aa = driver.findElement(By.xpath("//*[contains(@class, 'wh-rating-choices-holder')]"));
        bb = aa.findElement(By.xpath(".//*[contains(text(), '5')]"));
        action.moveToElement(bb).perform();
        break;
    }
    inc++;
}
System.out.println(bb.getAttribute("outerHTML"));

Thread.sleep(200) could be overkill, try something lower, like 50 or 20. Thread.sleep(200)可能会过大,请尝试较低的值,例如50或20。

PS. PS。 It is possible you will need to close the pop-up first, the one that has class="af-icon-cross" 您可能需要先关闭弹出窗口,该弹出窗口具有class="af-icon-cross"

Seems you were close. 看来您很亲密。 You need to induce WebDriverWait for the <a> elements with class="hover" to be clickable and you can use the following solution: 您需要使class="hover"<a>元素的WebDriverWait成为可单击的,并且可以使用以下解决方案:

WebElement rating_holder = driver.findElement(By.xpath("//div[@class='wh-rating-choices']"));
((JavascriptExecutor)driver).executeScript("arguments[0].removeAttribute('style')", rating_holder)
List<WebElement> allStars = new WebDriverWait(driver, 20).until(ExpectedConditions.visibilityOfAllElementsLocatedBy(By.xpath("//div[@class='wh-rating-choices']/div[@class='wh-rating-choices-holder']//a")));
System.out.println("<<<<<<<<<<<<------List of all stars, size------------>>>>>>>>>>"+allStars.size());
for (WebElement e : allStars) {
    if(e.getAttribute("innerHTML").contains("5"))
    {
        new Actions(driver).moveToElement(e).build().perform();
        new WebDriverWait(driver, 20).until(ExpectedConditions.elementToBeClickable(By.xpath("//div[@class='wh-rating-choices-holder']//a[@class='hover']"))).click();
    }
}

The issue with your code is that you are looking for A tags that already have the 'hover' class before you even hover. 代码的问题在于,您甚至在悬停之前正在寻找已经具有'hover'类的A标签。 As you stated, the 'hover' class doesn't get added until after the hover occurs. 如您所述,只有发生悬停之后才添加“悬停”类。 So you would need to change your initial locator to not include the 'hover' class. 因此,您需要更改您的初始定位器以包括“ hover”类。

I prefer to use CSS selectors over XPath unless XPath is required (finding element by contained text or DOM traversal). 除非需要XPath(通过包含的文本或DOM遍历查找元素),否则我更喜欢在XPath上使用CSS选择器。 You can do some googling for more info. 您可以进行谷歌搜索以获取更多信息。 Here's is tested code. 这是经过测试的代码。

// find all A tags inside the containing DIV
List<WebElement> stars = driver.findElements(By.cssSelector("div.wh-rating-choices-holder > a"));

// loop through each element and hover
Actions action = new Actions(driver);
for (WebElement e : stars)
{
    action.moveToElement(e).perform();
}

// after all the hovering is done, fetch the same elements but expect that they will now contain the 'hover' class
stars = driver.findElements(By.cssSelector("div.wh-rating-choices-holder > a.hover"));

// Assert (TestNG) that there are 5 stars that were hovered
Assert.assertEquals(stars.size(), 5, "Verify 5 elements were hovered");

// click the 5th star
stars.get(4).click();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM