Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

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:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
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.

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.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
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.

Choosing a reliable locator

Use the most stable, meaningful locator available in the page’s actual markup.

  • ID: use a unique, stable id when 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.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

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.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

When 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.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

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.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Performance, reliability, and test design

  • Use one driver session for a coherent test flow and always call quit() in a finally block.
  • 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.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

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.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

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.

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.