Eclipse Java Selenium webdriver - 无法选择下拉项(ElementNotVisibleException)

时间:2015-10-15 14:58:57

标签: java eclipse selenium drop-down-menu

我的菜单中有一个下拉列表,我在点击下拉列表后尝试选择两个可用选项之一。我无法获得显示的选项,因此我无法点击任何一个。 这是页面上下拉列表的源代码:

<span class="ribbondropdown combined importantribbonbutton">
<div class="button_ribbon hasimage ">
<div id="ribbon_nav_dashboard_dropper" class="button_ribbon_dropper ">
<div class="inner"></div>

<div class="button_ribbon_dropdownsection" style="left: 1520px; top: 40px; display: block;">
<table class="dropdownlist" width="100%" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td class="icon"></td>
<td class="value">Option 1</td>
</tr>
<tr>
<td class="icon"></td>
<td class="value">Option 2</td>
</tr>
</tbody>
</table>
</div>
</div>
</span>

前四行是我要点击的区域。其余代码用于点击后可见的部分,此处我想点击“选项2”。

我现在正在使用以下内容:

driver.findElement(By.id("ribbon_nav_dashboard_dropper")).click();
driver.findElement(By.xpath("//div[@class='value' and text()='Option 2']")).click();
然而,这会导致失败:

org.openqa.selenium.ElementNotVisibleException: Element is not currently visible and so may not be interacted with

如果我注释掉第二行,只需点击下拉列表即可显示选项,并让测试显示未显示的选项。如果我手动执行此操作,我会得到两个选项。我查看了另一个具有相同异常的问题,但建议的解决方案对我不起作用:Java webdriver: Element not visible exception

3 个答案:

答案 0 :(得分:0)

您是否尝试将元素滚动到可见范围,然后再对其执行操作。如果元素在可见区域之外,则硒不能对其发射动作。

WebElement webelement = driver.findElement(By.xpath("//div[@class='value' and text()='Option 2']"))
JavascriptExecutor jsExecutor = (JavascriptExecutor) driver;
jsExecutor.executeScript("arguments[0].scrollIntoView(false);", webElement);
webElement.click();

答案 1 :(得分:0)

事实证明,我试图在下拉菜单中点击的选项位于一段代码中,该代码不可用。我不确定为什么自动点击不会改变给定元素的样式,但这是显示选项所必需的。我自动使用以下内容更改了元素的样式:

JavascriptExecutor js = (JavascriptExecutor) driver;
WebElement element = driver.findElement(By.xpath("//div[@class='dropdownsection']"));
js.executeScript("arguments[0].setAttribute('style', 'left: 1520px; top: 40px; display: block;')",element);

现在样式已更改,包含可用选项的代码部分处于活动状态,显示我的选项,现在我可以单击我的首选选项:

driver.findElement(By.xpath("//*[@class='value' and text()='Option 2']")).click();

答案 2 :(得分:0)

我将首先告诉您我正在学习HTML格式和语法,因此您可能会发现我在解决问题方面有很长的路要走。我尝试根据您的示例在本地创建基本网页,但我无法为此提案的任何验证创建下拉列表。

有人说......

  

&#34;如果我注释掉第二行,只需点击下拉列表即可   显示选项并使测试显示它未显示的选项。&#34;

首先关注此事。如果您无法显示该元素,那么您将永远无法点击它。

根据描述的行为,我认为您的组合ID查找可能是结构中的错误元素。

By.id("ribbon_nav_dashboard_dropper")

下面的Junit课程基本上是我如何进行测试,如果我有下拉的正确元素。在 buildLookups 方法中填写字符串数组,测试用例应告诉您输入的选项将允许选项[2]&#39;被点击。

我还在实现 performValidation 方法在这种情况下如何工作方面做了一些工作,但我建议仔细检查,以确保我已正确理解问题

package stackoverflow.proof.selenium;

import java.util.Collection;
import java.util.List;
import java.util.Map;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;

import com.google.common.base.Function;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;

/**
 * Parameterized test which can be used to validate lookups for a single well-defined desired interaction in Selenium.
 * 
 */
@RunWith(Parameterized.class)
public class SeleniumLookupValidationUtil {
    /** Test URL where the element should be validated.*/
    private static final String TEST_URL = "myURL";
    /** Function which converts a String into a {@link By#id(String)} reference.*/
    private static final Function<String, By> AS_ID_LOOKUP = new Function<String, By>() {
        @Override
        public By apply(String arg0) {
            System.out.println("Id Lookup: " + arg0);
            return By.id(arg0);
        }
    };
    /** Function which converts a String into a {@link By#xpath(String)} reference.*/
    private static final Function<String, By> AS_XPATH_LOOKUP = new Function<String, By>() {
        @Override
        public By apply(String arg0) {
            System.out.println("xpath Lookup: " + arg0);
            return By.xpath(arg0);
        }
    };
    /** Function which converts a String into a {@link By#cssSelector(String)} reference.*/
    private static final Function<String, By> AS_CSS_SELECTOR_LOOKUP = new Function<String, By>() {
        @Override
        public By apply(String arg0) {
            System.out.println("css Lookup: " + arg0);
            return By.cssSelector(arg0);
        }
    };
    /** Function which converts a String into a {@link By#className(String)} reference.*/
    private static final Function<String, By> AS_CLASS_NAME_LOOKUP = new Function<String, By>() {
        @Override
        public By apply(String arg0) {
            System.out.println("className Lookup: " + arg0);
            return By.className(arg0);
        }
    };
    /** Function which converts a String into a {@link By#linkText(String)} reference.*/
    private static final Function<String, By> AS_LINK_TEXT_LOOKUP = new Function<String, By>() {
        @Override
        public By apply(String arg0) {
            System.out.println("LinkText Lookup: " + arg0);
            return By.linkText(arg0);
        }
    };

    /**
     * Creates the data for running the test instance.
     * @return Collection of Object arrays.  Each array in the collection represents a different test execution.
     */
    @Parameters(name="{0}")
    public static Collection<Object[]> buildLookups() {
        //TODO:  Fill in add as many possible lookups for the drop-down element as you can find.
        String[] ids = new String[]{"id1", "id2"};
        String[] xpaths = new String[]{};
        String[] cssSelectors = new String[]{};
        String[] classNames = new String[]{"A", "B"};
        String[] linkTexts = new String[]{};

        //I use the map so I can loop through the dataset later.
        Map<Function<String, By>, String[]> associations = Maps.newHashMap();
        associations.put(AS_ID_LOOKUP, ids);
        associations.put(AS_XPATH_LOOKUP,xpaths);
        associations.put(AS_CSS_SELECTOR_LOOKUP, cssSelectors);
        associations.put(AS_CLASS_NAME_LOOKUP, classNames);
        associations.put(AS_LINK_TEXT_LOOKUP, linkTexts);

        List<Object[]> parameters = Lists.newArrayList();
        for (Function<String, By> converter: associations.keySet()) {
            String[] lookupStrings = associations.get(converter);
            for (String lookup : lookupStrings) {
                By by = converter.apply(lookup);
                parameters.add(new Object[]{by});
            }
        }

        return parameters;
    }

    /** The By lookup to use for the current test validation.*/
    private final By target;
    /** WebDriver for testing.*/
    private WebDriver driver;

    /**
     * Test constructor.
     * @param lookup By to be used for this validation.
     */
    public SeleniumLookupValidationUtil(By lookup) {
        this.target = lookup;
    }

    /**
     * Creates the webdriver and establishes our validation state.
     */
    @Before
    public void initWebDriver() {
        driver = new FirefoxDriver();
        driver.get(TEST_URL);
        //TODO:  Any other setup to make the test case valid.
    }

    /**
     * Performs the thing we actually want to know about.
     */
    @Test
    public void performValidation() {
        WebDriverWait wait = new WebDriverWait(driver, 30);
        wait.until(ExpectedConditions.elementToBeClickable(target));
        WebElement option2 = wait.until(ExpectedConditions.elementToBeClickable(By.xpath("//div[@class='value' and text()='Option 2']")));
        option2.click();
    }

    /**
     * Closes all test browser windows and destroys the driver reference.
     */
    @After
    public void destroyWebDriver() {
        for (String window : driver.getWindowHandles()) {
            driver.switchTo().window(window);
            driver.close();
        }
    }
}

我使用了google.guava api,你需要该库来运行这段代码。这是我用于该引用的maven pom依赖项:

 <dependency>
      <groupId>com.google.guava</groupId>
      <artifactId>guava</artifactId>
      <version>LATEST</version>
      <scope>compile</scope>
    </dependency>

最好的运气。