spectie 0.0.3

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