0

Geb uses a static field called content to define the contents of a page or module. The value of the content field is a closure.

 
class GebishOrgHomePage extends Page {
    static content = {
        manualsMenu {
            module MenuModule, $("#header-content ul li", 0)
        }
        links { $('.link-list li a') }
    }
}

Intellij already has support for this content dsl, however it does not support the module and moduleList methods. This causes limited auto-complete support when working with modules.

To fix this I'd like to write a GroovyDSL script that adds the missing method definitions to the content closure and its nested closures. However, I've no idea how to add methods to a closure that is not passed to a method, since enclosingCall requires a concrete method name.

And the other thing is that those methods must have a generic return type like this:


<T extends Module> T module(Class<T> m) {
    // return an instance of T
}
Leonard Brünings
  • 12,408
  • 1
  • 46
  • 66

1 Answers1

1

If you use the latest snapshot then module() calls will be understood by your IDE. This is down to moving module() to Navigator exactly for what you are after - autocompletion and strong typing.

Have a look at the current version of section 6.4 of the Book of Geb. The moduleList() will be gone in a future release and that section explains what to use instead. The module() method taking a map argument to initialise module properties will also go, you now initialise the module yourself and pass the instance to module() and there is an example of doing this in 6.4. Thanks to all that you will get autocompletion around module defintions and usage in IntelliJ.

erdi
  • 6,944
  • 18
  • 28
  • Thanks for the info, but there are some overloads missing – Leonard Brünings Jun 10 '15 at 19:09
  • e.g. ` T module(Map params, Class extends Module> moduleClass, Navigator base)` – Leonard Brünings Jun 10 '15 at 19:16
  • I explained what happened to the overloads and what to use instead in my answer. – erdi Jun 10 '15 at 19:23
  • Sorry I misread your answer regarding the overloads, may I ask why you retire the `moduleList` and the overloaded `module` methods? I liked the old methods since they made it clear from the beginning what is supposed to happen in the content closure. The new way looks harder to understand at first glance since you can now have the module in front or after the `$` selector, or even in a collect closure. I get that it works programmatically, but I think it is less clear to read. - Thanks – Leonard Brünings Jun 10 '15 at 23:52
  • The goal of it all is to make it more strongly typed so that you get the autocompletion from IDE. IntelliJ will understand keys and values passed into the map taking default constructor of your parameterised modules and it won't be able to autocomplete them when they are passed to the old map taking `module()` method. This is why we introduced support for using module instances and not only classes with these methods and I don't think that the map taking `module()` will be retained. Thinking about it now, we could retain the `moduleList()` helper method though. – erdi Jun 11 '15 at 20:26
  • Thanks for the explanation, I would vote for keeping the helper method. – Leonard Brünings Jun 12 '15 at 09:28
  • Bringing back `moduleList()` will only work for the use case when you pass in a class and not a parameterised (instantiated) module because Geb will need to instantiate the module as there are multiple instances needed - you are creating a list of modules in the end. That's probably why I decided that it's not worth it/confusing. If you feel like you would like it to be kept then please create an issue for this in the tracker. – erdi Jun 12 '15 at 17:48