How to fill ckeditor from capybara with webkit or selenium driver

≡放荡痞女 提交于 2019-12-04 08:04:49

问题


How can I fill a CKEditor area within Capybara, assuming I'm using a javascript capable driver like capybara-webkit or selenium?


回答1:


Inspired from what I found here, I came up with the solution of using javascript to both set the data on the hidden textarea and on the CKEditor object. Neither seemed sufficient, depending on the circumstances.

def fill_in_ckeditor(locator, opts)
  content = opts.fetch(:with).to_json # convert to a safe javascript string
  page.execute_script <<-SCRIPT
    CKEDITOR.instances['#{locator}'].setData(#{content});
    $('textarea##{locator}').text(#{content});
  SCRIPT
end

# Example:
fill_in_ckeditor 'email_body', :with => 'This is my message!'



回答2:


A small addition to Marc-André's awesome answer

If you are using nested form or multiple textareas in the same page generated IDs are pretty ugly and hard to write into tests (e.g. person_translations_attributes_2_biography) with this small addition to his method you can locate ckeditors using their labels instead of ID

# Used to fill ckeditor fields
# @param [String] locator label text for the textarea or textarea id
def fill_in_ckeditor(locator, params = {})
  # Find out ckeditor id at runtime using its label
  locator = find('label', text: locator)[:for] if page.has_css?('label', text: locator)
  # Fill the editor content
  page.execute_script <<-SCRIPT
      var ckeditor = CKEDITOR.instances.#{locator}
      ckeditor.setData('#{params[:with]}')
      ckeditor.focus()
      ckeditor.updateElement()
  SCRIPT
end

In this way instead of this

fill_in_ckeditor 'person_translations_attributes_2_biography', with: 'Some text'

you can write this

fill_in_ckeditor 'Biography', with: 'Some text'



回答3:


RSpec + Capybara support file to work with ckeditor instances

module Ckeditor
  class Instance
    attr_reader :capybara
    private :capybara

    def initialize(instance_id, capybara)
      @instance_id, @capybara = instance_id, capybara
    end

    def val(value)
      capybara.execute_script "jQuery('textarea##{@instance_id}').val('#{value}')"
    end

    def reload_all
      capybara.execute_script "for(var instance in CKEDITOR.instances) { if(CKEDITOR.instances.hasOwnProperty(instance)) {CKEDITOR.instances[instance].destroy(true);} }"
      capybara.execute_script "CKEDITOR.replaceAll();"
    end
  end
end

# usage
# rte = Ckeditor::Instance.new(:my_instance_id, page)
# rte.val 'foo'
# rte.reload_all
# NOTE: page is provided by Capybara

https://gist.github.com/3308129




回答4:


For me Marc-André's answer switches iframe context in webkit driver. See this capybara-webkit issue

I found another way to fill in ckeditor input which doesn't change iframe context:

  def fill_in_ckeditor(id, with:)
    within_frame find("#cke_#{id} iframe") do
      find('body').base.send_keys with
    end
  end

and call it

fill_in_ckeditor 'comment', with: 'This is my message!'

Works both with webkit and selenium drivers

Inspired by this post



来源:https://stackoverflow.com/questions/10957869/how-to-fill-ckeditor-from-capybara-with-webkit-or-selenium-driver

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!