Skip to content

Commit

Permalink
documentation tweaks to work round gdoc rendering limitations
Browse files Browse the repository at this point in the history
  • Loading branch information
robfletcher committed Apr 30, 2010
1 parent 2a6939d commit ce45c79
Show file tree
Hide file tree
Showing 10 changed files with 26 additions and 25 deletions.
1 change: 1 addition & 0 deletions .gitignore
@@ -1,6 +1,7 @@
*.iws
*.log
*.zip
docs/
docs-*/
.idea/
eclipse/
Expand Down
14 changes: 7 additions & 7 deletions src/docs/guide/1. Introduction.gdoc
Expand Up @@ -2,27 +2,27 @@ The Selenium RC plugin aims to make "Selenium RC":http://seleniumhq.org/projects

h3. Source Code

Source code for the plugin is hosted on "GitHub":http://github.com/robfletcher/grails-selenium-rc. Please feel free to fork the project and submit pull requests back to the trunk.
Source code for the plugin is hosted on "GitHub":http://github.com/robfletcher/grails-selenium-rc - Please feel free to fork the project and submit pull requests back to the trunk.

h3. Bugs and Feature Requests

Please raise bugs and feature requests against "Grails-Selenium-RC on JIRA":http://jira.codehaus.org/browse/GRAILSPLUGINS/component/14229.
Please raise bugs and feature requests against "Grails-Selenium-RC on JIRA":http://jira.codehaus.org/browse/GRAILSPLUGINS/component/14229

h3. Roadmap

* Upgrade to Selenium 2.0 / WebDriver.
* Support "Selenium Grid":http://selenium-grid.seleniumhq.org/.
* Support for other testing frameworks such as "EasyB":http://www.easyb.org/.
* Upgrade to Selenium 2.0 / WebDriver
* Support "Selenium Grid":http://selenium-grid.seleniumhq.org/
* Support for other testing frameworks such as "EasyB":http://www.easyb.org/

h3. Changelog
h4. Version 1.0

* Optionally capture screenshot on test case failure
* Selenium interface is decorated with waitFor* and *AndWait methods
* Selenium interface is decorated with _waitFor\*_ and _\*AndWait_ methods
* Selenium runner's context text is set correctly at the start of each test
* Firefox 3.6 and Firefox on OSX support via Selenium Server 1.0.3
* Specify JavaScript user extensions via config and invoke user extension methods directly from Groovy
* Optionally use `-remote` instead of config or system properties to run in remote mode
* Optionally use @-remote@ instead of config or system properties to run in remote mode

h4. Version 0.2

Expand Down
2 changes: 1 addition & 1 deletion src/docs/guide/2. Getting Started.gdoc
Expand Up @@ -22,5 +22,5 @@ h3. Writing Selenium RC Tests
Selenium tests should be placed under the @test/selenium@ directory. As with other test types you can use packages to group your tests if you wish.

{warning}
You should _not_ extend any of the base test classes in the Selenium API such as "SeleneseTestCase":api:com.thoughtworks.selenium.SeleneseTestCase or "GroovySeleneseTestCase":api:com.thoughtworks.selenium.GroovySeleneseTestCase as these tests will attempt to create a separate Selenium instance (and open another browser window) for every single test! The plugin starts a Selenium instance for you when @grails test-app@ runs the functional test phase. Your tests simply need to connect to that running Selenium instance.
You should _not_ extend any of the base test classes in the Selenium API such as "SeleneseTestCase":http://release.seleniumhq.org/selenium-remote-control/1.0-beta-2/doc/java/com/thoughtworks/selenium/SeleneseTestCase.html or "GroovySeleneseTestCase":http://release.seleniumhq.org/selenium-remote-control/1.0-beta-2/doc/java/com/thoughtworks/selenium/GroovySeleneseTestCase.html as these tests will attempt to create a separate Selenium instance (and open another browser window) for every single test! The plugin starts a Selenium instance for you when @grails test-app@ runs the functional test phase. Your tests simply need to connect to that running Selenium instance.
{warning}
2 changes: 1 addition & 1 deletion src/docs/guide/2.1. The SeleniumAware Mixin.gdoc
@@ -1,4 +1,4 @@
The simplest way to write Selenium tests is to create a class that extends [GroovyTestCase|api:groovy.util.GroovyTestCase] and add the @SeleniumAware@ mixin that the plugin provides. The mixin class simply makes the running instance of [Selenium|api:com.thoughtworks.selenium.Selenium] available:
The simplest way to write Selenium tests is to create a class that extends "GroovyTestCase":http://groovy.codehaus.org/gapi/groovy/util/GroovyTestCase.html and add the @SeleniumAware@ mixin that the plugin provides. The mixin class simply makes the running instance of "Selenium":http://release.seleniumhq.org/selenium-remote-control/1.0-beta-2/doc/java/com/thoughtworks/selenium/Selenium.html available:

{code}
import grails.plugins.selenium.SeleniumAware
Expand Down
8 changes: 4 additions & 4 deletions src/docs/guide/2.2. Enhancements to Selenium.gdoc
@@ -1,10 +1,10 @@
The @selenium@ property provided by the @SeleniumAware@ mixin is actually an extension of the standard [Selenium|api:com.thoughtworks.selenium.Selenium] object that enhances it in a number of ways.
The @selenium@ property provided by the @SeleniumAware@ mixin is actually an extension of the standard "Selenium":http://release.seleniumhq.org/selenium-remote-control/1.0-beta-2/doc/java/com/thoughtworks/selenium/Selenium.html object that enhances it in a number of ways.

h3. waitFor...

* Any _is..._ methods in @Selenium@ have an equivalent _waitFor_ taking the same parameters.
* Any _get..._ methods in @Selenium@ have an equivalent _waitFor_ taking the same parameters plus an _'expectation'_ String.
* Any _get..._ methods in @Selenium@ have an equivalent _waitFor_ taking the same parameters plus a "Hamcrest Matcher":http://code.google.com/p/hamcrest/.
* Any _is..._ methods in @Selenium@ have an equivalent _waitFor_ taking the same parameters
* Any _get..._ methods in @Selenium@ have an equivalent _waitFor_ taking the same parameters plus an _'expectation'_ String
* Any _get..._ methods in @Selenium@ have an equivalent _waitFor_ taking the same parameters plus a "Hamcrest Matcher":http://code.google.com/p/hamcrest/

{code}
// waitFor... equivalents of is... methods
Expand Down
4 changes: 2 additions & 2 deletions src/docs/guide/4. Using Page Objects.gdoc
@@ -1,7 +1,7 @@
Simple Selenium RC tests will interact directly with the @selenium@ object to drive the browser. However, once you go beyond a handful of simple tests this can make your tests difficult to maintain as they are dealing with the fine-grained details of the page. Some of the problems with this approach include:

* Page element locators (whether _XPath_, _CSS_, element Ids, etc.) are repeated throughout the tests and have to be changed in many places when you change the page structure.
* Multiple Selenium commands representing a single _logical_ action may be repeated in several tests. Utility class that group commands together can easily get out of control and turn into "God Objects":http://en.wikipedia.org/wiki/God_object.
* Page element locators (whether XPath, CSS, element Ids, etc.) are repeated throughout the tests and have to be changed in many places when you change the page structure.
* Multiple Selenium commands representing a single _logical_ action may be repeated in several tests. Utility class that group commands together can easily get out of control and fall prey to the "God Objects":http://en.wikipedia.org/wiki/God_object anti-pattern.

h3. What is a page object?

Expand Down
4 changes: 2 additions & 2 deletions src/docs/guide/4.1. Writing Page Object Classes.gdoc
Expand Up @@ -99,7 +99,7 @@ Even if your page object does not cache any state, consider having such a method

h3. Observing the state of the page

A page object class typically has methods that observe the state of the page, such as _getWidgetTitle()_, _getHighlightedNavigationItem()_, _isLoginFormVisible()_, _getErrorMessages()_, etc. You implement these by grabbing data from the page using Selenium and converting where necessary into a more logical format for your tests to make assertions about. For example:
A page object class typically has methods that observe the state of the page, such as _getWidgetTitle_ or _getHighlightedNavigationLink_ etc. You implement these by grabbing data from the page using Selenium and converting where necessary into a more logical format for your tests to make assertions about. For example:

{code}
String getFlashMessage() {
Expand Down Expand Up @@ -136,7 +136,7 @@ List<String> getErrorMessages() {
}
{code}

This page object method returns a _List_ of all the error messages displayed on the page or an empty list if there aren't any error messages. First it counts how many _li_ elements appear inside the _"errors"_ _div_ using Selenium's @getXpathCount@ method then applies @collect@ to a Groovy range, calling Selenium's @getText@ method for each _li_ in turn. If the @getXpathCount@ call returns zero the method simply returns an empty list.
This page object method returns a _List_ of all the error messages displayed on the page or an empty list if there aren't any error messages. First it counts how many _li_ elements appear inside the _"errors" div_ using Selenium's @getXpathCount@ method then applies @collect@ to a Groovy range, calling Selenium's @getText@ method for each _li_ in turn. If the @getXpathCount@ call returns zero the method simply returns an empty list.

The test now doesn't have to worry about how to scrape error messages from the page, it can make nice simple assertions such as:

Expand Down
6 changes: 3 additions & 3 deletions src/docs/guide/5. Data Driving Selenium Tests.gdoc
@@ -1,8 +1,8 @@
One of the most important considerations when writing Selenium tests is how to set up the data that the tests require. If you are purely running your Selenium tests against _localhost_ this is actually reasonably straightforward. Since the Selenium tests are running in the same JVM as the Grails application under test, the tests have direct access to the application's domain objects and can set up data very easily.

{note}
{warning}
Data-driving using direct access to application domain classes is *not* appropriate when running Selenium tests against a remote application, i.e. when @selenium.remote = true@ is set. In that case the Selenium tests and the application are running in separate JVMs.
{note}
{warning}

For example:

Expand Down Expand Up @@ -57,4 +57,4 @@ Again, the @withTransaction@ block ensures that the deletes are flushed and comm

h3. Test-wide data setup in JUnit 4 tests

In Grails 1.3+ you can have set up and tear down methods that run before and after _all_ tests in a class rather than each individual test by annotating @static void@ methods with [\@BeforeClass|api:org.junit.BeforeClass] and [\@AfterClass|api:org.junit.AfterClass]. Obviously this will not be appropriate for all test cases. In particular any tests that create or edit data may well need to use a per-method tear down. However, when appropriate it can be a good optimization.
In Grails 1.3+ you can have set up and tear down methods that run before and after _all_ tests in a class rather than each individual test by using @static void@ methods with "\@BeforeClass":http://www.junit.org/apidocs/org/junit/BeforeClass.html and "\@AfterClass":http://www.junit.org/apidocs/org/junit/AfterClass.html annotations. Obviously this will not be appropriate for all test cases. In particular any tests that create or edit data may well have to use a per-method tear down. However, when appropriate it can be a good optimization.
4 changes: 2 additions & 2 deletions src/docs/guide/6. Other Test Frameworks.gdoc
@@ -1,6 +1,6 @@
Selenium tests do not have to be written as JUnit test cases. The @SeleniumAware@ mixin could be applied to almost any test case written in another framework. Page objects are also agnostic of the test framework.

Currently the plugin has tested support for "Spock":http://grails.org/plugin/spock. Also, when using Grails 1.3+ tests can be written using JUnit 4 conventions. Other testing frameworks such as "EasyB":http://www.easyb.org/ and "JBehave":http://jbehave.org/, may well work with a limited amount of effort.
Currently the plugin has tested support for the "Spock":http://grails.org/plugin/spock plugin. Also, when using Grails 1.3+ tests can be written using JUnit 4 conventions. Other testing frameworks such as "EasyB":http://www.easyb.org/ and "JBehave":http://jbehave.org/ may well work with a limited amount of effort.

h3. Writing Selenium tests with JUnit 4

Expand All @@ -21,7 +21,7 @@ class HomepageTests {
}
{code}

Notice that the test does not extend any base class and annotates each test method with `@Test`.
Notice that the test annotates each test method with "\@Test":http://www.junit.org/apidocs/org/junit/Test.html and does not extend a base class.

h3. Writing Selenium tests with Spock

Expand Down
6 changes: 3 additions & 3 deletions src/docs/guide/7. Extending GrailsSeleniumTestCase.gdoc
@@ -1,12 +1,12 @@
{warning}
The @GrailsSeleniumTestCase@ class is considered deprecated. It is still available for backwards compatibility but will not be enhanced any further and may be removed in a future plugin version. The plugin now decorates the [Selenium|api:com.thoughtworks.selenium.Selenium] object itself with _waitFor_ methods and the "Hamcrest matcher":http://code.google.com/p/hamcrest/ API provides a better alternative to the assertion methods provided by @SeleneseTestBase@.
The @GrailsSeleniumTestCase@ class is considered deprecated. It is still available for backwards compatibility but will not be enhanced any further and may be removed in a future plugin version. The plugin now decorates the "Selenium":http://release.seleniumhq.org/selenium-remote-control/1.0-beta-2/doc/java/com/thoughtworks/selenium/Selenium.html object itself with _waitFor_ methods and the "Hamcrest matcher":http://code.google.com/p/hamcrest/ API provides a better alternative to the assertion methods provided by @SeleneseTestBase@.
{warning}

Instead of using the @SeleniumAware@ mixin you can extend @grails.plugins.selenium.GrailsSeleniumTestCase@ which provides everything the mixin does with some additional capabilities. Firstly you can use some of the more advanced assertions provided by the [SeleneseTestBase|api:com.thoughtworks.selenium.SeleneseTestBase] class as well as the various _verify_ methods, the _seleniumEquals_ method, etc.
Instead of using the @SeleniumAware@ mixin you can extend @grails.plugins.selenium.GrailsSeleniumTestCase@ which provides everything the mixin does with some additional capabilities. Firstly you can use some of the more advanced assertions provided by the "SeleneseTestBase":http://release.seleniumhq.org/selenium-remote-control/1.0-beta-2/doc/java/com/thoughtworks/selenium/SeleneseTestBase.html class as well as the various _verify_ methods, the _seleniumEquals_ method, etc.

h3. Using _assert..._, _verify..._ and _waitFor..._ convenience methods

Extending @GrailsSeleniumTestCase@ enables you to directly _assert, verify_ or _waitFor_ certain Selenium conditions. Any [Selenium|api:com.thoughtworks.selenium.Selenium] method starting with _is_ can be used as a boolean assertion by replacing the _is_ with _assert, verify_ or _waitFor_ in the method call. Likewise any Selenium method starting with _get_ can be used as an equality assertion. Some examples:
Extending @GrailsSeleniumTestCase@ enables you to directly _assert, verify_ or _waitFor_ certain Selenium conditions. Any "Selenium":http://release.seleniumhq.org/selenium-remote-control/1.0-beta-2/doc/java/com/thoughtworks/selenium/Selenium.html method starting with _is_ can be used as a boolean assertion by replacing the _is_ with _assert, verify_ or _waitFor_ in the method call. Likewise any Selenium method starting with _get_ can be used as an equality assertion. Some examples:

{code}
assertTrue selenium.isTextPresent("Welcome to Grails") // normal form
Expand Down

0 comments on commit ce45c79

Please sign in to comment.