IanWatson
IanWatson

Reputation: 1739

Geb WaitFor Element's class to refresh issue

I have a JSF/ADF page which has a "button" which starts of as

<a id="pt1:r1:0:proBut" class="xfe p_AFDisabled" style="text-decoration:none;">
  <span id="pt1:r1:0:pgl13" class="x26j x1a">Proceed</span>
</a>

Another button is then pressed which changes this button to enabled.

<a id="pt1:r1:0:proBut" class="xfe" href="#" onclick="return false;" style="text-decoration:none;">
  <span id="pt1:r1:0:pgl13" class="x26j x1a">Proceed</span>
</a>

You can see there is a different class for the a element. When the element is disabled its class is "xfe p_AFDisabled", when it is active it changes to "xfe".

I have a Geb Page which contains a method which will wait until the button becomes enabled and looks like this

   class CustomerSelection extends Page {
    static at = { waitFor(100) {$("div",id:"pt1:pt_pgl10").$("div").$("span").text() == "Customer Selection"} }
    static content = {
        customers { $("div",id:"pt1:r1:0:pc1:tt1::db").$("table").$("tbody")}
        proceedButton(to: Dashboard) { $("a",id: "pt1:r1:0:proBut",class: "xfe")}   
    }

    void selectCustomer(int position) {
        customers.$("tr",position).click()
        println "selected customer!"
        waitFor {proceedButton.present}
        println "proceedButton present " + proceedButton.@class
    }

    void proceed() {
        proceedButton.click()
    }
}

However when I run this test via a SpockTest

package xx;

import geb.spock.GebReportingSpec

class LoginSpec extends GebReportingSpec {

    def "login"() {
        when:
            to Login
            report "login screen"
        and:
            login(username,password)
        and:
            at CustomerSelection
        and:
            selectCustomer(0)
        and:
            proceed()
        then:
            at Dashboard
        where:
            username   | password
            "x"        | "x"
    }

}

The output of println is

selected customer!
proceedButton present xfe p_AFDisabled

Which shows that the class is still xfe p_AFDisabled and has not finished processing.

It seems like the

waitFor {proceedButton.present}

is not working correctly?

EDIT ---

I have altered the waitFor to

waitFor {proceedButton.@class == "xfe"}

and the proceedButton definition to

proceedButton(to: Dashboard) { $("a",id: "pt1:r1:0:proBut")}    

hence removing the class attribute

Which works, however I'm not happy with the solution as there is now 2 places with DOM specific tasks. I would prefer the class attribute to be moved back into the button definition?

EDIT 2----

I have added a new element to the Geb page which looks like this:

proceedButtonActive(wait: true, required: false) {proceedButton.@class == "xfe"}

I can then just call this element in the selectCustomer method and it works. However there are still 2 elements required for this logic. 1 is the ideal.

Upvotes: 0

Views: 2495

Answers (1)

erdi
erdi

Reputation: 6954

You need to change your selector to filter out elements that have p_AFDisabled class on them:

proceedButton(to: Dashboard, required: false) { 
    $("a", id: "pt1:r1:0:proBut").not(class: "p_AFDisabled") 
}

Technically you don't even need to call isPresent() on processButton because if it's not present then that definition will return a "falsey" value and waitFor {} will not return. So selectCustomer() becomes:

void selectCustomer(int position) {
    customers.$("tr",position).click()
    waitFor { proceedButton }
}

Upvotes: 3

Related Questions