spectie 0.0.3

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 (58) hide show
  1. data/LICENSE +21 -0
  2. data/README.rdoc +85 -0
  3. data/Rakefile +8 -0
  4. data/VERSION.yml +4 -0
  5. data/initialize.rb +6 -0
  6. data/lib/spectie.rb +3 -0
  7. data/lib/spectie/configuration.rb +10 -0
  8. data/lib/spectie/main.rb +26 -0
  9. data/lib/spectie/rails.rb +2 -0
  10. data/lib/spectie/rails_story_example_group.rb +55 -0
  11. data/lib/spectie/selenium.rb +3 -0
  12. data/lib/spectie/selenium/configuration.rb +27 -0
  13. data/lib/spectie/selenium/story_example_group.rb +51 -0
  14. data/lib/spectie/story_example_group_methods.rb +40 -0
  15. data/rake_tasks/package.rake +51 -0
  16. data/rake_tasks/publish.rake +40 -0
  17. data/rake_tasks/spec.rake +42 -0
  18. data/rake_tasks/utility.rake +11 -0
  19. data/rdoc/classes/Spectie.html +135 -0
  20. data/rdoc/classes/Spectie/Configuration.html +175 -0
  21. data/rdoc/classes/Spectie/Configuration/ForScenarios.html +111 -0
  22. data/rdoc/classes/Spectie/Configuration/Selenium.html +220 -0
  23. data/rdoc/classes/Spectie/Main.html +161 -0
  24. data/rdoc/classes/Spectie/RailsStoryExampleGroup.html +118 -0
  25. data/rdoc/classes/Spectie/SeleniumStoryExampleGroup.html +119 -0
  26. data/rdoc/classes/Spectie/StoryExampleGroupMethods.html +254 -0
  27. data/rdoc/created.rid +1 -0
  28. data/rdoc/files/README_rdoc.html +266 -0
  29. data/rdoc/files/lib/spectie/configuration_rb.html +101 -0
  30. data/rdoc/files/lib/spectie/main_rb.html +108 -0
  31. data/rdoc/files/lib/spectie/rails_rb.html +109 -0
  32. data/rdoc/files/lib/spectie/rails_story_example_group_rb.html +182 -0
  33. data/rdoc/files/lib/spectie/selenium/configuration_rb.html +101 -0
  34. data/rdoc/files/lib/spectie/selenium/story_example_group_rb.html +101 -0
  35. data/rdoc/files/lib/spectie/selenium_rb.html +110 -0
  36. data/rdoc/files/lib/spectie/story_example_group_methods_rb.html +101 -0
  37. data/rdoc/files/lib/spectie_rb.html +110 -0
  38. data/rdoc/fr_class_index.html +34 -0
  39. data/rdoc/fr_file_index.html +36 -0
  40. data/rdoc/fr_method_index.html +38 -0
  41. data/rdoc/index.html +24 -0
  42. data/rdoc/rdoc-style.css +208 -0
  43. data/script/selenium_webapp +45 -0
  44. data/script/spec +10 -0
  45. data/spec/example_run_state_tracking.rb +65 -0
  46. data/spec/selenium_config.rb +11 -0
  47. data/spec/spec_helper.rb +10 -0
  48. data/spec/spectie/rails_helper.rb +29 -0
  49. data/spec/spectie/rails_story_example_group_spec.rb +59 -0
  50. data/spec/spectie/selenium/configuration_spec.rb +91 -0
  51. data/spec/spectie/selenium/spec_helper.rb +16 -0
  52. data/spec/spectie/selenium/story_example_group_spec.rb +132 -0
  53. data/spec/spectie/spec_helper.rb +1 -0
  54. data/spec/spectie/story_example_group_methods_spec.rb +217 -0
  55. data/spec/spectie_spec.rb +46 -0
  56. data/spec/support/rails_app/controllers/application_controller.rb +2 -0
  57. data/tags +19899 -0
  58. metadata +125 -0
@@ -0,0 +1,11 @@
1
+ Spec::Runner.configure do |config|
2
+ config.selenium.driver_options = {
3
+ :host => "10.211.55.127",
4
+ :port => 4444,
5
+ :browser => "*firefox",
6
+ :timeout_in_seconds => 300,
7
+ :url => "http://10.211.55.1:4567"
8
+ }
9
+ config.selenium.start_browser_once = true
10
+ config.selenium.controlled = false
11
+ end
@@ -0,0 +1,10 @@
1
+ require File.expand_path(File.dirname(__FILE__) + "/example_run_state_tracking")
2
+
3
+ require File.expand_path(File.dirname(__FILE__) + "/../initialize")
4
+
5
+ $LOAD_PATH.unshift File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib'))
6
+ require 'spectie'
7
+
8
+ Spec::Runner.configure do |config|
9
+ config.mock_with :mocha
10
+ end
@@ -0,0 +1,29 @@
1
+ require File.expand_path(File.dirname(__FILE__) + "/spec_helper")
2
+
3
+ Dir[File.expand_path(File.dirname(__FILE__) + "/../../vendor/rails/*/lib")].each do |rails_lib|
4
+ $:.unshift rails_lib
5
+ end
6
+
7
+ ENV["RAILS_ENV"] = "test"
8
+ $:.unshift File.expand_path(File.dirname(__FILE__) + "/../support/rails_app/controllers")
9
+
10
+ require "initializer"
11
+ require "action_controller"
12
+
13
+ ActionController::Base.session = {:key => "_myapp_session", :secret => "a"*30}
14
+
15
+ require "spectie/rails"
16
+
17
+ module HelperToTestRailsIntegration
18
+ def method_missing(method, *args, &block)
19
+ if method.to_sym == :i_dont_exist_in_the_integration_session
20
+ # handled here
21
+ else
22
+ super
23
+ end
24
+ end
25
+ end
26
+
27
+ Spec::Runner.configure do |config|
28
+ config.include HelperToTestRailsIntegration
29
+ end
@@ -0,0 +1,59 @@
1
+ require File.expand_path(File.dirname(__FILE__) + "/rails_helper")
2
+
3
+ class TestsController < ApplicationController
4
+ def index; render :text => "<p>Hello there!</p>" end
5
+ end
6
+ # Not sure why the following line needs to exist, I would think it'd just use the default routes from routes.rb,
7
+ # but apparently not. Need to figure out why, but not now.
8
+ ActionController::Routing::Routes.add_route "/tests/:action", :controller => "tests"
9
+
10
+ module Spectie
11
+ describe "Rails Stories" do
12
+
13
+ track_example_run_state
14
+
15
+ it "is registered by default for the 'integration' behavior type" do
16
+ created_example_group = Spec::Example::ExampleGroupFactory.create_example_group(:type => :integration) {}
17
+ created_example_group.superclass.should == RailsStoryExampleGroup
18
+ end
19
+
20
+ it "can include a helper module that defines method_missing" do
21
+ (example_group = Class.new(RailsStoryExampleGroup)).class_eval do
22
+ Scenario "I'm going to call a method that doesn't exist in the integration session" do
23
+ i_dont_exist_in_the_integration_session
24
+ end
25
+ end
26
+
27
+ @options.run_examples
28
+
29
+ example.should be_successful
30
+ end
31
+
32
+ it "can make a controller request and inspect the response" do
33
+ example_group = Class.new(RailsStoryExampleGroup)
34
+ example_group.Scenario "Make a request to a controller" do
35
+ Given :i_want_to_write_an_integration_test_for_rails
36
+ When :i_make_a_controller_request
37
+ Then :i_can_assert_the_response
38
+ end
39
+
40
+ example_group.class_eval do
41
+ def i_want_to_write_an_integration_test_for_rails; end
42
+
43
+ def i_make_a_controller_request
44
+ get "/tests"
45
+ end
46
+
47
+ def i_can_assert_the_response
48
+ response.should be_success
49
+ response.should have_tag("p", "Hello there!")
50
+ end
51
+ end
52
+
53
+ example_group.run(@options)
54
+
55
+ example.should_not be_failed
56
+ end
57
+
58
+ end
59
+ end
@@ -0,0 +1,91 @@
1
+ require File.expand_path(File.dirname(__FILE__) + "/spec_helper")
2
+
3
+ module Spectie
4
+ module Configuration
5
+ describe Selenium do
6
+ it "creates a configuration the first time it's accessed" do
7
+ Spec::Runner.configuration.selenium.should_not be_nil
8
+ Spec::Runner.configuration.selenium.class.should == Selenium
9
+ end
10
+
11
+ it "provides driver options" do
12
+ config = Selenium.new
13
+ config.driver_options = "blah"
14
+ config.driver_options.should == "blah"
15
+ end
16
+
17
+ it "raises an error if driver options are not set before they're accessed" do
18
+ config = Selenium.new
19
+ lambda { config.driver_options }.should raise_error
20
+ end
21
+
22
+ describe "affect on example group runs" do
23
+ track_example_run_state
24
+
25
+ it "only starts the driver once for multiple example groups if browser reset instead of restart is enabled" do
26
+ @original_value = Spec::Runner.configuration.selenium.start_browser_once
27
+ begin
28
+ start_call_count = 0
29
+ ::Selenium::Client::Driver.stubs(:new).
30
+ returns(mock_driver = stub_everything("mock selenium driver"))
31
+ mock_driver.stubs(:start).with { start_call_count += 1; true }
32
+
33
+ Spec::Runner.configuration.selenium.start_browser_once = true
34
+
35
+ example_group1 = Class.new(SeleniumStoryExampleGroup)
36
+ example_group1.class_eval do
37
+ def teardown_mocks_for_rspec
38
+ # do nothing so that the mock persists through to the second example group
39
+ end
40
+ end
41
+ example_group1.Scenario "The selenium driver is started once" do
42
+ start_call_count.should == 1
43
+ end
44
+ example_group2 = Class.new(SeleniumStoryExampleGroup)
45
+ example_group2.Scenario "The selenium driver is still started once" do
46
+ start_call_count.should == 1
47
+ end
48
+
49
+ with_selenium_control { @options.run_examples }
50
+ example.should be_successful
51
+ ensure
52
+ Spec::Runner.configuration.selenium.start_browser_once = @original_value
53
+ end
54
+ end
55
+
56
+ it "starts the driver for each example if browser reset instead of restart is disabled" do
57
+ @original_value = Spec::Runner.configuration.selenium.start_browser_once
58
+ begin
59
+ start_call_count = 0
60
+ ::Selenium::Client::Driver.stubs(:new).
61
+ returns(mock_driver = stub_everything("mock selenium driver"))
62
+ mock_driver.stubs(:start).with { start_call_count += 1; true }
63
+
64
+ Spec::Runner.configuration.selenium.start_browser_once = false
65
+
66
+ example_group1 = Class.new(SeleniumStoryExampleGroup)
67
+ example_group1.class_eval do
68
+ def teardown_mocks_for_rspec
69
+ # do nothing so that the mock persists through to the second example group
70
+ end
71
+ end
72
+ example_group1.Scenario "The selenium driver is started once" do
73
+ start_call_count.should == 1
74
+ end
75
+ example_group2 = Class.new(SeleniumStoryExampleGroup)
76
+ example_group2.Scenario "The selenium driver is started twice" do
77
+ start_call_count.should == 2
78
+ end
79
+
80
+ with_selenium_control { @options.run_examples }
81
+ example.should be_successful
82
+ ensure
83
+ Spec::Runner.configuration.selenium.start_browser_once = @original_value
84
+ end
85
+ end
86
+
87
+ end
88
+
89
+ end
90
+ end
91
+ end
@@ -0,0 +1,16 @@
1
+ require File.expand_path(File.dirname(__FILE__) + "/../spec_helper")
2
+ require "spectie/selenium"
3
+ require File.expand_path(File.dirname(__FILE__) + "/../../selenium_config")
4
+
5
+ module SeleniumStoryExampleGroupTestingHelper
6
+ def with_selenium_control
7
+ Spec::Runner.configuration.selenium.controlled = true
8
+ yield
9
+ ensure
10
+ Spec::Runner.configuration.selenium.controlled = false
11
+ end
12
+ end
13
+
14
+ Spec::Runner.configure do |config|
15
+ config.include(SeleniumStoryExampleGroupTestingHelper)
16
+ end
@@ -0,0 +1,132 @@
1
+ require File.expand_path(File.dirname(__FILE__) + "/spec_helper")
2
+
3
+ module Spectie
4
+ describe "Selenium Stories" do
5
+
6
+ track_example_run_state
7
+
8
+ it "can open a path, inspect response, and interact with elements" do
9
+ example_group = Class.new(SeleniumStoryExampleGroup)
10
+ example_group.Scenario "Open a page and click on a link" do
11
+ Given :i_am_on_a_page_with_a_link
12
+ When :i_click_a_link
13
+ Then :i_go_to_the_destination
14
+ end
15
+
16
+ example_group.class_eval do
17
+ def i_am_on_a_page_with_a_link
18
+ open "/"
19
+ wait_for_text "Whazzup!?"
20
+ end
21
+ def i_click_a_link
22
+ wait_for_element "link=Click me"
23
+ click "link=Click me"
24
+ end
25
+ def i_go_to_the_destination
26
+ wait_for_text "Booyah!"
27
+ end
28
+ end
29
+
30
+ with_selenium_control { @options.run_examples }
31
+
32
+ example.should be_successful
33
+ end
34
+
35
+ share_examples_for "the browser is in a consistent state for each example" do
36
+ it "supports a session for each example in a group" do
37
+ example_group = Class.new(SeleniumStoryExampleGroup)
38
+ example_group.Scenario "I can see my session info when I log in" do
39
+ Given :i_log_in
40
+ When :i_am_sent_back_to_the_home_page
41
+ Then :i_see_session_info
42
+ end
43
+ example_group.Scenario "I can't see the session info from the last example" do
44
+ Given :i_am_a_guest_user
45
+ When :i_am_on_the_home_page
46
+ Then :i_dont_see_the_session_info_of_the_last_user
47
+ end
48
+
49
+ example_group.class_eval do
50
+ class << self
51
+ attr_accessor :login
52
+ end
53
+ def login; self.class.login end
54
+ end
55
+ example_group.login = "joeschmoe"
56
+
57
+ example_group.class_eval do
58
+ def i_log_in
59
+ open "/"
60
+ type "id=login", login
61
+ click "id=submit_login"
62
+ end
63
+ def i_am_sent_back_to_the_home_page
64
+ wait_for_page_to_load
65
+ wait_for_text "Whazzup!?"
66
+ end
67
+ def i_see_session_info
68
+ wait_for_text login
69
+ end
70
+ def i_am_a_guest_user; end
71
+ def i_am_on_the_home_page
72
+ open "/"
73
+ end
74
+ def i_dont_see_the_session_info_of_the_last_user
75
+ text?(login).should be_false
76
+ end
77
+ end
78
+
79
+ with_selenium_control { @options.run_examples }
80
+
81
+ example.should be_successful
82
+ end
83
+
84
+ it "deletes all cookies between each example" do
85
+ example_group = Class.new(SeleniumStoryExampleGroup)
86
+ example_group.Scenario "I do something that creates cookies" do
87
+ Given :i_create_a_bunch_of_cookies
88
+ end
89
+ example_group.Scenario "I have no cookies :(" do
90
+ Then :i_have_no_cookies
91
+ end
92
+
93
+ example_group.class_eval do
94
+ def i_create_a_bunch_of_cookies
95
+ create_cookie "a=1"
96
+ create_cookie "b=2"
97
+ cookies.should == "a=1; b=2"
98
+ end
99
+ def i_have_no_cookies
100
+ cookies.should == ""
101
+ end
102
+ end
103
+
104
+ with_selenium_control { @options.run_examples }
105
+
106
+ example.should be_successful
107
+ end
108
+ end
109
+
110
+ describe "browser restart before each example" do
111
+ it_should_behave_like "the browser is in a consistent state for each example"
112
+ before :each do
113
+ @original_value = Spec::Runner.configuration.selenium.start_browser_once
114
+ Spec::Runner.configuration.selenium.start_browser_once = false
115
+ end
116
+ after :each do
117
+ Spec::Runner.configuration.selenium.start_browser_once = @original_value
118
+ end
119
+ end
120
+
121
+ describe "browser reset instead of restart before each example" do
122
+ it_should_behave_like "the browser is in a consistent state for each example"
123
+ before :each do
124
+ @original_value = Spec::Runner.configuration.selenium.start_browser_once
125
+ Spec::Runner.configuration.selenium.start_browser_once = true
126
+ end
127
+ after :each do
128
+ Spec::Runner.configuration.selenium.start_browser_once = @original_value
129
+ end
130
+ end
131
+ end
132
+ end
@@ -0,0 +1 @@
1
+ require File.expand_path(File.dirname(__FILE__) + "/../spec_helper")
@@ -0,0 +1,217 @@
1
+ require File.expand_path(File.dirname(__FILE__) + "/spec_helper")
2
+
3
+ module Spectie
4
+
5
+ class StoryExampleGroup
6
+ include StoryExampleGroupMethods
7
+ end
8
+
9
+ describe StoryExampleGroup do
10
+
11
+ track_example_run_state
12
+
13
+ it "supports 'xScenario' method for disabling an example" do
14
+ example_group = Class.new(StoryExampleGroup)
15
+ example_ran_as_scenario = false
16
+ Kernel.expects(:warn).with { |message| message =~ /^Example disabled/ }
17
+
18
+ example_group.xScenario "As a user, I want to make a series of requests for our mutual benefit" do
19
+ example_ran_as_scenario = true
20
+ end
21
+ example_group.run(@options)
22
+
23
+ example_ran_as_scenario.should be_false
24
+ end
25
+
26
+ it "supports pending scenarios" do
27
+ example_group = Class.new(StoryExampleGroup)
28
+ example_group.Scenario "As a user, I want to make a series of requests for our mutual benefit"
29
+ @options.reporter.expects(:example_finished).with(anything, ::Spec::Example::ExamplePendingError)
30
+
31
+ example_group.run(@options)
32
+ end
33
+
34
+ it "supports 'scenario' method for creating an example" do
35
+ example_group = Class.new(StoryExampleGroup)
36
+ example_ran_as_scenario = false
37
+
38
+ example_group.Scenario "As a user, I want to make a series of requests for our mutual benefit" do
39
+ example_ran_as_scenario = true
40
+ end
41
+ example_group.run(@options)
42
+
43
+ example_ran_as_scenario.should be_true
44
+ end
45
+
46
+ [:Given, :When, :Then, :And].each do |scenario_method|
47
+ it "can use #{scenario_method} to call scenario statements from within the scenario" do
48
+ example_group = Class.new(StoryExampleGroup) do
49
+ class << self
50
+ attr_accessor :scenario_statement_was_executed
51
+ end
52
+ end
53
+
54
+ example_group.Scenario "As a user, I want to make a series of requests for our mutual benefit" do
55
+ send scenario_method, :i_am_executed
56
+ end
57
+
58
+ example_group.class_eval do
59
+ def i_am_executed
60
+ self.class.scenario_statement_was_executed = true
61
+ end
62
+ end
63
+ example_group.run(@options)
64
+
65
+ example_group.scenario_statement_was_executed.should be_true
66
+ end
67
+ end
68
+
69
+ it "has access to the scenario statements defined on a parent example group" do
70
+ parent_example_group = Class.new(StoryExampleGroup) do
71
+ class << self
72
+ attr_accessor :scenario_statement_was_executed
73
+ end
74
+ end
75
+ parent_example_group.class_eval do
76
+ def i_am_executed
77
+ self.class.scenario_statement_was_executed = true
78
+ end
79
+ end
80
+ example_group = Class.new(parent_example_group)
81
+
82
+ example_group.Scenario "As a user, I want to make a series of requests for our mutual benefit" do
83
+ Given :i_am_executed
84
+ end
85
+ example_group.run(@options)
86
+
87
+ example_group.scenario_statement_was_executed.should be_true
88
+ end
89
+
90
+ it "can override the definition of a scenario statement on a parent example group" do
91
+ parent_example_group = Class.new(StoryExampleGroup) do
92
+ class << self
93
+ attr_accessor :scenario_statement_was_executed
94
+ end
95
+ end
96
+ parent_example_group.class_eval do
97
+ def i_am_executed
98
+ self.class.scenario_statement_was_executed = "parent"
99
+ end
100
+ end
101
+ example_group = Class.new(parent_example_group)
102
+ example_group.class_eval do
103
+ def i_am_executed
104
+ self.class.scenario_statement_was_executed = "child"
105
+ end
106
+ end
107
+
108
+ example_group.Scenario "As a user, I want to make a series of requests for our mutual benefit" do
109
+ Given :i_am_executed
110
+ end
111
+ example_group.run(@options)
112
+
113
+ example_group.scenario_statement_was_executed.should == "child"
114
+ end
115
+
116
+ it "supports scenario statement nesting" do
117
+ example_group = Class.new(StoryExampleGroup)
118
+ example_group.class_eval do
119
+ class << self
120
+ attr_accessor :nested_statement_was_executed
121
+ end
122
+ end
123
+ example_group.Scenario "As a tester, I want to be able to write nested dsl statements" do
124
+ Given :this_statement_takes_a_block do
125
+ Then :i_can_nest_a_statement
126
+ end
127
+ end
128
+ example_group.class_eval do
129
+ def this_statement_takes_a_block
130
+ yield
131
+ end
132
+ def i_can_nest_a_statement
133
+ self.class.nested_statement_was_executed = true
134
+ end
135
+ end
136
+
137
+ example_group.run(@options)
138
+
139
+ example.should_not be_failed
140
+ example_group.nested_statement_was_executed.should be_true
141
+ end
142
+
143
+ xit "handles scenario statements that start with 'should'" do
144
+ # This example doesn't quite describe the issue. For some reason,
145
+ # RSpec treates methods inside an example group that start with
146
+ # 'should' differently, and counts them as examples. Need to
147
+ # figure out why before going any futher w/this.
148
+ example_group = Class.new(StoryExampleGroup)
149
+ example_group.class_eval do
150
+ class << self
151
+ attr_accessor :called_the_method
152
+ end
153
+ end
154
+ example_group.Scenario "As a tester, I want to start a scenario statement with 'should'" do
155
+ Given :this_statement_calls_a_method_starting_with_should
156
+ end
157
+ example_group.class_eval do
158
+ def this_statement_calls_a_method_starting_with_should
159
+ should_do_something
160
+ end
161
+ def should_do_something
162
+ self.class.called_the_method = true
163
+ 1.should == 1
164
+ end
165
+ end
166
+
167
+ example_group.run(@options)
168
+
169
+ example_group.called_the_method.should be_true
170
+ example.should_not be_failed
171
+ end
172
+
173
+ it "shares state between the scenario and the scenario statements" do
174
+ example_group = Class.new(StoryExampleGroup)
175
+
176
+ example_group.Scenario "As a user, I want to make a series of requests for our mutual benefit" do
177
+ Given :the_example_has_state
178
+ @state.should == 1
179
+ @state = 2
180
+ Then :the_state_is_shared
181
+ end
182
+
183
+ example_group.class_eval do
184
+ def the_example_has_state
185
+ @state = 1
186
+ end
187
+ def the_state_is_shared
188
+ @state.should == 2
189
+ end
190
+ end
191
+ example_group.run(@options)
192
+
193
+ example.should_not be_failed
194
+ end
195
+
196
+ it "can invoke any method defined in the example group as a scenario statement" do
197
+ example_group = Class.new(StoryExampleGroup)
198
+ example_group.class_eval do
199
+ class << self
200
+ attr_accessor :normal_method_executed
201
+ end
202
+ def a_normal_method_defined_in_the_example_group
203
+ self.class.normal_method_executed = true
204
+ end
205
+ end
206
+
207
+ example_group.Scenario "As a user, I want to make a series of requests for our mutual benefit" do
208
+ Given :a_normal_method_defined_in_the_example_group
209
+ end
210
+
211
+ example_group.run(@options)
212
+
213
+ example.should_not be_failed
214
+ example_group.normal_method_executed.should be_true
215
+ end
216
+ end
217
+ end