ifndef::snippets-dir[]
:snippets-dir: ../../../../manual-snippets/src/test/groovy
:rb-snippets-dir: ../../../../manual-snippets/real-browser/src/test/groovy
:cm-snippets-dir: ../../../../../module/geb-core/src/main/groovy
:ct-snippets-dir: ../../../../../module/geb-core/src/test/groovy
endif::[]
= IDE support

Geb does not require any special plugins or configuration for use inside an IDE.
However, there are some considerations that will be addressed in this chapter.

== Execution

Geb _scripts_ can be executed in an IDE if that IDE supports executing Groovy scripts.
All IDEs that support Groovy typically support this.
There are typically only two concerns in the configuration of this: getting the Geb classes on the classpath, and the `GebConfig.groovy` file.

Geb _tests_ can be executed in an IDE if that IDE supports Groovy scripts and the testing framework that you are using with Geb.
If you are using JUnit or Spock (which is based on JUnit) this is trivial, as all modern Java IDEs support JUnit.
As far as the IDE is concerned, the Geb test is simply a JUnit test and no special support is required.
As with executing scripts, the IDE must put the Geb classes on the classpath for test execution and the `GebConfig.groovy` file must be accessible (typically putting this file at the root of the
test source tree is sufficient).

In both cases, the simplest way to create such an IDE configuration is to use a build tool (such as Gradle or Maven) that supports IDE integration.
This will take care of the classpath setup and other concerns.

== Authoring assistance (autocomplete and navigation)

This section discusses what kind of authoring assistance can be provided by IDEs and usage patterns that enable better authoring support.

=== Dynamism and conciseness vs tooling support

Geb heavily embraces the dynamic typing offered by Groovy, to achieve conciseness for the purpose of readability.
This immediately reduces the amount of authoring assistance that an IDE can provide when authoring Geb code.
This is an intentional compromise.
The primary cost in functional/acceptance testing is in the _maintenance_ of the test suite over time.
Geb optimizes for this in several ways, one of which being the focus on intention revealing code (which is achieved through conciseness).

That said, if authoring support is a concern for you, read on to learn for details on ways to forsake conciseness in order to improve authoring support.

[[strong-typing]]
=== Strong typing

In order to gain improved authoring support, you must include types in your tests and page objects.
Additionally, you must explicitly access the browser and page objects instead of relying on dynamic dispatch.

Here's an example of idiomatic (untyped) Geb code.

[source,groovy]
----
include::{snippets-dir}/ide/StrongTypingSpec.groovy[tag=untyped,indent=0]
----

The same code written with types would look like:

[source,groovy]
----
include::{snippets-dir}/ide/StrongTypingSpec.groovy[tag=typed,indent=0]
----

Where the page objects are:

[source,groovy]
----
include::{snippets-dir}/ide/StrongTypingSpec.groovy[tag=pages,indent=0]
----

In summary:

. Use the `browser` object explicitly (made available by the testing adapters)
. Use the page instance returned by the `to()` and `at()` methods instead of calling through the browser
. Use methods on the `Page` classes instead of the `content {}` block and dynamic properties
. If you need to use content definition options like `required:` and `wait:` then you can still reference content elements defined using the DSL in methods on `Page` and `Module` classes as usual, e.g.:
+
[source,groovy]
----
include::{snippets-dir}/ide/StrongTypingSpec.groovy[tag=types_with_content,indent=0]
----
<1> Wait here for the async definition to return a non-empty Navigator...

[NOTE]
====
IntelliJ IDEA contains support for certain constructs introduced by Geb which makes some of the above not necessary.
Ensure that you familiarise yourself with the <<intellij-support, section on what that support entails>> if you are a user of IntelliJ IDEA.
====

Using this "`typed`" style is not an all or nothing proposition.
The typing options exist on a spectrum and can be used selectively where/when the cost of the extra "`noise`" is worth it to achieve better IDE support.
For example, a mix of using the `content {}` DSL and methods can easily be used.
The key enabler is to capture the result of the `to()` and `at()` methods in order to access the page object instance.

[[at-check-assertions-ide]]
==== Performing assertions as part of an at check

An alternative to tracking current page instance using variables to gain improved authoring support is using {at-method-taking-class-and-closure-api-link}[`at()` methods that take a closure as the last argument].
Each statement in that closure is <<at-check-assertions, implicitly asserted>> and its delegate is set to the page passed as the first argument.
Thanks to using `@DelegatesTo` annotation on the closure parameter in the method signature, IDEs which support that annotation understand that calls are delegated to a given page instance and can provide code completion.

The example from the previous section could be rewritten in the following way:

[source,groovy]
----
include::{snippets-dir}/ide/StrongTypingSpec.groovy[tag=at,indent=0]
----

[[intellij-support]]
==== IntelliJ IDEA support

IntelliJ IDEA (since version 12) has special support for authoring Geb code.
This is built in to the Groovy support; no additional installations are required.

The support provides:

* Understanding of implicit browser methods (e.g. `to()`, `at()`) in test classes (e.g. `extends GebSpec`)
* Understanding of content defined via the Content DSL (within `Page` and `Module` classes only)
* Completion in `at {}` and `content {}` blocks

This effectively enables more authoring support with less explicit type information.
As an example of that means, let's revisit the sample from the <<strong-typing, section about strong typing>> and see how it can be simplified while keeping full autocompletion support if using IntelliJ IDEA:

[tabs]
====
IntelliJ IDEA::
+
[source,groovy]
----
include::{snippets-dir}/intellij/StrongTypingSpec.groovy[tag=typed,indent=0]
----

Others::
+
[source,groovy]
----
include::{snippets-dir}/ide/StrongTypingSpec.groovy[tag=typed,indent=0]
----
====

Where the page objects are:

[tabs]
====
IntelliJ IDEA::
+
[source,groovy]
----
include::{snippets-dir}/intellij/StrongTypingSpec.groovy[tag=pages,indent=0]
----

Others::
+
[source,groovy]
----
include::{snippets-dir}/ide/StrongTypingSpec.groovy[tag=pages,indent=0]
----
====

The Geb development team would like to thank the good folks at JetBrains for adding this explicit support for Geb to IntelliJ IDEA.
