locomotivecms 3.0.0.rc3 → 3.0.0.rc4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +3 -3
- data/README.md +1 -1
- data/app/assets/stylesheets/locomotive/unauthorized/_public.scss +7 -4
- data/app/controllers/locomotive/errors_controller.rb +4 -0
- data/app/helpers/locomotive/errors_helper.rb +2 -4
- data/app/models/locomotive/concerns/content_entry/csv.rb +4 -0
- data/app/models/locomotive/concerns/content_entry/slug.rb +0 -2
- data/app/models/locomotive/concerns/content_type/sync.rb +2 -2
- data/app/models/locomotive/concerns/page/templatized.rb +1 -1
- data/app/models/locomotive/concerns/site/access_points.rb +3 -3
- data/app/models/locomotive/theme_asset.rb +0 -1
- data/app/views/locomotive/developers_documentation/_wagon.html.slim +2 -2
- data/app/views/locomotive/devise_mailer/reset_password_instructions.html.slim +1 -0
- data/app/views/locomotive/errors/no_site.json +1 -0
- data/app/views/locomotive/shared/_sidebar.html.slim +1 -1
- data/app/views/locomotive/shared/_sidebar_without_site.html.slim +1 -1
- data/app/views/locomotive/shared/header/_account_menu.html.slim +2 -2
- data/config/locales/en.yml +1 -1
- data/config/routes.rb +4 -2
- data/lib/generators/locomotive/install/install_generator.rb +9 -9
- data/lib/generators/locomotive/install/templates/carrierwave.rb +23 -12
- data/lib/generators/locomotive/install/templates/carrierwave_aws.rb +36 -0
- data/lib/generators/locomotive/install/templates/mongoid.yml +97 -35
- data/lib/locomotive/dependencies.rb +1 -1
- data/lib/locomotive/middlewares/site.rb +10 -4
- data/lib/locomotive/mongoid/patches.rb +1 -1
- data/lib/locomotive/steam_adaptor.rb +6 -4
- data/lib/locomotive/version.rb +1 -1
- data/spec/dummy/config/application.rb +0 -3
- data/spec/dummy/config/initializers/devise.rb +128 -58
- data/spec/dummy/config/mongoid.yml +95 -78
- data/spec/models/locomotive/content_entry_spec.rb +6 -6
- data/spec/requests/locomotive/steam/cache_spec.rb +1 -1
- data/spec/requests/site_spec.rb +25 -0
- data/spec/support/mongoid.rb +2 -0
- metadata +16 -189
- data/features/api/accounts.feature +0 -43
- data/features/api/authentication.feature +0 -41
- data/features/api/authorization/accounts.feature +0 -165
- data/features/api/authorization/content_assets.feature +0 -147
- data/features/api/authorization/content_entries.feature +0 -202
- data/features/api/authorization/content_types.feature +0 -237
- data/features/api/authorization/current_site.feature +0 -30
- data/features/api/authorization/memberships.feature +0 -225
- data/features/api/authorization/pages.feature +0 -189
- data/features/api/authorization/sites.feature +0 -212
- data/features/api/authorization/snippets.feature +0 -179
- data/features/api/authorization/theme_assets.feature +0 -185
- data/features/api/authorization/translations.feature +0 -253
- data/features/api/content_entries.feature +0 -184
- data/features/api/content_types.feature +0 -156
- data/features/api/editable_elements.feature +0 -190
- data/features/api/entries_custom_fields.feature +0 -150
- data/features/api/memberships.feature +0 -26
- data/features/api/pages.feature +0 -72
- data/features/backoffice/authorization/account_settings.feature +0 -28
- data/features/backoffice/authorization/content_type.feature +0 -35
- data/features/backoffice/authorization/current_site.feature +0 -53
- data/features/backoffice/authorization/inline_front_end_editing.feature +0 -46
- data/features/backoffice/authorization/pages.feature +0 -95
- data/features/backoffice/authorization/theme_assets.feature +0 -50
- data/features/backoffice/content_types/edit.feature +0 -20
- data/features/backoffice/content_types/email.feature +0 -26
- data/features/backoffice/content_types/has_many.feature +0 -80
- data/features/backoffice/content_types/integer.feature +0 -26
- data/features/backoffice/content_types/localized.feature +0 -63
- data/features/backoffice/content_types/many_to_many.feature +0 -70
- data/features/backoffice/content_types/tags.feature +0 -22
- data/features/backoffice/content_types/uniqueness.feature +0 -29
- data/features/backoffice/contents.feature +0 -93
- data/features/backoffice/editable_elements.feature +0 -22
- data/features/backoffice/installation.feature +0 -33
- data/features/backoffice/login.feature +0 -33
- data/features/backoffice/mounting.feature +0 -13
- data/features/backoffice/my_account.feature +0 -22
- data/features/backoffice/pages.feature +0 -73
- data/features/backoffice/regressions.feature +0 -19
- data/features/backoffice/site.feature +0 -71
- data/features/backoffice/snippets.feature +0 -39
- data/features/backoffice/theme_assets.feature +0 -72
- data/features/backoffice/translations.feature +0 -50
- data/features/public/basic.feature +0 -30
- data/features/public/contact_form.feature +0 -98
- data/features/public/content_entries.feature +0 -69
- data/features/public/editable_elements.feature +0 -138
- data/features/public/has_many.feature +0 -8
- data/features/public/inheritance.feature +0 -157
- data/features/public/inline_front_end_editing.feature +0 -26
- data/features/public/many_to_many.feature +0 -64
- data/features/public/new_contact_form.feature +0 -95
- data/features/public/pages.feature +0 -116
- data/features/public/pagination.feature +0 -8
- data/features/public/robots.feature +0 -22
- data/features/public/session.feature +0 -40
- data/features/public/sitemap.feature +0 -74
- data/features/public/snippets.feature +0 -21
- data/features/public/tablerow.feature +0 -42
- data/features/public/tags.feature +0 -45
- data/features/step_definitions/api_steps.rb +0 -179
- data/features/step_definitions/backoffice/mounting_steps.rb +0 -22
- data/features/step_definitions/backoffice_steps.rb +0 -47
- data/features/step_definitions/content_assets_steps.rb +0 -12
- data/features/step_definitions/content_types_steps.rb +0 -135
- data/features/step_definitions/current_site_steps.rb +0 -43
- data/features/step_definitions/editable_elements_steps.rb +0 -24
- data/features/step_definitions/membership_steps.rb +0 -19
- data/features/step_definitions/more_web_steps.rb +0 -131
- data/features/step_definitions/page_steps.rb +0 -133
- data/features/step_definitions/pagination_steps.rb +0 -35
- data/features/step_definitions/pickle_steps.rb +0 -100
- data/features/step_definitions/relationships_steps.rb +0 -110
- data/features/step_definitions/site_steps.rb +0 -111
- data/features/step_definitions/snippet_steps.rb +0 -37
- data/features/step_definitions/theme_asset_steps.rb +0 -64
- data/features/step_definitions/translation_steps.rb +0 -7
- data/features/step_definitions/web_steps.rb +0 -225
- data/features/step_definitions/within_steps.rb +0 -14
- data/features/support/cleaner.rb +0 -4
- data/features/support/env.rb +0 -82
- data/features/support/factory_girl.rb +0 -2
- data/features/support/http.rb +0 -22
- data/features/support/locales.rb +0 -5
- data/features/support/paths.rb +0 -62
- data/features/support/pickle.rb +0 -24
- data/features/support/selectors.rb +0 -57
@@ -1,110 +0,0 @@
|
|
1
|
-
Given %r{^I have an? "([^"]*)" model which has many "([^"]*)"$} do |parent_model, child_model|
|
2
|
-
@parent_model = FactoryGirl.build(:content_type, site: @site, name: parent_model).tap do |ct|
|
3
|
-
ct.entries_custom_fields.build label: 'Body', type: 'string', required: false
|
4
|
-
ct.save!
|
5
|
-
end
|
6
|
-
@child_model = FactoryGirl.build(:content_type, site: @site, name: child_model).tap do |ct|
|
7
|
-
ct.entries_custom_fields.build label: 'Body', type: 'string', required: false
|
8
|
-
ct.entries_custom_fields.build label: parent_model.singularize.downcase, type: 'belongs_to', required: false, class_name: @parent_model.entries_class_name
|
9
|
-
ct.save!
|
10
|
-
end
|
11
|
-
|
12
|
-
@parent_model.entries_custom_fields.build({
|
13
|
-
label: child_model,
|
14
|
-
type: 'has_many',
|
15
|
-
class_name: @child_model.entries_class_name,
|
16
|
-
inverse_of: parent_model.singularize.downcase
|
17
|
-
})
|
18
|
-
|
19
|
-
@parent_model.save
|
20
|
-
end
|
21
|
-
|
22
|
-
Given %r{^I set up a has_many relationship between "([^"]*)" and "([^"]*)"$} do |source_name, target_name|
|
23
|
-
source_model = @site.content_types.where(name: source_name).first
|
24
|
-
target_model = @site.content_types.where(name: target_name).first
|
25
|
-
|
26
|
-
source_model.entries_custom_fields.build({
|
27
|
-
label: target_name,
|
28
|
-
type: 'has_many',
|
29
|
-
class_name: target_model.entries_class_name,
|
30
|
-
inverse_of: source_name.singularize.downcase
|
31
|
-
})
|
32
|
-
|
33
|
-
source_model.save
|
34
|
-
end
|
35
|
-
|
36
|
-
Given %r{^I set up a many_to_many relationship between "([^"]*)" and "([^"]*)"$} do |first_name, last_name|
|
37
|
-
first_model = @site.content_types.where(name: first_name).first
|
38
|
-
last_model = @site.content_types.where(name: last_name).first
|
39
|
-
|
40
|
-
first_model.entries_custom_fields.build({
|
41
|
-
label: last_name,
|
42
|
-
type: 'many_to_many',
|
43
|
-
class_name: last_model.entries_class_name,
|
44
|
-
inverse_of: first_name.pluralize.downcase
|
45
|
-
})
|
46
|
-
|
47
|
-
first_model.save
|
48
|
-
|
49
|
-
last_model.entries_custom_fields.build({
|
50
|
-
label: first_name,
|
51
|
-
type: 'many_to_many',
|
52
|
-
class_name: first_model.entries_class_name,
|
53
|
-
inverse_of: last_name.pluralize.downcase
|
54
|
-
})
|
55
|
-
|
56
|
-
last_model.save
|
57
|
-
end
|
58
|
-
|
59
|
-
Given %r{^I attach the "([^"]*)" ([\S]*) to the "([^"]*)" ([\S]*)$} do |target_name, target_model_name, souce_name, source_model_name|
|
60
|
-
target_model = @site.content_types.where(name: target_model_name.pluralize.capitalize).first
|
61
|
-
source_model = @site.content_types.where(name: source_model_name.pluralize.capitalize).first
|
62
|
-
|
63
|
-
target_entry = target_model.entries.where(_slug: target_name.permalink).first
|
64
|
-
source_entry = source_model.entries.where(_slug: souce_name.permalink).first
|
65
|
-
|
66
|
-
source_entry.send(target_model_name.pluralize.downcase.parameterize('_').to_sym).push(target_entry)
|
67
|
-
end
|
68
|
-
|
69
|
-
Then /^I should be able to view a paginated list of a has many association$/ do
|
70
|
-
# Create models
|
71
|
-
step %{I have an "Articles" model which has many "Comments"}
|
72
|
-
|
73
|
-
# Create contents
|
74
|
-
article = @parent_model.entries.create!(slug: 'parent', body: 'Parent')
|
75
|
-
@child_model.entries.create!(slug: 'one', body: 'One', article: article)
|
76
|
-
@child_model.entries.create!(slug: 'two', body: 'Two', article: article)
|
77
|
-
@child_model.entries.create!(slug: 'three', body: 'Three', article: article)
|
78
|
-
@child_model.entries.create!(slug: 'four', body: 'Four', article: article, _visible: false)
|
79
|
-
|
80
|
-
# Create a page
|
81
|
-
raw_template = %{
|
82
|
-
{% for article in models.articles %}
|
83
|
-
{{ article.body }}
|
84
|
-
{% paginate article.comments by 2 %}
|
85
|
-
{% for comment in paginate.collection %}
|
86
|
-
{{ comment.body }}
|
87
|
-
{% endfor %}
|
88
|
-
{{ paginate | default_pagination }}
|
89
|
-
{% endpaginate %}
|
90
|
-
{% endfor %}
|
91
|
-
}
|
92
|
-
|
93
|
-
# Create a page
|
94
|
-
FactoryGirl.create(:page, site: @site, slug: 'hello', parent: @site.pages.root.first, raw_template: raw_template)
|
95
|
-
|
96
|
-
# The page should have the first two comments
|
97
|
-
visit '/hello'
|
98
|
-
|
99
|
-
page.should have_content 'One'
|
100
|
-
page.should have_content 'Two'
|
101
|
-
page.should_not have_content 'Three'
|
102
|
-
page.should_not have_content 'Four'
|
103
|
-
|
104
|
-
# The second page should have the last comment
|
105
|
-
click_link '2'
|
106
|
-
page.should_not have_content 'One'
|
107
|
-
page.should_not have_content 'Two'
|
108
|
-
page.should have_content 'Three'
|
109
|
-
page.should_not have_content 'Four'
|
110
|
-
end
|
@@ -1,111 +0,0 @@
|
|
1
|
-
# Creates a Locomotive::Site record
|
2
|
-
#
|
3
|
-
# examples:
|
4
|
-
# - I have the site: "some site" set up
|
5
|
-
# - I have the site: "some site" set up with name: "Something", domain: "test2"
|
6
|
-
#
|
7
|
-
Given /^I have the site: "([^"]*)" set up(?: with #{capture_fields})?$/ do |site_factory, fields|
|
8
|
-
attributes = parse_fields(fields)
|
9
|
-
id = attributes.delete('id')
|
10
|
-
@site = FactoryGirl.build(site_factory, attributes)
|
11
|
-
@site.id = id if id
|
12
|
-
@site.save & @site.reload
|
13
|
-
@site.should_not be_nil
|
14
|
-
|
15
|
-
@admin = @site.memberships.first.account
|
16
|
-
@admin.should_not be_nil
|
17
|
-
# same api key for all the tests
|
18
|
-
@admin.api_key = 'd49cd50f6f0d2b163f48fc73cb249f0244c37074'
|
19
|
-
@admin.save
|
20
|
-
end
|
21
|
-
|
22
|
-
Given /^I have a site set up$/ do
|
23
|
-
step %{I have the site: "test site" set up}
|
24
|
-
end
|
25
|
-
|
26
|
-
Given /^I have a designer and an author$/ do
|
27
|
-
site = Locomotive::Site.first
|
28
|
-
FactoryGirl.create(:designer, site: site)
|
29
|
-
FactoryGirl.create(:author, site: site)
|
30
|
-
end
|
31
|
-
|
32
|
-
Given /^the site "(.*?)" has locales "(.*?)"$/ do |name, locales|
|
33
|
-
site = Locomotive::Site.where(name: name).first
|
34
|
-
site.update_attribute :locales, locales.split(',').map(&:strip)
|
35
|
-
|
36
|
-
# very important to set the locale fallbacks
|
37
|
-
site.locales.each do |locale|
|
38
|
-
::Mongoid::Fields::I18n.fallbacks_for(locale, site.locale_fallbacks(locale))
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
Given /^multi_sites is disabled$/ do
|
43
|
-
Locomotive.config.multi_sites = false
|
44
|
-
Locomotive.after_configure
|
45
|
-
end
|
46
|
-
|
47
|
-
Then /^I should be a administrator of the "([^"]*)" site$/ do |name|
|
48
|
-
site = Locomotive::Site.where(name: name).first
|
49
|
-
m = site.memberships.detect { |m| m.account_id == @admin._id && m.admin? }
|
50
|
-
m.should_not be_nil
|
51
|
-
end
|
52
|
-
|
53
|
-
# sets the robot_txt for a site
|
54
|
-
|
55
|
-
Given /^a robot_txt set to "([^"]*)"$/ do |value|
|
56
|
-
@site.update_attributes(robots_txt: value)
|
57
|
-
end
|
58
|
-
|
59
|
-
Then /^I should be able to add a domain to my site$/ do
|
60
|
-
visit edit_current_site_path
|
61
|
-
|
62
|
-
within('#site_domains_input') do
|
63
|
-
fill_in 'domain', with: 'monkeys.com'
|
64
|
-
end
|
65
|
-
click_link '+ add'
|
66
|
-
click_button 'Save'
|
67
|
-
|
68
|
-
page.should have_content 'My site was successfully updated'
|
69
|
-
@site.reload.domains.should include 'monkeys.com'
|
70
|
-
end
|
71
|
-
|
72
|
-
Then /^I should be able to remove a domain from my site$/ do
|
73
|
-
@site.domains = [ 'monkeys.com' ]
|
74
|
-
@site.save!
|
75
|
-
|
76
|
-
visit edit_current_site_path
|
77
|
-
|
78
|
-
click_link 'Delete'
|
79
|
-
click_button 'Save'
|
80
|
-
|
81
|
-
page.should have_content 'My site was successfully updated'
|
82
|
-
@site.reload.domains_without_subdomain.should be_blank
|
83
|
-
end
|
84
|
-
|
85
|
-
Then /^I should be able to remove a membership from my site$/ do
|
86
|
-
@new_account = FactoryGirl.create(:author, site: @site)
|
87
|
-
@site.save!
|
88
|
-
|
89
|
-
visit edit_current_site_path
|
90
|
-
|
91
|
-
click_link 'Delete'
|
92
|
-
click_button 'Save'
|
93
|
-
|
94
|
-
page.should have_content 'My site was successfully updated'
|
95
|
-
@site.reload.memberships.collect(&:account).should_not include(@new_account)
|
96
|
-
end
|
97
|
-
|
98
|
-
Then /^I should be able to save the site with AJAX$/ do
|
99
|
-
visit edit_current_site_path
|
100
|
-
|
101
|
-
# Prevent the default behaviour so we're sure it's AJAX
|
102
|
-
js = <<-EOF
|
103
|
-
$('form').submit(function(event) {
|
104
|
-
event.preventDefault();
|
105
|
-
});
|
106
|
-
EOF
|
107
|
-
page.execute_script(js)
|
108
|
-
|
109
|
-
click_button 'Save'
|
110
|
-
page.should have_content 'My site was successfully updated'
|
111
|
-
end
|
@@ -1,37 +0,0 @@
|
|
1
|
-
### Snippets
|
2
|
-
|
3
|
-
# helps create a simple snippet with a slug and template
|
4
|
-
def new_snippet(name, template = nil)
|
5
|
-
@site.snippets.new(:name => name, :template => template)
|
6
|
-
end
|
7
|
-
|
8
|
-
def create_snippet(name, template = nil)
|
9
|
-
snippet = new_snippet(name, template)
|
10
|
-
snippet.save!
|
11
|
-
snippet
|
12
|
-
end
|
13
|
-
|
14
|
-
# creates a snippet
|
15
|
-
|
16
|
-
Given /^a snippet named "([^"]*)" with the template:$/ do |name, template|
|
17
|
-
@snippet = create_snippet(name, template)
|
18
|
-
end
|
19
|
-
|
20
|
-
Given /^a snippet named "([^"]*)" with id "([^"]*)" and template:$/ do |name, id, template|
|
21
|
-
@snippet = new_snippet(name, template)
|
22
|
-
@snippet.id = BSON::ObjectId(id)
|
23
|
-
@snippet.save!
|
24
|
-
end
|
25
|
-
|
26
|
-
When /^I change the snippet template to "([^"]*)"$/ do |code|
|
27
|
-
page.evaluate_script "window.application_view.view.editor.setValue('#{code}')"
|
28
|
-
end
|
29
|
-
|
30
|
-
# checks to see if a string is in the slug
|
31
|
-
Then /^I should have "(.*)" in the (.*) snippet/ do |content, snippet_slug|
|
32
|
-
snippet = @site.snippets.where(:slug => snippet_slug).first
|
33
|
-
raise "Could not find snippet: #{snippet_slug}" unless snippet
|
34
|
-
|
35
|
-
snippet.template.should == content
|
36
|
-
end
|
37
|
-
|
@@ -1,64 +0,0 @@
|
|
1
|
-
### Theme assets
|
2
|
-
|
3
|
-
# helps create a theme asset
|
4
|
-
def new_plain_text_asset(name, type)
|
5
|
-
FactoryGirl.build(:theme_asset, {
|
6
|
-
:site => @site,
|
7
|
-
:plain_text_name => name,
|
8
|
-
:plain_text => 'Lorem ipsum',
|
9
|
-
:plain_text_type => type,
|
10
|
-
:performing_plain_text => true
|
11
|
-
})
|
12
|
-
end
|
13
|
-
|
14
|
-
def create_plain_text_asset(name, type)
|
15
|
-
asset = new_plain_text_asset(name, type)
|
16
|
-
asset.save!
|
17
|
-
end
|
18
|
-
|
19
|
-
# creates various theme assets
|
20
|
-
|
21
|
-
Given /^a javascript asset named "([^"]*)"$/ do |name|
|
22
|
-
@asset = create_plain_text_asset(name, 'javascript')
|
23
|
-
end
|
24
|
-
|
25
|
-
Given /^a javascript asset named "([^"]*)" with id "([^"]*)"$/ do |name, id|
|
26
|
-
@asset = new_plain_text_asset(name, 'javascript')
|
27
|
-
@asset.id = BSON::ObjectId(id)
|
28
|
-
@asset.save!
|
29
|
-
end
|
30
|
-
|
31
|
-
Given /^a stylesheet asset named "([^"]*)"$/ do |name|
|
32
|
-
@asset = create_plain_text_asset(name, 'stylesheet')
|
33
|
-
end
|
34
|
-
|
35
|
-
Given /^a stylesheet asset named "([^"]*)" with id "([^"]*)"$/ do |name, id|
|
36
|
-
@asset = new_plain_text_asset(name, 'stylesheet')
|
37
|
-
@asset.id = BSON::ObjectId(id)
|
38
|
-
@asset.save!
|
39
|
-
end
|
40
|
-
|
41
|
-
Given /^I have an image theme asset named "([^"]*)"$/ do |name|
|
42
|
-
@asset = FactoryGirl.create(:theme_asset, :site => @site, :source => File.open(Rails.root.join('..', 'fixtures', 'assets', '5k.png')))
|
43
|
-
@asset.source_filename = name
|
44
|
-
@asset.save!
|
45
|
-
end
|
46
|
-
|
47
|
-
# other stuff
|
48
|
-
|
49
|
-
# change the template
|
50
|
-
When /^I change the theme asset code to "([^"]*)"$/ do |plain_text|
|
51
|
-
page.evaluate_script "window.application_view.view.editor.setValue('#{plain_text}')"
|
52
|
-
end
|
53
|
-
|
54
|
-
Then /^I should see "([^"]*)" as the theme asset code$/ do |code|
|
55
|
-
find(:css, "#theme_asset_plain_text").value.should == code
|
56
|
-
end
|
57
|
-
|
58
|
-
Then /^I should see a delete link$/ do
|
59
|
-
page.has_css?(".box ul li .more a.remove").should be_true
|
60
|
-
end
|
61
|
-
|
62
|
-
Then /^I should not see a delete link$/ do
|
63
|
-
page.has_css?(".box ul li .more a.remove").should be_false
|
64
|
-
end
|
@@ -1,7 +0,0 @@
|
|
1
|
-
Given /^a translation with key "(.*?)" and id "(.*?)" with values:$/ do |key, id, table|
|
2
|
-
translation = @site.translations.build
|
3
|
-
translation.id = BSON::ObjectId(id)
|
4
|
-
translation.key = key
|
5
|
-
translation.values = table.raw.inject({}) { |memo,values| memo.merge(values.first => values.last) }
|
6
|
-
translation.save!
|
7
|
-
end
|
@@ -1,225 +0,0 @@
|
|
1
|
-
# TL;DR: YOU SHOULD DELETE THIS FILE
|
2
|
-
# IMPORTANT: This file is generated by cucumber-rails - edit at your own peril.
|
3
|
-
# It is recommended to regenerate this file in the future when you upgrade to a
|
4
|
-
# newer version of cucumber-rails. Consider adding your own code to a new file
|
5
|
-
# instead of editing this one. Cucumber will automatically load all features/**/*.rb
|
6
|
-
# files.
|
7
|
-
|
8
|
-
require 'uri'
|
9
|
-
require 'cgi'
|
10
|
-
require File.expand_path(File.join(File.dirname(__FILE__), "..", "support", "paths"))
|
11
|
-
require File.expand_path(File.join(File.dirname(__FILE__), "..", "support", "selectors"))
|
12
|
-
|
13
|
-
module WithinHelpers
|
14
|
-
def with_scope(locator)
|
15
|
-
locator ? within(*selector_for(locator)) { yield } : yield
|
16
|
-
end
|
17
|
-
end
|
18
|
-
World(WithinHelpers)
|
19
|
-
|
20
|
-
# Single-line step scoper
|
21
|
-
When /^(.*) within (.*[^:])$/ do |step, parent|
|
22
|
-
with_scope(parent) { step step }
|
23
|
-
end
|
24
|
-
|
25
|
-
# Multi-line step scoper
|
26
|
-
When /^(.*) within (.*[^:]):$/ do |step, parent, table_or_string|
|
27
|
-
with_scope(parent) { step "#{step}:", table_or_string }
|
28
|
-
end
|
29
|
-
|
30
|
-
Given /^(?:|I )am on (.+)$/ do |page_name|
|
31
|
-
visit path_to(page_name)
|
32
|
-
end
|
33
|
-
|
34
|
-
When /^(?:|I )go to (.+)$/ do |page_name|
|
35
|
-
visit path_to(page_name)
|
36
|
-
end
|
37
|
-
|
38
|
-
When /^(?:|I )press "([^"]*)"$/ do |button|
|
39
|
-
click_button(button)
|
40
|
-
end
|
41
|
-
|
42
|
-
When /^(?:|I )follow "([^"]*)"$/ do |link|
|
43
|
-
first(:link, link).click
|
44
|
-
end
|
45
|
-
|
46
|
-
When /^(?:|I )fill in "([^"]*)" with "([^"]*)"$/ do |field, value|
|
47
|
-
fill_in(field, with: value)
|
48
|
-
end
|
49
|
-
|
50
|
-
When /^(?:|I )fill in "([^"]*)" for "([^"]*)"$/ do |value, field|
|
51
|
-
fill_in(field, with: value)
|
52
|
-
end
|
53
|
-
|
54
|
-
# Use this to fill in an entire form with data from a table. Example:
|
55
|
-
#
|
56
|
-
# When I fill in the following:
|
57
|
-
# | Account Number | 5002 |
|
58
|
-
# | Expiry date | 2009-11-01 |
|
59
|
-
# | Note | Nice guy |
|
60
|
-
# | Wants Email? | |
|
61
|
-
#
|
62
|
-
# TODO: Add support for checkbox, select og option
|
63
|
-
# based on naming conventions.
|
64
|
-
#
|
65
|
-
When /^(?:|I )fill in the following:$/ do |fields|
|
66
|
-
fields.rows_hash.each do |name, value|
|
67
|
-
step %{I fill in "#{name}" with "#{value}"}
|
68
|
-
end
|
69
|
-
end
|
70
|
-
|
71
|
-
When /^(?:|I )select "([^"]*)" from "([^"]*)"$/ do |value, field|
|
72
|
-
begin
|
73
|
-
select(value, from: field)
|
74
|
-
rescue Capybara::ElementNotFound
|
75
|
-
container = find('.select2', text: field)
|
76
|
-
container.find('a').click
|
77
|
-
find(:css, 'input.select2-input').set(value.first)
|
78
|
-
page.has_css?('ul.select2-results li.select2-result', visible: true)
|
79
|
-
clicked = false
|
80
|
-
page.all('ul.select2-results li.select2-result').each do |e|
|
81
|
-
if e.text == value
|
82
|
-
e.click
|
83
|
-
clicked = true
|
84
|
-
break
|
85
|
-
end
|
86
|
-
end
|
87
|
-
find('.select2-drop').click unless clicked
|
88
|
-
page.has_no_css?("ul.select2-results li.select2-result", visible: true)
|
89
|
-
end
|
90
|
-
end
|
91
|
-
|
92
|
-
When /^(?:|I )check "([^"]*)"$/ do |field|
|
93
|
-
check(field)
|
94
|
-
end
|
95
|
-
|
96
|
-
When /^(?:|I )uncheck "([^"]*)"$/ do |field|
|
97
|
-
uncheck(field)
|
98
|
-
end
|
99
|
-
|
100
|
-
When /^(?:|I )choose "([^"]*)"$/ do |field|
|
101
|
-
choose(field)
|
102
|
-
end
|
103
|
-
|
104
|
-
When /^(?:|I )attach the file "([^"]*)" to "([^"]*)"$/ do |path, field|
|
105
|
-
attach_file(field, File.expand_path(path))
|
106
|
-
end
|
107
|
-
|
108
|
-
Then /^(?:|I )should see "([^"]*)"$/ do |text|
|
109
|
-
if page.respond_to? :should
|
110
|
-
page.should have_content(text)
|
111
|
-
else
|
112
|
-
assert page.has_content?(text)
|
113
|
-
end
|
114
|
-
end
|
115
|
-
|
116
|
-
Then /^(?:|I )should see \/([^\/]*)\/$/ do |regexp|
|
117
|
-
regexp = Regexp.new(regexp)
|
118
|
-
|
119
|
-
if page.respond_to? :should
|
120
|
-
page.should have_xpath('//*', text: regexp)
|
121
|
-
else
|
122
|
-
assert page.has_xpath?('//*', text: regexp)
|
123
|
-
end
|
124
|
-
end
|
125
|
-
|
126
|
-
Then /^(?:|I )should not see "([^"]*)"$/ do |text|
|
127
|
-
if page.respond_to? :should
|
128
|
-
page.should have_no_content(text)
|
129
|
-
else
|
130
|
-
assert page.has_no_content?(text)
|
131
|
-
end
|
132
|
-
end
|
133
|
-
|
134
|
-
Then /^(?:|I )should not see \/([^\/]*)\/$/ do |regexp|
|
135
|
-
regexp = Regexp.new(regexp)
|
136
|
-
|
137
|
-
if page.respond_to? :should
|
138
|
-
page.should have_no_xpath('//*', text: regexp)
|
139
|
-
else
|
140
|
-
assert page.has_no_xpath?('//*', text: regexp)
|
141
|
-
end
|
142
|
-
end
|
143
|
-
|
144
|
-
Then /^the "([^"]*)" field(?: within (.*))? should contain "([^"]*)"$/ do |field, parent, value|
|
145
|
-
with_scope(parent) do
|
146
|
-
field = find_field(field)
|
147
|
-
field_value = (field.tag_name == 'textarea') ? field.text : field.value
|
148
|
-
if field_value.respond_to? :should
|
149
|
-
field_value.should =~ /#{value}/
|
150
|
-
else
|
151
|
-
assert_match(/#{value}/, field_value)
|
152
|
-
end
|
153
|
-
end
|
154
|
-
end
|
155
|
-
|
156
|
-
Then /^the "([^"]*)" field(?: within (.*))? should not contain "([^"]*)"$/ do |field, parent, value|
|
157
|
-
with_scope(parent) do
|
158
|
-
field = find_field(field)
|
159
|
-
field_value = (field.tag_name == 'textarea') ? field.text : field.value
|
160
|
-
if field_value.respond_to? :should_not
|
161
|
-
field_value.should_not =~ /#{value}/
|
162
|
-
else
|
163
|
-
assert_no_match(/#{value}/, field_value)
|
164
|
-
end
|
165
|
-
end
|
166
|
-
end
|
167
|
-
|
168
|
-
Then /^the "([^"]*)" checkbox(?: within (.*))? should be checked$/ do |label, parent|
|
169
|
-
with_scope(parent) do
|
170
|
-
field_checked = find_field(label)['checked']
|
171
|
-
if field_checked.respond_to? :should
|
172
|
-
field_checked.should be_true
|
173
|
-
else
|
174
|
-
assert field_checked
|
175
|
-
end
|
176
|
-
end
|
177
|
-
end
|
178
|
-
|
179
|
-
Then /^the "([^"]*)" checkbox(?: within (.*))? should not be checked$/ do |label, parent|
|
180
|
-
with_scope(parent) do
|
181
|
-
field_checked = find_field(label)['checked']
|
182
|
-
if field_checked.respond_to? :should
|
183
|
-
field_checked.should be_false
|
184
|
-
else
|
185
|
-
assert !field_checked
|
186
|
-
end
|
187
|
-
end
|
188
|
-
end
|
189
|
-
|
190
|
-
Then /^(?:|I )should be on (.+)$/ do |page_name|
|
191
|
-
current_path = URI.parse(current_url).path
|
192
|
-
if current_path.respond_to? :should
|
193
|
-
current_path.should == path_to(page_name)
|
194
|
-
else
|
195
|
-
assert_equal path_to(page_name), current_path
|
196
|
-
end
|
197
|
-
end
|
198
|
-
|
199
|
-
Then /^(?:|I )should have the following query string:$/ do |expected_pairs|
|
200
|
-
query = URI.parse(current_url).query
|
201
|
-
actual_params = query ? CGI.parse(query) : {}
|
202
|
-
expected_params = {}
|
203
|
-
expected_pairs.rows_hash.each_pair{|k,v| expected_params[k] = v.split(',')}
|
204
|
-
|
205
|
-
if actual_params.respond_to? :should
|
206
|
-
actual_params.should == expected_params
|
207
|
-
else
|
208
|
-
assert_equal expected_params, actual_params
|
209
|
-
end
|
210
|
-
end
|
211
|
-
|
212
|
-
Then /^show me the page$/ do
|
213
|
-
save_and_open_page
|
214
|
-
end
|
215
|
-
|
216
|
-
Then(/^I click on "(.*?)"$/) do |selector|
|
217
|
-
find(selector).click
|
218
|
-
end
|
219
|
-
|
220
|
-
When(/^I select2 "(.*?)" from "(.*?)"$/) do |text, from|
|
221
|
-
page.find("#s2id_#{from} a").click
|
222
|
-
find(:xpath, "//body").find("input.select2-input").set(text)
|
223
|
-
page.execute_script(%|$("input.select2-input:visible").keyup();|)
|
224
|
-
find(:xpath, '//body').find('ul.select2-results li', text: text).click
|
225
|
-
end
|
@@ -1,14 +0,0 @@
|
|
1
|
-
# http://mislav.uniqpath.com/2010/09/cuking-it-right/
|
2
|
-
|
3
|
-
{
|
4
|
-
# 'as a movie title in the results' => 'ol.movies h1',
|
5
|
-
# 'in a button' => 'button, input[type=submit]',
|
6
|
-
# 'in the navigation' => 'nav'
|
7
|
-
}.
|
8
|
-
each do |within, selector|
|
9
|
-
Then /^(.+) #{within}$/ do |step|
|
10
|
-
with_scope(selector) do
|
11
|
-
Then step
|
12
|
-
end
|
13
|
-
end
|
14
|
-
end
|
data/features/support/cleaner.rb
DELETED
data/features/support/env.rb
DELETED
@@ -1,82 +0,0 @@
|
|
1
|
-
# IMPORTANT: This file is generated by cucumber-rails - edit at your own peril.
|
2
|
-
# It is recommended to regenerate this file in the future when you upgrade to a
|
3
|
-
# newer version of cucumber-rails. Consider adding your own code to a new file
|
4
|
-
# instead of editing this one. Cucumber will automatically load all features/**/*.rb
|
5
|
-
# files.
|
6
|
-
|
7
|
-
ENV['RAILS_ENV'] ||= 'test'
|
8
|
-
ENV["RAILS_ROOT"] ||= File.join(File.dirname(__FILE__), '../', '../', 'spec', 'dummy')
|
9
|
-
|
10
|
-
require 'cucumber/rails'
|
11
|
-
require 'cucumber/formatter/unicode' # Remove this line if you don't want Cucumber Unicode support
|
12
|
-
require 'cucumber/rails/rspec'
|
13
|
-
require 'cucumber/rails/world'
|
14
|
-
|
15
|
-
require 'factory_girl'
|
16
|
-
|
17
|
-
require 'capybara'
|
18
|
-
require 'capybara/rails'
|
19
|
-
require 'capybara/cucumber'
|
20
|
-
require 'capybara/session'
|
21
|
-
require 'capybara/poltergeist'
|
22
|
-
|
23
|
-
require 'json_spec/cucumber'
|
24
|
-
|
25
|
-
require 'resolv'
|
26
|
-
require 'uri'
|
27
|
-
|
28
|
-
def ensure_host_resolution(app_host)
|
29
|
-
hosts = Resolv::Hosts.new
|
30
|
-
app_host_name = URI.parse(app_host).host
|
31
|
-
begin
|
32
|
-
hosts.getaddress(app_host_name)
|
33
|
-
rescue Resolv::ResolvError
|
34
|
-
raise "Unable to resolve ip address for #{app_host_name}. Please consider adding an entry to '/etc/hosts' that associates #{app_host_name} with '127.0.0.1'."
|
35
|
-
end
|
36
|
-
end
|
37
|
-
|
38
|
-
JsonSpec.configure do
|
39
|
-
exclude_keys "id", "_id", "created_at", "updated_at"
|
40
|
-
end
|
41
|
-
|
42
|
-
Capybara.configure do |config|
|
43
|
-
config.default_selector = :css
|
44
|
-
config.server_port = 9886
|
45
|
-
config.app_host = 'http://test.example.com:9886'
|
46
|
-
|
47
|
-
ensure_host_resolution(config.app_host)
|
48
|
-
end
|
49
|
-
|
50
|
-
Capybara.default_wait_time = 5
|
51
|
-
|
52
|
-
Capybara.javascript_driver = :poltergeist
|
53
|
-
|
54
|
-
# Stop endless errors like
|
55
|
-
# ~/.rvm/gems/ruby-1.9.2-p0@global/gems/rack-1.2.1/lib/rack/utils.rb:16:
|
56
|
-
# warning: regexp match /.../n against to UTF-8 string
|
57
|
-
# more information here: https://github.com/jnicklas/capybara/issues/243
|
58
|
-
$VERBOSE = nil
|
59
|
-
|
60
|
-
# By default, any exception happening in your Rails application will bubble up
|
61
|
-
# to Cucumber so that your scenario will fail. This is a different from how
|
62
|
-
# your application behaves in the production environment, where an error page will
|
63
|
-
# be rendered instead.
|
64
|
-
#
|
65
|
-
# Sometimes we want to override this default behaviour and allow Rails to rescue
|
66
|
-
# exceptions and display an error page (just like when the app is running in production).
|
67
|
-
# Typical scenarios where you want to do this is when you test your error pages.
|
68
|
-
# There are two ways to allow Rails to rescue exceptions:
|
69
|
-
#
|
70
|
-
# 1) Tag your scenario (or feature) with @allow-rescue
|
71
|
-
#
|
72
|
-
# 2) Set the value below to true. Beware that doing this globally is not
|
73
|
-
# recommended as it will mask a lot of errors for you!
|
74
|
-
#
|
75
|
-
ActionController::Base.allow_rescue = false
|
76
|
-
|
77
|
-
require File.expand_path(File.dirname(__FILE__) + '/../../spec/support/carrierwave')
|
78
|
-
require File.expand_path(File.dirname(__FILE__) + '/../../spec/support/locomotive')
|
79
|
-
|
80
|
-
World(Locomotive::Engine.routes.url_helpers) # Load engine routes
|
81
|
-
|
82
|
-
Locomotive.configure_for_test(true)
|
data/features/support/http.rb
DELETED
@@ -1,22 +0,0 @@
|
|
1
|
-
module HTTPHelpers
|
2
|
-
|
3
|
-
attr_accessor :default_params
|
4
|
-
|
5
|
-
def add_default_params(params)
|
6
|
-
default_params.merge!(params)
|
7
|
-
end
|
8
|
-
|
9
|
-
def do_request(type, base_url, url, params)
|
10
|
-
request_method = type.downcase.to_sym
|
11
|
-
send(request_method, URI.join(base_url, url).to_s, default_params.merge(params))
|
12
|
-
end
|
13
|
-
|
14
|
-
protected
|
15
|
-
|
16
|
-
def default_params
|
17
|
-
@default_params ||= {}
|
18
|
-
end
|
19
|
-
|
20
|
-
end
|
21
|
-
|
22
|
-
World(HTTPHelpers)
|