Selenium使用scroll(Java)在动态下拉列表中查找元素
我在玩selenium,最近刚开始查看下拉列表和选择元素 为了学习Selenium,我使用以下网站: 有一个下拉网格,我试图在其中查找元素。 因为下拉菜单是动态的,并且有一个滚动条,所以我需要向下滚动并找到一个元素。 有人能给我一些提示,告诉我如何在这样的下拉列表中找到并选择一个元素吗? 假设我想选择:Selenium使用scroll(Java)在动态下拉列表中查找元素,java,selenium,drop-down-menu,scrollbar,Java,Selenium,Drop Down Menu,Scrollbar,我在玩selenium,最近刚开始查看下拉列表和选择元素 为了学习Selenium,我使用以下网站: 有一个下拉网格,我试图在其中查找元素。 因为下拉菜单是动态的,并且有一个滚动条,所以我需要向下滚动并找到一个元素。 有人能给我一些提示,告诉我如何在这样的下拉列表中找到并选择一个元素吗? 假设我想选择: Item: contains "Envelopes" Unit: "EA" Unit Cost: gather then 0.2 这是我的密码: By itemPic
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);
}
}
xpath(“/html/body/div[2]/div/div/div/div/div/div[1]/div[2]/div/div/div[4]/div[1]/div/div/div/div[1]/div/div/div/div/form/table/tbody[2]/table/tbody/tr/td[1]”;
driver.findElement(itemPicker).click();
WebDriverWait wait=新的WebDriverWait(驱动程序,30);
wait.until(ExpectedConditions.elementtobelickable(itemPicker));
driver.findElement(itemPicker.sendKeys();
布尔查找=假;
而(!find){
By menuItems=ByClocator.xpath(//tr[contains(@id,\“isc\u PickListMenu\”));
列出所有=driver.findElements(menuItems);
试一试{
//验证DOM中是否仍然存在所有元素
for(WebElement:all){
element.findElements(按.tagName(“td”));
}
}捕获(StaleElementReferenceException e){
all=驱动程序的findElements(menuItems);
}
for(WebElement:all){
列表列=element.findElements(按.tagName(“td”));
字符串currenlyProcessedItem=columns.get(0.getText();
如果(currenlyProcessedItem.matches(“.*信封。*”)){
if(columns.get(1.getText().equals(“Ea”)){
if(Double.parseDouble(columns.get(2.getText())>0.2){
发现=真;
元素。单击();
打破
}
}
}
}
if(find){//加载另一组列表项
driver.findElement(By.id(“isc_3N”)).sendKeys(key.PAGE_DOWN);
}
}
问题是我无法向下滚动列表并确定要选择的项目。
另外,我也不知道我的aproach是否最优。您只能在此选择列表中选择一项。 我想问题是,你想找的东西不在清单上。 只要选择列表打开,滚动条就不重要 如果您只是尝试选择一个项目,那么这适用于“Glue UHU Clear Gum 250ml”项目
使用下面的解决方案,我能够得到下拉列表中的元素来解析。在滚动内容时,实现中存在明显的时间依赖性,以解释StaleElementExceptions,但我希望这些可以用更多的努力过滤掉 如果你的考试没有通过,试着增加分数 “pollingEvery”时间为1/秒。我很确定这会是一个好消息 根据它运行的机器,这可能需要 寻址
/**要在下拉列表中找到的所需文本*/
String text=“信封牛皮纸305 x 255mm(12 x 10)(84GSM)”;
//String text=“笔稳定器808圆珠笔细黑色”;
/**
*尝试在可滚动的gwt下拉列表容器中查找引用的测试。
*
*行为严重依赖于时间,并且随着下拉列表中内容的增加,时间会逐渐延长。
*
*我相信这是可以优化的,但作为一个证明,它做的工作。
*/
@试验
public void gwtDropdownWithScrollContent(){
WebDriver=newfirefoxdriver();
试一试{
司机,快(
"http://www.smartclient.com/smartgwt/showcase/?sc_selenium=true#featured_dropdown_grid_category");
WebDriverWait wait=新的WebDriverWait(驱动程序,240);
By dropdownTwiddle=By.xpath(“./*[@id='isc_1Y']”);
//找到组合并点击旋转按钮展开选项。
WebElement we=wait.until(ExpectedConditions.elementtobelickable(dropdownTwiddle));//查找下拉列表
we.click();
/*
*创建一个与webdriver wait一起使用的函数
*并尝试在每行的第一个字段中查找所需的文本。
*
*如果找不到该元素,将解析滚动条,并使用Actions类获取
*滚动条并向下移动。然后等待循环并重试。
*/
函数scrollFinder=新函数(){
By optionTable=By.xpath(“./*[@id='isc_3A']”);
By scrollElement=By.xpath(“./*[@id='isc_3N']/table/tbody/tr/td/img”);
公共WebElement应用(WebDriver arg0){
WebElement表=arg0.findElement(optionTable);
List visibleEntries=table.findElements(By.xpath(“.//tr”);
WebElement引用=null;
for(WebElement元素:visibleEntries){
if(ExpectedConditions.stalenessOf(元素).apply(arg0)){
//如果向下滚动发生,并且我们太快地返回并在刷新前抓取表中的内容,就会发生这种情况。
//似乎与web驱动程序等待的轮询配置直接相关。
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();
}
}
/** 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();
}
}