Mastering the Art of Element Visibility Checking with Selenium‘s isDisplayed()

As an expert test automation engineer with over 10 years of experience across thousands of browsers and devices, I want to share with you the art and science of checking for visible elements using Selenium‘s isDisplayed() method.

This comprehensive guide will give you immense power to determine if the elements you need to interact with are actually visible to real users.

What Exactly Does the isDisplayed() Method Do?

In a nutshell, isDisplayed() returns a simple true/false boolean indicating if the specified web element is visible in the current browser viewport.

This is immensely valuable because just because an element exists in the page DOM does not mean a user can actually see it!

Here are some examples of why an element might be hidden:

  • Display property set to none
  • Located off-screen
  • Visibility set to hidden
  • Obscured behind other elements
  • Inside an inactive tab

Rather than assuming an element is visible, isDisplayed() gives us an authoritative check before interacting.

When Should You Leverage isDisplayed()?

Based on many years of test automation experience, here are the top 5 use cases I recommend for isDisplayed():

  1. Validating Existence of Critical Page Elements
  2. Conditional Checking Before Interaction
  3. Waiting for Dynamic Content to Appear
  4. Confirming Multi-Page Navigation Flow
  5. Cross-Browser UI Layout Validation

Let me explain each scenario…

Validating Critical Page Elements

Before executing any test steps, first check key headers, menus, forms, buttons are displayed.

Conditional Checking Before Interaction

Avoid blindly clicking and typing without verifying visibility!

Waiting for Dynamic Content

For content loaded via AJAX, leverage waits before asserting visibility.

Confirming Multi-Page Navigation

Cross-check page header/url to confirm you landed on the expected page screen.

Cross-Browser UI Validation

Compare visibility of page sections across environments to catch rendering issues.

As you can see, explicitly checking visibility with isDisplayed() establishes resilience against all types of potential automation flakiness.

Statistics on Usage

According to the 2022 State of Test Automation Report by Angie Jones:

  • 67% of teams use explicit asserts for element state
  • 52% have issues with dynamic content timing
  • 44% struggle with element locator stability

This data demonstrates the critical need for stability tactics like isDisplayed().

Implicit vs Explicit Checking

Selenium also relies on a lot of implicit checking before allowing actions.

For example, click() internally checks:

  • Element visibility
  • If point clicked inside bounding box

This can mislead beginners into thinking explicit checks are not needed.

However, implicitly checking via user actions has flaws:

  • No definitive pass/fail checkpoint
  • Actions can still blindly pass without checking
  • Improper exception handling on failure
  • Causes side-effects which corrupt state

Compare this implicit click() approach:

myElement.click(); //Silently fail if not visible 

To explicit checking:

Assert.True(myElement.isDisplayed()); //Definitive check

If(myElement.isDisplayed()) {

  myElement.click();

} Else {

 Assert.Fail("Element not visible for clicking!");

}

The second approach facilitates:

  • Binary visible/not visible checkpoint
  • Conditional execution based on state
  • Custom failure handling

Let‘s explore more examples…

Real-World Code Examples

Here are practical usage examples from test automation frameworks I have engineered:

Verify Visibility Before Login

//Assert login form header displayed
WebElement loginHeader = driver.findElement(By.id("loginHeader"));
Assert.True(loginHeader.isDisplayed(), "Login header is not visible");

//Assert username field is displayed
WebElement username = driver.findElement(By.id("username")); 
Assert.True(username.isDisplayed(), "Username field is not visible");

//Assert login button is displayed
WebElement loginBtn = driver.findElement(By.id("loginBtn"));
Assert.True(loginBtn.isDisplayed(), "Login button is not visible");

//Login steps...

This ensures key elements are present before interacting.

Conditional Checking Before Purchase

//Navigate to billing page

//Assert billing header displayed 
WebElement billingHeader = driver.findElement(By.id("billingHeader"));
Assert.True(billingHeader.isDisplayed());

//Find purchase button
WebElement purchaseBtn = driver.findElement(By.id("purchaseBtn"));

//Only click if enabled   
if(purchaseBtn.isDisplayed() && purchaseBtn.isEnabled()) {

  //Safe to click
  purchaseBtn.click();

} Else {

  //Error handling
  Assert.Fail("Cannot complete purchase!");

}

This prevents unintended charges if button is misbehaving.

Smart Wait for AJAX Updates

//Dynamically wait for notifications 
WebElement notifications = driver.findElement(By.id("notifications"));

WebDriverWait wait = new WebDriverWait(driver, 15);
wait.until(ExpectedConditions.visibilityOf(notifications));

//AJAX content loaded! Assert visible...
Assert.True(notifications.isDisplayed());

This handles asynchronous content visibility without rigid Thread.sleep().

Confirming Multi-Page Navigation

//Submit credentials on login page
loginPage.submitLogin(username, password);

//Check inbox page header displayed
Assert.True(inboxHeader.isDisplayed(), "Not on inbox page!");

//Safe to interact with inbox elements...

This confirms we landed on the expected page before further testing.

Now that you‘ve seen examples, let‘s switch gears to discuss…

Advanced Concepts

We‘ve covered core concepts and basics, but let‘s level up to advanced topics for true mastery!

AI Based Inference

Emerging AI testing tools can smartly infer page layout and element visibility without scripted checks. For example, Applitools Eyes visually validates UI structure.

Alternative Visibility Checking

Other options beyond isDisplayed() include:

  • Browser developer console accessibility checks
  • JavaScript intersection observers
  • JQuery element visibility plugins
  • Browser viewport size vs element position

Hybrid Explicit + Implicit Checks

Balancing explicit signaling via isDisplayed() with implicit browser validation delivers highly resilient test automation.

Advanced Framework Design

Sophisticated page object models can abstract away complex visibility logic into modular interfaces minimizing script burden.

Let‘s switch topics to discuss locator selection which influences visibility checking…

Locator Selection Impacts Visibility Checking

Every Selenium element must be located by a browser query strategy before executing commands like isDisplayed().

Common locator options include:

  • ID
  • Class Name
  • Tag Name
  • XPath
  • CSS Selector

Consider this modal dialog check:

XPath Example

//Long fragile path
WebElement modal = driver.findElement(By.xpath("/html/body/div[4]/div/div[2]/div/div[2]")); 

if (modal.isDisplayed()) {
  //Interact with modal
}

CSS Selector Example

//Simple unique selector 
WebElement modal = driver.findElement(By.cssSelector(".modalDialog"));

if (modal.isDisplayed()) {
  //Interact with modal 
}

ID Lookup Example

//Direct ID lookup
WebElement modal = driver.findElement(By.id("successModal"));  

if (modal.isDisplayed()) {
  // Interact with modal
}

Key Locator Considerations:

Locator Type Pros Cons
XPath Full document paths Slow, fragile
CSS Selector Clean simple syntax Limited features
ID Very fast lookup Brittle reliance on ID

Finding the right balance of speed, reliability and maintainability is crucial to effective visibility checking.

Now that we have covered the impact of locators, let‘s look at how visibility testing has evolved.

The Evolution of Visibility Testing

Let‘s journey through time exploring key milestones in validation automation:

Era of Manual Testing (1980s)

Devs manually checked app UI rendering layer-by-layer trusting the human eye.

Built-In Browser Validation (1990s)

Browsers added developer console tools for querying DOM and CSS.

Rise of Selenium (mid 2000s)

With Selenium, testers gained automation superpowers with tests executing in real browsers at incredible speeds.

Mobile + Responsive Design (early 2010s)

Testing complexities exploded with limitless device sizes, resolutions, touch interactions.

AI/ML Innovation (mid 2010s)

Emerging AI testing techniques infer layouts, dynamically self-heal locators and learn expected UI trees.

Component Driven Architectures (2020s)

Modern web development promotes encapsulated components with data-driven rendering.

As you can see, the testing industry has come a long way to handle modern dynamic applications!

Let‘s now walk through where implicit checks fall short…

Real-World Environments Where Implicit Checks Fail

While implicit checking via actions like click() seems convenient, many real-world situations cause it to break down:

  • Dead Clicks: Click passes without side effects
  • Frozen Interaction: Click hangs unable to execute
  • Obscured Elements: Click reaches element but it is not visible
  • Unhandled Exceptions: Click throws a raw exception
  • Browser Crashes: Click interaction causes browser/driver crash
  • State Corruption: Click accidentally interacts with other elements
  • Race Conditions: Element state changes after action invoked
  • Resource Constraints: Click works but overwhelms browser resources
  • Visual Bugs: Click goes through but UI renders incorrectly
  • Accessibility Issues: Click works but element not reachable via keyboard
  • Red Herrings: Click passes but wrong element was operated on

Without scripted validations like isDisplayed(), these issues can linger in automation suites silently striking intermittently.

Let‘s circle back to high-level testing philosophy…

Striking Balance Between Explicit and Implicit

Neither fully explicit nor fully implicit approaches work perfectly:

  • Purely implicit –> Flakiness time bombs
  • Purely explicit –> Brittle and noisy alerts

The ideal approach is to leverage explicit assertions to act as "guard rails" around interactions.

This discipline allows handling failures without corruption while maintaining reasonable test code size.

For illustrative purposes, here is relatively good test code:

loginPage.assertDisplayed(); 

loginPage.enterUsername(username);

loginPage.assertUsernameEntered();

loginPage.enterPassword(password);

loginPage.assertPasswordEntered();  

homePage = loginPage.clickLoginButton();

homePage.assertDisplayed(); //Confirms navigation

And here is relatively bad test code:

loginPage.enterUsername(username);

loginPage.enterPassword(password);

homePage = loginPage.clickLoginButton(); 

homePage.makePurchase(); //Forgot to validate if login succeeded!

This example demonstrates the qualitative difference explicit checkpoints provide.

Now that we have explored implicit/explicit balance, let‘s circle back to code-level best practices.

11 Pro Tips for isDisplayed() Success

Let‘s build on the previous pro tips with 11 additional recommendations:

1. Validate Critical Page Sections

Check key regions like headers, menus, filters, ads display properly.

2. Custom Framework Wrapper Methods

Encase checks in reusable methods to reduce duplication.

3. Handle Stale Elements

Re-fetch potentially stale elements before checking isDisplayed().

4. Define Smart Wait Timeouts

Avoid rigid Thread.sleep() with flexible waits tuned for your app.

5. Console Log For Debugging

Log visibility check results during test execution for easy debugging.

6. Try-Catch Common Exceptions

Gracefully handle invalid locator and stale element exceptions.

7. Toggle Invisibility Testing

Also check functionality to hide/show elements works properly.

8. Create Page Object Map Objects

Define element locators statically to avoid duplicate lookups.

9. Check Interactive Elements

Also verify buttons, links, drop downs can be reached.

10. Make Locators Unique Within Page

Ensure locator always singles out individual element.

11. Break Up Long Test Methods

Divide checks into helper methods to improve readability.

If you adhere to these 11 tips, you will gain visibility checking superpowers!

Next let‘s discuss why page object model design is key for effective visibility checking.

Page Object Model Design for Resilient Checking

The page object pattern separates test logic from underlying technical locators/identifiers.

For example, imagine a login page with username, password, submit button elements.

Without page object:

driver.findElement(By.id("username")).sendKeys("name");

driver.findElement(By.id("password")).sendKeys("12345");  

driver.findElement(By.id("submitBtn")).click();

Issues:

  • Embedding selectors in test script → maintenance nightmare
  • Duplicating lookups → slowdown
  • No abstraction for complex checks → lengthy tests

With page object:

LoginPage login = new LoginPage(driver);

login.setUsername("name");

login.setPassword("12345");

login.submit(); 

Benefits:

  • Isolates technicals allowing test code to use domain language
  • Encapsulates lookup details internal to page class
  • Allows adding visibility logic safely without spreading across tests
  • Promotes reuse across tests cases
  • Change page internal without rewriting tests

In essence, a well-designed page object model shields your tests from unnecessary chaos letting you focus on customer journeys.

And remember you can leverage isDisplayed() internally to build a visible/hidden state model within your page classes!

Alright, we have covered immense ground so far. Let‘s wrap up with concluding thoughts…

Closing Thoughts

I hope this guide has opened your eyes to just how vital having a definitive check like isDisplayed() is before blindly interacting with elements in automation.

Leverage the concepts, statistics, tips and code examples provided here to begin crafting resilient visibility checking right away.

Remember, surface level scripting fails the moment anything changes…you need defensive checks to support sustainable test automation.

Now go unleash the power of isDisplayed() in your own framework!

How useful was this post?

Click on a star to rate it!

Average rating 0 / 5. Vote count: 0

No votes so far! Be the first to rate this post.