spree_variant_options 0.1.0.rc1
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.
- 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
|
+

|
9
|
+
|
10
|
+
#### After "Medium" is selected, "Medium Blue" is out of stock:
|
11
|
+
|
12
|
+

|
13
|
+
|
14
|
+
#### And after "Green" is selected:
|
15
|
+

|
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
|
+
|