kookaburra 2.0.0 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. checksums.yaml +4 -4
  2. data/.rspec +1 -0
  3. data/.travis.yml +1 -3
  4. data/README.markdown +259 -181
  5. data/Rakefile +11 -2
  6. data/kookaburra.gemspec +1 -0
  7. data/lib/kookaburra.rb +24 -9
  8. data/lib/kookaburra/api_client.rb +1 -1
  9. data/lib/kookaburra/api_driver.rb +1 -1
  10. data/lib/kookaburra/assertion.rb +1 -1
  11. data/lib/kookaburra/configuration.rb +25 -9
  12. data/lib/kookaburra/configuration/proxy.rb +55 -0
  13. data/lib/kookaburra/dependency_accessor.rb +7 -0
  14. data/lib/kookaburra/exceptions.rb +11 -3
  15. data/lib/kookaburra/mental_model.rb +5 -5
  16. data/lib/kookaburra/rack_app_server.rb +3 -12
  17. data/lib/kookaburra/test_helpers.rb +53 -12
  18. data/lib/kookaburra/ui_driver/ui_component.rb +9 -2
  19. data/lib/kookaburra/version.rb +1 -1
  20. data/spec/integration/test_a_rack_application_spec.rb +3 -2
  21. data/spec/integration/test_multiple_applications_spec.rb +96 -0
  22. data/spec/kookaburra/api_client_spec.rb +6 -5
  23. data/spec/kookaburra/api_driver_spec.rb +18 -0
  24. data/spec/kookaburra/configuration/proxy_spec.rb +39 -0
  25. data/spec/kookaburra/configuration_spec.rb +54 -2
  26. data/spec/kookaburra/mental_model_spec.rb +22 -20
  27. data/spec/kookaburra/test_helpers_spec.rb +60 -24
  28. data/spec/kookaburra/ui_driver/scoped_browser_spec.rb +3 -2
  29. data/spec/kookaburra/ui_driver/ui_component/address_bar_spec.rb +2 -1
  30. data/spec/kookaburra/ui_driver/ui_component_spec.rb +48 -14
  31. data/spec/kookaburra/ui_driver_spec.rb +4 -3
  32. data/spec/kookaburra_spec.rb +19 -14
  33. data/spec/spec_helper.rb +79 -0
  34. data/spec/support/shared_examples/it_can_have_ui_components.rb +2 -2
  35. data/spec/support/shared_examples/it_can_make_assertions.rb +3 -3
  36. data/spec/support/shared_examples/it_has_a_dependency_accessor.rb +3 -4
  37. metadata +25 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 0096d882dd0e4a30ea2ff6f38744a307ca77b596
4
- data.tar.gz: 97dd32061c90235865ed398517c59c356d0b3b38
3
+ metadata.gz: 40ba91318bee567ced157fa2bd8d51367a88e584
4
+ data.tar.gz: 6a4c31b072f15bf12fb4802910172a385daab48b
5
5
  SHA512:
6
- metadata.gz: 2022e2a53bef18d607ada46e5043d2f17c79f4699f4ee02b5d06c4b12c9d219727fee3bb2cee84e55383a35697d2918552a295b49e165d13bc0505a311c59097
7
- data.tar.gz: 86883520f7835ebcd750f01448d39727ffa48c9f8c8d564b5b8ca42bd12e17468d6f7ee11aeb958a398f1facf939a09bb108f2c3e7bc6e9e68f67c246664d047
6
+ metadata.gz: 857eaede49769932c27334a67814fe48a150195085068d33391b5a59b123885bdaa428f4340b85eb40886371dd802dd893410d4ce04f958f829183db747379e8
7
+ data.tar.gz: a8a53de66691968681c4a8765f2fef89c668ec132fd23ae17e95daf825392a36ae588f692379ca2512e40f9e82a282f0a67a914f34522b87ad7666ebcf894b7c
data/.rspec CHANGED
@@ -1 +1,2 @@
1
1
  --color
2
+ -t ~slow
@@ -3,7 +3,5 @@ before_install:
3
3
  - "sh -e /etc/init.d/xvfb start"
4
4
  rvm:
5
5
  - "2.1.2"
6
- - "2.0.0"
7
- - "1.9.3"
8
6
  env:
9
- - "DISPLAY=:99.0"
7
+ - "DISPLAY=:99.0 CODECLIMATE_REPO_TOKEN=476ff0f469278c42a67f2682736e2522cda104a104e01ba6dbe532e9934de3b1"
@@ -1,17 +1,19 @@
1
1
  # Kookaburra #
2
2
 
3
- Kookaburra is a framework for implementing the [Window Driver] [Window Driver] pattern in
4
- order to keep acceptance tests maintainable.
3
+ Kookaburra is a framework for implementing the [Window Driver] [Window Driver]
4
+ pattern in order to keep acceptance tests maintainable.
5
+
6
+ [![Code Climate](https://codeclimate.com/github/jwilger/kookaburra/badges/gpa.svg)](https://codeclimate.com/github/jwilger/kookaburra)
7
+ [![Test Coverage](https://codeclimate.com/github/jwilger/kookaburra/badges/coverage.svg)](https://codeclimate.com/github/jwilger/kookaburra)
5
8
 
6
9
  ## Requirements ##
7
10
 
8
- Requires Ruby 1.9.3 or greater. Tested with both MRI and JRuby (note
9
- that you must run JRuby in 1.9 compatability mode.)
11
+ Requires Ruby 2.1.0 or greater.
10
12
 
11
13
  ## Installation ##
12
14
 
13
- Kookaburra is available as a Rubygem and [published on Rubygems.org] [Kookaburra Gem],
14
- so installation is trivial:
15
+ Kookaburra is available as a Rubygem and
16
+ [published on Rubygems.org] [Kookaburra Gem], so installation is trivial:
15
17
 
16
18
  gem install kookaburra
17
19
 
@@ -24,51 +26,53 @@ following:
24
26
 
25
27
  ## Setup ##
26
28
 
27
- Kookaburra abstracts some common patterns for implementing the Window Driver
28
- testing pattern for web applications. You will need to tell Kookaburra which
29
- classes contain the specific Domain Driver implementations for your application
30
- as well as which driver to use for running the tests (currently only tested with
31
- [Capybara] [Capybara]).
32
-
33
- Kookaburra is designed to run tests agains a remote web server (although that
34
- server could be running on the same machine, it doesn't need to be), and it is
35
- the responsibility of the test implementation to ensure that the server is
36
- running.
37
-
38
- The fact that Kookaburra runs against a remote server means that *it is not
39
- limited to testing only Ruby web applications*. As long as your application
40
- exposes a web-service API for use by the APIDriver and an HTML user interface
41
- for use by the UIDriver, you can use Kookaburra to test it. Also, as long as
42
- you're careful with both your application and test designs, you're not limited
43
- to running your tests only in an isolated testing environment; you could run
44
- the same test suite you use for development against your staging or production
45
- systems.
29
+ Kookaburra abstracts some common patterns for implementing the Window
30
+ Driver testing pattern for web applications. You will need to tell
31
+ Kookaburra which classes contain the specific Domain Driver
32
+ implementations for your application as well as which driver to use for
33
+ running the tests (currently only tested with [Capybara] [Capybara]).
34
+
35
+ Kookaburra is designed to run tests against one or more remote web
36
+ servers (although the server(s) could be running on the same machine, it
37
+ doesn't need to be), and it is the responsibility of the test
38
+ implementation to ensure that the server is running.
39
+
40
+ The fact that Kookaburra runs against a remote server means that *it is
41
+ not limited to testing only Ruby web applications*. As long as your
42
+ application exposes a web-service API for use by the APIDriver and an
43
+ HTML user interface for use by the UIDriver, you can use Kookaburra to
44
+ test it. Also, as long as you're careful with both your application and
45
+ test designs, you're not limited to running your tests only in an
46
+ isolated testing environment; you could run the same test suite you use
47
+ for development against your staging or production systems.
46
48
 
47
49
  ### Testing an Application Running Locally ###
48
50
 
49
- The fact that Kookaburra is designed to support running tests against a remote
50
- server does not, of course, mean that the application cannot be running locally.
51
- It is possible to have your test suite manage the process of starting and
52
- stopping your server for you. Examples of how to do so with a Rack application
53
- are presented below, but you should be able to take the same basic approach with
54
- other types of application servers.
55
-
56
- Although Capybara is capable of starting a Rack application server on
57
- its own, the default setup only starts the server up on-demand when you
58
- call a method that requires the browser to interact with the web
59
- application. Because the APIClient layer does not use Capybara, it is
60
- necessary to manage the server process on your own. Otherwise the server
61
- would not be guaranteed to be running when you call the APIClient
62
- methods (particularly as these often appear in "Given" statements that
51
+ The fact that Kookaburra is designed to support running tests against a
52
+ remote server does not, of course, mean that the application cannot be
53
+ running locally. It is possible to have your test suite manage the
54
+ process of starting and stopping your server(s) for you. Examples of how
55
+ to do so with a Rack application are presented below, but you should be
56
+ able to take the same basic approach with other types of application
57
+ servers.
58
+
59
+ Although Capybara is capable of starting a Rack application server on
60
+ its own, the default setup only starts the server up on-demand when you
61
+ call a method that requires the browser to interact with the web
62
+ application. Because the APIClient layer does not use Capybara, it is
63
+ necessary to manage the server process on your own. Otherwise the server
64
+ would not be guaranteed to be running when you call the APIClient
65
+ methods (particularly as these often appear in "Given" statements that
63
66
  are run before you start interacting with the web browser.)
64
67
 
65
- Keep in mind that, even if your server is capable of being started up in another
66
- thread within the same Ruby process that is executing your test suite, you will
67
- want to avoid doing so unless you are using a Ruby interpreter that supports
68
- native threads. Otherwise, when the APIClient makes an HTTP call to your
69
- application's API, it will block while waiting for a response, thus preventing
70
- your application from being able to respond to that request and resulting in a
71
- timeout error in your tests.
68
+ **Keep in mind that, even if your server is capable of being started up in
69
+ another thread within the same Ruby process that is executing your test
70
+ suite, you will want to avoid doing so unless you are using a Ruby
71
+ interpreter that supports native threads. Otherwise, when the APIClient
72
+ makes an HTTP call to your application's API, it will block while
73
+ waiting for a response, thus preventing your application from being able
74
+ to respond to that request and resulting in a timeout error in your
75
+ tests.**
72
76
 
73
77
  ### RSpec ###
74
78
 
@@ -106,13 +110,46 @@ add the following to `spec/support/kookaburra_setup.rb`:
106
110
  c.include(Kookaburra::TestHelpers, :type => :request)
107
111
  end
108
112
 
113
+ #### Testing Multiple Applications
114
+
115
+ Sometimes you need to test a business process that spans multiple
116
+ "applications" in your platform. Kookaburra can be configured to operate
117
+ against multiple remote applications by defining them in the
118
+ configuration block as follows:
119
+
120
+ Kookaburra.configure do |c|
121
+ c.application(:app_one) do |a|
122
+ a.api_driver_class = AppOne::APIDriver
123
+ a.ui_driver_class = AppOne::UIDriver
124
+ a.app_host = 'http://app_one.example.com:1234'
125
+ end
126
+
127
+ c.application(:app_two) do |a|
128
+ a.api_driver_class = AppTwo::APIDriver
129
+ a.ui_driver_class = AppTwo::UIDriver
130
+ a.app_host = 'http://app_two.example.com:1234'
131
+ end
132
+
133
+ c.browser = Capybara::Session.new(:selenium)
134
+ c.server_error_detection { |browser|
135
+ browser.has_css?('head title', :text => 'Internal Server Error')
136
+ }
137
+ end
138
+
139
+ This changes the way you use the `#api` and `#ui` test helpers
140
+ (explained below) so that you must qualify each one with the name of the
141
+ application, i.e. `#app_one.api`, and `#app_two.ui`. Configuration
142
+ parameters set on the base configuration (e.g. `c.browser = #...`) are
143
+ shared between all named applications that do not specifically override
144
+ them.
145
+
109
146
  #### Managing startup and shutdown of a Rack application server ####
110
147
 
111
- While developing, it can be helpful to run your integration specs against a
112
- locally-running server that is managed by your test suite. The setup is similar
113
- to that in the previous section, but it adds before and after hooks to launch
114
- and shut down a Rack application server. Just add the following to
115
- `spec/support/kookaburra_setup.rb`:
148
+ While developing, it can be helpful to run your integration specs
149
+ against a locally-running server that is managed by your test suite. The
150
+ setup is similar to that in the previous section, but it adds before and
151
+ after hooks to launch and shut down a Rack application server. Just add
152
+ the following to `spec/support/kookaburra_setup.rb`:
116
153
 
117
154
  require 'kookaburra/test_helpers'
118
155
  require 'kookaburra/rack_app_server'
@@ -157,14 +194,15 @@ and shut down a Rack application server. Just add the following to
157
194
 
158
195
  ### Cucumber ###
159
196
 
160
- The following examples depict how you might configure [Cucumber] [Cucumber] to
161
- run tests against an already running application server (e.g. a remote staging
162
- site) and a Rack application server that is managed by the test suite.
197
+ The following examples depict how you might configure [Cucumber]
198
+ [Cucumber] to run tests against an already running application server
199
+ (e.g. a remote staging site) and a Rack application server that is
200
+ managed by the test suite.
163
201
 
164
202
  #### Testing an already running server ####
165
203
 
166
- If you are running your tests against an already running server, you can simply
167
- add the following to `features/support/kookaburra_setup.rb`:
204
+ If you are running your tests against an already running server, you can
205
+ simply add the following to `features/support/kookaburra_setup.rb`:
168
206
 
169
207
  require 'kookaburra/test_helpers'
170
208
 
@@ -187,13 +225,46 @@ add the following to `features/support/kookaburra_setup.rb`:
187
225
 
188
226
  World(Kookaburra::TestHelpers)
189
227
 
228
+ #### Testing Multiple Applications
229
+
230
+ Sometimes you need to test a business process that spans multiple
231
+ "applications" in your platform. Kookaburra can be configured to operate
232
+ against multiple remote applications by defining them in the
233
+ configuration block as follows:
234
+
235
+ Kookaburra.configure do |c|
236
+ c.application(:app_one) do |a|
237
+ a.api_driver_class = AppOne::APIDriver
238
+ a.ui_driver_class = AppOne::UIDriver
239
+ a.app_host = 'http://app_one.example.com:1234'
240
+ end
241
+
242
+ c.application(:app_two) do |a|
243
+ a.api_driver_class = AppTwo::APIDriver
244
+ a.ui_driver_class = AppTwo::UIDriver
245
+ a.app_host = 'http://app_two.example.com:1234'
246
+ end
247
+
248
+ c.browser = Capybara::Session.new(:selenium)
249
+ c.server_error_detection { |browser|
250
+ browser.has_css?('head title', :text => 'Internal Server Error')
251
+ }
252
+ end
253
+
254
+ This changes the way you use the `#api` and `#ui` test helpers
255
+ (explained below) so that you must qualify each one with the name of the
256
+ application, i.e. `#app_one.api`, and `#app_two.ui`. Configuration
257
+ parameters set on the base configuration (e.g. `c.browser = #...`) are
258
+ shared between all named applications that do not specifically override
259
+ them.
260
+
190
261
  #### Managing startup and shutdown of a Rack application server ####
191
262
 
192
- While developing, it can be helpful to run your acceptance tests against a
193
- locally-running server that is managed by your test suite. The setup is similar
194
- to that in the previous section, but it adds before and after hooks to launch
195
- and shut down a Rack application server. Just add the following to
196
- `features/support/kookaburra_setup.rb`:
263
+ While developing, it can be helpful to run your acceptance tests against
264
+ a locally-running server that is managed by your test suite. The setup
265
+ is similar to that in the previous section, but it adds before and after
266
+ hooks to launch and shut down a Rack application server. Just add the
267
+ following to `features/support/kookaburra_setup.rb`:
197
268
 
198
269
  require 'kookaburra/test_helpers'
199
270
  require 'kookaburra/rack_app_server'
@@ -234,10 +305,10 @@ and shut down a Rack application server. Just add the following to
234
305
 
235
306
  ## Defining Your Testing DSL ##
236
307
 
237
- Kookaburra extracts some common patterns that make it easier to use the Window
238
- Driver pattern along with various Ruby testing frameworks, but you still need to
239
- define your own testing DSL. An acceptance testing stack using Kookaburra has
240
- the following layers:
308
+ Kookaburra extracts some common patterns that make it easier to use the
309
+ Window Driver pattern along with various Ruby testing frameworks, but
310
+ you still need to define your own testing DSL. An acceptance testing
311
+ stack using Kookaburra has the following layers:
241
312
 
242
313
  1. The **Business Specification Language** (Cucumber scenarios or other
243
314
  spcification documents)
@@ -249,12 +320,12 @@ the following layers:
249
320
 
250
321
  ### The Business Specification Language ###
251
322
 
252
- The business specification language consists of the highest-level descriptions
253
- of a feature that are suitable for sharing with the non/less-technical
254
- stakeholders on a project.
323
+ The business specification language consists of the highest-level
324
+ descriptions of a feature that are suitable for sharing with the
325
+ non/less-technical stakeholders on a project.
255
326
 
256
- Gherkin is the external DSL used by Cucumber for this purpose, and you might
257
- have the following scenario defined for an e-commerce application:
327
+ Gherkin is the external DSL used by Cucumber for this purpose, and you
328
+ might have the following scenario defined for an e-commerce application:
258
329
 
259
330
  # purchase_items_in_cart.feature
260
331
 
@@ -274,40 +345,38 @@ have the following scenario defined for an e-commerce application:
274
345
  And I see that my default payment options will be used
275
346
  And I see that my default shipping options will be used
276
347
 
277
- Note that the scenario is focused on business concepts versus interface details,
278
- i.e. you "choose to check out" rather than "click on the checkout button". If
279
- for some reason your e-commerce system was going to be a terminal application
280
- rather than a web application, you would not need to change this scenario at
281
- all, because the actual business concepts described would not change (and
282
- although Kookaburra's focus is on testing web applications, it could likely be
283
- adapted to other environments.)
348
+ Note that the scenario is focused on business concepts versus interface
349
+ details, i.e. you "choose to check out" rather than "click on the
350
+ checkout button". If for some reason your e-commerce system was going to
351
+ be a terminal application rather than a web application, you would not
352
+ need to change this scenario at all, because the actual business
353
+ concepts described would not change (and although Kookaburra's focus is
354
+ on testing web applications, it could likely be adapted to other
355
+ environments.)
284
356
 
285
357
  ### The Test Implementation ###
286
358
 
287
359
  The Test Implementation layer exists as the line in between the Business
288
- Specification Language and the Domain Driver, and it includes Cucumber step
289
- definitions, RSpec example blocks, Test::Unit tests, etc. At this layer, your
290
- code orchestrates calls into the Domain Driver to mimic user interactions under
291
- various conditions and make assertions about the results.
292
-
293
- **Test assertions always belong within the test implementation layer.** Some
294
- testing frameworks such as RSpec add methods like `#should` to `Object`, which
295
- has the effect of poisoning the entire Ruby namespace with these methods---if
296
- you are using RSpec, you can call `#should` anywhere in your code and it will
297
- work when RSpec is loaded. Do not be tempted to call a testing library's Object
298
- decorators anywhere outside of your test implementation (such as within
299
- `UIDriver` or `UIComponent` subclasses.) Doing so will tightly couple your
300
- Domain Driver and/or Window Driver implementation to a specific testing library.
301
-
302
- `Kookaburra::UIDriver::UIComponent` provides an `#assert` method for use inside
303
- your own UIComponents. This method exists to verify preconditions and provide
304
- more informative error messages; it is not intended to be used for test
305
- verifications.
306
-
307
- `Kookaburra::TestHelpers` provides a convenient way to make assertions about the
308
- mental model. If you are using Test::Unit, see
309
- `Kookaburra::TestHelpers#assert_mental_model_of`; for RSpec, see
310
- `Kookaburra::TestHelpers#match_mental_model_of`.
360
+ Specification Language and the Domain Driver, and it includes Cucumber
361
+ step definitions, RSpec example blocks, Test::Unit tests, etc. At this
362
+ layer, your code orchestrates calls into the Domain Driver to mimic user
363
+ interactions under various conditions and make assertions about the
364
+ results.
365
+
366
+ **Test assertions always belong within the test implementation layer.**
367
+ Some testing frameworks such as RSpec add methods like `#should` to
368
+ `Object`, which has the effect of poisoning the entire Ruby namespace
369
+ with these methods---if you are using RSpec, you can call `#should`
370
+ anywhere in your code and it will work when RSpec is loaded. Do not be
371
+ tempted to call a testing library's Object decorators anywhere outside
372
+ of your test implementation (such as within `UIDriver` or `UIComponent`
373
+ subclasses.) Doing so will tightly couple your Domain Driver and/or
374
+ Window Driver implementation to a specific testing library.
375
+
376
+ `Kookaburra::UIDriver::UIComponent` provides an `#assert` method for use
377
+ inside your own UIComponents. This method exists to verify preconditions
378
+ and provide more informative error messages; it is not intended to be
379
+ used for test verifications.
311
380
 
312
381
  Given the Cucumber scenario above, here is how the test implementation layer
313
382
  might look:
@@ -343,24 +412,26 @@ might look:
343
412
  end
344
413
 
345
414
  Then "I see that my default payment options will be used" do
346
- ui.order_summary.payment_options.should match_mental_model_of(:default_payment_options)
347
- # Or if you prefer Test::Unit style assertions...
348
- # assert_mental_model_matches(:default_payment_options, ui.order_summary.payment_options)
415
+ expect(ui.order_summary.payment_options).to \
416
+ eq get_data(:payment_optons)[:default]
349
417
  end
350
418
 
351
419
  Then "I see that my default shipping options will be used" do
352
- ui.order_summary.shipping_options.should match_mental_model_of(:default_shipping_options)
420
+ expect(ui.order_summary.shipping_options).to \
421
+ eq get_data(:shipping_options)[:default]
353
422
  end
354
423
 
355
424
  The step definitions contain neither explicitly shared state (instance
356
- variables) nor any logic branches; they are simply wrappers around calls into
357
- the Domain Driver layer. There are a couple of advantages to this approach.
425
+ variables) nor any logic branches; they are simply wrappers around calls
426
+ into the Domain Driver layer. There are a couple of advantages to this
427
+ approach.
358
428
 
359
- First, because step definitions are so simple, it isn't necessary to force *Very
360
- Specific Wording* on the business analyst/product owner who is writing the
361
- specs. For instance, if she writes "I see a summary of my order" in another
362
- scenario, it's not a big deal to have the following in your step definitions (as
363
- long as the author of the spec confirms that they really mean the same thing):
429
+ First, because step definitions are so simple, it isn't necessary to
430
+ force *Very Specific Wording* on the business analyst/product owner who
431
+ is writing the specs. For instance, if she writes "I see a summary of my
432
+ order" in another scenario, it's not a big deal to have the following in
433
+ your step definitions (as long as the author of the spec confirms that
434
+ they really mean the same thing):
364
435
 
365
436
  Then "I see my order summary" do
366
437
  ui.order_summary.should be_visible
@@ -370,18 +441,18 @@ long as the author of the spec confirms that they really mean the same thing):
370
441
  ui.order_summary.should be_visible
371
442
  end
372
443
 
373
- The step definitions are nothing more than a natural language reference to an
374
- action in the Domain Driver; there is no overwhelming maintenance cost to the
375
- slight duplication, and it opens up the capacity for more readable Gherkin
376
- specs. The fewer false road blocks you put between your product owner and a
377
- written specification, the easier it becomes to ensure her participation in this
378
- process.
444
+ The step definitions are nothing more than a natural language reference
445
+ to an action in the Domain Driver; there is no overwhelming maintenance
446
+ cost to the slight duplication, and it opens up the capacity for more
447
+ readable Gherkin specs. The fewer false road blocks you put between your
448
+ product owner and a written specification, the easier it becomes to
449
+ ensure her participation in this process.
379
450
 
380
- The second advantage is that by pushing all of the complexity down into the
381
- Domain Driver, it's now trivial to reuse the exact same code in
382
- developer-centric integration tests. This ensures you have parity between the
383
- way the automated acceptance tests run and any additional testing that the
384
- development team needs to add in.
451
+ The second advantage is that by pushing all of the complexity down into
452
+ the Domain Driver, it's now trivial to reuse the exact same code in
453
+ developer-centric integration tests. This ensures you have parity
454
+ between the way the automated acceptance tests run and any additional
455
+ testing that the development team needs to add in.
385
456
 
386
457
  Using RSpec, the test implementation would be as follows:
387
458
 
@@ -390,52 +461,58 @@ Using RSpec, the test implementation would be as follows:
390
461
  describe "Purchase Items in Cart" do
391
462
  example "Using Existing Billing and Shipping Information" do
392
463
  api.existing_account(:my_account)
393
- api.default_payment_options_specified_for(:my_account)
394
- api.default_shipping_options_specified_for(:my_account)
395
- api.an_item_in_my_shopping_cart(:my_account)
464
+ api.default_payment_options_specified
465
+ api.default_shipping_options_specified
466
+ api.an_item_in_my_shopping_cart
396
467
 
397
- ui.sign_in(:my_account)
468
+ ui.sign_in
398
469
  ui.choose_to_check_out
399
470
 
400
- ui.order_summary.should be_visible
401
- ui.order_summary.payment_options.should == k.get_data(:default_payment_options)[:my_account]
402
- ui.order_summary.shipping_options.should == k.get_data(:default_shipping_options)[:my_account]
471
+ expect(ui.order_summary).to be_visible
472
+ expect(ui.order_summary.payment_options).to \
473
+ eq get_data(:payment_optons)[:default]
474
+
475
+ expect(ui.order_summary.shipping_options).to \
476
+ eq get_data(:shipping_options)[:default]
403
477
  end
404
478
  end
405
479
 
406
480
  ### The Domain Driver ###
407
481
 
408
- The Domain Driver layer is where you build up an internal DSL that describes the
409
- business concepts of your application at a fairly high level. It consists of two
410
- top-level drivers: the `APIDriver` (available via `#api`) used to set up
411
- state for your tests and the UIDriver (available via `#ui`) for describing the
412
- tasks that a user can accomplish with the application.
482
+ The Domain Driver layer is where you build up an internal DSL that
483
+ describes the business concepts of your application at a fairly high
484
+ level. It consists of two top-level drivers: the `APIDriver` (available
485
+ via `#api`) used to set up state for your tests and the UIDriver
486
+ (available via `#ui`) for describing the tasks that a user can
487
+ accomplish with the application.
413
488
 
414
489
  #### Mental Model ####
415
490
 
416
- `Kookaburra::MentalModel` is the component via which the `APIDriver` and the
417
- `UIDriver` share information, and it is intended to represent your application
418
- user's mental picture of the data they are working with. For instance, if you
419
- create a user account via the `APIDriver`, you would store the login
420
- credentials for that account in the `MentalModel` instance, so the `UIDriver`
421
- knows what to use when you tell it to `#sign_in`. This is what allows the
422
- Cucumber step definitions to remain free from explicitly shared state.
423
-
424
- Kookaburra automatically configures your `APIDriver` and your `UIDriver` to
425
- share a `MentalModel` instance, which is available to both of them via their
426
- `#mental_model` method.
427
-
428
- The `MentalModel` instance will return a `MentalModel::Collection` for any method
429
- called on the object. The `MentalModel::Collection` object behaves like a `Hash`
430
- for the most part; however, it will raise a `Kookaburra::UnknownKeyError` if you
431
- try to access a key that has not yet been assigned a value.
432
-
433
- Deletions (via `#delete` or `#delete_if`) will actually remove the key/value
434
- pair from the collection, but add it to a sub-collection (available at
435
- `MentalModel::Collection#deleted`). This reflects the fact that the user's
436
- mental model of the dataset would also include any intentional exceptions -
437
- the user will, for example, want to verify that an item they deleted does
438
- not appear to be available in the system.
491
+ `Kookaburra::MentalModel` is the component via which the `APIDriver` and
492
+ the `UIDriver` share information, and it is intended to represent your
493
+ application user's mental picture of the data they are working with. For
494
+ instance, if you create a user account via the `APIDriver`, you would
495
+ store the login credentials for that account in the `MentalModel`
496
+ instance, so the `UIDriver` knows what to use when you tell it to
497
+ `#sign_in`. This is what allows the Cucumber step definitions to remain
498
+ free from explicitly shared state.
499
+
500
+ Kookaburra automatically configures your `APIDriver` and your `UIDriver`
501
+ to share a `MentalModel` instance, which is available to both of them
502
+ via their `#mental_model` method.
503
+
504
+ The `MentalModel` instance will return a `MentalModel::Collection` for
505
+ any method called on the object. The `MentalModel::Collection` object
506
+ behaves like a `Hash` for the most part; however, it will raise a
507
+ `Kookaburra::UnknownKeyError` if you try to access a key that has not
508
+ yet been assigned a value.
509
+
510
+ Deletions (via `#delete` or `#delete_if`) will actually remove the
511
+ key/value pair from the collection, but add it to a sub-collection
512
+ (available at `MentalModel::Collection#deleted`). This reflects the fact
513
+ that the user's mental model of the dataset would also include any
514
+ intentional exceptions - the user will, for example, want to verify that
515
+ an item they deleted does not appear to be available in the system.
439
516
 
440
517
  Here's an example of MentalModel behavior:
441
518
 
@@ -461,11 +538,11 @@ Here's an example of MentalModel behavior:
461
538
 
462
539
  #### API Driver ####
463
540
 
464
- The `Kookaburra::APIDriver` is used to create a particular "preexisting" state
465
- within your application's data and ensure you have a handle to that data (when
466
- needed) prior to interacting with the UI. You will create a subclass of
467
- `Kookaburra::APIDriver` in which you will create part of the Domain Driver DSL
468
- for your application:
541
+ The `Kookaburra::APIDriver` is used to create a particular "preexisting"
542
+ state within your application's data and ensure you have a handle to
543
+ that data (when needed) prior to interacting with the UI. You will
544
+ create a subclass of `Kookaburra::APIDriver` in which you will create
545
+ part of the Domain Driver DSL for your application:
469
546
 
470
547
  # lib/my_app/kookaburra/api_driver.rb
471
548
 
@@ -521,9 +598,9 @@ paths.
521
598
  #### UI Driver ####
522
599
 
523
600
  `Kookaburra::UIDriver` provides the necessary tools for driving your
524
- application's user interface with the Window Driver pattern. You will subclass
525
- `Kookaburra::UIDriver` for your application and implement your testing DSL
526
- within your subclass:
601
+ application's user interface with the Window Driver pattern. You will
602
+ subclass `Kookaburra::UIDriver` for your application and implement your
603
+ testing DSL within your subclass:
527
604
 
528
605
  # lib/my_app/kookaburra/ui_driver.rb
529
606
 
@@ -541,15 +618,16 @@ within your subclass:
541
618
 
542
619
  ### The Window Driver Layer ###
543
620
 
544
- While your `APIDriver` and `UIDriver` provide a DSL that represents actions
545
- your users can perform in your application, the [Window Driver] [Window Driver]
546
- layer describes the individual user interface components that the user interacts
547
- with to perform these tasks. By describing each interface component using an OOP
548
- approach, it is much easier to maintain your acceptance/integration tests,
549
- because the implementation details of each component are captured in a single
550
- place. For example, if/when the implementation of your application's sign in
551
- screen changes, you can fix every single test that needs to log a user into the
552
- system just by updating the `SignInScreen` class.
621
+ While your `APIDriver` and `UIDriver` provide a DSL that represents
622
+ actions your users can perform in your application, the
623
+ [Window Driver] [Window Driver] layer describes the individual user
624
+ interface components that the user interacts with to perform these
625
+ tasks. By describing each interface component using an OOP approach, it
626
+ is much easier to maintain your acceptance/integration tests, because
627
+ the implementation details of each component are captured in a single
628
+ place. For example, if/when the implementation of your application's
629
+ sign in screen changes, you can fix every single test that needs to log
630
+ a user into the system just by updating the `SignInScreen` class.
553
631
 
554
632
  You describe the various user interface components by sub-classing
555
633
  `Kookaburra::UIDriver::UIComponent`:
@@ -603,11 +681,12 @@ whatever is passed to `Kookaburra.new` as the `:browser` option.
603
681
  Presently, we have only used Capybara as the application driver for
604
682
  Kookaburra.
605
683
 
606
- It's possible that something other than Capybara could be passed in, as long as
607
- that something presented the same API. In reality, using something other than
608
- Capybara is likely to require some changes to Kookaburra itself. If you have a
609
- particular interest in making this work, please feel free to fork the project
610
- and send us a [GitHub pull request] [Pull Request] with your changes.
684
+ It's possible that something other than Capybara could be passed in, as
685
+ long as that something presented the same API. In reality, using
686
+ something other than Capybara is likely to require some changes to
687
+ Kookaburra itself. If you have a particular interest in making this
688
+ work, please feel free to fork the project and send us a [GitHub pull
689
+ request] [Pull Request] with your changes.
611
690
 
612
691
  ## Contributing to kookaburra ##
613
692
 
@@ -627,8 +706,7 @@ and send us a [GitHub pull request] [Pull Request] with your changes.
627
706
 
628
707
  ## Copyright ##
629
708
 
630
- Copyright © 2011 John Wilger. See LICENSE.txt for
631
- further details.
709
+ Copyright © 2011 John Wilger. See LICENSE.txt for further details.
632
710
 
633
711
  [Window Driver]: http://martinfowler.com/eaaDev/WindowDriver.html "Window Driver - Martin Fowler"
634
712
  [Kookaburra Gem]: https://rubygems.org/gems/kookaburra "kookaburra | RubyGems.org | your community gem host"