Is there a difference between expect(locator).to_be_visible()
and locator.wait_for()
? Should I prefer one over the other?
I've looked up the __doc__
s:
wait_for
: Returns when element specified by locator satisfies the state
option. (state
defaults to 'visible'
).to_be_visible
: Ensures that Locator points to an attached and visible DOM node.Still, not very clear. Is it possible for a locator to be visible but not attached? If so, would they be equal if I know for sure that the located element is attached?
Is it possible for a locator to be visible but not attached?
No, it's impossible. For an element to be visible, it needs to be attached to the DOM tree (in the document), as well as have a non-zero height and width, be in the viewport, not have other elements on top of it, etc. In other words, visible is a subset of attached in the sense that all visible elements must be attached, but not all attached elements are visible.
wait_for
isn't an explicit assertion. It's a locator method that lets you block until a particular visibility/attachment predicate (the various options are described in the docs) is satisfied. It can be used in testing scenarios without expect
, but this is a bit unusual. The primary use case is when you want an element to be in some sort of attached/visibility state but don't have a particular action to take on it.
Since most locator actions auto-wait, you generally won't need wait_for
much in browser automation--just use the auto-waiting action like .click()
, .fill()
, .text_content()
, etc.
to_be_visible
is an explicit assertion that an element is attached and visible. You can think of it as an expect-oriented subset of the functionality that wait_for
provides.
Generally, use to_be_visible
if you're writing tests (it's a common assertion), otherwise use wait_for
for rare cases when you're doing normal browser automation and you need to block until an element is visible, without taking action (this is relatively uncommon).
If you're writing tests where you expect an element to be attached but don't care about visibility, you might be interested in to_be_attached
, which provides another part of the functionality of wait_for
in assertion form.
There are some gotchas with similar assertions like to_be_hidden
, which has a somewhat misleading name at the time of writing because it passes even if an element isn't attached. See this answer for detailed analysis.