Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Espresso - withEffectiveVisibility vs isDisplayed

Whats´s the difference between isDisplayed and withEffectiveVisibility?

onView(withText("Much Dagger")).check(matches(withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE)));


onView(withText("Much Dagger")).check(matches(ViewMatchers.isDisplayed());
like image 234
Daniel Gomez Rico Avatar asked Jul 06 '15 04:07

Daniel Gomez Rico


2 Answers

According to the Documentation

Returns a matcher that matches {@link View}s that have "effective" visibility set to the given value. Effective visibility takes into account not only the view's visibility value, but also that of its ancestors. In case of View.VISIBLE, this means that the view and all of its ancestors have visibility=VISIBLE. In case of GONE and INVISIBLE, it's the opposite - any GONE or INVISIBLE parent will make all of its children have their effective visibility.

Note:

Contrary to what the name may imply, view visibility does not directly translate into whether the view is displayed on screen (use isDisplayed() for that). For example, the view and all of its ancestors can have visibility=VISIBLE, but the view may need to be scrolled to in order to be actually visible to the user. Unless you're specifically targeting the visibility value with your test, use isDisplayed.

So if using for verifying if a view is visible use isDisplayed() but for other verification incase if invisible and gone use withEffectiveVisibilty()

like image 190
UDI Avatar answered Oct 24 '22 15:10

UDI


As the previous answer suggests that isDisplayed() verifies whether the target view is present in the Visible Rectangle of the Screen. However, there is a catch of using it. According to the official documentation, isDisplayed() -

select views that are partially displayed (eg: the full height/width of the view is greater than the height/width of the visible rectangle).

But practically, this always doesn't work. If the target view has more than 80% visible in the Visible Rectangle, then only isDisplayed() works. But if your view's Visible presence below that threshold, then you need to use isDisplayingAtLeast(). This method takes the custom percentage amount, which you feel the view is occupying in the Visible Rectangle. This won't work if your View is out of the Visible Rectangle (0% Visible) or fully visible in the Visible Rectangle (100% visible). If you want to ensure if the view is completely present in the visible Rectangle, then you can use isCompletelyDisplayed).

Bottom-line is, if you want to ensure whether the target View is visible to user (i.e. as a user you can see it on screen), then go for isDisplayed() or other variations of it.

Now coming to the purpose of withEffectiveVisibility(). It basically ensures that the Target view has the desired Visibility attribute set to it. It can validate three Visibility State - VISIBLE, INVISIBLE and GONE. Remember, this validation doesn't require the view to be present in the Visible Rectangle. The view just needs to be present in the View Hierarchy. When a layout is inflated, it creates a ViewTree and your view can be anywhere (i.e. in any node) in that Tree. The visibility state that they've in the Tree, is verified by this method.

So the bottom-line is, when you want to validate a View Visibility state, which is currently inside / outside of the Visible Rectangle, you can use this method. Example - If you've a scrollable layout where the CTA (i.e. Button) is at very bottom and interacting with it changes the Visibility state of a View which is at very top of the layout, then without scrolling to the top of the layout, you can assert the Visibility State change.

like image 22
Abhishek Avatar answered Oct 24 '22 14:10

Abhishek