Rails 3.1, capybara-webkit, how to execute javascript inside a link?

Is it possible to execute javascript in a link with capybara click_link('next_page') ?

The link is as follows:

 <a onclick="$('#submit_direction').attr('value', '1');$('#quizForm').submit()" id="next_page" href="#">Next Question</a> 

I read in capybara on github that I can submit the form by clicking on the submit button as follows:

 click_on('Submit Answer') 

But, in my case, I need to submit the form using javascript to the link, so how to check the link that has javascript inside? click_link('next_page') not enough?

EDIT

after installation :js=> true my test looks like this:

  it "should pass when answering all correct", :js=>true do login_as(student, :scope => :student) visit ("/student_courses") #page.execute_script("$('#submit_direction').attr('value', '1');$('#quizForm').submit()") trace "HTML:------------", page.html end 

Before: js => true, I could normally visit the page. But I noticed that the page cannot be visited after: js => true, here is the error I received after visiting the page:

GET "/ student_courses" for 127.0.0.1 on 2012-01-23 06:29:26 +0200 (5010.7ms) UPDATE "students" SET "last_sign_in_at" = '2012-01-23 04: 29: 26.274285', was launched current_sign_in_at "= '2012-01-23 04: 29: 26.274285'," last_sign_in_ip "= '127.0.0.1'," current_sign_in_ip "= '127.0.0.1'," sign_in_count "= 1," updated_at "= '2012-01 -23 04: 29: 26.276279 "WHERE" students "." Id "= 1 SQLite3 :: BusyException: database is locked: UPDATE" students "SET" last_sign_in_at "= '2012-01-23 04: 29: 26.274285'," current_sign_in_at "= '2012-01-23 04: 29: 26.274285 ', "last_sign_in_ip" =' 127.0.0.1 ', "current_sign_in_ip" =' 127.0.0.1 ', "sign_in_count" = 1, "updated_at" =' 2012-01-23 04: 29: 26.276279 “WHERE“ students ”." Id "= 1 HTML: ------------__ Internal Server Error

Internal Server Error

cannot roll back a transaction - SQL queries are executed
WEBrick / 1.3.1 (Ruby / 1.9.3 / 2011-10-30) at 127.0.0.1haps4718

So why is SQLite3 :: BusyException: now the database is locked ?!

+2
source share
3 answers

I just spent 8 hours solving a similar problem, and I found a solution. Fix is ​​so simple that I could cry.

First diagnosis

The reason you get " SQLite3::BusyException: database is locked " is because you are running an asynchronous stream, namely a view form that ends with the "database record" race going to the main test stream. In fact, as your test is already completed and your “after each” database cleanup procedure (defined in your spec_helper) is performed, the form action just started trying to run business logic (which is based on the data that your test after: each the hook is busy destroying).

This problem is much more common in tests that click on the AJAX POST button and then end without claiming something about changing the view.

Secondly, the correction

As it turns out, Capybara is designed to “synchronize” all your requests. But only if you implicitly allow this. Please note that after submitting your form you do not see Capybara on your page. Therefore, he thinks that everything is ready, and your data goes beyond the scope (while the form submission thread hangs in the background.)

Just add the following line of code at the end of the test, and it should suddenly work:

 page.should_not have_content "dude, you forgot to assert anything about the view" 

Third, make it beautiful

Do not use execute_script. For Kapiba. But also do not rely on "click_on" because it is not a great abstraction. You must know too much about its internal elements. Instead, use a CSS selector like this:

 page.find("#submit_button").click 

And one more thing: your test should not try to manipulate the DOM. A good Selenium test suggests that it should follow the same steps as a regular user.

So in conclusion

 it "should pass when answering all correct", :js => true do login_as(student, :scope => :student) visit ("/student_courses") page.find(".my-js-enabled-button").click page.find("#submit_button").click # Synchronizes your view to your database state before exiting test, # Therefore makes sure no threads remain unfinished before your teardown. page.should_not have_content "dude, you forgot to expect / assert anything." end 
+8
source

To expand Alex's comment, Capybara will not run JS unless it is explicitly enabled for these tests.

To do this, use: js => true for any described block or a separate test, for example.

 describe "in such and such a context", :js => true do # some stuff end 
+1
source

It should work. with capybara, you are essentially testing your application through a browser and it will behave the same.

-1
source

All Articles