Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

SeleniumBase Wait: Why Isn’t Your Image Visible?

Wondering why SeleniumBase isn’t waiting for images to load? Learn how to properly wait for image visibility using the right selectors.
Frustrated developer debugging image visibility in SeleniumBase test with broken image icon and visible error selector Frustrated developer debugging image visibility in SeleniumBase test with broken image icon and visible error selector
  • 🧪 SeleniumBase tells the difference between "presence" and "visibility." Using the wrong wait methods often causes tests to fail.
  • 🖼️ Images with display: none or loaded via JavaScript are not visible—even if they are in the DOM.
  • 🚀 Using wait_for_element_visible() with the right SeleniumBase selectors makes sure images show up before tests continue.
  • 📸 Tools like highlight() and screenshots show if images are visible in CI environments where screens cannot be seen.
  • 👀 Lazy-loaded images often need you to scroll down before waiting will work. Many testers forget this.

SeleniumBase Wait: Why Isn’t Your Image Visible?

SeleniumBase makes web testing faster and simpler. But it can be very frustrating to run a test and find your image is not "visible," even though it is in the HTML. If your SeleniumBase wait does not work as you expect—especially with image visibility—you are not alone. We will explain how SeleniumBase sees visibility, how it uses selectors, and what often goes wrong with lazy loading or when content loads over time. This will help you make your image waits reliable.


Understanding the Wait Problem in SeleniumBase

When writing SeleniumBase test scripts, you might think an image showing in your browser means the script should also see it. But visibility in tests is more complex.

The main thing is the difference between presence and visibility—two very different things in both Selenium and SeleniumBase:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

  • Presence: The image element exists in the DOM (Document Object Model). The browser has created it, but it may not be visible to someone using the website.
  • Visibility: The image has loaded, is not hidden by CSS (display: none, visibility: hidden), has opacity above 0, can be seen on screen, and is not covered by another element.

You might write this simple wait method that may not be enough:

self.wait_for_element_present("img#main-logo")

Your test passes, but a user cannot see the image. That is because the HTML is hiding the image, or the image has not loaded yet. SeleniumBase has not failed—your way you set up the wait has.

Real-World Scenario: Lazy-Loaded Images

Let’s take a common way websites work—lazy loading. This makes pages load faster by only loading images until a user scrolls down.

In this case, the <img> tag might already be in the DOM, but its src has not loaded yet. Or JavaScript might add the tag once it comes into view. Your test passes on presence but fails when checking the layout or if the image actually shows.

This can make tests seem to pass when they should not. A real user sees… nothing.


What SeleniumBase Considers 'Visible'

According to the W3C standards, visibility means several things that SeleniumBase follows when using methods like wait_for_element_visible():

  1. The DOM contains the element.
  2. The element is displayed and does not have display: none.
  3. The element is not hidden using visibility: hidden.
  4. The element is on the screen, or able to be scrolled into view.
  5. The element does not have opacity: 0.

SeleniumBase simplifies this check into a single method:

self.wait_for_element_visible("img#main-logo")

This method waits until the browser shows the image completely, just like a user would see it—which means fewer times the test says it passed when it should not have.

Here’s a comparison:

Wait Method What It Checks
wait_for_element_present() Only that the element exists in the DOM
wait_for_element_visible() DOM presence and that it's displayable on screen
wait_for_text() Checks that certain text is there

Using the right method makes tests more stable and matches how a user acts.


Common Developer Mistakes When Waiting for Images

There are several common reasons for failed SeleniumBase waits on images:

❌ Using the Wrong Wait Method

Using wait_for_element_present() checks for existence—not user visibility. The test might pass even if a user sees nothing.

❌ Weak or Inaccurate Selectors

Sometimes, developers use general selectors like "img". This can give unclear results if multiple images exist. Or worse, they use a class name that changes each time the code is updated.

❌ JavaScript Rendering Delays

JavaScript frameworks like React, Angular, or Vue often show images a little bit after the page loads. If a test checks for elements too early, it will fail. You need to wait long enough and confirm the image can be seen.

❌ Premature Assertions

Checks written before an image shows make tests unstable. The test might pass on your computer but fail when run on a build server because of network or computer speed differences. Always wait, then check.


Demystifying SeleniumBase Selectors

The SeleniumBase selector is very important for waiting on images. Understanding how they work makes sure your waits find the correct elements.

SeleniumBase allows both CSS and XPath selectors. Here are examples for waiting on images:

CSS Selector

self.wait_for_element_visible("img[src*='logo']")

This matches any <img> whose src includes “logo”.

XPath Selector

self.wait_for_element_visible("xpath://img[contains(@src,'logo')]")

This does the same thing, using XPath syntax.

Best Practices for Selectors

  • ✅ Be specific: "img#main-logo" is better than just "img"
  • 📌 Use attributes that do not change, like id or data-testid when available
  • 🚫 Avoid classes that change because of your website's build process
  • ⚠️ Test selectors against the HTML you actually see using browser DevTools

Using wait_for_element_visible() the Right Way

This method is key to making your test match what the user sees. Syntax:

self.wait_for_element_visible("img#hero-image", timeout=10)

Important considerations:

  • selector: Your SeleniumBase selector
  • timeout (optional): How many seconds to keep checking
  • Default timeout is 10 seconds unless overridden

Choosing the right amount of time needs careful thought. Too short and your test fails for no good reason. Too long and you make the test take too long.

For content that changes, it is better to use a longer timeout.


Debugging Visibility Issues in SeleniumBase

When visibility checks seem to fail even when you are sure the element can be seen, checking for problems helps a lot.

🔍 Highlight Hard-to-find Elements

Visually highlight where SeleniumBase thinks the element is:

self.highlight("img#example-image")

A red outline shows up around the element to confirm it is on screen and correctly found.

📸 Add Screenshots

Take a picture of the screen before a failure happens using:

self.save_screenshot("debug_visible.png")

Screenshots are very helpful in CI pipelines like GitHub Actions or Jenkins.

📃 Log Test Flow

Use print() statements or self.log() to confirm if page scripts have run:

print("Waiting for image to load...")

These small practices really help in making tests that sometimes fail more stable and easier to fix.


Differences Between SeleniumBase and Core Selenium

Traditional Selenium needs you to write a lot more code for waiting with full syntax combinations:

Core Selenium Example

from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

WebDriverWait(driver, 10).until(
    EC.visibility_of_element_located((By.ID, "logo-img"))
)

SeleniumBase Equivalent

self.wait_for_element_visible("#logo-img", timeout=10)

SeleniumBase makes tests easier to read and faster—saving dozens of lines across entire test files. It helps testers, no matter their skill level.


Case Study: Waiting for a Delayed Image to Load

Let’s say your app sometimes loads the main image slowly because of server problems. SeleniumBase handles this situation well:

from seleniumbase import BaseCase

class DelayedImageTest(BaseCase):
    def test_wait_for_lazy_image(self):
        self.open("https://example.com/delayed-image")
        self.wait_for_element_visible("img#delayed-load", timeout=7)
        self.assert_element("img#delayed-load")

Explanation:

  • Navigates to URL.
  • Waits up to 7 seconds for the image to become visible.
  • Checks that the image is now on the page and a user can see it.

If the image fails to load, the test shows that it timed out.


Best Practices for Waiting on Images

When working with image visibility in SeleniumBase:

✅ Always prefer wait_for_element_visible() over present
✅ Make selectors specific to unique IDs or filenames
✅ Allow enough time for the wait if things take time to show up
✅ Use debug tools like highlight() and screenshots when tests do not work as planned


Advanced Tip: Handling Lazy-Loading Images

Lazy loading is common in modern web apps because it makes things faster. But it makes automated testing harder.

For tests:

  • Scroll the element into view first
  • Then wait for visibility
self.scroll_to("img#lazy-logo")
self.wait_for_element_visible("img#lazy-logo", timeout=10)

SeleniumBase cannot find an image that only shows up after you scroll. Scroll first, then use your wait code.


Additional Wait Methods in SeleniumBase

Besides wait_for_element_visible(), other waits are for other things:

Method Purpose
wait_for_element_present() Checks if the element is in the DOM, even if you cannot see it
wait_for_element_absent() Waits until an element is removed—good for when elements disappear
wait_for_element_clickable() Checks if you can click the element (it can be seen + is active)
wait_for_text() Good for checking text under images, alternative text, or labels that change

Understanding the timing and situation for these methods helps you better match what a real user does.


When Image Still Doesn’t Load: What Else to Check

If your image does not show up but your waits are written correctly:

  • 🌐 Missing Assets: Is the staging or test environment missing the image files?
  • ⚙️ Network/Ad Blockers: Are any proxy tools or browser extensions causing problems?
  • 🧪 DevTools Help a Lot: Use self.open_devtools() or browser DevTools manually
  • 🤖 What the Test Sees vs. What a User Sees: Do real users see the image? Or is the server set up wrong?

Finally: TDD is not about making the test pass—it is about making sure the user's actual experience is checked.


SeleniumBase lets you write clear, dependable tests—but only if you learn to wait correctly and use the right SeleniumBase selectors. With the right method (wait_for_element_visible()), a good selector, and some ways to find problems, your problems with images loading can go away for good. Follow these tips, and feel free to look at more SeleniumBase docs when unusual situations come up.

And what works on your computer might not work on the build server. Screenshots and logs are very helpful when things do not work as expected.


Citations
W3C. (2023). DOM: Visibility standards and specifications. World Wide Web Consortium (W3C). Retrieved from https://www.w3.org/TR/css-display-3/#visibility

SeleniumHQ. (2022). Explicit and Implicit Waits in Selenium. Selenium Documentation. Retrieved from https://www.selenium.dev/documentation/webdriver/waits/

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading