FactoryGirl.create and :js => true

I’m trying to test a basic search functionality on my homepage that uses jQuery autocomplete. This is the test I’ve got at this point:

context "when they enter a city with providers in the search box and don't click search" do
	scenario "they're shown that city in an autosuggest list", :js => true do
	example_page = FactoryGirl.create(:page)

	visit root_path
	find('.homepage_search_box').set "Chicago"
	page.execute_script("$('input#search').trigger('focus')")
	page.execute_script("$('input#search').trigger('keydown')")

	sleep(2)
	expect(page).to have_content  "Chicago, IL"
end

end

When the test runs, it fails to find the “page” I supposedly created using a Factory (model: Page, name: “Chicago, IL”) in the database, and so offers no autoocomplete suggestions. However, this same basic functionality works (i.e., the test passes) for the case where the user clicks search instead of waits for autocomplete to work. The basic difference is the :js => true option.

In this blog post I came across the idea that :js => true causes selenium to “run in a different thread” and in that thread, my Factory for Page has not been created.

How do I deal with this issue appropriately? From some other posts here on upcase, it looks like I need to implement some logic surrounding transactional fixtures and/or database_cleaner.

Thanks in advance for your help!

–Dean

Rails defaults to using transactional fixtures, so when a test finishes, it triggers a rollback of the database to its previous state. This ensures the database remains in a clean state between tests, but prevents any changes being visible to Capybara drivers running in a separate process, such as Selenium, Poltergeist or capybara-webkit.

So when testing JS, the common approach is to disable transactions, and clean the database afterwards, using the database_cleaner gem. You can see this in the code for Upcase itself:

2 Likes

Thanks Andy, this worked perfectly and my homepage autosuggest test now passes!