Selenium在动态下拉列表中使用滚动查找元素(Java)

vq8itlhq  于 2023-06-28  发布在  Java
关注(0)|答案(3)|浏览(136)

我在玩 selenium ,最近才开始看下拉菜单和选择元素。
为了学习Selenium,我使用以下网站:http://www.smartclient.com/smartgwt/showcase/?sc_selenium=true#featured_dropdown_grid_category
有一个下拉网格,我正试图在其中定位一个元素。由于下拉列表是动态的,并且有一个滚动条,所以我需要向下滚动并定位一个元素。谁能给予我提示,我如何找到并选择这样的下拉列表中的一个元素?假设我想选择:

Item: contains "Envelopes"
Unit: "EA"
Unit Cost: gather then 0.2

下面是我的代码:

By itemPicker = ByScLocator.xpath("/html/body/div[2]/div/div/div/div/div[1]/div[2]/div/div/div[4]/div[1]/div/div/div/div[1]/div/div/div/form/table/tbody[2]/tr[2]/td[2]/table/tbody/tr/td[1]");
            driver.findElement(itemPicker).click();
            WebDriverWait wait = new WebDriverWait(driver, 30);
            wait.until(ExpectedConditions.elementToBeClickable(itemPicker));
            driver.findElement(itemPicker).sendKeys();

            boolean find = false;           
                while (!find) {

                    By menuItems = ByScLocator.xpath("//tr[contains(@id, \"isc_PickListMenu_\")]");
                    List<WebElement> all = driver.findElements(menuItems);

                    try {
                        //Verify if all elements still exists in DOM
                        for (WebElement element : all) {
                            element.findElements(By.tagName("td"));
                        }
                    } catch (StaleElementReferenceException e) {
                        all = driver.findElements(menuItems);
                    }

                    for (WebElement element : all) {
                        List<WebElement> columns = element.findElements(By.tagName("td"));                          
                        String currenlyProcessedItem = columns.get(0).getText();
                        if (currenlyProcessedItem.matches(".*Envelopes.*")) {
                            if (columns.get(1).getText().equals("Ea")) {
                                if (Double.parseDouble(columns.get(2).getText()) > 0.2) {
                                        find = true;
                                    element.click();
                                    break;
                                }
                            }
                        }
                    }

                    if (find) { //load another set of list items
                            driver.findElement(By.id("isc_3N")).sendKeys(Keys.PAGE_DOWN);
                    }

        }

问题是,我无法向下滚动列表,并确定我想选择的项目。我也不知道我的方法是否最佳。

lndjwyie

lndjwyie1#

在此选择列表中只能选择一个项目。我想问题是,你要找的东西不在单子上。只要选择列表处于打开状态,滚动条就不重要。
如果您尝试只选择一个项目,那么这适用于项目“胶水UHU透明胶250ml”

public class selectItem {
    @Test
    public void selectItem(){
    WebDriver driver = new FirefoxDriver();
    driver.manage().window().maximize();
    driver.get("http://www.smartclient.com/smartgwt/showcase/?sc_selenium=true#featured_dropdown_grid_category");

    // Open select list
    driver.findElement(By.id("isc_1Y")).click();
    // Select row based on a string present
    driver.findElement(By.xpath("//div[contains(text(), 'Glue UHU Clear Gum 250ml')]")).click();

    driver.quit();
    }
}
xzv2uavs

xzv2uavs2#

使用下面的解决方案,我能够在下拉列表中获得要解决的元素。在滚动内容时,实现中有明显的时间依赖性来解释StaleElementExceptions,但我希望这些可以通过多一点努力过滤掉。
如果测试没有立即通过,请尝试将'pollingEvery'时间增加到1/秒。我很确定这将基于它正在运行的机器,这可能需要寻址。

/** Desired text to find in the dropdown.*/
    String text = "Envelopes Kraft 305 x 255mm (12 x 10) (84GSM)";
    //String text = "Pens Stabiliner 808 Ballpoint Fine Black";

    /**
     * Test to try to find a reference inside a scrollable gwt dropdown container.
     * <p/>
     * Behavior is heavily timing dependent and will take progressively longer as the content in the dropdown increases.
     * <p/>
     * I'm sure this can be optimized, but as a proof it does the job.
     */
    @Test
    public void gwtDropdownWithScrollContent() {

        WebDriver driver = new FirefoxDriver();
        try {
            driver.get(
                "http://www.smartclient.com/smartgwt/showcase/?sc_selenium=true#featured_dropdown_grid_category");
            WebDriverWait wait = new WebDriverWait(driver, 240);
            By dropdownTwiddle = By.xpath(".//*[@id='isc_1Y']");
            //Find the combo and hit the twiddle button to expand the options.
            WebElement we = wait.until(ExpectedConditions.elementToBeClickable(dropdownTwiddle)); // Find the drop down
            we.click();

            /*
             * Create a function to use with the webdriver wait. Each iteration it will resolve the table object, find
             * all of the rows, and try to find the desired text in the first <td> field of each row.
             * 
             * If the element is not found, the scroll bar is resovled and the Actions class is used to get a hold of
             * the scroll bar and move it down. Then the wait loops and tries again.
             */
            Function<WebDriver, WebElement> scrollFinder = new Function<WebDriver, WebElement>() {
                By optionTable = By.xpath(".//*[@id='isc_3A']");
                By scrollElement = By.xpath(".//*[@id='isc_3N']/table/tbody/tr/td/img");

                public WebElement apply(WebDriver arg0) {
                    WebElement table = arg0.findElement(optionTable);
                    List<WebElement> visibleEntries = table.findElements(By.xpath(".//tr"));
                    WebElement reference = null;

                    for (WebElement element : visibleEntries) {
                        if (ExpectedConditions.stalenessOf(element).apply(arg0)) {
                            //This happens if the scroll down happens and we loop back too quickly and grab the contents of the table before it refreshes.
                            //Seems to be tied directly to the poll configuration for the web driver wait.
                            continue;
                        }
                        WebElement firstColumn = element.findElement(By.xpath(".//td"));
                        String colVal = firstColumn.getText();
                        if (!Strings.isNullOrEmpty(colVal)) {
                            if (text.equalsIgnoreCase(firstColumn.getText())) {
                                reference = element;
                                break;
                            }
                        }
                    }

                    if (reference == null) {
                        //If the element wasn't found then scroll down and retry the effort.
                        WebElement scrollBar = arg0.findElement(scrollElement);
                        Actions actions = new Actions(arg0);
                        //The offset below may be increased to make a larger scroll effort between iterations.
                        actions.moveToElement(scrollBar).clickAndHold().moveByOffset(0, 5).release().build().perform();
                    }

                    return reference;
                }
            };
            //XXX:  THIS is the time to increase if the test doesn't seem to "work".
            wait.pollingEvery(500, TimeUnit.MILLISECONDS); // Setting too low can cause StaleElementException inside the
                                                           // loop. When scrolling down the Object can be refreshed and
                                                           // disconnected from the DOM. 

            Assert.assertNotNull(wait.until(scrollFinder));
        } finally {
            driver.close();
        }

    }

祝你好运。

9njqaruj

9njqaruj3#

使用滚动在动态下拉列表中查找元素(Selenium Java)

{driver.get("https://www.amazon.com/");
    Actions action = new Actions(driver);
    
    WebElement all = driver.findElement(By.cssSelector("#searchDropdownBox"));
    all.click();
    Thread.sleep(2000);
    
    action.moveToElement(all).perform();

    action.sendKeys(Keys.ARROW_DOWN).sendKeys(Keys.ARROW_DOWN).sendKeys(Keys.ARROW_DOWN).sendKeys(Keys.ARROW_DOWN)
            .sendKeys(Keys.ARROW_DOWN).sendKeys(Keys.ARROW_DOWN).sendKeys(Keys.ARROW_DOWN).sendKeys(Keys.ARROW_DOWN)
            .sendKeys(Keys.ARROW_DOWN).sendKeys(Keys.ARROW_DOWN).sendKeys(Keys.ARROW_DOWN).sendKeys(Keys.ARROW_DOWN)
            .sendKeys(Keys.ARROW_DOWN).sendKeys(Keys.ARROW_DOWN).sendKeys(Keys.ARROW_DOWN).sendKeys(Keys.ARROW_DOWN)
            .sendKeys(Keys.ARROW_DOWN).sendKeys(Keys.ARROW_DOWN).sendKeys(Keys.ARROW_DOWN).sendKeys(Keys.ARROW_DOWN)
            .sendKeys(Keys.ARROW_DOWN).sendKeys(Keys.ARROW_DOWN).sendKeys(Keys.ENTER).perform();
    Thread.sleep(2000);}

相关问题