简体   繁体   中英

Rails Rspec Capybara Selenium JS create not showing after pressing submit

I am building a web shop, the functionality is already there, namely: in ONE screen there is a list of products and a list of ordered items. When in a product pressing order, this product then shows up immediately in this list.

As you can guess, when wanting to do this with a test, using selenium I see Firefox starting up, I think I even see the button being pressed, but then obviously nothing happens. No item in my order list.

Using Rails 5 with an updated capybara and selenium webdriver.

gem 'rspec-rails', '~> 3.5', '>= 3.5.1'
gem 'capybara', '~> 2.10', '>= 2.10.1'
gem "factory_girl_rails", "~> 4.7"
gem 'selenium-webdriver', '~> 3.0'
gem 'database_cleaner', '~> 1.5', '>= 1.5.3'  
gem "email_spec", "~> 1.6.0"

creating_order_spec.rb

require 'rails_helper'

RSpec.feature 'User can fill his shopping cart', js: true do
  let!(:category) { FactoryGirl.create(:category, name: 'Honey') }
  let!(:cheap_product) { FactoryGirl.create(:product, name: 'Honey lolly', 
                                                      price: '0,80',
                                                      category: category) }
  let!(:expensive_product) { FactoryGirl.create(:product, name: 'Honeyjar 400ml', 
                                                      price: '3,95',
                                                      category: category) }

  before do
    visit categories_path
  end

  scenario 'with different products' do
    page.find('.product', :text => 'Honey lolly').click_button('ADD TO CART')
    page.find('.product', :text => 'Honeyjar 400ml').click_button('ADD TO CART')

    within('#order') do
      expect(page).to have_content 'Honey lolly'
      expect(page).to have_content 'Honeyjar 400ml'
      expect(page).to have_content 0.80 + 3.95
    end
  end
end

Database_cleaning.rb

RSpec.configure do |config|  
  config.before(:suite) do
    DatabaseCleaner.clean_with(:truncation)
  end

  config.before(:each) do
    DatabaseCleaner.strategy = :transaction
  end

  config.use_transactional_fixtures = false

  config.before(:each, :js => true) do
    DatabaseCleaner.strategy = :truncation
  end    

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

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

Then I run it and get:

Failure/Error: expect(page).to have_content 'Honey lolly'
       expected to find text "Honey lolly" in "Total € 0,00"

Which means that nothing has happened to my order, or the total would have been more than € 0,00.

EDIT

This is the JS that only somehow doesn't work in tests.

$('#order').html("<%= j render 'orders/order' %>")

EDIT 2

test.log

 Started POST "/bookings" for 127.0.0.1 at 2016-11-14 10:11:00 +0100 Processing by BookingsController#create as JS Parameters: {"utf8"=>"✓", "booking"=>{"product_id"=>"1", "product_quantity"=>"5"}} [1m[36mProduct Load (0.5ms)[0m [1m[34mSELECT "products".* FROM "products" WHERE "products"."id" = $1 LIMIT $2[0m [["id", 1], ["LIMIT", 1]] [1m[35m (0.4ms)[0m [1m[35mBEGIN[0m [1m[36mBooking Exists (0.7ms)[0m [1m[34mSELECT 1 AS one FROM "bookings" WHERE "bookings"."order_id" IS NULL AND "bookings"."product_id" = $1 LIMIT $2[0m [["product_id", 1], ["LIMIT", 1]] [1m[35m (0.1ms)[0m [1m[31mROLLBACK[0m Rendering bookings/create.js.erb Rendered orders/_order.html.erb (0.9ms) Rendered bookings/create.js.erb (2.8ms) Completed 200 OK in 14ms (Views: 4.8ms | ActiveRecord: 2.2ms) 

Seems that there is no SQL statement triggered for the order. While normally it should be to fill in the total.

bookings_controller.rb

def create
  @booking = @order.bookings.find_by(product_id: params[:booking][:product_id])
  if @booking
    @booking.product_quantity = params[:booking][:product_quantity]
    @booking.save
  else
    @booking = @order.bookings.new(booking_params)
    @product = @booking.product
    @booking.product_name = @product.name
    @booking.product_price = @product.price
  end
  @order.save
  respond_to do |format|
      format.html { redirect_to categories_path }
      format.js { render layout: false }
  end
end

order.save triggers an extra method called .sum_all_bookings . This is not showing up in the SQL. Herein lies somewhere the error of the order staying unchanged in the view (#order).

Most likely cause is an error in one of your JS assets that's preventing the behavior you're expecting from being attached. Things can work fine in dev mode when the assets aren't concatenated (so an error in one file doesn't prevent the other files from being processed), but then fail in the test and production environments when an error in one file can prevent the JS concatenated after it from being parsed/processed.

Additionally you find 2 (I assume they are different since you're expecting 2 products to be added) elements with id = Product ('#product'). That is invalid html since ids are required to be unique, so could lead to weird issues.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM