- 🧪 SeleniumBase tells the difference between "presence" and "visibility." Using the wrong wait methods often causes tests to fail.
- 🖼️ Images with
display: noneor 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:
- 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 above0, 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():
- The DOM contains the element.
- The element is displayed and does not have
display: none. - The element is not hidden using
visibility: hidden. - The element is on the screen, or able to be scrolled into view.
- 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
idordata-testidwhen 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 selectortimeout(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/