spree_variant_options 0.1.0.rc1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +8 -0
- data/Gemfile +2 -0
- data/LICENSE +25 -0
- data/README.md +129 -0
- data/Rakefile +26 -0
- data/Versionfile +4 -0
- data/app/models/product_decorator.rb +27 -0
- data/app/views/products/_cart_form.html.erb +32 -0
- data/app/views/products/_variant_options.html.erb +43 -0
- data/config/cucumber.yml +8 -0
- data/features/step_definitions/variant_options.rb +125 -0
- data/features/step_definitions/web_steps.rb +138 -0
- data/features/support/env.rb +56 -0
- data/features/support/factories.rb +45 -0
- data/features/support/helper_methods.rb +28 -0
- data/features/support/paths.rb +36 -0
- data/features/support/selectors.rb +39 -0
- data/features/variant_options.feature +108 -0
- data/lib/dummy_hooks/after_migrate.rb.sample +1 -0
- data/lib/dummy_hooks/before_migrate.rb +1 -0
- data/lib/spree_variant_options.rb +26 -0
- data/lib/spree_variant_options/version.rb +3 -0
- data/public/images/out-of-stock.png +0 -0
- data/public/javascripts/product.js +38 -0
- data/public/javascripts/variant_options.js +211 -0
- data/public/stylesheets/variant_options.css +68 -0
- data/spree_variant_options.gemspec +37 -0
- data/test/test_helper.rb +22 -0
- data/test/unit/product_test.rb +46 -0
- metadata +217 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
Copyright (c) 2011 Spencer Steffen and Citrus, released under the New BSD License All rights reserved.
|
2
|
+
|
3
|
+
Redistribution and use in source and binary forms, with or without modification,
|
4
|
+
are permitted provided that the following conditions are met:
|
5
|
+
|
6
|
+
* Redistributions of source code must retain the above copyright notice,
|
7
|
+
this list of conditions and the following disclaimer.
|
8
|
+
* Redistributions in binary form must reproduce the above copyright notice,
|
9
|
+
this list of conditions and the following disclaimer in the documentation
|
10
|
+
and/or other materials provided with the distribution.
|
11
|
+
* Neither the name of the Rails Dog LLC nor the names of its
|
12
|
+
contributors may be used to endorse or promote products derived from this
|
13
|
+
software without specific prior written permission.
|
14
|
+
|
15
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
16
|
+
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
17
|
+
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
18
|
+
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
19
|
+
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
20
|
+
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
21
|
+
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
22
|
+
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
23
|
+
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
24
|
+
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
25
|
+
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
data/README.md
ADDED
@@ -0,0 +1,129 @@
|
|
1
|
+
Spree Variant Options
|
2
|
+
=====================
|
3
|
+
|
4
|
+
Spree Variant Options is a very simple spree extension that groups your variants by option types and values. To get a better idea let's let a few images do the explaining.
|
5
|
+
|
6
|
+
|
7
|
+
#### When no selection has been made:
|
8
|
+
![Spree Variant Options - No selection](http://spree-docs.s3.amazonaws.com/spree_variant_options/1.jpg)
|
9
|
+
|
10
|
+
#### After "Medium" is selected, "Medium Blue" is out of stock:
|
11
|
+
|
12
|
+
![Spree Variant Options - Option Type/Value selected](http://spree-docs.s3.amazonaws.com/spree_variant_options/2.jpg)
|
13
|
+
|
14
|
+
#### And after "Green" is selected:
|
15
|
+
![Spree Variant Options - Variant Selcted](http://spree-docs.s3.amazonaws.com/spree_variant_options/3.jpg)
|
16
|
+
|
17
|
+
To see it in action, follow the steps for "Demo" below.
|
18
|
+
|
19
|
+
|
20
|
+
Installation
|
21
|
+
------------
|
22
|
+
|
23
|
+
If you don't already have an existing Spree site, [click here](https://gist.github.com/946719) then come back later... You can also read the Spree docs [here](http://spreecommerce.com/documentation/getting_started.html)...
|
24
|
+
|
25
|
+
Spree Variant Options hasn't been released to rubygems so you'll have to install it from the source. Just add the following to your Gemfile:
|
26
|
+
|
27
|
+
gem 'spree_variant_options', :git => 'git://github.com/citrus/spree_variant_options.git'
|
28
|
+
|
29
|
+
Now, bundle up with:
|
30
|
+
|
31
|
+
bundle
|
32
|
+
|
33
|
+
Spree Variant Options doesn't require any rake tasks or generators, but you'll need include `app/views/products/_variant_options.html.erb` in your product show view.
|
34
|
+
|
35
|
+
If you don't have a custom version of `_cart_form.html.erb` in your application, then don't worry about a thing, spree_variant_options will include the partial for you. Otherwise, just replace the entire `<% if @product.has_variants? %>` block with:
|
36
|
+
|
37
|
+
<%= render 'variant_options' %>
|
38
|
+
|
39
|
+
|
40
|
+
Versions
|
41
|
+
--------
|
42
|
+
|
43
|
+
Spree Variant Options works on Spree 0.30.1 and above... Please let me know if you run into any issues.
|
44
|
+
|
45
|
+
|
46
|
+
Testing
|
47
|
+
-------
|
48
|
+
|
49
|
+
Clone this repo to where you develop, bundle up, then run `dummier' to get the show started:
|
50
|
+
|
51
|
+
git clone git://github.com/citrus/spree_variant_options.git
|
52
|
+
cd spree_variant_options
|
53
|
+
bundle install
|
54
|
+
bundle exec dummier
|
55
|
+
|
56
|
+
|
57
|
+
This will generate a fresh rails app in test/dummy, install spree & spree_variant_options, then migrate the test database. Sweet.
|
58
|
+
|
59
|
+
|
60
|
+
### Spork + Cucumber
|
61
|
+
|
62
|
+
To run the cucumber features, boot spork like this:
|
63
|
+
|
64
|
+
bundle exec spork
|
65
|
+
|
66
|
+
Then, in another window, run:
|
67
|
+
|
68
|
+
cucumber --drb
|
69
|
+
|
70
|
+
|
71
|
+
### Spork + Test::Unit
|
72
|
+
|
73
|
+
If you want to run shoulda tests, start spork with:
|
74
|
+
|
75
|
+
bundle exec spork TestUnit
|
76
|
+
#or
|
77
|
+
bundle exec spork t
|
78
|
+
|
79
|
+
In another window, run all tests:
|
80
|
+
|
81
|
+
testdrb test/**/*_test.rb
|
82
|
+
|
83
|
+
Or just a specific test:
|
84
|
+
|
85
|
+
testdrb test/unit/supplier_test.rb
|
86
|
+
|
87
|
+
|
88
|
+
### No Spork
|
89
|
+
|
90
|
+
If you don't want to spork, just use rake:
|
91
|
+
|
92
|
+
# cucumber/capybara
|
93
|
+
rake cucumber
|
94
|
+
|
95
|
+
# test/unit
|
96
|
+
rake test
|
97
|
+
|
98
|
+
# both
|
99
|
+
rake
|
100
|
+
|
101
|
+
POW!
|
102
|
+
|
103
|
+
|
104
|
+
Demo
|
105
|
+
----
|
106
|
+
|
107
|
+
You can easily use the test/dummy app as a demo of spree_variant_options. Just `cd` to where you develop and run:
|
108
|
+
|
109
|
+
git clone git://github.com/citrus/spree_variant_options.git
|
110
|
+
cd spree_variant_options
|
111
|
+
mv lib/dummy_hooks/after_migrate.rb.sample lib/dummy_hooks/after_migrate.rb
|
112
|
+
bundle install
|
113
|
+
bundle exec dummier
|
114
|
+
cd test/dummy
|
115
|
+
rails s
|
116
|
+
|
117
|
+
|
118
|
+
Contributors
|
119
|
+
------------
|
120
|
+
|
121
|
+
So far it's just me; Spencer Steffen.
|
122
|
+
|
123
|
+
If you'd like to help out feel free to fork and send me pull requests!
|
124
|
+
|
125
|
+
|
126
|
+
License
|
127
|
+
-------
|
128
|
+
|
129
|
+
Copyright (c) 2011 Spencer Steffen and Citrus, released under the New BSD License All rights reserved.
|
data/Rakefile
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
require 'rubygems'
|
3
|
+
begin
|
4
|
+
require 'bundler/setup'
|
5
|
+
rescue LoadError
|
6
|
+
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
7
|
+
end
|
8
|
+
|
9
|
+
#require 'rake'
|
10
|
+
require 'rake/testtask'
|
11
|
+
|
12
|
+
Bundler::GemHelper.install_tasks
|
13
|
+
|
14
|
+
Rake::TestTask.new(:test) do |t|
|
15
|
+
t.libs << 'lib'
|
16
|
+
t.libs << 'test'
|
17
|
+
t.pattern = 'test/**/*_test.rb'
|
18
|
+
t.verbose = false
|
19
|
+
end
|
20
|
+
|
21
|
+
require 'cucumber/rake/task'
|
22
|
+
Cucumber::Rake::Task.new do |t|
|
23
|
+
t.cucumber_opts = %w{--format pretty}
|
24
|
+
end
|
25
|
+
|
26
|
+
task :default => [ :test, :cucumber ]
|
data/Versionfile
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
Product.class_eval do
|
2
|
+
|
3
|
+
include ActionView::Helpers::NumberHelper
|
4
|
+
|
5
|
+
def option_values
|
6
|
+
option_types.map{|i| i.option_values }.flatten.uniq
|
7
|
+
end
|
8
|
+
|
9
|
+
def grouped_option_values
|
10
|
+
option_values.group_by(&:option_type)
|
11
|
+
end
|
12
|
+
|
13
|
+
def variant_options_hash
|
14
|
+
return @variant_options_hash if @variant_options_hash
|
15
|
+
@variant_options_hash = Hash[grouped_option_values.map{ |type, values|
|
16
|
+
[type.id.inspect, Hash[values.map{ |value|
|
17
|
+
[value.id.inspect, Hash[variants.includes(:option_values).select{ |variant|
|
18
|
+
variant.option_values.select{ |val|
|
19
|
+
val.id == value.id && val.option_type_id == type.id
|
20
|
+
}.length == 1 }.map{ |v| [ v.id, { :id => v.id, :count => v.count_on_hand, :price => number_to_currency(v.price) } ] }]
|
21
|
+
]
|
22
|
+
}]]
|
23
|
+
}]
|
24
|
+
@variant_options_hash
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
<%= form_for :order, :url => populate_orders_url do |f| %>
|
2
|
+
<%= hook :inside_product_cart_form do %>
|
3
|
+
|
4
|
+
<% if product_price(@product) %>
|
5
|
+
<%= hook :product_price do %>
|
6
|
+
<p class="prices">
|
7
|
+
<%= t("price") %>
|
8
|
+
<br />
|
9
|
+
<span class="price selling"><%= product_price(@product) %></span>
|
10
|
+
</p>
|
11
|
+
<% end %>
|
12
|
+
<% end %>
|
13
|
+
|
14
|
+
<%= render 'variant_options' %>
|
15
|
+
|
16
|
+
<% if @product.has_stock? || Spree::Config[:allow_backorders] %>
|
17
|
+
<%= text_field_tag (@product.has_variants? ? :quantity : "variants[#{@product.master.id}]"),
|
18
|
+
1, :class => "title", :size => 3 %>
|
19
|
+
|
20
|
+
<button type='submit' class='large primary'>
|
21
|
+
<%= image_tag('/images/add-to-cart.png') + t('add_to_cart') %>
|
22
|
+
</button>
|
23
|
+
<% else %>
|
24
|
+
<%= content_tag('strong', t('out_of_stock')) %>
|
25
|
+
<% end %>
|
26
|
+
|
27
|
+
<% end %>
|
28
|
+
<% end %>
|
29
|
+
|
30
|
+
<% content_for :head do %>
|
31
|
+
<%= javascript_include_tag 'product' %>
|
32
|
+
<% end %>
|
@@ -0,0 +1,43 @@
|
|
1
|
+
<% if @product.has_variants? %>
|
2
|
+
<div id="product-variants">
|
3
|
+
<h2><%= t('variants') %></h2>
|
4
|
+
|
5
|
+
<% index = 0 %>
|
6
|
+
<% @product.grouped_option_values.each do |type, values| %>
|
7
|
+
<div id="<%= dom_id(type) %>" class="variant-options index-<%= index %>">
|
8
|
+
<h3 class="variant-option-type"><%= type.presentation %></h3>
|
9
|
+
<ul class="variant-option-values">
|
10
|
+
<% values.each do |value| %>
|
11
|
+
<% classes = ["option-value"] %>
|
12
|
+
<% if index == 0 %>
|
13
|
+
<% variants = @variants.select{|i| i.option_values.select{|j| j.option_type_id == type.id && j == value }.length == 1 } %>
|
14
|
+
<% if variants.empty? %>
|
15
|
+
<% classes << "unavailable" %>
|
16
|
+
<% else %>
|
17
|
+
<% classes << (variants.sum(&:count_on_hand) < 1 ? "out-of-stock" : "in-stock") %>
|
18
|
+
<% end %>
|
19
|
+
<% end %>
|
20
|
+
<li>
|
21
|
+
<%= link_to content_tag(:span, value.presentation), "#", :title => value.presentation, :class => classes.join(" "), :rel => "#{type.id}-#{value.id}" %>
|
22
|
+
</li>
|
23
|
+
<% end %>
|
24
|
+
<li class="clear-option"><%= link_to "X", "#clear", :class => "clear-button clear-index-#{index}" %></li>
|
25
|
+
<li class="clear"></li>
|
26
|
+
</ul>
|
27
|
+
</div>
|
28
|
+
<% index += 1 %>
|
29
|
+
<% end %>
|
30
|
+
<%= hidden_field_tag "products[#{@product.id}]", "", :id => "variant_id", :class => "hidden" %>
|
31
|
+
<script type="text/javascript">
|
32
|
+
//<![CDATA[
|
33
|
+
var variant_options = new VariantOptions(<%== @product.variant_options_hash.to_json %>);
|
34
|
+
//]]>
|
35
|
+
</script>
|
36
|
+
|
37
|
+
</div>
|
38
|
+
<% end%>
|
39
|
+
|
40
|
+
<% content_for :head do %>
|
41
|
+
<%= stylesheet_link_tag 'variant_options' %>
|
42
|
+
<%= javascript_include_tag 'variant_options' %>
|
43
|
+
<% end %>
|
data/config/cucumber.yml
ADDED
@@ -0,0 +1,8 @@
|
|
1
|
+
<%
|
2
|
+
rerun = File.file?('rerun.txt') ? IO.read('rerun.txt') : ""
|
3
|
+
rerun_opts = rerun.to_s.strip.empty? ? "--format #{ENV['CUCUMBER_FORMAT'] || 'progress'} features" : "--format #{ENV['CUCUMBER_FORMAT'] || 'pretty'} #{rerun}"
|
4
|
+
std_opts = "--format #{ENV['CUCUMBER_FORMAT'] || 'pretty'} --strict --tags ~@wip"
|
5
|
+
%>
|
6
|
+
default: <%= std_opts %> features
|
7
|
+
wip: --tags @wip:3 --wip features
|
8
|
+
rerun: <%= rerun_opts %> --format rerun --out rerun.txt --strict --tags ~@wip
|
@@ -0,0 +1,125 @@
|
|
1
|
+
#===============================
|
2
|
+
# Helpers
|
3
|
+
|
4
|
+
def variant_by_descriptor(descriptor)
|
5
|
+
values = descriptor.split(" ")
|
6
|
+
values.map! { |word| OptionValue.find_by_presentation(word) rescue nil }.compact!
|
7
|
+
return if values.blank?
|
8
|
+
@product.variants.includes(:option_values).select{|i| i.option_value_ids.sort == values.map(&:id) }.first
|
9
|
+
end
|
10
|
+
|
11
|
+
|
12
|
+
#===============================
|
13
|
+
# Givens
|
14
|
+
|
15
|
+
Given /^I have a product( with variants)?$/ do |has_variants|
|
16
|
+
@product = Factory.create(has_variants ? :product_with_variants : :product)
|
17
|
+
end
|
18
|
+
|
19
|
+
Given /^the "([^"]*)" variant is out of stock$/ do |descriptor|
|
20
|
+
flunk unless @product
|
21
|
+
@variant = variant_by_descriptor(descriptor)
|
22
|
+
@variant.update_attributes(:count_on_hand => 0)
|
23
|
+
end
|
24
|
+
|
25
|
+
Given /^I have an? "([^"]*)" variant( for .*)?$/ do |descriptor, price|
|
26
|
+
price = price ? price.gsub(/[^\d\.]/, '').to_f : 10.00
|
27
|
+
values = descriptor.split(" ")
|
28
|
+
flunk unless @product && values.length == @product.option_types.length
|
29
|
+
@variant = variant_by_descriptor(descriptor)
|
30
|
+
return @variant if @variant
|
31
|
+
@product.option_type_ids.each_with_index do |otid, index|
|
32
|
+
word = values[index]
|
33
|
+
val = OptionValue.find_by_presentation(word) || Factory.create(:option_value, :option_type_id => otid, :presentation => word, :name => word.downcase)
|
34
|
+
values[index] = val
|
35
|
+
end
|
36
|
+
@variant = Factory.create(:variant, :product => @product, :option_values => values, :price => price)
|
37
|
+
@product.reload
|
38
|
+
end
|
39
|
+
|
40
|
+
|
41
|
+
#===============================
|
42
|
+
# Whens
|
43
|
+
|
44
|
+
When /^I click the (current|first|last) clear button$/ do |parent|
|
45
|
+
link = case parent
|
46
|
+
when 'first'; find(".clear-index-0")
|
47
|
+
when 'last'; find(".clear-index-#{@product.option_types.length - 1}")
|
48
|
+
else find(".clear-button:last")
|
49
|
+
end
|
50
|
+
assert_not_nil link
|
51
|
+
link.click
|
52
|
+
end
|
53
|
+
|
54
|
+
#===============================
|
55
|
+
# Thens
|
56
|
+
|
57
|
+
Then /^the source should contain the options hash$/ do
|
58
|
+
assert source.include?("VariantOptions(#{@product.variant_options_hash.to_json})")
|
59
|
+
end
|
60
|
+
|
61
|
+
Then /^I should see (enabled|disabled)+ links for the ((?!option).*) option type$/ do |state, option_type|
|
62
|
+
enabled = state == "enabled"
|
63
|
+
option_type = case option_type
|
64
|
+
when "first"; @product.option_types.first;
|
65
|
+
when "second"; @product.option_types[1];
|
66
|
+
when "last"; @product.option_types.last;
|
67
|
+
end
|
68
|
+
assert_seen option_type.presentation, :within => "#option_type_#{option_type.id} h3.variant-option-type"
|
69
|
+
option_type.option_values.each do |value|
|
70
|
+
rel = "#{option_type.id}-#{value.id}"
|
71
|
+
link = find("#option_type_#{option_type.id} a[rel='#{option_type.id}-#{value.id}']")
|
72
|
+
assert_not_nil link
|
73
|
+
assert_equal value.presentation, link.text
|
74
|
+
assert_equal "#", link.native.attribute('href').last
|
75
|
+
assert_equal "option-value #{enabled ? 'in-stock' : 'locked'}", link.native.attribute('class')
|
76
|
+
assert_equal rel, link.native.attribute('rel') # obviously!
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
Then /^I should have a hidden input for the selected variant$/ do
|
81
|
+
flunk unless @product
|
82
|
+
field = find("input[type=hidden]#variant_id")
|
83
|
+
assert_not_nil field
|
84
|
+
assert_equal "products[#{@product.id}]", field.native.attribute("name")
|
85
|
+
assert_equal "", field.native.attribute("value")
|
86
|
+
end
|
87
|
+
|
88
|
+
Then /^the add to cart button should be (enabled|disabled)?$/ do |state|
|
89
|
+
enabled = state == "enabled"
|
90
|
+
button = find("#cart-form button[type=submit]")
|
91
|
+
assert_equal !enabled, button.native.attribute("disabled") == "true"
|
92
|
+
end
|
93
|
+
|
94
|
+
Then /^I should see an (out-of|in)-stock link for "([^"]*)"$/ do |state, button|
|
95
|
+
in_stock = state == "in"
|
96
|
+
buttons = button.split(", ")
|
97
|
+
buttons.each do |button|
|
98
|
+
link = find_link(button)
|
99
|
+
assert_equal "option-value #{in_stock ? 'in' : 'out-of'}-stock", link.native.attribute("class")
|
100
|
+
assert_not_nil link
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
Then /^I should see "([^"]*)" selected within the (first|second|last) set of options$/ do |button, group|
|
105
|
+
parent = case group
|
106
|
+
when 'first'; '.variant-options.index-0'
|
107
|
+
when 'second'; '.variant-options.index-1'
|
108
|
+
when 'last'; ".variant-options.index-#{@product.option_values.length - 1}"
|
109
|
+
end
|
110
|
+
within parent do
|
111
|
+
link = find_link(button)
|
112
|
+
assert_not_nil link
|
113
|
+
assert link.native.attribute("class").include?("selected")
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
Then /^I should not see a selected option$/ do
|
118
|
+
assert_raises Capybara::ElementNotFound do
|
119
|
+
find(".option-value.selected")
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
Then /^I should be on the cart page$/ do
|
124
|
+
assert_equal cart_path, current_path
|
125
|
+
end
|
@@ -0,0 +1,138 @@
|
|
1
|
+
require 'uri'
|
2
|
+
require 'cgi'
|
3
|
+
require File.expand_path("../../support/paths.rb", __FILE__)
|
4
|
+
require File.expand_path("../../support/selectors.rb", __FILE__)
|
5
|
+
|
6
|
+
def get_parent(parent)
|
7
|
+
case parent.sub(/^the\s/, '')
|
8
|
+
when "flash notice"; ".flash"
|
9
|
+
when "first set of options"; "#option_type_#{@product.option_types.first.id}"
|
10
|
+
when "second set of options"; "#option_type_#{@product.option_types[1].id}"
|
11
|
+
when "variant images label"; "#variant-images"
|
12
|
+
when "price"; ".prices .price"
|
13
|
+
else "[set-your-parent] #{parent}"
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
|
18
|
+
#========================================================================
|
19
|
+
# Givens
|
20
|
+
|
21
|
+
Given /^I'm on the ((?!page).*) page$/ do |path|
|
22
|
+
path = "#{path.downcase.gsub(/\s/, '_')}_path".to_sym
|
23
|
+
begin
|
24
|
+
visit send(path)
|
25
|
+
rescue
|
26
|
+
puts "#{path} could not be found!"
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
Given /^I'm on the ((?!page).*) page for (.*)$/ do |path, id|
|
31
|
+
case id
|
32
|
+
when "the first product"
|
33
|
+
id = @product ||= Product.last
|
34
|
+
end
|
35
|
+
path = "#{path.downcase.gsub(/\s/, '_')}_path".to_sym
|
36
|
+
begin
|
37
|
+
visit send(path, id)
|
38
|
+
rescue
|
39
|
+
puts "#{path} could not be found!"
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
|
44
|
+
#========================================================================
|
45
|
+
# Actions
|
46
|
+
|
47
|
+
When /^(?:|I )press "([^"]*)"$/ do |button|
|
48
|
+
# wtf button text spree!
|
49
|
+
button = "#popup_ok" if button == "OK"
|
50
|
+
click_button(button)
|
51
|
+
end
|
52
|
+
|
53
|
+
When /^I press "([^"]*)" in (.*)$/ do |button, parent|
|
54
|
+
# wtf button text spree!
|
55
|
+
button = "#popup_ok" if button == "OK"
|
56
|
+
within get_parent(parent) do
|
57
|
+
click_button(button)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
When /^(?:|I )follow "([^"]*)"$/ do |link|
|
62
|
+
click_link(link)
|
63
|
+
end
|
64
|
+
|
65
|
+
When /^(?:|I )follow "([^"]*)" within (.*)$/ do |link, parent|
|
66
|
+
within get_parent(parent) do
|
67
|
+
click_link(link)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
|
72
|
+
When /^I wait for (\d+) seconds?$/ do |seconds|
|
73
|
+
sleep seconds.to_f
|
74
|
+
end
|
75
|
+
|
76
|
+
When /^I confirm the popup message$/ do
|
77
|
+
find_by_id("popup_ok").click
|
78
|
+
end
|
79
|
+
|
80
|
+
|
81
|
+
|
82
|
+
|
83
|
+
|
84
|
+
|
85
|
+
#========================================================================
|
86
|
+
# Assertions
|
87
|
+
|
88
|
+
Then /^I should see "([^"]*)"$/ do |text|
|
89
|
+
assert page.has_content?(text)
|
90
|
+
end
|
91
|
+
|
92
|
+
Then /^I should see "([^"]*)" in (.*)$/ do |text, parent|
|
93
|
+
within get_parent(parent) do
|
94
|
+
assert page.has_content?(text)
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
Then /^I should not see "([^"]*)"$/ do |text|
|
99
|
+
assert_not page.has_content?(text)
|
100
|
+
end
|
101
|
+
|
102
|
+
Then /^I should not see "([^"]*)" in (.*)$/ do |text, parent|
|
103
|
+
within get_parent(parent) do
|
104
|
+
assert_not page.has_content?(text)
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
Then /^"([^"]*)" should equal "([^"]*)"$/ do |field, value|
|
109
|
+
assert_equal value, find_field(field).value
|
110
|
+
end
|
111
|
+
|
112
|
+
Then /^"([^"]*)" should have "([^"]*)" selected$/ do |field, value|
|
113
|
+
field = find_field(field)
|
114
|
+
has_match = field.text =~ /#{value}/
|
115
|
+
has_match = field.value =~ /#{value}/ unless has_match
|
116
|
+
assert has_match
|
117
|
+
end
|
118
|
+
|
119
|
+
|
120
|
+
#========================================================================
|
121
|
+
# Forms
|
122
|
+
|
123
|
+
When /^(?:|I )fill in "([^"]*)" with "([^"]*)"$/ do |field, value|
|
124
|
+
fill_in(field, :with => value)
|
125
|
+
end
|
126
|
+
|
127
|
+
When /^(?:|I )fill in the following:$/ do |fields|
|
128
|
+
fields.rows_hash.each do |name, value|
|
129
|
+
When %{I fill in "#{name}" with "#{value}"}
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
When /^(?:|I )select "([^"]*)" from "([^"]*)"$/ do |value, field|
|
134
|
+
select(value, :from => field)
|
135
|
+
end
|
136
|
+
|
137
|
+
|
138
|
+
|