In Geb, what is the difference between displayed and present?
Asked Answered
R

3

7

I am writing functional tests and dealing with a modal window that fades in and out.

What is the difference between displayed and present?

For example I have:

settingsModule.container.displayed and settingsModule.container.present

where settingsModule represents my modal window.

When testing my modal window (the modal from Twitter's bootstrap), I usually do this:

def "should do ... "() {
    setup:
    topMenu.openSettingsModal()     

    expect:
    settingsModule.timeZone.value() == "Asia/Hong_Kong"

    cleanup:
    settingsModule.closeSettingsModal()
}

def "should save the time zone"() {
        setup:
        topMenu.openSettingsModal()             
        settingsModule.timeZone = "Japan"

        when:               
        settingsModule.saveSettings()       

        then:
        settingsModule.alertSuccess.size() == 1
        settingsModule.alertSuccess.text() == "Settings updated"

        when:
        settingsModule.saveSettings()       

        then:
        settingsModule.alertSuccess.size() == 1

        cleanup:
        settingsModule.closeSettingsModal()
    }

and on and on. In my modules, I have:

    void openSettingsModal() {                  
        username.click()
        settingsLink.click()            
    }

void closeSettingsModal() {
        form.cancel().click()       
    }

I always get a complain: "Element must be displayed to click".

In my openSettingsModal and closeSettingsModal, i tried many combination of waitFor with time interval and using present or not ... Can't figure it out.

Any pointers would be highly appreciated. Thanks!

Reims answered 23/8, 2012 at 18:55 Comment(0)
P
6

I think the main difference is that present would check that there is an element in your DOM, whereas displayed checks on the visibility of this element.

Remember that webdriver simulates the actual experience of an user using and clicking the website using a mouse, so if the element is not visible to them, they will not be able to click on it.

I wonder if your issue has to do with settingsLink not being in the DOM when the page is first loaded. If you are waiting for a dialog to popup and a link to live in this dialog, then you probably want to set something like

content{
   settingsLink( required: false ) { $( '...' }
   settingsModal( required: false ) { $( '#modalDialog' ) }
}

your waitfor should look something like

username.click()
waitFor{ settingsModal.displayed }
settingsLink.click()

I would stick with the book of geb conventions and just use displayed all the time.

Geb Manual - Determining visibility

Plica answered 24/8, 2012 at 0:18 Comment(1)
I tried your solution but it didn't work. The solution I proposed goes in the same direction with some tweaks. Thank you!Reims
R
4

Thanks for your reply. I was actually able to resolve my issue.

The problem was that the modal window had an animation of 500ms. Opening and closing the window several times in my tests made them succeed/fail inconsistently.

What I ended up doing is hooking the the "shown" event provided by the plugin. I ended up adding a "shown" class to the modal and check for it every 100ms during 1s.

void openSettingsModal() {      
    username.click()
    settingsLink.click()
    waitFor (1, 0.1) { $("#settingsModal", class: "shown").size() == 1 }
}

void closeSettingsModal() {
    form.cancel().click()   
    waitFor (1, 0.1) { $("#settingsModal", class: "shown").size() == 0 }    
}

As a side note, the tests were failing in Chrome and Firefox BUT were passing in IE!! I am guessing that because IE 8 doesn't support animations that my tests were passing.

It is all good now.

I hope it will help someone someday!

Reims answered 24/8, 2012 at 19:21 Comment(1)
You can also use isDisplayed() function like so waitFor (1, 0.1) { $("#settingsModal").isDisplayed() }Postmortem
S
0

Where we can use displayed?

If a particular element you are removing or deleting, if it is still there in DOM and not displayed in page, you can use assert thatelement.displayed == false which will make sure that element is not displayed in the page (but still it is present in DOM)

Where we can use present?

In the same example as above, after removing,if the element is not found at the DOM ,you should use present for verification

assert thatelement.present == false

Hope you understand....

Adding to the above, present takes more time in script execution

Sain answered 4/9, 2016 at 11:27 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.