Come posso riempire un'area di CKEditor all'interno di Capybara, supponendo che io stia usando un driver capace di javascript come capybara-webkit o selenio?Come compilare ckeditor da capybara con webkit o selenio
risposta
Ispirato da ciò che ho trovato here, mi si avvicinò con la soluzione di usare JavaScript sia per impostare i dati sulla nascosta textarea
e sull'oggetto CKEditor
. Nessuno dei due sembrava sufficiente, a seconda delle circostanze.
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!'
RSpec + Capybara a lavorare con le istanze CKEditor
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
una piccola aggiunta al Marc-André's awesome answer
Se si utilizza formato nidificato o più aree di testo nella stessa gli ID generati dalle pagine sono piuttosto brutti e difficili da scrivere nei test (ad esempio person_translations_attributes_2_biography
) con questa piccola aggiunta a metodo di s è possibile individuare ckeditors utilizzando le loro etichette al posto di 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 questo modo, invece di questo
fill_in_ckeditor 'person_translations_attributes_2_biography', with: 'Some text'
è possibile scrivere questo
fill_in_ckeditor 'Biography', with: 'Some text'
Stavo per scrivere qualcosa esattamente come questo quando ho letto la risposta di Marc-André. Sono contento di aver continuato a leggere. Grazie! –
se si usa ckeditor.updateElement() per impostare il valore dell'elemento textarea nascosto (invece di impostarlo direttamente con jquery, come nella risposta di Marc-André) si potrebbero verificare test di errore casuali, quando capybara non è in attesa sul tuo js per finire l'esecuzione. quando si aggiunge la pagina .dovrebbe have_field (locator, con: params [: with], visible: false) capybara attende che l'elemento di testo nascosto abbia il valore previsto. – wnm
Per me Marc-André's answer interruttori contesto iframe in driver webkit. Vedo this capybara-webkit issue
ho trovato un altro modo per riempire in ingresso ckeditor che non cambia contesto iframe:
def fill_in_ckeditor(id, with:)
within_frame find("#cke_#{id} iframe") do
find('body').base.send_keys with
end
end
e lo chiamano
fill_in_ckeditor 'comment', with: 'This is my message!'
Opere entrambe con WebKit e selenio driver
Ispirato a this post
Grazie per questo, mi ha davvero risparmiato un sacco di tempo. Una piccola correzione: in capybara 2.1.0, 'browser.execute_script' sopra dovrebbe essere' page.execute_script'. –
@BalintErdi: risolto, grazie! –
ottimo metodo qui. ha funzionato come un fascino ... basta copiare e incollare. – nfriend21