cmsimple 0.2.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 (221) hide show
  1. data/.gitignore +31 -0
  2. data/.rspec +1 -0
  3. data/.travis.yml +16 -0
  4. data/Gemfile +20 -0
  5. data/Gemfile.ci +5 -0
  6. data/LICENSE +19 -0
  7. data/README.md +118 -0
  8. data/Rakefile +47 -0
  9. data/app/assets/javascripts/cmsimple.js +61 -0
  10. data/app/assets/javascripts/cmsimple/controllers/editor.coffee +102 -0
  11. data/app/assets/javascripts/cmsimple/lib/namespaces.coffee +3 -0
  12. data/app/assets/javascripts/cmsimple/lib/support.coffee +4 -0
  13. data/app/assets/javascripts/cmsimple/mercury/config.js +462 -0
  14. data/app/assets/javascripts/cmsimple/mercury/handlers.coffee +9 -0
  15. data/app/assets/javascripts/cmsimple/models/image.coffee +49 -0
  16. data/app/assets/javascripts/cmsimple/models/page.coffee +106 -0
  17. data/app/assets/javascripts/cmsimple/models/path.coffee +31 -0
  18. data/app/assets/javascripts/cmsimple/models/version.coffee +29 -0
  19. data/app/assets/javascripts/cmsimple/panels/images/index.coffee +2 -0
  20. data/app/assets/javascripts/cmsimple/panels/images/list.coffee +48 -0
  21. data/app/assets/javascripts/cmsimple/panels/images/panel.coffee +69 -0
  22. data/app/assets/javascripts/cmsimple/panels/images/selection.coffee +52 -0
  23. data/app/assets/javascripts/cmsimple/panels/page_metadata.coffee +42 -0
  24. data/app/assets/javascripts/cmsimple/panels/publish.coffee +32 -0
  25. data/app/assets/javascripts/cmsimple/panels/redirects/form.coffee +51 -0
  26. data/app/assets/javascripts/cmsimple/panels/redirects/index.coffee +2 -0
  27. data/app/assets/javascripts/cmsimple/panels/redirects/list.coffee +34 -0
  28. data/app/assets/javascripts/cmsimple/panels/redirects/panel.coffee +39 -0
  29. data/app/assets/javascripts/cmsimple/panels/sitemap/index.coffee +2 -0
  30. data/app/assets/javascripts/cmsimple/panels/sitemap/panel.coffee +40 -0
  31. data/app/assets/javascripts/cmsimple/panels/sitemap/sortable.coffee +55 -0
  32. data/app/assets/javascripts/cmsimple/panels/sitemap/tree.coffee +61 -0
  33. data/app/assets/javascripts/cmsimple/panels/versions/index.coffee +2 -0
  34. data/app/assets/javascripts/cmsimple/panels/versions/list.coffee +51 -0
  35. data/app/assets/javascripts/cmsimple/panels/versions/panel.coffee +53 -0
  36. data/app/assets/javascripts/cmsimple/views/image_library/_item.jst.hamlc +24 -0
  37. data/app/assets/javascripts/cmsimple/views/image_library/list.jst.hamlc +8 -0
  38. data/app/assets/javascripts/cmsimple/views/redirects/_path.jst.hamlc +6 -0
  39. data/app/assets/javascripts/cmsimple/views/redirects/list.jst.hamlc +19 -0
  40. data/app/assets/javascripts/cmsimple/views/sitemap/_page.jst.hamlc +9 -0
  41. data/app/assets/javascripts/cmsimple/views/sitemap/tree.jst.hamlc +5 -0
  42. data/app/assets/javascripts/cmsimple/views/versions/_item.jst.hamlc +6 -0
  43. data/app/assets/javascripts/cmsimple/views/versions/list.jst.hamlc +4 -0
  44. data/app/assets/stylesheets/cmsimple.css +15 -0
  45. data/app/assets/stylesheets/cmsimple/forms.css +10 -0
  46. data/app/assets/stylesheets/cmsimple/panels.css +399 -0
  47. data/app/assets/stylesheets/cmsimple/toolbar-images.css +27 -0
  48. data/app/assets/stylesheets/mercury_overrides.css +2 -0
  49. data/app/controllers/cmsimple/front_controller.rb +38 -0
  50. data/app/controllers/cmsimple/images_controller.rb +28 -0
  51. data/app/controllers/cmsimple/mercury_controller.rb +7 -0
  52. data/app/controllers/cmsimple/pages_controller.rb +89 -0
  53. data/app/controllers/cmsimple/paths_controller.rb +23 -0
  54. data/app/controllers/cmsimple/snippets_controller.rb +23 -0
  55. data/app/controllers/cmsimple/versions_controller.rb +17 -0
  56. data/app/helpers/cmsimple/regions_helper.rb +38 -0
  57. data/app/models/cmsimple/image.rb +19 -0
  58. data/app/models/cmsimple/page.rb +203 -0
  59. data/app/models/cmsimple/path.rb +63 -0
  60. data/app/models/cmsimple/region.rb +43 -0
  61. data/app/models/cmsimple/snippet.rb +64 -0
  62. data/app/models/cmsimple/version.rb +18 -0
  63. data/app/uploaders/image_attachment_uploader.rb +53 -0
  64. data/app/views/cmsimple/images/_form.html.haml +13 -0
  65. data/app/views/cmsimple/images/new.html.haml +5 -0
  66. data/app/views/cmsimple/pages/_form.html.haml +49 -0
  67. data/app/views/cmsimple/pages/_form_extras.html.haml +2 -0
  68. data/app/views/cmsimple/pages/edit.html.haml +3 -0
  69. data/app/views/cmsimple/pages/new.html.haml +3 -0
  70. data/app/views/cmsimple/pages/publish.html.haml +12 -0
  71. data/app/views/cmsimple/snippets/index.html.haml +5 -0
  72. data/app/views/cmsimple/templates/default.html.haml +4 -0
  73. data/app/views/layouts/editor.html.haml +12 -0
  74. data/app/views/layouts/panel.html.haml +9 -0
  75. data/cmsimple.gemspec +44 -0
  76. data/config.ru +4 -0
  77. data/config/application.rb +1 -0
  78. data/config/cucumber.yml +8 -0
  79. data/config/environment.rb +2 -0
  80. data/config/routes.rb +34 -0
  81. data/db/migrate/20120201221410_create_cmsimple_pages.rb +10 -0
  82. data/db/migrate/20120222185901_add_title_parent_id_and_position_to_pages.rb +10 -0
  83. data/db/migrate/20120229185214_add_slug_to_pages.rb +7 -0
  84. data/db/migrate/20120323200439_add_is_root_to_page.rb +5 -0
  85. data/db/migrate/20120328174339_add_meta_info_to_cmsimple_pages.rb +9 -0
  86. data/db/migrate/20120329172857_create_cmsimple_path.rb +11 -0
  87. data/db/migrate/20120407024752_create_cmsimple_images.rb +13 -0
  88. data/db/migrate/20120410041105_add_timestamps_to_cmsimple_pages.rb +7 -0
  89. data/db/migrate/20120425211937_add_published_at_to_cmsimple_pages.rb +6 -0
  90. data/db/migrate/20120430175047_create_cmsimple_versions.rb +13 -0
  91. data/db/migrate/20120831233927_rename_path_to_current_uri_on_paths.rb +5 -0
  92. data/features/create.feature +18 -0
  93. data/features/delete.feature +12 -0
  94. data/features/edit.feature +54 -0
  95. data/features/publishing.feature +31 -0
  96. data/features/redirects.feature +27 -0
  97. data/features/step_definitions/mercury_steps.rb +440 -0
  98. data/features/step_definitions/page_steps.rb +269 -0
  99. data/features/step_definitions/web_steps.rb +254 -0
  100. data/features/support/env.rb +77 -0
  101. data/features/support/mercury_content.rb +25 -0
  102. data/features/support/mercury_selectors.rb +148 -0
  103. data/features/support/paths.rb +16 -0
  104. data/features/support/selectors.rb +26 -0
  105. data/features/support/utils.rb +18 -0
  106. data/features/versioning.feature +27 -0
  107. data/features/visit.feature +7 -0
  108. data/lib/cmsimple.rb +22 -0
  109. data/lib/cmsimple/configuration.rb +65 -0
  110. data/lib/cmsimple/exts/to_bool.rb +25 -0
  111. data/lib/cmsimple/page_responder.rb +46 -0
  112. data/lib/cmsimple/rails.rb +5 -0
  113. data/lib/cmsimple/regions_proxy.rb +32 -0
  114. data/lib/cmsimple/template_resolver.rb +14 -0
  115. data/lib/cmsimple/template_responder.rb +12 -0
  116. data/lib/cmsimple/version.rb +3 -0
  117. data/lib/generators/cmsimple/install/install_generator.rb +46 -0
  118. data/lib/generators/cmsimple/install/templates/default.html.erb +10 -0
  119. data/lib/generators/cmsimple/install/templates/default.html.haml +6 -0
  120. data/lib/generators/cmsimple/install/templates/initializer.rb +22 -0
  121. data/lib/generators/cmsimple/snippet/snippet_generator.rb +56 -0
  122. data/lib/generators/cmsimple/snippet/templates/cell.rb +18 -0
  123. data/lib/generators/cmsimple/snippet/templates/display.html.erb +14 -0
  124. data/lib/generators/cmsimple/snippet/templates/display.html.haml +11 -0
  125. data/lib/generators/cmsimple/snippet/templates/options.html.erb +18 -0
  126. data/lib/generators/cmsimple/snippet/templates/options.html.haml +12 -0
  127. data/script/app +2 -0
  128. data/script/migrate +2 -0
  129. data/script/rails +8 -0
  130. data/spec/fixtures/rails.png +0 -0
  131. data/spec/helpers/regions_helper_spec.rb +62 -0
  132. data/spec/javascripts/controllers/editor_spec.coffee +57 -0
  133. data/spec/javascripts/models/image_geometry_spec.coffee +64 -0
  134. data/spec/javascripts/models/image_spec.coffee +4 -0
  135. data/spec/javascripts/models/page_spec.coffee +121 -0
  136. data/spec/javascripts/models/path_spec.coffee +39 -0
  137. data/spec/javascripts/models/version_spec.coffee +31 -0
  138. data/spec/javascripts/panels/images/selection_spec.coffee +104 -0
  139. data/spec/javascripts/panels/sitemap/panel_spec.coffee +10 -0
  140. data/spec/javascripts/panels/sitemap/sortable_spec.coffee +63 -0
  141. data/spec/javascripts/panels/sitemap/tree_spec.coffee +62 -0
  142. data/spec/javascripts/spec_helper.coffee +25 -0
  143. data/spec/javascripts/support/stubs.coffee +16 -0
  144. data/spec/lib/page_responder_spec.rb +58 -0
  145. data/spec/lib/regions_proxy_spec.rb +47 -0
  146. data/spec/models/image_spec.rb +46 -0
  147. data/spec/models/page_spec.rb +237 -0
  148. data/spec/models/path_spec.rb +71 -0
  149. data/spec/models/region_spec.rb +14 -0
  150. data/spec/models/snippet_spec.rb +57 -0
  151. data/spec/models/version_spec.rb +7 -0
  152. data/spec/rails_app/.gitignore +33 -0
  153. data/spec/rails_app/Rakefile +7 -0
  154. data/spec/rails_app/app/assets/images/rails.png +0 -0
  155. data/spec/rails_app/app/assets/javascripts/application.js +9 -0
  156. data/spec/rails_app/app/assets/stylesheets/application.css +7 -0
  157. data/spec/rails_app/app/cells/example/display.html.haml +2 -0
  158. data/spec/rails_app/app/cells/example/options.html.haml +15 -0
  159. data/spec/rails_app/app/cells/example_cell.rb +19 -0
  160. data/spec/rails_app/app/cells/image_example/display.html.haml +4 -0
  161. data/spec/rails_app/app/cells/image_example/options.html.haml +15 -0
  162. data/spec/rails_app/app/cells/image_example_cell.rb +18 -0
  163. data/spec/rails_app/app/controllers/application_controller.rb +3 -0
  164. data/spec/rails_app/app/helpers/application_helper.rb +2 -0
  165. data/spec/rails_app/app/mailers/.gitkeep +0 -0
  166. data/spec/rails_app/app/models/.gitkeep +0 -0
  167. data/spec/rails_app/app/views/cmsimple/_snippet_list.html.haml +8 -0
  168. data/spec/rails_app/app/views/cmsimple/templates/default.html.haml +19 -0
  169. data/spec/rails_app/app/views/cmsimple/templates/test.html.haml +2 -0
  170. data/spec/rails_app/app/views/layouts/application.html.haml +13 -0
  171. data/spec/rails_app/config.ru +4 -0
  172. data/spec/rails_app/config/application.rb +65 -0
  173. data/spec/rails_app/config/boot.rb +9 -0
  174. data/spec/rails_app/config/database.example.yml +22 -0
  175. data/spec/rails_app/config/database.travis.yml +8 -0
  176. data/spec/rails_app/config/environment.rb +5 -0
  177. data/spec/rails_app/config/environments/development.rb +30 -0
  178. data/spec/rails_app/config/environments/test.rb +39 -0
  179. data/spec/rails_app/config/initializers/backtrace_silencers.rb +7 -0
  180. data/spec/rails_app/config/initializers/cells.rb +1 -0
  181. data/spec/rails_app/config/initializers/cmsimple.rb +3 -0
  182. data/spec/rails_app/config/initializers/inflections.rb +10 -0
  183. data/spec/rails_app/config/initializers/mime_types.rb +5 -0
  184. data/spec/rails_app/config/initializers/secret_token.rb +7 -0
  185. data/spec/rails_app/config/initializers/session_store.rb +8 -0
  186. data/spec/rails_app/config/initializers/teabag.rb +58 -0
  187. data/spec/rails_app/config/initializers/wrap_parameters.rb +14 -0
  188. data/spec/rails_app/config/locales/en.yml +5 -0
  189. data/spec/rails_app/config/routes.rb +61 -0
  190. data/spec/rails_app/db/seeds.rb +11 -0
  191. data/spec/rails_app/lib/assets/.gitkeep +0 -0
  192. data/spec/rails_app/lib/tasks/.gitkeep +0 -0
  193. data/spec/rails_app/public/404.html +26 -0
  194. data/spec/rails_app/public/422.html +26 -0
  195. data/spec/rails_app/public/500.html +26 -0
  196. data/spec/rails_app/public/robots.txt +5 -0
  197. data/spec/rails_app/script/rails +6 -0
  198. data/spec/rails_app/vendor/assets/stylesheets/.gitkeep +0 -0
  199. data/spec/rails_app/vendor/plugins/.gitkeep +0 -0
  200. data/spec/spec_helper.rb +31 -0
  201. data/spec/support/active_model_lint_example.rb +14 -0
  202. data/spec/teabag_env.rb +28 -0
  203. data/vendor/assets/images/sitemap/has-changes.png +0 -0
  204. data/vendor/assets/images/sitemap/published.png +0 -0
  205. data/vendor/assets/images/sitemap/unpublished.png +0 -0
  206. data/vendor/assets/images/toolbar/metadata.png +0 -0
  207. data/vendor/assets/images/toolbar/publish.png +0 -0
  208. data/vendor/assets/images/toolbar/redirect.png +0 -0
  209. data/vendor/assets/images/toolbar/sitemap.png +0 -0
  210. data/vendor/assets/images/toolbar/snippets.png +0 -0
  211. data/vendor/assets/images/toolbar/unpublished.png +0 -0
  212. data/vendor/assets/images/tree-line-horizontal-last.png +0 -0
  213. data/vendor/assets/images/tree-line-horizontal.png +0 -0
  214. data/vendor/assets/images/tree-line-vertical.png +0 -0
  215. data/vendor/assets/javascripts/jquery-serializeObject.js +107 -0
  216. data/vendor/assets/javascripts/jquery.to-json.js +74 -0
  217. data/vendor/assets/javascripts/jquery.ui.nestedSortable-1.3.4.js +391 -0
  218. data/vendor/assets/javascripts/moment-1.6.2.js +918 -0
  219. data/vendor/assets/javascripts/underscore-1.3.1.js +31 -0
  220. data/vendor/assets/stylesheets/jasmine-modified.css +216 -0
  221. metadata +686 -0
@@ -0,0 +1,269 @@
1
+
2
+ Given 'a page exists at a custom path with custom content' do
3
+ @content = '<h1>Hello!</h1>'
4
+ @page = Cmsimple::Page.create!(title: 'About', published: true)
5
+ @path = @page.uri
6
+ @page.update_content({:editable1 => {:value => @content}})
7
+ @page.publish!
8
+ end
9
+
10
+ When "I visit that page's path" do
11
+ visit @path
12
+ end
13
+
14
+ When "I save and reload the page" do
15
+ step(%{I click on the "save" button})
16
+ visit current_path
17
+ end
18
+
19
+ When "I visit that page's edit path" do
20
+ visit ['/editor', @path].join
21
+ end
22
+
23
+ When "I visit the current page's public path" do
24
+ visit current_path.gsub('/editor', '')
25
+ end
26
+
27
+ When "I visit the current page's edit path" do
28
+ visit ['/editor', current_path].join
29
+ end
30
+
31
+ When "I add a new redirect" do
32
+ step %(the editor won't prompt when leaving the page)
33
+ click_button 'Add Redirect'
34
+ fill_in 'From', :with => '/redirect-path'
35
+ fill_in 'To', :with => '/about'
36
+ click_button 'Create'
37
+ end
38
+
39
+ When "I delete the redirect" do
40
+ within '.mercury-panel .redirects' do
41
+ link = find '.remove'
42
+ link.click
43
+ end
44
+ end
45
+
46
+ When "I add a new duplicate redirect" do
47
+ step %(the editor won't prompt when leaving the page)
48
+ page.driver.execute_script("window.alert = function(message){jQuery('body').append('<span>' + message + '</span>')}")
49
+ click_button 'Add Redirect'
50
+ fill_in 'From', :with => '/about'
51
+ fill_in 'To', :with => '/about-us'
52
+ click_button 'Create'
53
+ end
54
+
55
+ When "I visit the new redirect" do
56
+ step %(the editor won't prompt when leaving the page)
57
+ visit '/redirect-path'
58
+ end
59
+
60
+ When "I expand the toolbar if necessary" do
61
+ page.first(:css, '.mercury-toolbar-expander').try(:click)
62
+ end
63
+
64
+ When "I edit the page's metadata" do
65
+ step %{the toolbar should be visible}
66
+ step %{I expand the toolbar if necessary}
67
+ step %{I click on the "editMetadata" button}
68
+ step %{the modal window should be visible}
69
+ end
70
+
71
+ When "I open the sitemap" do
72
+ step %{the toolbar should be visible}
73
+ step %{I expand the toolbar if necessary}
74
+ step %{I click on the "sitemap" button}
75
+ step %{the sitemap panel should be visible}
76
+ end
77
+
78
+ When "I open the redirects" do
79
+ step %{the toolbar should be visible}
80
+ step %{I expand the toolbar if necessary}
81
+ step %{I click on the "redirects" button}
82
+ step %{the redirect panel should be visible}
83
+ end
84
+
85
+ When "I open the page's history" do
86
+ step %{the toolbar should be visible}
87
+ step %{I expand the toolbar if necessary}
88
+ step %{I click on the "history" button}
89
+ step %{the history panel should be visible}
90
+ end
91
+
92
+ When "I view the old version" do
93
+ within '.mercury-panel .versions' do
94
+ link = all('.view').last
95
+ link.click
96
+ end
97
+ end
98
+
99
+ When "I add a new page" do
100
+ click_button 'Add Page'
101
+ step %{the modal window should be visible}
102
+ fill_in 'Title', :with => 'Some new page'
103
+ click_button 'Create Page'
104
+ end
105
+
106
+ When "I add a new home page" do
107
+ click_button 'Add Page'
108
+ step %{the modal window should be visible}
109
+ fill_in 'Title', :with => 'Some new page'
110
+ check 'Home Page'
111
+ click_button 'Create Page'
112
+ end
113
+
114
+ When /^I change the template to "([^"]*)"/ do |template|
115
+ select template, :from => 'Template'
116
+ click_button 'Update Page'
117
+ end
118
+
119
+ When /^I change the seo info of the page/ do
120
+ fill_in 'Keywords', :with => 'some_keyword, someother_keyword'
121
+ fill_in 'Description', :with => 'This is a description of the page'
122
+ fill_in 'Browser title', :with => 'This is a new title for the browser'
123
+ click_button 'Update Page'
124
+ end
125
+
126
+ When /^I change the slug to "([^"]*)"/ do |path|
127
+ fill_in 'Slug', :with => path
128
+ click_button 'Update Page'
129
+ end
130
+
131
+ When "I publish the current page" do
132
+ step %{I change the contents of editable1 to "This is a published page"}
133
+ step %{I click on the "save" button}
134
+ step %{I click on the "publish" button}
135
+ step %{the modal window should be visible}
136
+ wait_for_client_page_refresh do
137
+ click_button 'Publish'
138
+ end
139
+ end
140
+
141
+ When "I make changes to the current page" do
142
+ step %{I change the contents of editable1 to "This is changed content"}
143
+ wait_for_client_page_refresh do
144
+ step %{I click on the "save" button}
145
+ end
146
+ end
147
+
148
+ When "I publish a new version of the current page" do
149
+ step %{I change the contents of editable1 to "This is a new version"}
150
+ step %{I click on the "save" button}
151
+ step %{I click on the "publish" button}
152
+ step %{the modal window should be visible}
153
+ click_button 'Publish'
154
+ end
155
+
156
+ Then "I should see that page's content" do
157
+ page.driver.response.body.should =~ /#{@content}/
158
+ end
159
+
160
+ Then "I should see that page's content in it's template" do
161
+ region = <<-HTML
162
+ <section data-mercury='full' id='editable1'>
163
+ #{@content}
164
+ </section>
165
+ HTML
166
+ page.driver.response.body.should =~ /#{region}/
167
+ puts page.driver.response.body
168
+ end
169
+
170
+ Then "I should be able to edit that page's content" do
171
+ sleep(1)
172
+ within_frame 'mercury_iframe' do
173
+ within '[data-mercury]' do
174
+ page.body.should =~ /#{@content}/
175
+ end
176
+ end
177
+ end
178
+
179
+ Then "I should be redirected to the new page" do
180
+ current_path.should == '/editor/some-new-page'
181
+ end
182
+
183
+ Then "I should be redirected to the home page" do
184
+ current_path.should =~ /^\/editor\/?$/
185
+ end
186
+
187
+ Then "I should be redirected to the about page" do
188
+ current_path.should == '/about'
189
+ end
190
+
191
+ Then "I should see the page in the sitemap" do
192
+ within '.mercury-panel .sitemap' do
193
+ page.should have_content 'Some new page'
194
+ end
195
+ end
196
+
197
+ Then "I should see the path in the redirects" do
198
+ within '.mercury-panel .redirects' do
199
+ page.should have_content '/redirect-path'
200
+ end
201
+ end
202
+
203
+ Then "I should not see the path in the redirects" do
204
+ within '.mercury-panel' do
205
+ page.should_not have_content '/redirect-path'
206
+ end
207
+ end
208
+
209
+ Then "I should not see the duplicate path in the redirects" do
210
+ within '.mercury-panel' do
211
+ page.should_not have_content '/about'
212
+ end
213
+ end
214
+
215
+ Then "I should be alerted to the duplicate redirect" do
216
+ page.should have_content 'Source URL must be unique'
217
+ end
218
+
219
+ Then /^I should see that seo info on the page/ do
220
+ allow_hidden_elements do
221
+
222
+ visit current_path.gsub('/editor', '')
223
+ within('title') do
224
+ page.should have_content('This is a new title for the browser')
225
+ end
226
+ page.should have_css('meta[name="keywords"]')
227
+ page.should have_css('meta[content="some_keyword, someother_keyword"]')
228
+ page.should have_css('meta[name="description"]')
229
+ page.should have_css('meta[content="This is a description of the page"]')
230
+
231
+ end
232
+ end
233
+
234
+ Then "the current page should be publicly available" do
235
+ step %(I visit the current page's public path)
236
+ current_path.should_not =~ /\/editor/
237
+ page.should have_content('This is a published page')
238
+ end
239
+
240
+ Then "the current page should only show published content" do
241
+ step %(the current page should be publicly available)
242
+ end
243
+
244
+ Then "I there should be one version in the history panel" do
245
+ within '.mercury-panel .versions' do
246
+ page.should have_selector 'li', count: 1
247
+ end
248
+ end
249
+
250
+ Then "I should see the old version" do
251
+ within_frame 'mercury_iframe' do
252
+ within '[data-mercury]' do
253
+ page.should have_content('This is a published page')
254
+ end
255
+ end
256
+ end
257
+
258
+ Then "there should be an indication of unpublished changes" do
259
+ step %{I wait for ajax requests to complete}
260
+ within '.mercury-toolbar' do
261
+ page.should have_selector '.mercury-publish-button.unpublished'
262
+ end
263
+ end
264
+
265
+ Then "there should not be an indication of unpublished changes" do
266
+ within '.mercury-toolbar' do
267
+ page.should_not have_selector '.mercury-publish-button.unpublished'
268
+ end
269
+ end
@@ -0,0 +1,254 @@
1
+
2
+ # TL;DR: YOU SHOULD DELETE THIS FILE
3
+ #
4
+ # This file was generated by Cucumber-Rails and is only here to get you a head start
5
+ # These step definitions are thin wrappers around the Capybara/Webrat API that lets you
6
+ # visit pages, interact with widgets and make assertions about page content.
7
+ #
8
+ # If you use these step definitions as basis for your features you will quickly end up
9
+ # with features that are:
10
+ #
11
+ # * Hard to maintain
12
+ # * Verbose to read
13
+ #
14
+ # A much better approach is to write your own higher level step definitions, following
15
+ # the advice in the following blog posts:
16
+ #
17
+ # * http://benmabey.com/2008/05/19/imperative-vs-declarative-scenarios-in-user-stories.html
18
+ # * http://dannorth.net/2011/01/31/whose-domain-is-it-anyway/
19
+ # * http://elabs.se/blog/15-you-re-cuking-it-wrong
20
+ #
21
+
22
+
23
+ require 'uri'
24
+ require 'cgi'
25
+ require File.expand_path(File.join(File.dirname(__FILE__), "..", "support", "paths"))
26
+ require File.expand_path(File.join(File.dirname(__FILE__), "..", "support", "selectors"))
27
+
28
+ module WithinHelpers
29
+ def with_scope(locator)
30
+ locator ? within(*selector_for(locator)) { yield } : yield
31
+ end
32
+ end
33
+ World(WithinHelpers)
34
+
35
+ # Single-line step scoper
36
+ When /^(.*) within (.*[^:])$/ do |inner_step, parent|
37
+ with_scope(parent) { step inner_step }
38
+ end
39
+
40
+ # Multi-line step scoper
41
+ When /^(.*) within (.*[^:]):$/ do |inner_step, parent, table_or_string|
42
+ with_scope(parent) { step "#{inner_step}:", table_or_string }
43
+ end
44
+
45
+ Given /^(?:|I )am on (.+)$/ do |page_name|
46
+ visit path_to(page_name)
47
+ end
48
+
49
+ When /^(?:|I )go to (.+)$/ do |page_name|
50
+ visit path_to(page_name)
51
+ end
52
+
53
+ When /^(?:|I )press "([^"]*)"$/ do |button|
54
+ click_button(button)
55
+ end
56
+
57
+ When /^(?:|I )follow "([^"]*)"$/ do |link|
58
+ click_link(link)
59
+ end
60
+
61
+ When /^(?:|I )fill in "([^"]*)" with "([^"]*)"$/ do |field, value|
62
+ fill_in(field, :with => value)
63
+ end
64
+
65
+ When /^(?:|I )fill in "([^"]*)" for "([^"]*)"$/ do |value, field|
66
+ fill_in(field, :with => value)
67
+ end
68
+
69
+ # Use this to fill in an entire form with data from a table. Example:
70
+ #
71
+ # When I fill in the following:
72
+ # | Account Number | 5002 |
73
+ # | Expiry date | 2009-11-01 |
74
+ # | Note | Nice guy |
75
+ # | Wants Email? | |
76
+ #
77
+ # TODO: Add support for checkbox, select og option
78
+ # based on naming conventions.
79
+ #
80
+ When /^(?:|I )fill in the following:$/ do |fields|
81
+ fields.rows_hash.each do |name, value|
82
+ step %{I fill in "#{name}" with "#{value}"}
83
+ end
84
+ end
85
+
86
+ When /^(?:|I )select "([^"]*)" from "([^"]*)"$/ do |value, field|
87
+ select(value, :from => field)
88
+ end
89
+
90
+ When /^(?:|I )check "([^"]*)"$/ do |field|
91
+ check(field)
92
+ end
93
+
94
+ When /^(?:|I )uncheck "([^"]*)"$/ do |field|
95
+ uncheck(field)
96
+ end
97
+
98
+ When /^(?:|I )choose "([^"]*)"$/ do |field|
99
+ choose(field)
100
+ end
101
+
102
+ When /^(?:|I )attach the file "([^"]*)" to "([^"]*)"$/ do |path, field|
103
+ attach_file(field, File.expand_path(path))
104
+ end
105
+
106
+ Then /^(?:|I )should see "([^"]*)"$/ do |text|
107
+ if page.respond_to? :should
108
+ page.should have_content(text)
109
+ else
110
+ assert page.has_content?(text)
111
+ end
112
+ end
113
+
114
+ Then /^(?:|I )should see \/([^\/]*)\/$/ do |regexp|
115
+ regexp = Regexp.new(regexp)
116
+
117
+ if page.respond_to? :should
118
+ page.should have_xpath('//*', :text => regexp)
119
+ else
120
+ assert page.has_xpath?('//*', :text => regexp)
121
+ end
122
+ end
123
+
124
+ Then /^(?:|I )should not see "([^"]*)"$/ do |text|
125
+ if page.respond_to? :should
126
+ page.should have_no_content(text)
127
+ else
128
+ assert page.has_no_content?(text)
129
+ end
130
+ end
131
+
132
+ Then /^(?:|I )should not see \/([^\/]*)\/$/ do |regexp|
133
+ regexp = Regexp.new(regexp)
134
+
135
+ if page.respond_to? :should
136
+ page.should have_no_xpath('//*', :text => regexp)
137
+ else
138
+ assert page.has_no_xpath?('//*', :text => regexp)
139
+ end
140
+ end
141
+
142
+ Then /^the "([^"]*)" field(?: within (.*))? should contain "([^"]*)"$/ do |field, parent, value|
143
+ with_scope(parent) do
144
+ field = find_field(field)
145
+ field_value = (field.tag_name == 'textarea') ? field.text : field.value
146
+ if field_value.respond_to? :should
147
+ field_value.should =~ /#{value}/
148
+ else
149
+ assert_match(/#{value}/, field_value)
150
+ end
151
+ end
152
+ end
153
+
154
+ Then /^the "([^"]*)" field(?: within (.*))? should not contain "([^"]*)"$/ do |field, parent, value|
155
+ with_scope(parent) do
156
+ field = find_field(field)
157
+ field_value = (field.tag_name == 'textarea') ? field.text : field.value
158
+ if field_value.respond_to? :should_not
159
+ field_value.should_not =~ /#{value}/
160
+ else
161
+ assert_no_match(/#{value}/, field_value)
162
+ end
163
+ end
164
+ end
165
+
166
+ Then /^the "([^"]*)" field should have the error "([^"]*)"$/ do |field, error_message|
167
+ begin
168
+ element = find_field(field)
169
+ rescue Capybara::ElementNotFound => ex
170
+ # radio buttons in formtastic don't follow capybara's expectation of field labels
171
+ element = page.find(:xpath, "//li/fieldset/legend/label[contains(normalize-space(string(.)), '#{field}')]")
172
+ end
173
+
174
+ wrapping_element = element.find(:xpath, 'ancestor::li')
175
+ form_for_input = element.find(:xpath, 'ancestor::form[1]')
176
+
177
+ classes = wrapping_element[:class].split(' ')
178
+ classes.should include('error'), "'#{field}' doesn't have class 'error'"
179
+
180
+ error_paragraph = wrapping_element.find(:xpath, './/*[@class="inline-errors"][1]')
181
+ error_paragraph.should have_content(error_message), "'#{field}' doesn't have message '#{error_message}'"
182
+ end
183
+
184
+ Then /^the "([^"]*)" field should have no error$/ do |field|
185
+ element = find_field(field)
186
+ wrapping_element = element.find(:xpath, 'ancestor::li')
187
+
188
+ classes = wrapping_element[:class].split(' ')
189
+ classes.should_not include('error')
190
+ end
191
+
192
+ Then /^the "([^"]*)" checkbox(?: within (.*))? should be checked$/ do |label, parent|
193
+ with_scope(parent) do
194
+ field_checked = find_field(label)['checked']
195
+ if field_checked.respond_to? :should
196
+ field_checked.should be_true
197
+ else
198
+ assert field_checked
199
+ end
200
+ end
201
+ end
202
+
203
+ Then /^the "([^"]*)" checkbox(?: within (.*))? should not be checked$/ do |label, parent|
204
+ with_scope(parent) do
205
+ field_checked = find_field(label)['checked']
206
+ if field_checked.respond_to? :should
207
+ field_checked.should be_false
208
+ else
209
+ assert !field_checked
210
+ end
211
+ end
212
+ end
213
+
214
+ Then /^(?:|I )should be on (.+)$/ do |page_name|
215
+ path = URI.parse(current_url).path
216
+ fragment = URI.parse(current_url).fragment
217
+ current_path = [path, fragment].compact.join('#')
218
+ current_path.gsub!(/\#$/, '')
219
+ if current_path.respond_to? :should
220
+ current_path.should == path_to(page_name)
221
+ else
222
+ assert_equal path_to(page_name), current_path
223
+ end
224
+ end
225
+
226
+ Then /^(?:|I )should have the following query string:$/ do |expected_pairs|
227
+ query = URI.parse(current_url).query
228
+ actual_params = query ? CGI.parse(query) : {}
229
+ expected_params = {}
230
+ expected_pairs.rows_hash.each_pair{|k,v| expected_params[k] = v.split(',')}
231
+
232
+ if actual_params.respond_to? :should
233
+ actual_params.should == expected_params
234
+ else
235
+ assert_equal expected_params, actual_params
236
+ end
237
+ end
238
+
239
+ Then /^show me the page$/ do
240
+ save_and_open_page
241
+ end
242
+
243
+ When /^(?:|I )wait for ajax requests to complete/ do
244
+ wait_until do
245
+ page.evaluate_script('$.active') == 0
246
+ end
247
+ end
248
+
249
+ And /^I accept confirmations$/ do
250
+ page.execute_script %Q{
251
+ window.confirm = function(){ return true };
252
+ }
253
+ end
254
+