即使使用JavascriptExecutor滚动也无法单击元素

时间:2017-09-10 17:02:55

标签: java eclipse selenium selenium-webdriver

以下是我的测试脚本。即使我在滚动窗口,我也无法点击该元素。我也试过使用显式等待。 我收到一个WebDriverException,说Element is not clickable at point (588, 1611)

driver.manage().timeouts().implicitlyWait(20, TimeUnit.SECONDS);
		int success = 0;
		driver.get("http://www.gcrit.com/build3/admin");
		driver.findElement(By.name("username")).sendKeys("admin");
		driver.findElement(By.name("password")).sendKeys("admin@123");
		driver.findElement(By.id("tdb1")).click();
		driver.findElement(By.xpath("//a[text()='Categories/Products']")).click();
		JavascriptExecutor jse = (JavascriptExecutor)driver;
		jse.executeScript("window.scrollTo(0,3004)","");
		
		String str = "Mockingjay";
		List <WebElement> lt1 = driver.findElements(By.tagName("td"));
		Iterator <WebElement> it1 = lt1.iterator();
	
		while(it1.hasNext())
		{
			
			WebElement el = it1.next();
			if(el.getText().contains(str))
			{
				WebDriverWait wait = new WebDriverWait(driver, 20);
				wait.until(ExpectedConditions.elementToBeClickable(el));
				el.click();
				break;
			}
			
		}
		
		driver.findElement(By.xpath("//span[text()='Edit']")).click();
		
		if(driver.findElement(By.xpath("//td[text()='Products Status:']/following-sibling::td/input[1]")).isSelected())
		{
			System.out.println("Changing the product status to 'Out of Stock'");
		}
		

这是源代码。我尝试将所有td tags放入列表中,在其中进行迭代以找到element并点击它。

 <tr class="dataTableRow" onmouseover="rowOverEffect(this)" onmouseout="rowOutEffect(this)" onclick="document.location.href='http://www.gcrit.com/build3/admin/categories.php?cPath=&amp;pID=1391'">
                <td class="dataTableContent"><a href="http://www.gcrit.com/build3/admin/categories.php?cPath=&amp;pID=1391&amp;action=new_product_preview"><img src="images/icons/preview.gif" border="0" alt="Preview" title=" Preview " /></a> LED TV/52"</td>
                <td class="dataTableContent" align="center">
<img src="images/icon_status_green.gif" border="0" alt="Active" title=" Active " width="10" height="10" />  <a href="http://www.gcrit.com/build3/admin/categories.php?action=setflag&amp;flag=0&amp;pID=1391&amp;cPath="><img src="images/icon_status_red_light.gif" border="0" alt="Set Inactive" title=" Set Inactive " width="10" height="10" /></a></td>
                <td class="dataTableContent" align="right"><a href="http://www.gcrit.com/build3/admin/categories.php?cPath=&amp;pID=1391"><img src="images/icon_info.gif" border="0" alt="Info" title=" Info " /></a> </td>
              </tr>
              <tr class="dataTableRow" onmouseover="rowOverEffect(this)" onmouseout="rowOutEffect(this)" onclick="document.location.href='http://www.gcrit.com/build3/admin/categories.php?cPath=&amp;pID=1494'">
                <td class="dataTableContent"><a href="http://www.gcrit.com/build3/admin/categories.php?cPath=&amp;pID=1494&amp;action=new_product_preview"><img src="images/icons/preview.gif" border="0" alt="Preview" title=" Preview " /></a> Mock</td>
                <td class="dataTableContent" align="center">
<img src="images/icon_status_green.gif" border="0" alt="Active" title=" Active " width="10" height="10" />  <a href="http://www.gcrit.com/build3/admin/categories.php?action=setflag&amp;flag=0&amp;pID=1494&amp;cPath="><img src="images/icon_status_red_light.gif" border="0" alt="Set Inactive" title=" Set Inactive " width="10" height="10" /></a></td>
                <td class="dataTableContent" align="right"><a href="http://www.gcrit.com/build3/admin/categories.php?cPath=&amp;pID=1494"><img src="images/icon_info.gif" border="0" alt="Info" title=" Info " /></a> </td>
              </tr>
              <tr class="dataTableRow" onmouseover="rowOverEffect(this)" onmouseout="rowOutEffect(this)" onclick="document.location.href='http://www.gcrit.com/build3/admin/categories.php?cPath=&amp;pID=1507'">
                <td class="dataTableContent"><a href="http://www.gcrit.com/build3/admin/categories.php?cPath=&amp;pID=1507&amp;action=new_product_preview"><img src="images/icons/preview.gif" border="0" alt="Preview" title=" Preview " /></a> Mockingjay</td>
                <td class="dataTableContent" align="center">
<img src="images/icon_status_green.gif" border="0" alt="Active" title=" Active " width="10" height="10" />  <a href="http://www.gcrit.com/build3/admin/categories.php?action=setflag&amp;flag=0&amp;pID=1507&amp;cPath="><img src="images/icon_status_red_light.gif" border="0" alt="Set Inactive" title=" Set Inactive " width="10" height="10" /></a></td>
                <td class="dataTableContent" align="right"><a href="http://www.gcrit.com/build3/admin/categories.php?cPath=&amp;pID=1507"><img src="images/icon_info.gif" border="0" alt="Info" title=" Info " /></a> </td>
              </tr>

3 个答案:

答案 0 :(得分:2)

当我编写这样的代码时,我尽量让事情变得简单。我把将要重用的代码放到函数中,以便更容易调用和更容易维护。

在您的情况下,您循环遍历所有TD,寻找包含与您要查找的产品相匹配的文本的元素。我们可以使用XPath搜索特定元素,而不是这样做。

//td[@class='dataTableContent'][contains(.,'Mockingjay')]

你也有滚动的代码,等待元素可点击等等,但没有必要。在Java / Selenium中,当您尝试单击元素时,如果它不可见,页面将自动滚动。

我查看了你的代码并将其分解为不同的操作并为每个代码编写了一个函数。然后我编写了使用这些函数来执行您尝试执行的操作的代码。这是工作代码,我没有看到Element is not clickable错误。

以下是功能

public static void deleteSelectedCategory()
{
    driver.findElement(By.cssSelector("#tdb4 > span.ui-button-text")).click();
}

public static void editSelectedCategory()
{
    driver.findElement(By.cssSelector("#tdb3 > span.ui-button-text")).click();
}

public static boolean isProductInStock(String productName)
{
    return !driver.findElements(By.xpath("//tr[./td[@class='dataTableContent'][contains(.,'" + productName + "')]]//img[@src='images/icon_status_green.gif']")).isEmpty();
}

public static void login(String username, String password)
{
    driver.findElement(By.name("username")).sendKeys(username);
    driver.findElement(By.name("password")).sendKeys(password);
    driver.findElement(By.id("tdb1")).click();
}

public static void selectCategory(String categoryName)
{
    driver.findElement(By.xpath("//a[.='Categories/Products']")).click();
    driver.findElement(By.xpath("//td[@class='dataTableContent'][contains(.,'" + categoryName + "')]")).click();
}

以下是驱动您的方案的代码

String productName = "Mockingjay"; // in stock
// String productName = "Baloon"; // out of stock
driver.get("http://www.gcrit.com/build3/admin");
login("admin", "admin@123");

selectCategory(productName);
boolean inStock = isProductInStock(productName);
System.out.println("Product is in stock: " + inStock);
if (inStock)
{
    editSelectedCategory();
    System.out.println("Changing the product status to 'Out of Stock'");
    // set the product to out of stock
}
顺便说一下,您无需编辑产品以查看产品是否缺货。红灯/绿灯表示是否缺货。我编写的代码检查页面上是否显示绿灯,如果是,则编辑产品并添加占位符,您可以在其中添加代码以将产品更改为缺货等。

答案 1 :(得分:1)

让我回答一下“无法点击”的根本原因。问题来自以下代码:

List <WebElement> lt1 = driver.findElements(By.tagName("td"));

代码会在页面上找到所有td,而不仅仅是td里面的&#39; Categories / Products&#39;表

列表中的第一个td已经无法点击,而其他一些td也无法点击。这就是为什么selenium报告不可点击的错误

要解决您的问题,您需要在上面的driver.findElements()中使用更严格的定位器,如下所示://tbody[tr[@class='dataTableHeadingRow']]//td[@class='dataTableContent'][1]

但我建议你采取Jeffc给出的解决方案。

即使在xpath以上,我也只能在&#39; Categories / Products&#39;内找到td。表,但在找到的列表中有许多不必要的td,浪费时间迭代每一个来过滤掉它们。

答案 2 :(得分:0)

我将非常具体地回答这个问题。我也会保持简单的方法。以下代码块会记录到网址中,点击 Categories/Products ,向下滚动以将元素 New Category 按钮带入Viewport作为参考,通过正确的 List 从所选元素中创建xpath,最后遍历列表并点击WebElement text() Mockingjay

package demo;

import java.util.List;

import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.firefox.FirefoxDriver;

public class Q46143300_gcreddy_site {

    public static void main(String[] args) {


        System.setProperty("webdriver.gecko.driver", "C:\\Utility\\BrowserDrivers\\geckodriver.exe");
        WebDriver driver = new FirefoxDriver(); 
        driver.get("http://www.gcrit.com/build3/admin");
        driver.findElement(By.name("username")).sendKeys("admin");
        driver.findElement(By.name("password")).sendKeys("admin@123");
        driver.findElement(By.xpath("//button[@id='tdb1']")).click();
        driver.findElement(By.xpath("//a[text()='Categories/Products']")).click();
        WebElement new_catagory = driver.findElement(By.id("tdb1"));
        JavascriptExecutor jse = (JavascriptExecutor)driver;
        jse.executeScript("arguments[0].scrollIntoView(true);",new_catagory);
        String str = "Mockingjay";
        List <WebElement> my_list = driver.findElements(By.xpath(".//*[@id='contentText']//td[@class='dataTableContent']"));
        for (WebElement item:my_list)
        {
            if(item.getAttribute("innerHTML").contains(str))
            {
                item.click();
                break;
            }

        }
    }

}