

自分でブラウザ上でテストを行うと成功するのですが、capybaraで行うと失敗します。
以下のように編集画面でsubmitされたらupdateを行うようにしておき

[code]

      def update
        #投稿ボタンが押されたらpublishedをtrueに。押されなかったら自動下書き保存。
        published_torf = params[:commit] ? true : false
        if published_torf
          @ranking.update(ranking_params)
          if @ranking.valid?
            @ranking.published = true
            @ranking.save
          end
          respond_with(@ranking)
        else
          @ranking.attributes = ranking_params
          @ranking.save validate: false
        end
      end
    
[/code]

以下のようにcapybaraを動作させました。

[code]

    require 'rails_helper'
    
    #deviseのテストヘルパー
    include Warden::Test::Helpers
    Warden.test_mode!
    
    describe 'ログイン処理' do
      let(:user) { create(:user) }
      let(:category) { create(:category) }
      describe '投稿・編集' do
        before(:each) do
          category
          login_as(user, :scope => :user)
        end
        scenario '投稿・編集成功' do
              visit root_path
              click_button '投稿'
              fill_in 'ランキングタイトル', with: 'タイトルですよ'
              find('#ranking_ranking_posts_attributes_0_title').set('記事タイトル3')
              find('#ranking_ranking_posts_attributes_1_title').set('記事タイトル2')
              find('#ranking_ranking_posts_attributes_2_title').set('記事タイトル1')
              all('#edit').first.set('hey')
              all('#edit')[1].set('hey')
              all('#edit')[2].set('hey')
              #投稿ボタンをクリックするとなぜかデータベースから存在していた編集中の記事が消える
              click_button '投稿'
              expect(page).to have_content 'タイトルですよ'  # => エラー発生
        end
      end
    end
    
[/code]

すると、以下のようなエラーが発生しました。

[code]

    Failure/Error: expect(page).to have_content 'タイトルですよ'
           expected to find text "タイトルですよ" in "RankingHook 100 P 新着順 Bootflat PORTFOLIO Web Design Branding & Identity Mobile Design Print User Interface ABOUT The Company History Vision GALLERY Flickr Picasa iStockPhoto PhotoDune CONTACT Basic Info Map Conctact Form Copyright © 2014 Flathemes.All rights reserved."
    
[/code]

pryで確認してみると、送信ボタンを押すとデータベースから記事が消えます。

ちなみに自動下書き保存機能をつけるため以下のように、新しくレコードが作られた場合保存してedit画面に飛ばすようにしています。

[code]

      def new
        @ranking = Ranking.new
        #この数字をcurrentuserの数字にする
        @ranking.posts_sum.times {
          @ranking.ranking_posts.build
        }
        @ranking.user = current_user
        @ranking.save validate: false
        redirect_to edit_ranking_path @ranking
      end
    
[/code]

と

[code]

      def edit
      end
    
[/code]

ごちゃごちゃしてしまいましたが、よろしくお願いします。

---追記---

以下がformです。

[code]

    <%= form_for(@ranking) do |f| %>
            <div class="row category_select">
              <div class="field col-sm-12">
                <div class="col-sm-4">
                  <%= f.label :category_id %>を選択してください。
                  <br/>
                  <%= f.collection_select(:category_id, @categories, :id, :name, {}, {class: 'form-control'}) %>
                </div>
              </div>
              <div class="clearfix"></div>
            </div>
            <div class="edit-rankingtop row">
              <div class="field col-sm-2 col-xs-12">
                <strong id="top_image_label">トップ画像</strong><br/>
                <% if @ranking.image.thumb %>
                    <%= image_tag @ranking.image.thumb, size: '65', id: 'top_image_thumb' %>
                <% end %>
                <div class="field">
                  <%= f.file_field :image %>
                  <br>
                  <%= f.hidden_field :image_cache %>
                </div>
              </div>
              <div class="field col-sm-10 col-xs-12">
                <%= f.label :title %>
                <br>
                <%= f.text_area :title, class: 'form-control', placeholder: '150文字以内に詰め込もう' %>
              </div>
              <br/>
    
              <div class="field">
                <%= f.hidden_field :user_id, :value => current_user.id %>
              </div>
              <div class="clearfix"></div>
            </div>
            <!--自動下書き保存機能の通知場所-->
            <% unless @ranking.published == true %>
                <div class="create-temp col-sm-12 col-xs-12"></div>
            <% end %>
    
            <br/>
            <% i = @ranking.posts_sum %>
            <div class="col-sm-10 col-xs-12 row">
              <div class="field col-sm-12">
                <%= f.fields_for :ranking_posts, @ranking.ranking_posts do |p| %>
                    <br/>
                    <h4>第<%= i %>位</h4>
    
                    <%= p.hidden_field :rank, :value => i %>
    
                    <div class="field">
                      <%= p.label :title %>
                      <%= p.text_field :title, class: 'form-control' %>
                    </div>
    
                    <div class="field">
                      <%= p.label :description %>
                      <%= p.text_area :description, class: 'form-control', id: 'edit' %>
                    </div>
    
                    <% i = i-1 %>
                <% end %>
              </div>
    
              <div class="actions col-sm-6 col-xs-12">
                <%= f.submit '投稿', :class => 'btn btn-success btn-block' %>
              </div>
        <% end %>
    
[/code]

それと、RankingとRankingPostモデルも載せておきます。

[code]

    class Ranking < ActiveRecord::Base
      belongs_to :user
      belongs_to :category
      has_many :ranking_posts, dependent: :destroy
      accepts_nested_attributes_for :ranking_posts
      mount_uploader :image, ImageUploader
      #順番
      default_scope -> { order('created_at DESC') }
    
      validates :title, :presence => true, length: {maximum: 150}
      validates :category_id, :presence => true
      validates_associated :ranking_posts, message: 'を完成させてください。'
    end
    
[/code]

と

[code]

    class RankingPost < ActiveRecord::Base
      belongs_to :ranking
      default_scope -> { order('rank DESC') }
      validates :title, :description, :rank, presence: true
    end
    
[/code]

です。よろしくお願いします。


CC BY-SA 3.0
2015-01-04T10:08:26.853
3045
2015-01-04T16:32:02.417
2015-01-04T13:12:16.857
4971
4971
question
ruby ruby-on-rails rspec capybara
capybaraでformでsubmitボタンを押すと、なぜかデータベースのデータが消えてしまいます。


form 内で閉じていない div 要素があったため、capybara が form 内の要素を toplevel
の要素として処理してしまっていたことが原因でした。そのため、form 内で入力されたデータが submit によってサーバに送られず、空のデータで DB
のレコードを更新することになった模様です。

ウェブブラウザから入力した場合に正常に処理されていたのは、ブラウザが閉じていない div 要素を適当に処理してくれていたためで、 **capybara は
HTML を厳密(strict)に処理している** 事になります。

※ これは「ハマりどころ」になりそうです

なお、div 要素をきちんと閉じるように訂正した所、テストが通る様になりました。


CC BY-SA 3.0
2015-01-04T15:45:33.053
3079
2015-01-04T16:32:02.417
2015-01-04T16:32:02.417
4971
3045
answer