2012-03-14 60 views
4

我有一个异步的JavaScript函数,我需要用水豚测试。我知道我必须在测试中使用js: true选项,并设置config.use_transactional_fixtures = false,然后输入一些database_cleaner,但我仍然无法正常工作。用Javascript(Rspec,Spork和FactoryGirl启动)的水豚

cart_spec贯穿将项目添加到购物车并购买它的整个过程(因此它嵌套得相当深)。

checkout.html.erb使用stripe库来处理信用卡。这就是我需要测试的javascript功能。

当我使用js: true选项运行测试时,sports_url上不存在“添加到购物车”的测试失败,表明运动未保存到数据库。

当我运行没有js: true选项的测试时,除it "should warn user that cc number is invalid" do之外的所有测试都通过了,因为那是javascript所在的位置。

我正在运行spork并尝试重新启动服务器。

编辑

的问题是,我的测试运行在域名www.example.com,所以我sports_url被定向至www.example.com/sports。我问了一个新问题here。如果我用sports_path访问它,它的效果很好。

以下是文件:

cart_spec:

require "spec_helper" 

describe "Cart" do 
    before do 
    @user = FactoryGirl.create(:user) 
    @cart = @user.carts.create! 
    end 

    describe "using stripe" do 
     before do 
     @sport = FactoryGirl.create(:sport) 
     end 

     describe "user adds sport to cart", js: true do 
     before do 
      visit sports_url 
      click_link "Add to Cart" 
     end 

     it "should be checkout page" do 
      page.should have_content("Total") 
     end 

     describe "user clicks checkout" do 
      before do 
      click_button "Checkout" 
      end 

      it "should redirect user to sign in form" do 
      page.should have_selector('h2', text: "Sign in") 
      end 

      describe "user logs on" do 
      before do 
       fill_in "Email", with: @user.email 
       fill_in "Password", with: @user.password 
       click_button "Sign in" 

      end 

      it "should be on checkout page" do 
       page.should have_selector('h2', text: "Checkout") 
      end 

      describe "user fills in form" do 
       context "with invalid cc number" do 
       before do 
        fill_in "card-number", with: 42 
        click_button "Submit Payment" 
       end 

       it "should warn user that cc number is invalid" do 
        page.should have_content("Your card number is invalid") 
       end 
       end 
      end 

      end 
     end 
     end 
    end 

    describe "GET /carts/checkout" do 
    subject { @cart } 

    it { should respond_to(:paypal_url) } 
    it { should respond_to(:apply_discount) } 

    it "paypal_url contains notification" do 
     @cart.paypal_url(root_url, payment_notifications_url).should include("&notify_url=http%3A%2F%2Fwww.example.com%2Fpayment_notifications") 
    end 

    it "paypal_url contains invoice id" do 
     @cart.paypal_url(root_url, payment_notifications_url).should match /&invoice=\d+&/ 
    end 

    it "paypal_url contains return url" do 
     @cart.paypal_url(root_url, payment_notifications_url).should include("&return=http%3A%2F%2Fwww.example.com") 
    end 
    end 

    describe "GET /carts/discount" do 
    it "should apply discount to all line items" do 
     @cart.line_items.build(:unit_price => 48) 

     @cart.apply_discount 

     @cart.line_items.each do |lineItem| 
      lineItem.unit_price.should == 9.99 
     end 
    end 
    end 

end 

checkout.html.erb:

<h2>Checkout</h2> 
<span class="payment-errors"></span> 
<form action="" method="POST" id="payment-form"> 
    <div class="form-row"> 
     <label>Card Number</label> 
     <input type="text" size="20" autocomplete="off" id ="card-number" class="card-number"/> 
    </div> 
    <div class="form-row"> 
     <label>CVC</label> 
     <input type="text" size="4" autocomplete="off" class="card-cvc"/> 
    </div> 
    <div class="form-row"> 
     <label>Expiration (MM/YYYY)</label> 
     <input type="text" size="2" class="card-expiry-month"/> 
     <span>/</span> 
     <input type="text" size="4" class="card-expiry-year"/> 
    </div> 
    <button type="submit" class="submit-button">Submit Payment</button> 
</form> 

<script type="text/javascript" src="https://js.stripe.com/v1/"></script> 
<script type="text/javascript"> 
    Stripe.setPublishableKey('pk_xIm00GVAKVLMWmfeR2J8GlmeHcyhL'); 

    $(document).ready(function() { 
     $("#payment-form").submit(function(event) { 
     // disable the submit button to prevent repeated clicks 
     $('.submit-button').attr("disabled", "disabled"); 

     Stripe.createToken({ 
      number: $('.card-number').val(), 
      cvc: $('.card-cvc').val(), 
      exp_month: $('.card-expiry-month').val(), 
      exp_year: $('.card-expiry-year').val() 
     }, stripeResponseHandler); 

     // prevent the form from submitting with the default action 
     return false; 
     }); 
    }); 

    function stripeResponseHandler(status, response) { 
     if (response.error) { 
      $('.submit-button').removeAttr("disabled"); 
      //show the errors on the form 
      $(".payment-errors").html(response.error.message); 
     } else { 
      var form$ = $("#payment-form"); 
      // token contains id, last4, and card type 
      var token = response['id']; 
      // insert the token into the form so it gets submitted to the server 
      form$.append("<input type='hidden' name='stripeToken' value='" + token + "'/>"); 
      // and submit 
      form$.get(0).submit(); 
     } 
    } 
</script> 

spec_helper:

require 'rubygems' 
require 'spork' 

Spork.prefork do 
    # Loading more in this block will cause your tests to run faster. However, 
    # if you change any configuration or code from libraries loaded here, you'll 
    # need to restart spork for it take effect. 
    # This file is copied to spec/ when you run 'rails generate rspec:install' 
    ENV["RAILS_ENV"] ||= 'test' 
    require File.expand_path("../../config/environment", __FILE__) 
    require 'rspec/rails' 
    require 'rspec/autorun' 

    # Requires supporting ruby files with custom matchers and macros, etc, 
    # in spec/support/ and its subdirectories. 
    Dir[Rails.root.join("spec/support/**/*.rb")].each {|f| require f} 

    RSpec.configure do |config| 
    # == Mock Framework 
    # 
    # If you prefer to use mocha, flexmock or RR, uncomment the appropriate line: 
    # 
    # config.mock_with :mocha 
    # config.mock_with :flexmock 
    # config.mock_with :rr 
    config.mock_with :rspec 

    # Remove this line if you're not using ActiveRecord or ActiveRecord fixtures 
    config.fixture_path = "#{::Rails.root}/spec/fixtures" 

    # If you're not using ActiveRecord, or you'd prefer not to run each of your 
    # examples within a transaction, remove the following line or assign false 
    # instead of true. 
    config.use_transactional_fixtures = false 

    # If true, the base class of anonymous controllers will be inferred 
    # automatically. This will be the default behavior in future versions of 
    # rspec-rails. 
    config.infer_base_class_for_anonymous_controllers = false 

    config.before(:suite) do 
     DatabaseCleaner.strategy = :truncation 
    end 

    config.before(:each) do 
     DatabaseCleaner.start 
    end 

    config.after(:each) do 
     DatabaseCleaner.clean 
    end 
    end 
end 

Spork.each_run do 
    # This code will be run each time you run your specs. 

end 
+0

喜的朋友,我不知道如何来测试我的网站使用PayPal accocunt用假数据,使用水豚RSpec的,可以请你帮我,我需要在明天完成.. – 2012-09-05 15:18:25

+0

你被困在什么地方? – 2012-09-05 18:42:03

+0

感谢您的回复,我一直坚持从我的网站到paypal(测试)的金钱交易。我的下一步是什么?请尽快回复... – 2012-09-06 17:58:33

回答

0

问题是我在使用visit <route>_url。 rails测试的默认域名是exmaple.com,所以我的浏览器试图访问www.example.com/sports,这是由国际互联网命名委员会慷慨保留的。

我将这些改为visit <route>_path,事情很好。

0

很难给你确切的回答。

当您运行JS规格时,有2个进程。有可能,当你在并行访问页面时,记录不会被保存。

  1. 尝试等待,直到@sport保存到数据库。 添加

wait_until { page.has_content? "Add to Cart" }

click_link "Add to Cart"

水豚将等待这些话(2秒以内)。要增加默认的等待时间,请将Capybara.default_wait_time = 5添加到spec_helper。

  1. 确保DatabaseCleaner策略确实是:truncation。我看到你的spec_helper。只是检查两次:)