如何使用SeleniumWebDriver和Java提取元素的显示属性

如何使用SeleniumWebDriver和Java提取元素的显示属性,java,selenium,selenium-webdriver,display,getattribute,xpath,Java,Selenium,Selenium Webdriver,Display,Getattribute,Xpath,无法在div中找到隐藏的元素 <div id="divDuplicateBarcodeCheck" class="spreadsheetEditGui" style="z- index: 1200; width: 640px; height: 420px; top: 496.5px; left: 640px; display:block"> ==$0 似乎在末尾有一个额外的/,您需要删除它。此外,您需要为元素located()的可见性引入WebDriverWait。因此,

无法在div中找到隐藏的元素

<div id="divDuplicateBarcodeCheck" class="spreadsheetEditGui" style="z- 

 index: 1200; width: 640px; height: 420px; top: 496.5px; left: 640px; 

display:block"> ==$0

似乎在末尾有一个额外的
/
,您需要删除它。此外,您需要为元素located()的可见性引入WebDriverWait。因此,您的代码行实际上是:

String abc = new WebDriverWait(d, 20).until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//label[contains(.,'Leave Balance')]//following::div[@id='applyleave_leaveBalance']"))).getAttribute("style");
System.out.println(abc);
if(abc.contains("block"))
{          
    d.findElement(By.id("duplicateBarcodeCheck")).click();   
    System.out.println("duplicate barcode Close");                                              
}
else    
{    
    System.out.println("Barcode selected");
}
实际上,
if()
块仍然是一种开销,您可以通过以下方式实现这一点:

try {
    new WebDriverWait(d, 20).until(ExpectedConditions.elementToBeClickable(By.xpath("//label[contains(.,'Leave Balance')]//following::div[@id='applyleave_leaveBalance']"))).click();
    System.out.println("duplicate barcode Close");  
} catch (NoSuchElementException e) {
     System.out.println("Barcode selected");
}

似乎在末尾有一个额外的
/
,您需要删除它。此外,您需要为元素located()的可见性引入WebDriverWait。因此,您的代码行实际上是:

String abc = new WebDriverWait(d, 20).until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//label[contains(.,'Leave Balance')]//following::div[@id='applyleave_leaveBalance']"))).getAttribute("style");
System.out.println(abc);
if(abc.contains("block"))
{          
    d.findElement(By.id("duplicateBarcodeCheck")).click();   
    System.out.println("duplicate barcode Close");                                              
}
else    
{    
    System.out.println("Barcode selected");
}
实际上,
if()
块仍然是一种开销,您可以通过以下方式实现这一点:

try {
    new WebDriverWait(d, 20).until(ExpectedConditions.elementToBeClickable(By.xpath("//label[contains(.,'Leave Balance')]//following::div[@id='applyleave_leaveBalance']"))).click();
    System.out.println("duplicate barcode Close");  
} catch (NoSuchElementException e) {
     System.out.println("Barcode selected");
}

没有
display
这样的属性。它是
style
属性的一部分

您可以找到元素并获取其属性样式:

String style = d.findElement(By.xpath("//div[@id='divDuplicateBarcodeCheck']")).getAttribute("style");
if(style.contains("block")) {          
    d.findElement(By.id("duplicateBarcodeCheck")).click();   
    System.out.println("duplicate barcode Close");                                              
} else {   
    System.out.println("Barcode selected");}
}
或者可以使用
cssSelector
直接找到该元素(也可以使用xpath):

请注意,如果找不到元素,上面将抛出
NoSuchElementException
。您可以使用
try catch
块执行类似的操作,就像在
if else
语句中执行的操作一样,如下所示:

try {
    d.findElement(By.cssSelector("div[id='divDuplicateBarcodeCheck'][style*='display: block']"));
    d.findElement(By.id("duplicateBarcodeCheck")).click();
    System.out.println("duplicate barcode Close");  
} catch (NoSuchElementException e) {
     System.out.println("Barcode selected");
}
boolean isElementVisible(final By by) {
    return driver.findElement(by).isDisplayed();
}

boolean isElementVisible(final WebElement element) {
    return element.isDisplayed();
}

没有
display
这样的属性。它是
style
属性的一部分

您可以找到元素并获取其属性样式:

String style = d.findElement(By.xpath("//div[@id='divDuplicateBarcodeCheck']")).getAttribute("style");
if(style.contains("block")) {          
    d.findElement(By.id("duplicateBarcodeCheck")).click();   
    System.out.println("duplicate barcode Close");                                              
} else {   
    System.out.println("Barcode selected");}
}
或者可以使用
cssSelector
直接找到该元素(也可以使用xpath):

请注意,如果找不到元素,上面将抛出
NoSuchElementException
。您可以使用
try catch
块执行类似的操作,就像在
if else
语句中执行的操作一样,如下所示:

try {
    d.findElement(By.cssSelector("div[id='divDuplicateBarcodeCheck'][style*='display: block']"));
    d.findElement(By.id("duplicateBarcodeCheck")).click();
    System.out.println("duplicate barcode Close");  
} catch (NoSuchElementException e) {
     System.out.println("Barcode selected");
}
boolean isElementVisible(final By by) {
    return driver.findElement(by).isDisplayed();
}

boolean isElementVisible(final WebElement element) {
    return element.isDisplayed();
}

如果我没有弄错,您正在尝试存档检查元素是否显示。您可以使用纯selenium和java执行类似的操作:

// the @FindBy annotation provides a lazy implementation of `findElement()` 
@FindBy(css = "#divDuplicateBarcodeCheck")
private WebElement barcode;

@Test
public void example() {
    driver.get("http://some.url");
    waitForElement(barcode);
    // isDisplay() is natively provided by type WebElement
    if (barcode.isDisplayed()) {
        // do something
    } else {
        // do something else
    }
}

private void waitForElement(final WebElement element) {
    final WebDriverWait wait = new WebDriverWait(driver, 5);
    wait.until(ExpectedConditions.visibilityOf(element));
}
您的测试(一个端到端的UI测试!)不应该坚持像
display:none
display:block
这样的实现细节。想象一下,实现将被更改为通过javascript或其他方式删除元素。一个好的selenium测试应该总是尽可能好地代表真实用户的观点。也就是说,如果用户界面的行为仍然相同,那么测试应该仍然成功。因此,您应该进行更一般的检查-是否显示元素

这是其
isDisplayed()
方法的基本功能之一,或者更准确地说,这是其
isDisplayed()方法的基本功能之一

引用Selenium的话:

布尔值显示()

是否显示此元素? 这种方法避免了必须 解析元素的“样式”属性。 返回: 是否显示该元素

此外,我建议为类似的事情编写一些小助手方法,根据我的经验,这是一个您将经常遇到的常见用例。 例如,helper方法可以如下所示:

try {
    d.findElement(By.cssSelector("div[id='divDuplicateBarcodeCheck'][style*='display: block']"));
    d.findElement(By.id("duplicateBarcodeCheck")).click();
    System.out.println("duplicate barcode Close");  
} catch (NoSuchElementException e) {
     System.out.println("Barcode selected");
}
boolean isElementVisible(final By by) {
    return driver.findElement(by).isDisplayed();
}

boolean isElementVisible(final WebElement element) {
    return element.isDisplayed();
}
如果您正在使用一些Selenium抽象,比如or,那么它们将变得更加方便,因为它们为assertJ、hamcrest、junit等著名的断言库提供了断言扩展和自定义匹配器

例如,使用FluentLenium和AssertJ(我个人可以推荐一个堆栈),您的问题的答案看起来很简单:

// check if element is displayed
assertThat(el("#divDuplicateBarcodeCheck")).isDisplayed();

// check if element is not displayed
assertThat(el("#divDuplicateBarcodeCheck")).isNotDisplayed();
还有一些想法:

如果可能,还应该使用CSS选择器,而不是xPath选择器。CSS选择器不那么脆弱,它会加快测试速度,并且可读性更好

您应该看看隐式等待,而不是使用线程睡眠(糟糕的做法)。您也可以自己实现类似的帮助器方法,例如:

void waitForElement(final WebElement element) {
    final WebDriverWait wait = new WebDriverWait(driver, 5);
    wait.until(ExpectedConditions.visibilityOf(element));
}

void waitForElement(final By by) {
    final WebDriverWait wait = new WebDriverWait(driver, 5);
    wait.until(ExpectedConditions.visibilityOfElementLocated(by));
}

void waitForElementIsInvisible(final By by) {
    final WebDriverWait wait = new WebDriverWait(driver, 5);
    wait.until(ExpectedConditions.invisibilityOfElementLocated(by));
}
或者(我推荐的)使用一个库,例如

如果您正在寻找更广泛的示例,您可以在此处查看:


如果我没有弄错,您将尝试存档检查元素是否显示。您可以使用纯selenium和java执行类似的操作:

// the @FindBy annotation provides a lazy implementation of `findElement()` 
@FindBy(css = "#divDuplicateBarcodeCheck")
private WebElement barcode;

@Test
public void example() {
    driver.get("http://some.url");
    waitForElement(barcode);
    // isDisplay() is natively provided by type WebElement
    if (barcode.isDisplayed()) {
        // do something
    } else {
        // do something else
    }
}

private void waitForElement(final WebElement element) {
    final WebDriverWait wait = new WebDriverWait(driver, 5);
    wait.until(ExpectedConditions.visibilityOf(element));
}
您的测试(一个端到端的UI测试!)不应该坚持像
display:none
display:block
这样的实现细节。想象一下,实现将被更改为通过javascript或其他方式删除元素。一个好的selenium测试应该总是尽可能好地代表真实用户的观点。也就是说,如果用户界面的行为仍然相同,那么测试应该仍然成功。因此,您应该进行更一般的检查-是否显示元素

这是其
isDisplayed()
方法的基本功能之一,或者更准确地说,这是其
isDisplayed()方法的基本功能之一

引用Selenium的话:

布尔值显示()

是否显示此元素? 这种方法避免了必须 解析元素的“样式”属性。 返回: 是否显示该元素

此外,我建议为类似的事情编写一些小助手方法,根据我的经验,这是一个您将经常遇到的常见用例。 例如,helper方法可以如下所示:

try {
    d.findElement(By.cssSelector("div[id='divDuplicateBarcodeCheck'][style*='display: block']"));
    d.findElement(By.id("duplicateBarcodeCheck")).click();
    System.out.println("duplicate barcode Close");  
} catch (NoSuchElementException e) {
     System.out.println("Barcode selected");
}
boolean isElementVisible(final By by) {
    return driver.findElement(by).isDisplayed();
}

boolean isElementVisible(final WebElement element) {
    return element.isDisplayed();
}
如果您正在使用一些Selenium抽象,比如or,那么它们将变得更加方便,因为它们为assertJ、hamcrest、junit等著名的断言库提供了断言扩展和自定义匹配器

例如,使用FluentLenium和AssertJ(我个人可以推荐一个堆栈),您的问题的答案看起来很简单:

// check if element is displayed
assertThat(el("#divDuplicateBarcodeCheck")).isDisplayed();

// check if element is not displayed
assertThat(el("#divDuplicateBarcodeCheck")).isNotDisplayed();
还有一些想法:

如果可能,还应该使用CSS选择器,而不是xPath选择器。CSS选择器不那么脆弱,它会加快测试速度,并且可读性更好

您应该查看隐式等待,而不是使用线程