简体   繁体   中英

How to extract the display attribute of an element using Selenium Webdriver and Java

unable to locate the hidden element in div

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

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

display:block"> ==$0

I want to locate the display element, but the element is hidden, i have written the code for it too.

String abc=d.findElement(By.xpath("//div[@id='divDuplicateBarcodeCheck']/"))
.getAttribute("display");
 System.out.println(abc);
 Thread.sleep(3000);
 if(abc.equalsIgnoreCase("block"))      
 {          
 d.findElement(By.id("duplicateBarcodeCheck")).click();   
System.out.println("duplicate barcode Close");                                              
}
else    
{    System.out.println("Barcode selected");}

There is no such attribute as display . It's part of style attribute.

You can either find the element and get its attribute 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");}
}

OR you can find this element directly with cssSelector (it's also possible with xpath):

WebElement abc = d.findElement(By.cssSelector("div[id='divDuplicateBarcodeCheck'][style*='display: block']"))

Note, that above will throw NoSuchElementException if the element was not found. You can use try-catch block to perform similar operations just like you did in if-else statement like this:

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");
}

If I'm getting you correct you are trying to archive checking if an element is displayed or not. You could do something like this using plain selenium and 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));
}

Your Test (an end-to-end UI test!) should not stick to an implementation detail like display:none or display:block . Imagine the implementation will be changed to remove the element via javascript or something. A good selenium test should always try represent a real users perspective as good as possible. Means if the UI will still behave the same your test should still be successful. Therefore you should do a more general check - is an element displayed or not.

This is one of the basic functionalities of Seleniums WebElement interface , or to be even more precise its isDisplayed() method.

Quote from the Selenium Java Docs :

boolean isDisplayed()

Is this element displayed or not? This method avoids the problem of having to parse an element's "style" attribute. Returns: Whether or not the element is displayed

Furthermore I would recommend to write some small helper methods for things like that, in my experience it's a common use case you'll face more often. helper method could for instance look something like this:

boolean isElementVisible(final By by) {
    return driver.findElement(by).isDisplayed();
}

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

If you are using some Selenium abstractions like FluentLenium or Selenide things will become even more convenient because they provide things like assertion extensions and custom matchers for well known assertion libraries like assertJ, hamcrest, junit.

For instance with FluentLenium and AssertJ (a stack that i can personally recommend) the answer for your problem is looking as easy as this:

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

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

Some more thoughts:

You should also use CSS selectors if possible instead of xPath selectors. CSS selectors are less fragile , it will speed up your tests and are better readable .

You should have a look at implicit waits instead of using Thread sleeps (bad practice). you can again implement helper methods like this by yourself, eg:

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));
}

or (what i would recommend) use a library for that, for instance Awaitility

If your are looking for a more extended example you can have a look here:

Seems there is an extra / at the end of the which you need to remove. Additionally, you need to induce WebDriverWait for visibilityOfElementLocated() . So effectively your line of code will be:

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");
}

Virtually, if() block is still an overhead and you can achieve the same with:

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");
}

Q1. I want to locate the display element, but the element is hidden, i have written the code for it too.

A1. As per your below code:

 <div id="divDuplicateBarcodeCheck" class="spreadsheetEditGui" style="z- index: 1200; width: 640px; height: 420px; top: 496.5px; left: 640px; display:block"> ==$0 

It doesn't look hidden, the problem is that your using incorrect xpath and element getter.

Use:

String abc = d.findElement(By.xpath("//div[@id='divDuplicateBarcodeCheck']"))
.getCssValue("display");

Instead of:

 => .getAttribute("display");

Alternative method using JavascriptExecutor:

JavascriptExecutor jse = (JavascriptExecutor) d;
String displayProperty = (String) jse.executeScript("return 
document.getElementById('divDuplicateBarcodeCheck').style.display");
System.out.println("Display property is: "+displayProperty);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM