kookaburra 2.0.0 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
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"