3

I want to use following function in 2-3 pages so i want to call that function but getting exception "static method is required..."

Here in Code CommonFunction is a class which extends Page Class

def  "User clicks on My Account Link"(){

    CommonFunction."User clicks on My Account Link"()   
}

I tried following approach also but still getting exception "geb.error.PageInstanceNotInitializedException: Instance of page class com.casestudy.util.CommonFunctions has not been initialized. Please pass it to Browser.to(), Browser.via(), Browser.page() or Browser.at() before using it."

CommonFunctions commonfunction= new CommonFunctions()
def  "User clicks on My Account Link"(){

     commonfunction."User clicks on My Account Link"()  
}

here is the code for the function User clicks on My Account link()

def  "User clicks on My Account Link"(){
    def actions = new Actions(driver)
    myaccountMenu.displayed
    WebElement myaccountMenu = myaccountMenu.firstElement()
    actions.click(myaccountMenu).build().perform()

}
Sujata Dwivedi
  • 131
  • 2
  • 9
  • You need to go to a page before you can interact with a page – tim_yates Apr 20 '16 at 07:14
  • Yes i have written the code like this: class HomePage extends CommonFunctions{ CommonFunction."User clicks on My Account Link"()} and CommonFunction class i have extended Page Class and imported this class geb.page – Sujata Dwivedi Apr 20 '16 at 08:49

3 Answers3

1

It's a bit unclear what you're trying to do exactly, but it looks like you have a "My Account" link on several pages, and you want to have a way to click this without repeating code on every page. If that's the case you should do this:

Create a "BasePage" class which all your other pages that have your "My Account" functionality should extend.

class BasePage extends Page{

  static content = {
    myAccountLink { $("#myAccountLink") } //CSS selector for the link you want on your page
  }

  //You don't actually need this method. In your tests you can just say myAccountLink.click() and it'll still work.
  def "User clicks on My Account Link"(){
    myAccountLink.click()
  }
}

Then your other pages can be defined as:

class HomePage extends BasePage {
  ... 
}

And in your tests whenever the browser is at a Page which extends from BasePage, you'll be able to call the method:

def "User can go to my account page"(){
 setup:
    to HomePage

 when: "The user clicks the MyAccount link"
   "User clicks on My Account Link"()

 then:
   at MyAccountPage
}
jk47
  • 755
  • 4
  • 10
  • Thank you actually i want to use this line of code in all the pages: def "User clicks on My Account Link"(){ def actions = new Actions(driver) myaccountMenu.displayed WebElement myaccountMenu = myaccountMenu.firstElement() actions.click(myaccountMenu).build().perform() } – Sujata Dwivedi Apr 22 '16 at 09:42
  • Hi, Please see my edited question hope you are able to understand, In selenium with Java we used to write common function in separate page or class and whenever these functions are required, we were calling by its object.function name so by this way our code was redundant free. – Sujata Dwivedi Apr 25 '16 at 10:57
  • There's no need to do that with Geb/Groovy. Did you try my solution? – jk47 Apr 25 '16 at 12:17
  • The site i am using need mouse hover, so action method is required and what you have suggested will not work for me as i have already tried in my code before posting this question to stack overflow. – Sujata Dwivedi Apr 26 '16 at 09:26
  • Can you not put that method in the BasePage class? Then all pages that extend it can use it – jk47 Apr 26 '16 at 10:07
  • Yes i have done this and i am getting the above error that i mentioned in my post. – Sujata Dwivedi Apr 26 '16 at 10:10
  • Please update your question to include the full code, and which classes each method is contained in – jk47 Apr 26 '16 at 10:15
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/110247/discussion-between-sujata-dwivedi-and-jk47). – Sujata Dwivedi Apr 26 '16 at 10:23
0

I have changed function name inside the child class and then calling the function inside child function (here parent function name is now different from child function name)

Thank you Jk what you suggested that is also working fine

Sujata Dwivedi
  • 131
  • 2
  • 9
0

If you have a common component that can exist on multiple pages, then what you want to do is to create a Geb 'Module' with its control accessors and then include that module in the pages that contain that module.

class moduleName extends Module {
    static clickUserLink() { userLink.click() }
    static content = {
        userLink = {$(locator)}
    }
}

class pageName extends Page {
    static content = {
        localName { module moduleName }
    }
}

That way your clickUserLink migrates to any page you've imported the module via localName.clickUserLink. You might also consider adding a waitFor(userLink) in the clickUserLink method or helper method.