How to fill tinymce-rails editor with capybara and selenium? - ruby-on-rails

I have trouble with using capybara to test tinymce form. I'm using tinymce-rails and have 7 editors in my form. Also I'm using asciimath plugin with tinymce.
Everything works fine, but I'm unable to write tests to fill in tinymce editor.
Here is how my step definition code looks like, very similar to what is described here:
within_frame("content_ifr") do
editor = page.find_by_id('tinymce')
editor.native.send_keys 'test'
end
The problem is when I run the following:
editor.native.clear # works, clear the editor area, I'm testing this with pry
editor.native.send_keys :tab # works, moves focus to next input
editor.native.send_keys 'test' # returns "", nothing happens, nothing in editor
So clear and send_keys :tab work as expected. But I can't send any string. send_keys function is always returning empty string, and nothing happens when I do test using pry.
What is going wrong here? and how can I debug / investigate the problem?
Thanks.

I know that this is an old question but I just found it while trying to solve this issue as well.
Although the original question said that he has 7 tinymce's on the same page I think that my solution might work for him too but I do know it will work if there is one tinymce as was my case.
In my request spec I used this:
page.execute_script('$(tinymce.editors[0].setContent("my content here"))')
The page.execute_script with tell it to run the jQuery function. It then finds the first tincymce editor and sets the content.
Worked like a charm for me. I think if there are more than one tinymce it can be called by its position.

Switching to chrome as described here solved my problem.
Obviously the problem is related with a bug in firefox driver.
Still i think it is a valid question for firefox.

Try to switch to an iframe that contains tinymce textarea input, and than send_keys:
# +session+ is an instance of Capybara::Session class
browser = session.driver.browser
browser.switch_to.frame(iframe_id)
editor.native.send_keys(text)
browser.switch_to.default_content

I had the same issue. After a day fighting, my tests finally passed.
The code that I am using is:
within_frame("producto_condiciones_ifr") do
editor = page.find_by_id('tinymce')
editor.native.send_keys 'filling text'
end
The first line is a method of capybara. The parameter passed is the ID of the iframe.
Line #2 is a must.
In line #3 goes the text that you wish to place inside TinyMCE

just came across this problem with RoR and rspec
I managed to solve by doing this:
within_frame { page.find_by_id("tinymce").set("new content here") }
the set method will replace any existing content by the new one
if you want to keep the current content and add things to it, use the send_keys method

Related

How to find out why rails feature test fails

we're currently working on a piece of mapping software, where we use Leaflet with custom left and right sidebars as well as a text-filter where we filter for different POI features. The whole thing looks like this:
The flow is as follows
A user visits a map under a unique link
The controller renders the HTML template first (no data is bein published)
Inside our javascript an ajax call fetches the data and renders markers, some panels, etc., etc.
We use capybara with poltergeist for all our feature tests.
In our master everything is working as it should be.
In another branch I added password protection, hence a bootstrap modal pops up if a map is password protected and has not yet been unlocked within the current session.
Everything is working fine except for some feature tests that fail lately and after messing around with stuff I still don't have a clue why exactly.
Let's see for example this test
feature 'Places map filter', js: true do
before do
#map = create :map, :full_public
create :place, :unreviewed, categories: 'Playground', map: #map
visit map_path(map_token: #map.public_token)
find('.open-sidebar').trigger('click')
end
scenario 'Nothing filters nothing' do
show_places
show_events
show_places_list_panel
expect(page).to <...>
end
...
end
Capybara claims to be unable to find some css elements. Calling screenshot_and_open_image reveals that it is still showing an overlay (hiding everything else) until all data have been loaded. Something seems to be hanging within my Javascript...
.
I've been messing around with the test-environment, which had an effect:
config.action_controller.asset_host = "file://#{::Rails.root}/public"
config.assets.prefix = 'assets_test'
The test passes since the data is now there. A screenshot reveals missing assets, which is guided by a proper warning message Not allowed to load local resource: <path>. I'm puzzled since querying the data happens via an ajax-call from one of the files that capybara tells to be unaccessible.
I don't know how to continue, since I don't want to start skipping tests. I hope you can help guiding me finding the error.
Thanks in advance,
Andi
Update
Thanks to Thomas for his hint on ES6 features. I used poltergeist's inspector mode and hence was able to discover an arrow function I introduced! That's why the JS driver couldn't deal with a callback I was passing to a promise which did not resolve...
Firstly, ensure you have js_errors: true in your Poltergeist driver registration - https://github.com/teampoltergeist/poltergeist#customization - so that you will get runtime JS errors reported.
Secondly, if you're using any ES6+ features in your JS code, make sure you transpiling them into ES5 compatible code since Poltergeist/PhantomJS only supports JS <= ES5, and will silently fail at JS parse time if it parses JS using features like let.
And finally, by using trigger you are bypassing Poltergeists checks that the button is actually clickable by the user, so make sure you're not clicking a button too early (before whatever behavior gets attached to the button is actually attached)

StaleElementReference Error Element not found in the cache

I'm using Capybara 2.1 with Ruby 1.9.3 using the selenium driver (with Minitest and Test Unit) in order to test a web app.
I am struggling with the StaleElementReferenceException problem. I have seen quite a number of discussions on the topic but I haven't been able to find a solution to the issue that I am facing.
So basically, I'm trying to find all pagination elements on my page using this code:
pagination_elements = page.all('.pagination a')
Then I'm doing some assertions on those elements like:
pagination_elements.first.must_have_content('1')
After those assertions, I'm continuing the test by clicking on the Next Page link to make sure that my future first pagination element will be the Previous Page.
To do that I'm retrieving paginations elements again :
new_pagination_elements = page.all('.pagination a')
And the Stale Error is occurring here, because I'm reaching elements that I've already reached. ( Here is the error )
You can see the link states here.
I really have no idea how to make this common test work properly.
Do you have any tips for a better way to reach my pagination elements?
I sometimes have some problem with AJAX intensive pages, in my case this workaround solves it:
begin
...
rescue Selenium::WebDriver::Error::StaleElementReferenceError
sleep 1
retry
end
I saw the main message in the gist is:
Element not found in the cache -
perhaps the page has changed since it was looked up
I have similar case before. There are two solutions:
Add page.reload before checking same stuff in new page, if you have set Capybara.automatic_reload = false in spec_helper
find a special element in new page which previous page doesn't have. This effect is equivalent to wait.
Another method is to use specific selector. For example, instead of
pagination_elements = page.all('.pagination a')
Use
pagination_elements = page.all('#post_123 .pagination a')
Append a unique id area to the selector and you should not meet such problem.
Interesting link about this error and how to fix it : http://stefan.haflidason.com/testing-with-rails-and-capybara-methods-that-wait-method-that-wont/
Apparently, in addition to race conditions, this error also appears due to misused within blocks. For example:
within '.edit_form' do
click '.edit_button'
# The error will appear here if the 'edit_button' is not a
# descendant of the 'edit_form'
end
HAve you tried to use WebDriver directly rather than via Capybara? This woudl potentially give you more control of when to and when to not cache objects.
e.g. (Apologies for the java syntax but should get the idea)
WebElement searchField = driver.findElement(By.CssSelector("input.foo"));
searchField.click();
searchField.sendKeys("foo foo");
System.out.println(searchField.getText());
//Do something elsewhere on the page which causes html to change (e.g. submit form)
.....
....
//This next line would throw stale object
System.out.println(searchField.getText());
//This line will not throw exception
searchField = driver.findElement(By.CssSelector("input.foo"));
System.out.println(searchField.getText());
Assigning "findElement" again to "searchField" means that we re-find the element. Knowing when to and when not re-assign is key went deciding how to cache your webelements.
I have not used Capybara, but I assume that it hides the caching strategy from you?

How do I link to a LABEL in org-mode?

In org-mode, I have defined a figure+caption like this:
#+CAPTION: My great figure
#+LABEL: fig:myfigure
[[myfigure.png]]
How do I write "See figure [myfigure]"? I've found the following syntax:
See figure \ref{fig:myfigure}
but this looks ugly in the source file. In particular, you cannot use it for actually jumping to the figure.
You actually don't need '#+NAME', it works fine if you use '#+LABEL', which won't break your short-caption for list of figures.
Orgmode does now offer a 'jumpable', enumerated or link with name of your choice in the exported (latex, html) text if you link with:
see figure [[fig:myfigure]].
or
see figure [[fig:myfigure][figurenameintext]].
I would have added this as a comment, but I don't have the reputation yet.
--
In response to your comment (still can't comment): you do need the '#+NAME' for it to jump within the .org source file; as mentioned in the manual, and i also just confirmed that works. Not sure about the short-captions in the latest version.
With a very recent org-mode, you can use #+name:, see:
http://thread.gmane.org/gmane.emacs.orgmode/62644/focus=62646
#+CAPTION: My great figure
#+LABEL: fig:myfigure
#+name: fig:myfigure
[[test.png]]
See figure [[fig:myfigure][test]].
This works for me to jump from the link , but has no effect when exporting, I'm afraid...

DNN jQuery conflict - pop up window won't close

I'm working on a DNN site that has been set up before my time here.
There's some conflict with the jQuery I believe, which prevents the modal pop up window in the attached calendar (link) events to not close properly:
http://www.sim-one.ca/NewsandEvents/calendar-of-events.aspx
I tried eliminating one script call at a time to see which one could be messing this up to no avail.
When I test this with the default theme it works like a charm.
Any ideas? Anyone came across something like this before?
Thank you!
You've got plenty of 404 errors on that page, ensure first, that files are in their place.
For example, http://www.sim-one.ca/NewsandEvents/Portals/_default/Skins/SimTwo/includes/js/jquery.listnav-2.1.js was not found. Ensure this path exists.
I agree with Anrie that your references are broken. For example, http://www.sim-one.ca/NewsandEvents/Portals/_default/Skins/SimTwo/includes/css/custom-theme/jquery-ui-1.8.9.custom.css is showing 404 but http://www.sim-one.ca/Portals/_default/Skins/SimTwo/includes/css/custom-theme/jquery-ui-1.8.9.custom.css
You can just use links like :
/Portals/_default/Skins/SimTwo/includes/css/custom-theme/jquery-ui-1.8.9.custom.css in order to fix this in skin file or use <%= SkinPath %>.
Try adding return false; on your event after calling the dnnModal.show()

Unable to send the TAB key during a Selenium integration test

As part of a Selenium integration test, I wrote the two following lines in Ruby to simulate entering an e-mail address into a text field and "moving the focus away":
#driver.find_element(:id, "user_email").send_keys "user#example.com"
#driver.find_element(:id, "some_other_element").click
The second line is not generic enough, because some_other_element might be unknown or non-existent. Thus, I wanted to replace the action of clicking another element with a TAB keystroke:
#driver.find_element(:id, "user_email").send_keys :tab
However, this does not seem to work, the element user_email does not lose its focus as expected. Also replacing :tab with "\xEE\x80\x84" does not help. Does anyone know what could be wrong here? How can I move the focus away of an element without simulating a click somewhere else?
Thanks for any help,
Dominik
I don't know how to do it without simulating a click, but clicking on <body> worked for me. This solution may be generic enough.
I think this should works well. Give it a try.
find('.myselector_name').native.send_keys(:tab)
Reference to answer is How do I simulate hitting enter in an input field with Capybara and ChromeDriver?

Resources