2012-03-14 32 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。只是檢查兩次:)