administer 0.2.2 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (120) hide show
  1. data/README.rdoc +3 -4
  2. data/app/controllers/administer/application_controller.rb +12 -0
  3. data/app/controllers/administer/entities_controller.rb +76 -0
  4. data/app/helpers/administer/dashboard_helper.rb +1 -1
  5. data/app/helpers/administer/entities_helper.rb +2 -0
  6. data/app/views/administer/dashboard/index.html.haml +1 -1
  7. data/app/views/administer/entities/_form.haml +9 -0
  8. data/app/views/administer/entities/edit.html.haml +9 -0
  9. data/app/views/administer/entities/index.html.haml +21 -0
  10. data/app/views/administer/entities/new.haml +9 -0
  11. data/app/views/administer/fields/_belongs_to.html.haml +2 -0
  12. data/app/views/administer/fields/_date_select.html.haml +2 -0
  13. data/app/views/administer/fields/_has_many.html.haml +4 -0
  14. data/app/views/administer/fields/_has_one.html.haml +2 -0
  15. data/app/views/administer/fields/_text_area.html.haml +2 -0
  16. data/app/views/administer/fields/_text_field.html.haml +2 -0
  17. data/app/views/administer/shared/_errors.html.haml +6 -0
  18. data/app/views/layouts/administer.html.haml +21 -0
  19. data/config/routes.rb +4 -4
  20. data/lib/administer.rb +1 -0
  21. data/lib/administer/active_record.rb +22 -0
  22. data/lib/administer/config.rb +37 -0
  23. data/lib/administer/config/controller_config.rb +24 -0
  24. data/lib/administer/config/model_config.rb +23 -0
  25. data/lib/administer/engine.rb +5 -0
  26. data/lib/administer/fields.rb +34 -0
  27. data/lib/administer/fields/association.rb +21 -0
  28. data/lib/administer/fields/base.rb +15 -0
  29. data/lib/administer/fields/belongs_to.rb +12 -0
  30. data/lib/administer/fields/date_select.rb +6 -0
  31. data/lib/administer/fields/field_builder.rb +25 -0
  32. data/lib/administer/fields/has_many.rb +22 -0
  33. data/lib/administer/fields/has_one.rb +24 -0
  34. data/lib/administer/fields/text_area.rb +6 -0
  35. data/lib/administer/fields/text_field.rb +6 -0
  36. data/lib/administer/model.rb +40 -13
  37. data/spec/controllers/administer/entities_controller_spec.rb +23 -0
  38. data/spec/{rails_root/spec/controllers → controllers}/posts_controller_spec.rb +1 -1
  39. data/spec/factories/categories.rb +3 -0
  40. data/spec/factories/comments.rb +3 -0
  41. data/spec/{rails_root/spec/factories → factories}/posts.rb +0 -0
  42. data/spec/lib/config/model_config_spec.rb +35 -0
  43. data/spec/lib/config_spec.rb +29 -0
  44. data/spec/lib/fields/field_builder_spec.rb +10 -0
  45. data/spec/{rails_root/spec/models/administer → lib}/model_spec.rb +5 -4
  46. data/spec/models/comment_spec.rb +5 -0
  47. data/spec/rails_root/Gemfile +2 -0
  48. data/spec/rails_root/Gemfile.lock +150 -0
  49. data/spec/rails_root/README +256 -0
  50. data/spec/rails_root/Rakefile +7 -0
  51. data/spec/rails_root/app/controllers/application_controller.rb +4 -0
  52. data/spec/rails_root/app/models/attachment.rb +3 -0
  53. data/spec/rails_root/app/models/category.rb +1 -0
  54. data/spec/rails_root/app/models/comment.rb +3 -0
  55. data/spec/rails_root/app/models/post.rb +8 -0
  56. data/spec/rails_root/app/views/layouts/application.html.erb +14 -0
  57. data/spec/rails_root/app/views/posts/_form.html.haml +19 -0
  58. data/spec/rails_root/app/views/posts/edit.html.haml +5 -0
  59. data/spec/rails_root/app/views/posts/index.html.haml +10 -0
  60. data/spec/rails_root/app/views/posts/new.html.haml +3 -0
  61. data/spec/rails_root/app/views/posts/show.html.haml +10 -0
  62. data/spec/rails_root/config.ru +4 -0
  63. data/spec/rails_root/config/cucumber.yml +8 -0
  64. data/spec/rails_root/config/database.yml +25 -0
  65. data/spec/rails_root/config/initializers/administer.rb +23 -0
  66. data/spec/rails_root/config/locales/en.yml +5 -0
  67. data/spec/rails_root/db/development.sqlite3 +0 -0
  68. data/spec/rails_root/db/migrate/20110104100347_add_publish_on_to_post.rb +9 -0
  69. data/spec/rails_root/db/migrate/20110214190645_add_category_to_post.rb +9 -0
  70. data/spec/rails_root/db/migrate/20110609184125_create_comments.rb +13 -0
  71. data/spec/rails_root/db/migrate/20110628215407_create_attachments.rb +13 -0
  72. data/spec/rails_root/db/schema.rb +44 -0
  73. data/spec/rails_root/db/test.sqlite3 +0 -0
  74. data/spec/rails_root/features/administer/dashboard.feature +15 -0
  75. data/spec/rails_root/features/administer/posts.feature +72 -0
  76. data/spec/rails_root/features/listing_posts.feature +15 -0
  77. data/spec/rails_root/features/managing_posts.feature +70 -0
  78. data/spec/rails_root/features/step_definitions/categories_steps.rb +6 -0
  79. data/spec/rails_root/features/step_definitions/comments_steps.rb +6 -0
  80. data/spec/rails_root/features/step_definitions/post_steps.rb +21 -0
  81. data/spec/rails_root/features/step_definitions/web_steps.rb +5 -2
  82. data/spec/rails_root/features/support/env.rb +32 -46
  83. data/spec/rails_root/features/support/factory_girl.rb +2 -0
  84. data/spec/rails_root/features/support/matchers.rb +55 -0
  85. data/spec/rails_root/features/support/paths.rb +2 -0
  86. data/spec/rails_root/features/support/selectors.rb +39 -0
  87. data/spec/rails_root/lib/tasks/cucumber.rake +65 -0
  88. data/spec/rails_root/log/development.log +19507 -0
  89. data/spec/rails_root/log/test.log +45042 -0
  90. data/spec/rails_root/public/404.html +26 -0
  91. data/spec/rails_root/public/422.html +26 -0
  92. data/spec/rails_root/public/500.html +26 -0
  93. data/spec/rails_root/public/favicon.ico +0 -0
  94. data/spec/rails_root/public/images/rails.png +0 -0
  95. data/spec/rails_root/public/javascripts/application.js +2 -0
  96. data/spec/rails_root/public/javascripts/controls.js +965 -0
  97. data/spec/rails_root/public/javascripts/dragdrop.js +974 -0
  98. data/spec/rails_root/public/javascripts/effects.js +1123 -0
  99. data/spec/rails_root/public/javascripts/prototype.js +6001 -0
  100. data/spec/rails_root/public/javascripts/rails.js +175 -0
  101. data/spec/rails_root/public/robots.txt +5 -0
  102. data/spec/rails_root/public/stylesheets/scaffold.css +60 -0
  103. data/spec/rails_root/script/cucumber +10 -0
  104. data/spec/rails_root/script/rails +6 -0
  105. data/spec/rails_root/spec/models/attachment_spec.rb +5 -0
  106. data/spec/rails_root/tmp/capybara/capybara-20101221001337.html +43 -0
  107. data/spec/rails_root/tmp/capybara/capybara-20101221001509.html +47 -0
  108. data/spec/rails_root/tmp/capybara/capybara-20110104162405.html +110 -0
  109. data/spec/rails_root/tmp/capybara/capybara-20110214224604.html +51 -0
  110. data/spec/rails_root/tmp/capybara/capybara-20110214225336.html +51 -0
  111. data/spec/rails_root/tmp/capybara/capybara-20110214225545.html +51 -0
  112. data/spec/{rails_root/spec/routing → routing}/posts_routing_spec.rb +1 -1
  113. data/spec/{rails_root/spec/spec_helper.rb → spec_helper.rb} +6 -4
  114. data/spec/{rails_root/spec/views → views}/posts/edit.html.haml_spec.rb +1 -1
  115. data/spec/{rails_root/spec/views → views}/posts/new.html.haml_spec.rb +1 -1
  116. data/spec/{rails_root/spec/views → views}/posts/show.html.haml_spec.rb +1 -1
  117. metadata +306 -46
  118. data/app/controllers/administer/models_controller.rb +0 -16
  119. data/app/views/administer/models/index.html.haml +0 -14
  120. data/spec/rails_root/spec/controllers/administer/models_controller_spec.rb +0 -19
@@ -0,0 +1,9 @@
1
+ class AddPublishOnToPost < ActiveRecord::Migration
2
+ def self.up
3
+ add_column :posts, :publish_on, :date
4
+ end
5
+
6
+ def self.down
7
+ remove_column :posts, :publish_on
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ class AddCategoryToPost < ActiveRecord::Migration
2
+ def self.up
3
+ add_column :posts, :category_id, :integer
4
+ end
5
+
6
+ def self.down
7
+ remove_column :posts, :category_id, :integer
8
+ end
9
+ end
@@ -0,0 +1,13 @@
1
+ class CreateComments < ActiveRecord::Migration
2
+ def self.up
3
+ create_table :comments do |t|
4
+ t.text :body
5
+ t.integer :post_id
6
+ t.timestamps
7
+ end
8
+ end
9
+
10
+ def self.down
11
+ drop_table :comments
12
+ end
13
+ end
@@ -0,0 +1,13 @@
1
+ class CreateAttachments < ActiveRecord::Migration
2
+ def self.up
3
+ create_table :attachments do |t|
4
+ t.integer :post_id
5
+ t.text :content
6
+ t.timestamps
7
+ end
8
+ end
9
+
10
+ def self.down
11
+ drop_table :attachments
12
+ end
13
+ end
@@ -0,0 +1,44 @@
1
+ # This file is auto-generated from the current state of the database. Instead
2
+ # of editing this file, please use the migrations feature of Active Record to
3
+ # incrementally modify your database, and then regenerate this schema definition.
4
+ #
5
+ # Note that this schema.rb definition is the authoritative source for your
6
+ # database schema. If you need to create the application database on another
7
+ # system, you should be using db:schema:load, not running all the migrations
8
+ # from scratch. The latter is a flawed and unsustainable approach (the more migrations
9
+ # you'll amass, the slower it'll run and the greater likelihood for issues).
10
+ #
11
+ # It's strongly recommended to check this file into your version control system.
12
+
13
+ ActiveRecord::Schema.define(:version => 20110628215407) do
14
+
15
+ create_table "attachments", :force => true do |t|
16
+ t.integer "post_id"
17
+ t.text "content"
18
+ t.datetime "created_at"
19
+ t.datetime "updated_at"
20
+ end
21
+
22
+ create_table "categories", :force => true do |t|
23
+ t.string "name"
24
+ t.datetime "created_at"
25
+ t.datetime "updated_at"
26
+ end
27
+
28
+ create_table "comments", :force => true do |t|
29
+ t.text "body"
30
+ t.integer "post_id"
31
+ t.datetime "created_at"
32
+ t.datetime "updated_at"
33
+ end
34
+
35
+ create_table "posts", :force => true do |t|
36
+ t.string "title"
37
+ t.text "body"
38
+ t.datetime "created_at"
39
+ t.datetime "updated_at"
40
+ t.date "publish_on"
41
+ t.integer "category_id"
42
+ end
43
+
44
+ end
@@ -0,0 +1,15 @@
1
+ Feature: Dashboard
2
+ In order to administer the blog
3
+ I want to use administration dashboard
4
+
5
+ Scenario: Viewing Dashboard page
6
+ When I am on the administer dashboard page
7
+ Then I should see "Administer Dashboard"
8
+ And I should see "Models:"
9
+ And I should see "Posts" within "ul.administer_model_list"
10
+ And I should see "Categories" within "ul.administer_model_list"
11
+
12
+ Scenario: Link to application home page
13
+ When I am on the administer dashboard page
14
+ And I follow "Go to application"
15
+ Then I should be on the home page
@@ -0,0 +1,72 @@
1
+ Feature: Managing posts via administer
2
+ In order to make sure administer works
3
+ I want to be able to manage posts via administer
4
+
5
+ Scenario: Listing posts
6
+ Given following posts exists:
7
+ | title | body |
8
+ | How to raise your kid | You should be good parent |
9
+ When I am on the administer dashboard page
10
+ And I follow "Posts"
11
+ Then I should see "How to raise your kid"
12
+ And I should see "You should be good parent"
13
+
14
+ Scenario: Creating posts
15
+ Given following categories exist:
16
+ | name |
17
+ | Awesome Posts |
18
+ Given following comments exist:
19
+ | body |
20
+ | First comment |
21
+ | What is this? |
22
+ When I am on administer posts list
23
+ And I follow "New Post"
24
+ Then I should see textfield with label "Title"
25
+ And I should see textarea with label "Body"
26
+ And I should see dateselect with label "Publish on"
27
+ And I should see select with label "Category"
28
+ And I should see checkbox with label "First comment"
29
+ And I should see checkbox with label "What is this"
30
+ And I fill in "Title" with "How to raise your kid"
31
+ And I fill in "Body" with "You should be good parent."
32
+ And I select "Awesome Posts" from "Category"
33
+ And I check "First comment"
34
+ And I press "Create Post"
35
+ Then I should be on administer posts list
36
+ And following posts should exist:
37
+ | title | body | category_name | comments |
38
+ | How to raise your kid | You should be good parent. | Awesome Posts | First comment |
39
+
40
+ Scenario: Creating invalid post
41
+ Given following categories exist:
42
+ | name |
43
+ | Awesome Posts |
44
+ When I am on administer posts list
45
+ And I follow "New Post"
46
+ Then I fill in "Body" with "Post without title"
47
+ And I press "Create Post"
48
+ Then I should see "can't be blank"
49
+ And there should be no posts
50
+
51
+ Scenario: Editing Posts
52
+ Given following posts exists:
53
+ | title | body |
54
+ | How to raise your kid | You should be good parent |
55
+ When I am on administer posts list
56
+ And I follow "Edit"
57
+ Then I fill in "Title" with "Can we?"
58
+ And I fill in "Body" with "Yes, we can"
59
+ And I press "Update Post"
60
+ Then I should be on administer posts list
61
+ And following posts should exist:
62
+ | title | body |
63
+ | Can we? | Yes, we can |
64
+
65
+ Scenario: Deleting post
66
+ Given following posts exists:
67
+ | title | body |
68
+ | How to raise your kid | You should be good parent |
69
+ When I am on administer posts list
70
+ And I press "Delete"
71
+ Then I should be on administer posts list
72
+ And there should be no posts
@@ -0,0 +1,15 @@
1
+ Feature: Listing Posts
2
+ In order to read blog
3
+ As a blog guest
4
+ I want to be able to list posts
5
+
6
+ Scenario: List all blog posts
7
+ Given following posts exists:
8
+ | title | body |
9
+ | How to raise your kid | You should be good parent |
10
+ | How to make great coffe | Add whipped cream to it |
11
+ When I am on the home page
12
+ Then I should see "How to raise your kid"
13
+ And I should see "You should be good parent"
14
+ And I should see "How to make great coffe"
15
+ And I should see "Add whipped cream to it"
@@ -0,0 +1,70 @@
1
+ Feature: Managing posts
2
+ In order to manage my blog
3
+ As a blog owner
4
+ I want to be able to manage posts
5
+
6
+ Scenario: Adding new blog post
7
+ Given no posts exist
8
+ When I am on the home page
9
+ And I follow "new post"
10
+ And I fill in "Title" with "How to disassemble atomic bomb?"
11
+ And I fill in "Body" with "You should avoid using fork for that."
12
+ And I press "Create Post"
13
+ Then I should be on posts list
14
+ And I should see "How to disassemble atomic bomb?"
15
+ And I should see "You should avoid using fork for that."
16
+
17
+ Scenario: Adding new blog post without title
18
+ Given no posts exist
19
+ When I am on the home page
20
+ And I follow "new post"
21
+ And I fill in "Body" with "You should avoid using fork for that."
22
+ And I press "Create Post"
23
+ Then I should see "Title can't be blank"
24
+ And there should be no posts
25
+
26
+ Scenario: Adding new blog post without body
27
+ Given no posts exist
28
+ When I am on the home page
29
+ And I follow "new post"
30
+ And I fill in "Title" with "How to disassemble atomic bomb?"
31
+ And I press "Create Post"
32
+ Then I should see "Body can't be blank"
33
+ And there should be no posts
34
+
35
+ @javascript
36
+ Scenario: Deleting blog post
37
+ Given following posts exists:
38
+ | title | body |
39
+ | How to raise your kid | You should be good parent |
40
+ When I am on the home page
41
+ Then I should see "How to raise your kid"
42
+ When I press "delete" and confirm
43
+ Then I should be on posts list
44
+ And I should not see "How to raise your kid"
45
+
46
+ @javascript
47
+ Scenario: Cancel deleting blog post
48
+ Given following posts exists:
49
+ | title | body |
50
+ | How to raise your kid | You should be good parent |
51
+ When I am on the home page
52
+ Then I should see "How to raise your kid"
53
+ When I press "delete" and not confirm
54
+ Then I should be on the home page
55
+ And I should see "How to raise your kid"
56
+
57
+ Scenario: Editing blog post
58
+ Given following posts exists:
59
+ | title | body |
60
+ | How to raise your kid | You should be good parent |
61
+ When I am on the home page
62
+ Then I should see "How to raise your kid"
63
+ When I follow "edit"
64
+ And I fill in "Title" with "What do you want to do today?"
65
+ And I fill in "Body" with "Every god damn thing"
66
+ And I press "Update"
67
+ Then I should be on posts list
68
+ And I should see "What do you want to do today"
69
+ And I should see "Every god damn thing"
70
+
@@ -0,0 +1,6 @@
1
+ Given /^following categories exist:$/ do |categories_table|
2
+ Category.destroy_all
3
+ categories_table.hashes.each do |attributes|
4
+ Factory(:category, attributes)
5
+ end
6
+ end
@@ -0,0 +1,6 @@
1
+ Given /^following comments exist:$/ do |comments_table|
2
+ Comment.destroy_all
3
+ comments_table.hashes.each do |attributes|
4
+ Factory(:comment, attributes)
5
+ end
6
+ end
@@ -8,3 +8,24 @@ Given /^following posts exists:$/ do |posts_table|
8
8
  Factory(:post, attributes)
9
9
  end
10
10
  end
11
+
12
+ Then /^there should be no posts$/ do
13
+ Post.all.should be_empty
14
+ end
15
+
16
+ Then /^following posts should exist:$/ do |posts_table|
17
+ posts_table.hashes.each do |attributes|
18
+ category = attributes.delete("category_name")
19
+ comments = attributes.delete("comments").try(:split, ";")
20
+ post = Post.first(:conditions => attributes)
21
+ post.should_not be_nil
22
+ post.category.name.should == category if category
23
+ if comments.present?
24
+ post_comments_mapped = post.comments.map(&:body)
25
+ comments.all? { |c| post_comments_mapped.should include(c) }
26
+ end
27
+ end
28
+ end
29
+
30
+
31
+
@@ -104,6 +104,10 @@ Then /^(?:|I )should see JSON:$/ do |expected_json|
104
104
  expected.should == actual
105
105
  end
106
106
 
107
+ Then /^(?:|I )should see (.*) with label "([^"]*)"$/ do |fieldtype, label|
108
+ page.should send("have_#{fieldtype}".to_sym, label)
109
+ end
110
+
107
111
  Then /^(?:|I )should see "([^"]*)"(?: within "([^"]*)")?$/ do |text, selector|
108
112
  with_scope(selector) do
109
113
  if page.respond_to? :should
@@ -193,7 +197,7 @@ Then /^the "([^"]*)" checkbox(?: within "([^"]*)")? should not be checked$/ do |
193
197
  end
194
198
 
195
199
  Then /^(?:|I )should be on (.+)$/ do |page_name|
196
- current_path = URI.parse(current_url).path
200
+ current_path = URI.parse(current_url).request_uri
197
201
  if current_path.respond_to? :should
198
202
  current_path.should == path_to(page_name)
199
203
  else
@@ -227,4 +231,3 @@ Then /^(?:|I )press "([^"]*)" and not confirm$/ do |button|
227
231
  page.evaluate_script("window.confirm = function(msg) { return false; }")
228
232
  When %{I press "#{button}"}
229
233
  end
230
-
@@ -4,61 +4,47 @@
4
4
  # instead of editing this one. Cucumber will automatically load all features/**/*.rb
5
5
  # files.
6
6
 
7
- ENV["RAILS_ENV"] ||= "test"
8
- require File.expand_path(File.dirname(__FILE__) + '/../../config/environment')
7
+ require 'cucumber/rails'
9
8
 
10
- require 'cucumber/formatter/unicode' # Remove this line if you don't want Cucumber Unicode support
11
- require 'cucumber/rails/rspec'
12
- require 'cucumber/rails/world'
13
- require 'cucumber/rails/active_record'
14
- require 'cucumber/web/tableish'
15
-
16
- require 'capybara/rails'
17
- require 'capybara/cucumber'
18
- require 'capybara/session'
19
- # require 'cucumber/rails/capybara_javascript_emulation' # Lets you click links with onclick javascript handlers without using @culerity or @javascript
20
9
  # Capybara defaults to XPath selectors rather than Webrat's default of CSS3. In
21
10
  # order to ease the transition to Capybara we set the default here. If you'd
22
11
  # prefer to use XPath just remove this line and adjust any selectors in your
23
12
  # steps to use the XPath syntax.
24
13
  Capybara.default_selector = :css
25
- Capybara.javascript_driver = :selenium
26
- Capybara.ignore_hidden_elements = true
27
14
 
28
- # If you set this to false, any error raised from within your app will bubble
29
- # up to your step definition and out to cucumber unless you catch it somewhere
30
- # on the way. You can make Rails rescue errors and render error pages on a
31
- # per-scenario basis by tagging a scenario or feature with the @allow-rescue tag.
15
+ # By default, any exception happening in your Rails application will bubble up
16
+ # to Cucumber so that your scenario will fail. This is a different from how
17
+ # your application behaves in the production environment, where an error page will
18
+ # be rendered instead.
32
19
  #
33
- # If you set this to true, Rails will rescue all errors and render error
34
- # pages, more or less in the same way your application would behave in the
35
- # default production environment. It's not recommended to do this for all
36
- # of your scenarios, as this makes it hard to discover errors in your application.
37
- ActionController::Base.allow_rescue = false
38
-
39
- # If you set this to true, each scenario will run in a database transaction.
40
- # You can still turn off transactions on a per-scenario basis, simply tagging
41
- # a feature or scenario with the @no-txn tag. If you are using Capybara,
42
- # tagging with @culerity or @javascript will also turn transactions off.
20
+ # Sometimes we want to override this default behaviour and allow Rails to rescue
21
+ # exceptions and display an error page (just like when the app is running in production).
22
+ # Typical scenarios where you want to do this is when you test your error pages.
23
+ # There are two ways to allow Rails to rescue exceptions:
43
24
  #
44
- # If you set this to false, transactions will be off for all scenarios,
45
- # regardless of whether you use @no-txn or not.
25
+ # 1) Tag your scenario (or feature) with @allow-rescue
46
26
  #
47
- # Beware that turning transactions off will leave data in your database
48
- # after each scenario, which can lead to hard-to-debug failures in
49
- # subsequent scenarios. If you do this, we recommend you create a Before
50
- # block that will explicitly put your database in a known state.
51
- Cucumber::Rails::World.use_transactional_fixtures = true
52
- # How to clean your database when transactions are turned off. See
53
- # http://github.com/bmabey/database_cleaner for more info.
54
- if defined?(ActiveRecord::Base)
55
- begin
56
- require 'database_cleaner'
57
- DatabaseCleaner.strategy = :truncation
58
- rescue LoadError => ignore_if_database_cleaner_not_present
59
- end
27
+ # 2) Set the value below to true. Beware that doing this globally is not
28
+ # recommended as it will mask a lot of errors for you!
29
+ #
30
+ ActionController::Base.allow_rescue = false
31
+
32
+ # Remove/comment out the lines below if your app doesn't have a database.
33
+ # For some databases (like MongoDB and CouchDB) you may need to use :truncation instead.
34
+ begin
35
+ DatabaseCleaner.strategy = :transaction
36
+ rescue NameError
37
+ raise "You need to add database_cleaner to your Gemfile (in the :test group) if you wish to use it."
60
38
  end
61
39
 
62
- # factory_girl setup
63
- require 'factory_girl'
64
- Dir["#{File.dirname(__FILE__)}/../../spec/factories/*.rb"].each {|f| require f}
40
+ # You may also want to configure DatabaseCleaner to use different strategies for certain features and scenarios.
41
+ # See the DatabaseCleaner documentation for details. Example:
42
+ #
43
+ # Before('@no-txn,@selenium,@culerity,@celerity,@javascript') do
44
+ # DatabaseCleaner.strategy = :truncation, {:except => %w[widgets]}
45
+ # end
46
+ #
47
+ # Before('~@no-txn', '~@selenium', '~@culerity', '~@celerity', '~@javascript') do
48
+ # DatabaseCleaner.strategy = :transaction
49
+ # end
50
+ #
@@ -0,0 +1,2 @@
1
+ require 'factory_girl'
2
+ Dir["#{File.dirname(__FILE__)}/../../../factories/*.rb"].each { |f| require f }
@@ -0,0 +1,55 @@
1
+ class Capybara::Session
2
+ def has_textfield?(locator)
3
+ find_field(:textfield, locator)
4
+ end
5
+
6
+ def has_textarea?(locator)
7
+ find_field(:textarea, locator)
8
+ end
9
+
10
+ def has_select?(locator)
11
+ find_field(:select, locator)
12
+ end
13
+
14
+ def has_dateselect?(locator)
15
+ id_prefix = find(:xpath, XPath::HTML.label(locator))[:for]
16
+ year = find_field(:select, "#{id_prefix}_1i")
17
+ month = find_field(:select, "#{id_prefix}_2i")
18
+ day = find_field(:select, "#{id_prefix}_3i")
19
+ year && month && day
20
+ end
21
+
22
+ def has_checkbox?(locator)
23
+ find_field(:checkbox, locator)
24
+ end
25
+
26
+ def find_field(type, locator)
27
+ all(:xpath, XPath::HTML.field_of_type(type, locator)).present?
28
+ end
29
+ end
30
+
31
+ module XPath::HTML
32
+ def self.field_of_type(type, locator)
33
+ xpath = fieldtype_to_xpath(type)
34
+ xpath = locate_field(xpath, locator)
35
+ xpath
36
+ end
37
+
38
+ def self.label(label)
39
+ anywhere(:label)[string.n.is(label)]
40
+ end
41
+
42
+ private
43
+ def self.fieldtype_to_xpath(type)
44
+ case type
45
+ when :textfield
46
+ descendant(:input)[~attr(:type).one_of('submit', 'image', 'radio', 'checkbox', 'hidden', 'file')]
47
+ when :checkbox
48
+ descendant(:input)[attr(:type) == 'checkbox']
49
+ when :textarea
50
+ descendant(:textarea)
51
+ when :select
52
+ descendant(:select)
53
+ end
54
+ end
55
+ end