Some links on this page are affiliate links: if you buy through them we may earn a commission, at no extra cost to you.
Find the element that actually handles the checkbox action, wait until it can receive input, click it, and then verify the state through the control’s real API. A visible <div> may only wrap a native <input type="checkbox"> and label, or it may itself be a custom widget. Use is_selected() for a native input; use aria-checked or the application’s resulting state for a custom checkbox.
Start by identifying the interactive element
Do not choose a selector merely because the element looks like a checkbox in the browser. Inspect the current DOM and determine which node receives the user action.
Native checkbox wrapped by a div
Many components use a container such as <div class="checkbox-row"> around a native input and a label. The wrapper supplies layout, while the input or associated label handles interaction. Prefer a stable ID, name, or other semantic selector for the input:
Quick wins for a faster PC:
Clear out junk files and repair common Windows errorsFree Scan →Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
locator = (By.ID, "my_checkbox")
checkbox = WebDriverWait(driver, 10).until(
EC.element_to_be_clickable(locator)
)
checkbox.click()
assert checkbox.is_selected()
is_selected() reports the selected state of a native selectable control. Replace my_checkbox with a locator that exists on the page you are automating; no generic selector can be correct for every site.
#1 Best Overall
Custom checkbox implemented by the div
A custom widget may have no native input. A common accessible implementation gives the element role="checkbox" and exposes its state with aria-checked:
custom_locator = (
By.CSS_SELECTOR,
'div[role="checkbox"][aria-label="Remember me"]'
)
custom_checkbox = WebDriverWait(driver, 10).until(
EC.element_to_be_clickable(custom_locator)
)
custom_checkbox.click()
assert custom_checkbox.get_attribute("aria-checked") == "true"
This is a locator pattern, not a promise about a particular site. The accessible name might come from visible text or aria-labelledby, and a widget may expose state differently. Inspect the markup and wait for the state transition after clicking.
Complete Python example
The following example shows the normal sequence: create a driver, open the page, locate the control, wait for interactability, click once only when necessary, and verify the final state. The URL and locator are deliberately placeholders for your target page.
The Tool Desk
Outbyte PC Repair FREERepair Windows errors before they cause bigger problemsFix Now →Outbyte Driver Updater FREEFix the driver behind crashes, sound loss and screen glitchesFind Drivers →from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
options = webdriver.ChromeOptions()
# options.add_argument("--headless=new") # enable if your run is headless
driver = webdriver.Chrome(options=options)
wait = WebDriverWait(driver, 10)
try:
driver.get("https://example.com/form")
locator = (By.CSS_SELECTOR, 'div[role="checkbox"][aria-label="Remember me"]')
checkbox = wait.until(EC.element_to_be_clickable(locator))
# Avoid toggling a control that is already in the desired state.
if checkbox.get_attribute("aria-checked") != "true":
checkbox.click()
wait.until(
lambda d: d.find_element(*locator).get_attribute("aria-checked") == "true"
)
finally:
driver.quit()
For a native input, replace the state test with checkbox.is_selected() and wait with a lambda that returns that value. The explicit wait handles a page that renders the control after navigation; it does not prove that the click produced the desired application result.
Rank #2
Choosing a reliable locator
Use the most stable, meaningful locator available in the page’s actual markup.
- ID: use a unique, stable
idwhen one is present. - Name or semantic attributes: a stable
name,role, and accessible label often describe the control better than a generated class. - CSS selector: combine role and accessible attributes, for example
div[role="checkbox"][aria-label="Remember me"]. - XPath: use it when the relationship between a label and control is the reliable fact, but avoid positional expressions such as “the third div.”
- Associated label: when the input is visually hidden but a label is clickable, locate the label or the input according to the behavior you confirmed in the DOM.
A broad selector such as div.checkbox can match a decorative wrapper, several controls, or a disabled instance. Narrow it with the real accessible name or form relationship.
Wait for both readiness and the resulting state
EC.element_to_be_clickable checks that the element is visible and enabled. Selenium then attempts to scroll it into view and interact with it. This condition is useful synchronization, but it cannot guarantee that an overlay will not cover the click point or that the application has finished processing the event.
For a dynamic widget, use a second wait after the click:
checkbox.click()
wait.until(
lambda d: d.find_element(*locator).get_attribute("aria-checked") == "true"
)
For a native input:
checkbox.click()
wait.until(lambda d: d.find_element(*locator).is_selected())
Read the initial state before clicking. A checkbox click toggles the value, so clicking an already checked control can uncheck it.
Keyboard interaction for accessible custom widgets
The WAI-ARIA checkbox pattern uses the Space key to change state when the checkbox has focus. Keyboard interaction is an alternative when the custom widget correctly implements that pattern and can receive focus.
from selenium.webdriver.common.keys import Keys
custom_checkbox = wait.until(EC.element_to_be_clickable(custom_locator))
custom_checkbox.click() # or focus it through the page’s normal interaction
custom_checkbox.send_keys(Keys.SPACE)
Do not assume that every div responds to Space. A plain div without the appropriate role, focus behavior, and event handling is not automatically a keyboard-operable checkbox. Verify the exposed state after the key press and use only one interaction route in a given test.
Do these 3 things before closing this tab:
1Fix the driver behind crashes, sound loss and screen glitches2Clear out junk files and repair common Windows errors3Scan for outdated or missing drivers - takes under a minuteWhen clicking the div does not work
Element not found
Confirm that the driver is on the expected URL and that the control exists in the current DOM. Check whether the page has switched to an iframe; Selenium must switch into the correct frame before locating its contents. Replace broad or positional selectors with a stable ID, name, CSS selector, or XPath grounded in the inspected markup.
Element not interactable
The node may be hidden, disabled, outside the usable viewport, or only a visual wrapper. Locate the actual input, label, or custom widget that accepts interaction. Selenium attempts to scroll an element into view, but it still reports an error when the element cannot be interacted with.
Element click intercepted
Selenium clicks the center of the element. A cookie layer, modal, sticky header, animation, or another element covering that center can intercept the click. Wait for the obstruction to disappear, dismiss it through the page’s normal control, or target the true clickable child. An element-to-be-clickable wait alone does not remove an overlay.
The click runs but the state does not change
First check whether the control started checked. A successful click may have toggled it off. For a custom widget, the attribute may update asynchronously or the application may expose the result somewhere other than aria-checked. Wait for the actual state transition or a resulting application change instead of assuming that the method call succeeded.
Free tools Windows power users keep installed
One-click scans. No signup required.
The page is still changing
Use explicit waits for visibility and clickability, then a separate wait for the expected state. Avoid arbitrary sleeps as the main synchronization method: a fixed delay can be too short on a slow run and wasteful on a fast one.
Comparing possible targets
| Target | Use it when | How to verify |
|---|---|---|
Native input[type="checkbox"] |
The input exists and represents the form value. | is_selected() |
| Associated label | The label is the documented or observed click surface for a hidden input. | Check the input’s is_selected() state |
Custom element with role="checkbox" |
The div itself handles the event and exposes an accessible name. | aria-checked or the application outcome |
| Keyboard route | The custom widget is focusable and implements the checkbox keyboard pattern. | Verify state after Space |
Prefer the native input or associated label when available because their state semantics are defined by the browser. Otherwise, use the custom widget’s role, accessible name, and exposed state.
Best Value
Performance, reliability, and test design
- Use one driver session for a coherent test flow and always call
quit()in afinallyblock. - Keep waits tied to observable conditions: visibility, enabled state, an attribute value, or an application result.
- Use stable selectors owned by the application rather than CSS classes generated by a build system.
- Make the test idempotent where possible: inspect the state and change it only when it differs from the desired value.
- Capture the page state or browser log when a failure is intermittent, so an intercepted click and a state-update race are distinguishable.
- Do not use JavaScript to force a click as the default fix. It can bypass the same visibility, overlay, and user-event behavior that the test is meant to exercise.
Or skip the browser setup
If your real goal is a clean image or PDF of a page rather than interactive checkbox testing, ScreenshotNeo provides a website screenshot API and MCP server. It accepts consent banners before capture and removes more than 60 known consent platforms, newsletter popups, and chat widgets; each step can be turned off. Bot checks or CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed, and the response identifies the page verdict and billing result in X-Page-Verdict and X-Billed headers.
One GET request is enough:
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
Python:
import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"}, timeout=90)
open("shot.webp", "wb").write(r.content)
Node.js:
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
See the ScreenshotNeo documentation for request options. Its MCP server supplies take_screenshot, get_page_info, and capture_pdf tools for Claude, Cursor, and other MCP clients. The Free plan includes 1,000 shots per month without a card; paid plans start at $5 for 3,000 shots. Create a free ScreenshotNeo account.
Recommended Free Tools
FAQ
Can I click any div with Selenium?
Selenium can issue a click to an element, but the div must be visible, enabled, and implemented as an interaction surface. A decorative wrapper may not change the checkbox state.
Why does is_selected() return false for my div?
is_selected() is intended for native selectable controls. Read the custom widget’s aria-checked value or assert the application state instead.
Should I click before checking the current value?
No. Read the current value first when the desired final state matters, because clicking toggles the control.
Frequently Asked Questions
Can I click any div with Selenium?
Selenium can issue a click to an element, but the div must be visible, enabled, and implemented as an interaction surface. A decorative wrapper may not change the checkbox state.
Why does is_selected() return false for my div?
is_selected() is intended for native selectable controls. Read the custom widget’s aria-checked value or assert the application state instead.
Should I click before checking the current value?
No. Read the current value first when the desired final state matters, because clicking toggles the control.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

