2017-05-24 57 views
0

目前的元素,我有這個測試:find方法不等待將出現從JSON文件

規格/功能/ cardx/cardx_spec.rb

it 'can edit cardx with the form' do 
    product = FactoryGirl.create(:product) 
    store = FactoryGirl.create(:store) 
    click_link(class: 'link-record-edit') 
    page.find(class: 'record-form') 
    fill_in 'field-start-date', with: Date.tomorrow.to_s 
    page.find(id: 'cardx-edit-form').fill_in 'field-end-date', with: (Date.tomorrow + 7).to_s 
    page.find(id: 'cardx-edit-form').select(product.name, from: { id: 'field-product' }) 
    page.find(id: 'cardx-edit-form').select(store.name, from: { id: 'field-store' }) 
    page.find(id: 'cardx-edit-form').click_button(t('button.save')) 
    changed = Cardx.find(@cardx.id) 
    result = changed.start_date == Date.tomorrow && changed.end_date == (Date.tomorrow + 7) && changed.product.name == product.name && changed.store.name == store.name 
    expect(result).to eq(true) 
end 

這個測試應該檢查如果我可以提交表單,但是此表單正在呈現並通過AJAX請求添加到DOM,當我點擊頁面中的鏈接時發生這種請求。這個呈現是通過一個JSON文件來的。 當我正常使用瀏覽器作爲用戶時,一切正常,但是當我運行這個測試(即使當我設置max_timeout爲50秒等荒謬值)時,它立即失敗,說它無法找到'record-form'元素。找不到應該等到max_timeout用完?

在我的測試中顯然發生的是,它不是試圖加載和呈現帶有表單代碼的JSON文件。有沒有解決這個問題的方法?

編輯:代碼我到目前爲止

的JavaScript加載形式

$(document).on('click', '.link-record-edit', function(e) { 
    //diferentiate between multiple searches on page 
    setRecord(this); 

    //set selected id 
    record[record_type].selected_id = $(this).attr('data-id'); 

    //mark selected row 
    markSelectedRow(); 

    if(record_type !== "default") { 
     //if in tab, open modal 
     $(record[record_type].form_placeholder).modal(); 
    } 

    //get ID for edition 
    (loadForm || console.error)(e); 

    e.preventDefault(); 
    }); 

function loadForm(ev, callback) { 
    //validate 
    if (typeof record[record_type].path_edit === 'undefined') { 
    return console.error("No definition for 'record[record_type].path_edit' on your page's js"); 
    } 

    target = []; 
    _event = null; 
    if(typeof event === 'undefined' || event === null) { 
    _event = ev; 
    } else { 
    _event = event; 
    } 
    if(_event.srcElement !== undefined && _event.srcElement.className !== undefined) { 
    target = _event.srcElement.className.split(" "); 
    } else if(_event.target !== undefined && _event.target.className !== undefined) { 
    target = _event.target.className.split(" "); 
    } 

    //show form block 
    $form_placeholder = ""; 
    if(record_type === "default") { 

    //is nome cases, with tabs, preselect first tab 
    $('[role="tabpanel"] a:first').tab('show'); 

    //if selected in default list, empty tab placeholders 
    $('.tab-pane [data-placeholder="true"]').html(''); 

    //add sidebar form 
    $('.width-switcher').filter(':visible').removeClass('col-sm-12').addClass('col-sm-6'); 
    $('.width-switcher:hidden').fadeIn('fast'); 
    $form_placeholder = record[record_type].form_placeholder; 

    } else if(target.indexOf("link-record-edit") > -1 || target.indexOf("link-record-new") > -1) { 
    $form_placeholder = record[record_type].form_placeholder + ' .modal-content'; 
    } 

    //last case cenario 
    if(record[record_type].inline_placeholder != null && $($form_placeholder).length == 0) { 
    $form_placeholder = record[record_type].form_placeholder; 
    } 

    loadSpinner($form_placeholder); 


    //enable/disable tabs 
    if(record[record_type].selected_id > 0 && record_type === "default") { 
     $(".nav-tabs").show(); 
    } else if(record_type === "default") { 
     $(".nav-tabs").hide(); 
    } 

    // Remove temporary buttons from hooks 
    $('.temporary').remove(); 

    // pass var to form of view/edit mode 
    $edit_mode = $('.editor-mode.active').length; 

    //get form data and place it on placeholder 
    $.ajax({ 
    url: record[record_type].path_edit.replace(':id', record[record_type].selected_id), 
    type: "GET", 
    dataType: "html", 
    data: { parent_id: record[record_type].parent_id, edit_mode: $edit_mode }, 
    success: function(result) { 
     //add form 
     $($form_placeholder).fadeOut(100, function() { 
     $(this).html(result).fadeIn(400, function() { 
      //as it fades in, set title and prettify form objects 

      //change title 
      setFormTitle(); 

      //refresh scripts for forms 
      formPluginRegresh(); 

      //new html on page, redistribute record types attributes 
      distributeRecordAttributes(); 

      removeSpinner(); 

      //callback if anyone waits 
      if(callback != null) { callback(); } 
     }); 
     }); 
    }, 
    error: function(jqXHR, textStatus, errorThrown) { 
     showMessage('error', $.parseJSON(jqXHR.responseText)); 
    } 
    }); 
} 

function update_inline_combos() { 
    //case inline, update dropdownlist 
    if($(record[record_type].form_placeholder).parents('.overflow').length > 0) { 
    //check existance of drops 
    drops = $('.input-group[data-record="'+record_type+'"]').find('> select'); 

    //fill in new data 
    $.ajax({ 
     url: record[record_type].path_list_drop, 
     type: "GET", 
     dataType: "html", 
     success: function(result) { 
      $.each(drops, function(index, value) { 
      //element's id 
      $id = $(value).attr('id'); 

      //add new data with :id, :name 
      setBoot('#'+$id, result); 
      }); 
     }, 
     error: function(jqXHR, textStatus, errorThrown) { 
      showMessage('error', $.parseJSON(jqXHR.responseText)); 
     } 
    }); 
    } 
} 

HTML我有

的index.html

<div class="col-sm-6 col-xs-12 width-switcher not-visible"> 
     <div class="box-container"> 
      <div class="box-header"> 
       <span class="title" id="edit-cardx-title">&nbsp;</span> 

       <!-- Split button --> 
       <button class="btn btn-xs btn-default pull-right close-width-switcher" type="button"> 
        <i class="fa fa-close"></i> 
       </button> 
      </div> 

      <div class="box-content no-padding"> 
       <div id="placeholder-form-cardx"> 
        <!-- FORM PLACEHOLDER --> 
       </div> 
      </div> 
     </div> 
    </div> 

_form.etml(部分即會放在佔位符上)

<%= render partial: 'partials/form_objects/form_title', format: :erb, locals: { optional: true } %> 

<%= simple_form_for(@cardx, remote: true, 
    url: url_for(action: 'update_or_create', controller: 'cardxes', format: 'json'), 
    html: { method: 'post', id: 'cardx-edit-form' }, 
    authenticity_token: true) do |f| %> 

    <%= f.error_notification %> 
    <%= f.hidden_field :id %> 

    <div class="form-inputs form-group"> 
     <div class="col-lg-2 col-md-3 col-sm-4 control-label"> 
      <%=t("label.start_date")%> 
     </div> 
     <div class="col-lg-10 col-md-9 col-sm-8"> 
      <%= f.input :start_date, as: :string, 
      input_html: {class: "date-picker day-datepicker", id: "field-start-date"}, 
      label: false, required: true, class: "form-control" %> 
     </div> 
    </div> 

    <div class="form-inputs form-group"> 
     <div class="col-lg-2 col-md-3 col-sm-4 control-label"> 
      <%=t("label.end_date")%> 
     </div> 
     <div class="col-lg-10 col-md-9 col-sm-8"> 
      <%= f.input :end_date, as: :string, 
      input_html: {class: "date-picker day-datepicker", id: "field-end-date"}, 
      label: false, required: true, class: "form-control" %> 
     </div> 
    </div> 
    <!-- 
    <div class="form-inputs form-group"> 
     <div class="col-lg-2 col-md-3 col-sm-4 control-label"> 
      <%#=t("label.end_date")%> 
     </div> 
     <div class="col-lg-10 col-md-9 col-sm-8"> 
      <%= f.collection_select :store_id, 
       Store.to_collection.list, :id, :name, 
       { include_blank: t("form.choose") }, 
       { class: "required" } %> 
     </div> 
    </div> 
    --> 
    <div class="form-inputs form-group"> 
     <div class="col-lg-2 col-md-3 col-sm-4 control-label"> 
      <%=t("label.store.one")%> 
     </div> 
     <div class="col-lg-10 col-md-9 col-sm-8"> 
      <%= f.collection_select :store_id, 
       Store.to_collection.list, :id, :name, 
       { include_blank: t("form.choose") }, 
       { class: "required selectpicker", id: "field-store" } %> 
     </div> 
    </div> 

    <div class="form-inputs form-group"> 
     <div class="col-lg-2 col-md-3 col-sm-4 control-label"> 
      <%=t("label.product.one")%> 
     </div> 
     <div class="col-lg-10 col-md-9 col-sm-8"> 
      <%= f.collection_select :product_id, 
       Product.to_collection.list, :id, :name, 
       { include_blank: t("form.choose"), required_field: true }, 
       { class: "selectpicker required", id: "field-product" } %> 
     </div> 
    </div> 

    <script> 
    $(function() { 
     $('.selectpicker').selectpicker({
  
     liveSearch: true, 
     liveSearchNormalize: true,
  
     size: 6,
  
     width: '100%', 
     dropupAuto: true, 
     actionsBox: false
  
     }); 
    }); 
    </script> 

    <%= render partial: "partials/form_objects/form_actions", 
       format: :erb, 
       locals: { f: f, record: @cardx } %> 

<% end %> 

預先感謝您

編輯:

我使用這個測試(爲簡單起見),以檢測是否加載窗體,我得到「無法找到CSS「#cardx - 編輯 - 形式」'

it 'show edit form when a cardex record is clicked' do 
     page.find('.link-record-edit', match: :first).click 
     page.find('#cardx-edit-form', wait: 50) 
     expect(page).to have_selector('#cardx-edit-form') 
    end 
+0

你能提供它的html代碼嗎? –

+0

@peterpawar在這裏它是 –

+0

你可以通過使用pry gem單擊鏈接之後和'page.find(class:'record-form')'之前調試步驟。在那裏你可以檢查表單元素是否可訪問。 –

回答

0

您的測試並未標js: true元數據,並且沒有等待的行爲正在發生指向您正在使用此測試的rack_test司機概率的事實。 rack_test驅動程序不支持JS,因此也不做任何等待(因爲沒有JS支持,沒有異步動作需要等待)。你應該能夠確認你的錯誤堆棧跟蹤,這可能會引用名稱中帶有'水豚/ rack_test'的文件。見 - https://github.com/teamcapybara/capybara#drivershttps://github.com/teamcapybara/capybara#using-capybara-with-rspec

+0

Ty爲答案!我已經嘗試過使用js:true,但我給了它另一個鏡頭,閱讀了文檔後,我發現我缺少驅動程序的要求。我發現後,它開始按預期工作。只有兩個問題:我的測試運行非常緩慢。 –

+0

@TiagoSerra確保您將Capybara.default_max_wait_time設置爲一個合理的值(<= 10,具體取決於您使用的硬件),但即使使用具有JS功能的驅動程序,測試也會顯着變慢,因爲它們具有所有開銷與控制/使用瀏覽器一起使用。不要忘了接受這個答案(左邊的複選標記),如果它解決了你的問題,所以問題被標記爲已回答。 –

+0

Ty爲答案和解釋。我確信我接受了答案。 –