2012-03-14 5 views
4

У меня есть асинхронная функция javascript, которую мне нужно протестировать с capybara. Я понимаю, что я должен использовать опцию js: true на тестах и ​​установить config.use_transactional_fixtures = false, а затем выбросить в database_cleaner, но я все еще не могу заставить его работать.Capybara с 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 с поддельными данными, используя capybara rspec, не могли бы вы помочь мне, мне нужно завершить к завтрашнему дню. –

+0

какую часть вы застряли? –

+0

спасибо за ваш ответ, я застрял на транзакции с моего сайта на paypal (тест). Что это мой следующий шаг? ответьте как можно скорее ... –

ответ

0

Проблема была в использовании visit <route>_url. Домен по умолчанию для рельсовых тестов - 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.Просто проверьте его дважды :)

 Смежные вопросы

  • Нет связанных вопросов^_^