If you can't update a nested object, getting a message like:
Failed to remove the existing associated parent.
The record failed to save after its foreign key was set to nil
you're probably not permitting the nested ID parameter to be used. Check your strong parameters #permit
to ensure that you're permitting the :id
parameter on the nested attributes.
Here's an interesting one: I had a site with two different sets of stylesheets, depending on what section of the site you were in. But when you clicked a link to go from one section to another, the new page was rendered with the previous section's stylesheets. If you refreshed the page, it would render with the correct stylesheets. What gives?
Well, Turbolinks. It replaces the body tag with the linked to page's body, but doesn't mess with the head element (except to replace the title tag). So your new page renders with the old page's stylesheets. Ugh. You'd think Turbolinks would be smart enough to recognize that the head element had changed and load the entire page, but no. Thanks, guys.
Are you using Turbolinks? If so, don't expect Jquery ready hooks to work correctly.
- You can't use
subject
in anaround
wrapper - You can't use
subject
in abefore(:all)
block
If your factory uses a mutable object for a field value, and your test changes that object, it will instantiate new foctory instances with the changed object, not the original object. For example:
factory :something
field1( {a: 123, b: 'hello'} )
end
a = create :something
a.field1[:a] = 456
b = create :something
b.field1[:a]
Will return 456 instead of 123!
We use the iCheck JS library to override our check boxes and radio buttons. Unfortunately, this really messes with Webkit's ability to find and click these elements. In short, you can't use click_on
to check or click them. Use the check_icheck_box
and choose_icheck_radio
methods in GeneralFeatureHelper
instead.
Similarly, we use the Chosen JS library to override our select tags, and Webkit doesn't like these either. Use the select_chosen_option
and method in GeneralFeatureHelper
.
Use the pick_date
method in GeneralFeatureHelper
to select a date from a date-picker calendar. It will navigate up to 24 months ahead to try to find the date. It currently does not navigate backwards.
To assert that a link is disabled, check whether the :disabled attribute is non-nil. It will be non-nil (probably just an empty string) if the element is disabled, and it will be nil if the element is enabled.
Asserting an element is disabled:
find('#my-link-id')[:disabled].should_not be_nil
Asserting an element is enabled:
find('#my-link-id')[:disabled].should be_nil
element.disabled?
and element['disabled']
and page.should have_selector('#my-link-id:not[disabled]')
all don't seem to work correctly. Note that this applies to links, and other methods appear to work correctly for input tags and buttons.
Webkit has special methods to handle confirmation dialogs and alerts. Here's sample code to first dismiss/cancel a confirmation dialog, and then accept it, and to assert the message displayed for each box. Note that the accept and dismiss commands must come before the event that triggers the dialog.
page.driver.dismiss_js_confirms!
click_on <something that triggers the dialog>
page.driver.confirm_messages.should include('Text expected on Confirmation Dialog here...')
# Now we're back on the regular page
page.driver.accept_js_confirms!
click_on <something that triggers the dialog>
page.driver.confirm_messages.should include('Text expected on Confirmation Dialog here...')
# Now we're wherever confirmation would have taken us
If you see record-not-found or Mongo DocumentNotFound errors, and you're sure you're passing the right ID parameter or whatever, it's probably because your test case is ending and the database cleaner is running before the last request is fully processed. If you're not testing anything on the page (e.g., page.should have_content...
) after you visit / click / submit, Capybara will end the test case and run the database cleaner right away, even if the last request is still not finished. Testing whether database changes have been made (e.g., Employee.find(id).should...
) won't cause it to wait for the request either. So -- make sure you test something on the page after the final visit / click / submit in a test case.
Use have_content
for text, not HTML. It will not match HTML. You might run into this if someone has put HTML tags in localized text, and then you test something like
page.should have_content( I18n.t( :my_text ) )
It won't find the content you're looking for, and your test will fail. You might be better off with something like:
page.body.should include( I18n.t( :my_text ) )
Or test something else!