Lee Longmore
2009-May-12 12:36 UTC
[rspec-users] How To Drive Out AJAX Functionality in a Rails View
I am new to RSpec and have just started to drive out my first Rails view using a spec. I have used the The RSpec Book (beta) to do the basic stuff like testing for the presence of a field but I am unsure where to start for driving out some AJAX functionality. In the view, I will have a text field that a user can enter a name into and then click on a link to check the availability of this name or otherwise. I plan to implement the check as an AJAX request, returning an HTML snippet or ''available'' or ''not available''. I would appreciate some help on what sort of examples one might write and the various mocks, stubs and helpers etc that can be used. Or alternatively a pointer to some existing information/tutorials on this topic. Thanks. mobile: +44(0)775 392 8067 home: +44(0) 208 8358256 email: lee_longmore at yahoo.co.uk -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://rubyforge.org/pipermail/rspec-users/attachments/20090512/9b678769/attachment.html>
Phlip
2009-May-12 13:33 UTC
[rspec-users] How To Drive Out AJAX Functionality in a Rails View
Lee Longmore wrote:> I am new to RSpec and have just started to drive out my first Rails view > using a spec. I have used the The RSpec Book (beta) to do the basic > stuff like testing for the presence of a field but I am unsure where to > start for driving out some AJAX functionality. > > In the view, I will have a text field that a user can enter a name into > and then click on a link to check the availability of this name or > otherwise. I plan to implement the check as an AJAX request, returning > an HTML snippet or ''available'' or ''not available''.gem install nokogiri rkelly assert2 ... require ''assert2/rjs'' specify ''a simple passing assertion works'' do xhr :get, :xhr_availability, :name => ''masone'' js = @response.body js.should send_js_to(:replace_html, ''label_7'', /available/) js.should send_js_to(:replace_html, ''label_7''){ span /available/ } end The first send_js_to just checks for a regexp to match the payload of the Element.update call. The second one uses {} to generate a Nokogiri Builder snippet of HTML, and match that. Here it''s just span, but it could have been more complex HTML. Google assert_xhtml for more on that.> I would appreciate some help on what sort of examples one might write > and the various mocks, stubs and helpers etc that can be used. Or > alternatively a pointer to some existing information/tutorials on this > topic.The RSpec community, in my exalted opinion, mocks too much! If you can''t use the real thing, it''s too coupled, so break it up! -- Phlip http://flea.sourceforge.net/resume.html
Phlip
2009-May-12 13:42 UTC
[rspec-users] How To Drive Out AJAX Functionality in a Rails View
Lee Longmore wrote:> I am new to RSpec and have just started to drive out my first Rails view > using a spec. I have used the The RSpec Book (beta) to do the basic > stuff like testing for the presence of a field but I am unsure where to > start for driving out some AJAX functionality.To test the onchange='''' of the field, start by pulling in the Test::Unit versions of the assertions: Spec::Runner.configure do |c| c.include Test::Unit::Assertions end Now use assert_xhtml to grab your edit field and return it as a Nokogiri node. This line does it for a <a href=''#''>All</a>: a = assert_xhtml{|x| x.a ''All'', :href => ''#'' } assert{ a[:onclick] =~ /new Ajax.Request.*xhr_run_all/ } .send_js_to is supposed to work in the second line, but I have not yet researched out how get rkelly to parse the Ajax.Request line. The point of using rkelly inside send_js_to (aka assert_rjs_) is it''s a real JavaScript lexer, not a Regexp, so when I get it working it will be very accurate! -- Phlip http://flea.sourceforge.net/resume.html
Mike Doel
2009-May-12 14:04 UTC
[rspec-users] How To Drive Out AJAX Functionality in a Rails View
On May 12, 2009, at 8:36 AM, Lee Longmore wrote:> I am new to RSpec and have just started to drive out my first Rails > view using a spec. I have used the The RSpec Book (beta) to do the > basic stuff like testing for the presence of a field but I am unsure > where to start for driving out some AJAX functionality.Check out Adam McCrea''s fork of webrat: http://github.com/adamlogic/webrat/tree/master It includes a submit_form_via_ajax method that I use to do this. It basically just forces Rails into treating the form request as asking for a .js response. There are limitations on what you can do with the response (e.g. inspecting the entire page is no longer possible), but you are able to look at the response body of the call and match it against regular expressions. So, I use features like: When I go to the homepage And I use a search term of "foo" And I press "search" And the edit_search_form is submitted via ajax Then the search results should have 2 bars with the critical step like: When /^the (.+) is submitted via ajax$/ do |form| submit_form_via_ajax form end I''ve left out a couple of things here (in particular, a step that fills in form fields to mimic javascript action), but this basic idea makes it possible to have acceptance tests for ajax based features that are written in the language of the customer and yet operate quickly (i.e. you don''t need to have selenium or something else like that involved to run this). The drawback of course is that it''s not really exercising the full end- to-end system. While I understand that this is frowned upon (and for good reason), in my case, I have decided that the speed of the tests (and thus my willingness to use them) makes up for the drawbacks involved. To limit my exposure, I''m working on including javascript unit tests that will ensure that the behavior I stub out above actually works as expected. Mike Doel
David Chelimsky
2009-May-12 14:07 UTC
[rspec-users] How To Drive Out AJAX Functionality in a Rails View
On Tue, May 12, 2009 at 8:33 AM, Phlip <phlip2005 at gmail.com> wrote:> Lee Longmore wrote: >> >> I am new to RSpec and have just started to drive out my first Rails view >> using a spec. I have used the The RSpec Book (beta) to do the basic stuff >> like testing for the presence of a field but I am unsure where to start for >> driving out some AJAX functionality. >> >> In the view, I will have a text field that a user can enter a name into >> and then click on a link to check the availability of this name or >> otherwise. I plan to implement the check as an AJAX request, returning an >> HTML snippet or ''available'' or ''not available''. > > gem install nokogiri rkelly assert2 > ... > require ''assert2/rjs'' > > ?specify ''a simple passing assertion works'' do > ? ?xhr :get, :xhr_availability, :name => ''masone'' > ? ?js = @response.body > ? ?js.should send_js_to(:replace_html, ''label_7'', /available/) > > ? ?js.should send_js_to(:replace_html, ''label_7''){ > ? ? ? ? ? ? ? ?span /available/ > ? ? ? ? ? ? ? ?} > ?end > > The first send_js_to just checks for a regexp to match the payload of the > Element.update call. The second one uses {} to generate a Nokogiri Builder > snippet of HTML, and match that. Here it''s just span, but it could have been > more complex HTML. Google assert_xhtml for more on that. > >> I would appreciate some help on what sort of examples one might write and >> the various mocks, stubs and helpers etc that can be used. Or alternatively >> a pointer to some existing information/tutorials on this topic. > > The RSpec community, in my exalted opinion, mocks too much! If you can''t use > the real thing, it''s too coupled, so break it up!Phlip, You could just say "be careful not to mock too much," which would be really good advice, but instead you make a generalizing and judgmental statement like this. When''s the last time you paired with someone in the RSpec community? Lee, Phlip has some really great ideas about some things, and assert2 is lovely, but based on several posts on this and other lists, I''d say he doesn''t really like RSpec, nor understand its underlying intent. So by all means listen to his advice, and by all means take advantage of assert2 for this particular problem, but please also understand that he is in no way the voice of the RSpec community. Cheers, David> > -- > ?Phlip > ?http://flea.sourceforge.net/resume.html > > _______________________________________________ > rspec-users mailing list > rspec-users at rubyforge.org > http://rubyforge.org/mailman/listinfo/rspec-users >
Lee
2009-May-12 14:09 UTC
[rspec-users] How To Drive Out AJAX Functionality in a Rails View
Thanks Philip. I should have added in my original post that I have included the Webrat::Matchers as instructed in The Rspec Book. Unless I have misunderstood you, it appears that RSpec with Webrat::Matchers do not support the driving out of AJAX functionality in views, hence the need to use Nokogiri. Is my understanding correct? Or is this your preferred approach but there are others? On May 12, 2:42?pm, Phlip <phlip2... at gmail.com> wrote:> Lee Longmore wrote: > > I am new to RSpec and have just started to drive out my first Rails view > > using a spec. I have used the The RSpec Book (beta) to do the basic > > stuff like testing for the presence of a field but I am unsure where to > > start for driving out some AJAX functionality. > > To test the onchange='''' of the field, start by pulling in the Test::Unit > versions of the assertions: > > ? ?Spec::Runner.configure do |c| > ? ? ?c.include Test::Unit::Assertions > ? ?end > > Now use assert_xhtml to grab your edit field and return it as a Nokogiri node. > This line does it for a <a href=''#''>All</a>: > > ? ? ?a = assert_xhtml{|x| ?x.a ''All'', :href => ''#'' ?} > ? ? ?assert{ a[:onclick] =~ /new Ajax.Request.*xhr_run_all/ } > > .send_js_to is supposed to work in the second line, but I have not yet > researched out how get rkelly to parse the Ajax.Request line. > > The point of using rkelly inside send_js_to (aka assert_rjs_) is it''s a real > JavaScript lexer, not a Regexp, so when I get it working it will be very accurate! > > -- > ? ?Phlip > ? ?http://flea.sourceforge.net/resume.html > > _______________________________________________ > rspec-users mailing list > rspec-us... at rubyforge.orghttp://rubyforge.org/mailman/listinfo/rspec-users
Matt Wynne
2009-May-12 15:04 UTC
[rspec-users] How To Drive Out AJAX Functionality in a Rails View
On 12 May 2009, at 15:07, David Chelimsky wrote:> Lee, > > Phlip has some really great ideas about some things, and assert2 is > lovely, but based on several posts on this and other lists, I''d say he > doesn''t really like RSpec, nor understand its underlying intent. So by > all means listen to his advice, and by all means take advantage of > assert2 for this particular problem, but please also understand that > he is in no way the voice of the RSpec community. > > Cheers, > DavidLee, One thing you might want to consider is looking at using a headless browser like ''celerity'' for testing your ajax code. This is quite a bit more involved for initial setup than using RSpec but will give you real confidence as you''re actually running your javascript inside a browser. There are quite a few people on this list who are doing this, using the ''progressive enhancement''[1] pattern to build a version of the page that works with raw HTML, then decorate it with javascript behaviour when the page loads. I''m not doing this myself in earnest, so I''ll say no more, but hopefully a couple of other people will chime in with some advice. [1]http://en.wikipedia.org/wiki/Progressive_enhancement Matt Wynne http://blog.mattwynne.net http://www.songkick.com
Lee
2009-May-12 15:06 UTC
[rspec-users] How To Drive Out AJAX Functionality in a Rails View
Thanks Mike. fyi, I am trying out Cucumber and Culerity for integration testing. Culerity provides for AJAX testing. Having written my first Cucumber (with Culerity) feature and set of scenarios, I was keen to then use RSpec to begin driving out the views, controllers etc so that I can eventually run the e2e Cucumber scenarios. On May 12, 3:04?pm, Mike Doel <m... at mikedoel.com> wrote:> On May 12, 2009, at 8:36 AM, Lee Longmore wrote: > > > I am new to RSpec and have just started to drive out my first Rails ? > > view using a spec. I have used the The RSpec Book (beta) to do the ? > > basic stuff like testing for the presence of a field but I am unsure ? > > where to start for driving out some AJAX functionality. > > Check out Adam McCrea''s fork of webrat: > > http://github.com/adamlogic/webrat/tree/master > > It includes a submit_form_via_ajax method that I use to do this. ?It ? > basically just forces Rails into treating the form request as asking ? > for a .js response. ?There are limitations on what you can do with the ? > response (e.g. inspecting the entire page is no longer possible), but ? > you are able to look at the response body of the call and match it ? > against regular expressions. ?So, I use features like: > > ? ? ?When I go to the homepage > ? ? ?And I use a search term of "foo" > ? ? ?And I press "search" > ? ? ?And the edit_search_form is submitted via ajax > ? ? ?Then the search results should have 2 bars > > with the critical step like: > > When /^the (.+) is submitted via ajax$/ do |form| > ? ?submit_form_via_ajax form > end > > I''ve left out a couple of things here (in particular, a step that ? > fills in form fields to mimic javascript action), but this basic idea ? > makes it possible to have acceptance tests for ajax based features ? > that are written in the language of the customer and yet operate ? > quickly (i.e. you don''t need to have selenium or something else like ? > that involved to run this). > > The drawback of course is that it''s not really exercising the full end- > to-end system. ?While I understand that this is frowned upon (and for ? > good reason), in my case, I have decided that the speed of the tests ? > (and thus my willingness to use them) makes up for the drawbacks ? > involved. ?To limit my exposure, I''m working on including javascript ? > unit tests that will ensure that the behavior I stub out above ? > actually works as expected. > > Mike Doel > > _______________________________________________ > rspec-users mailing list > rspec-us... at rubyforge.orghttp://rubyforge.org/mailman/listinfo/rspec-users
Lee
2009-May-12 15:33 UTC
[rspec-users] How To Drive Out AJAX Functionality in a Rails View
Thanks Matt. I have been trying out Cucumber and Culerity (Celerity) but rather than jump directly from Cucumber to coding the necessary views, controllers and models required for each scenario, I wanted to drive out the code using RSpec. So I''ve started to spec a view required by a scenario, and this is where I am confused about how I approach the AJAX aspects of the view in my specs.> One thing you might want to consider is looking at using a headless ? > browser like ''celerity'' for testing your ajax code. This is quite a ? > bit more involved for initial setup than using RSpec but will give you ? > real confidence as you''re actually running your javascript inside a ? > browser. There are quite a few people on this list who are doing this, ? > using the ''progressive enhancement''[1] pattern to build a version of ? > the page that works with raw HTML, then decorate it with javascript ? > behaviour when the page loads. > > I''m not doing this myself in earnest, so I''ll say no more, but ? > hopefully a couple of other people will chime in with some advice. > > [1]http://en.wikipedia.org/wiki/Progressive_enhancement > > Matt Wynnehttp://blog.mattwynne.nethttp://www.songkick.com > > _______________________________________________ > rspec-users mailing list > rspec-us... at rubyforge.orghttp://rubyforge.org/mailman/listinfo/rspec-users
Matt Wynne
2009-May-12 16:01 UTC
[rspec-users] How To Drive Out AJAX Functionality in a Rails View
On 12 May 2009, at 16:33, Lee wrote:> Thanks Matt. > > I have been trying out Cucumber and Culerity (Celerity) but rather > than jump directly from Cucumber to coding the necessary views, > controllers and models required for each scenario, I wanted to drive > out the code using RSpec. So I''ve started to spec a view required by a > scenario, and this is where I am confused about how I approach the > AJAX aspects of the view in my specs.If you''re using progressive enhancement though, I wouldn''t expect the views themselves to be any different - the code to add javascript behaviour is all in external js files. I''d personally recommend doing that over using the rails js generators that squirt behaviour into your onclick events. eugh.> >> One thing you might want to consider is looking at using a headless >> browser like ''celerity'' for testing your ajax code. This is quite a >> bit more involved for initial setup than using RSpec but will give >> you >> real confidence as you''re actually running your javascript inside a >> browser. There are quite a few people on this list who are doing >> this, >> using the ''progressive enhancement''[1] pattern to build a version of >> the page that works with raw HTML, then decorate it with javascript >> behaviour when the page loads. >> >> I''m not doing this myself in earnest, so I''ll say no more, but >> hopefully a couple of other people will chime in with some advice. >> >> [1]http://en.wikipedia.org/wiki/Progressive_enhancement >> >> Matt Wynnehttp://blog.mattwynne.nethttp://www.songkick.com >> >> _______________________________________________ >> rspec-users mailing list >> rspec-us... at rubyforge.orghttp://rubyforge.org/mailman/listinfo/rspec-users > _______________________________________________ > rspec-users mailing list > rspec-users at rubyforge.org > http://rubyforge.org/mailman/listinfo/rspec-usersMatt Wynne http://blog.mattwynne.net http://www.songkick.com
Phlip
2009-May-12 17:47 UTC
[rspec-users] How To Drive Out AJAX Functionality in a Rails View
David Chelimsky wrote:> You could just say "be careful not to mock too much," which would be > really good advice,Sorry; I thought I said that. This industry in general dislikes strong opinions... Mock on, everyone! > but instead you make a generalizing and judgmental> statement like this. When''s the last time you paired with someone in > the RSpec community?Well it''s not for want of trying! -- Phlip http://flea.sourceforge.net/resume.html
Lee
2009-May-13 07:47 UTC
[rspec-users] How To Drive Out AJAX Functionality in a Rails View
I found a potential solution from this blog: http://www.rubytutorials.net/2008/02/29/small-rspec-revelations-rjs/ In my spec for the view in which I want to include the AJAX functionality ("new.html.erb_spec.erb"), I have added a couple of Examples to drive out the some of the AJAX functionality: it "should render /Available/ if name does not exist" do @name_exists = false assigns[:name_exists] = @name_exists render "contexts/check.js.rjs" response.should have_rjs(:chained_replace_html, ''checkname'') do response.should have_text(/Available/) end end it "should render /Not available/ if name does not exist" do @name_exists = true assigns[:name_exists] = @name_exists render "contexts/check.js.rjs" response.should have_rjs(:chained_replace_html, ''checkname'') do response.should have_text(/Not available/) end end The rendered template "check.js.rjs" contains: if @name_exists page[''checkname''].update(''Not available'') else page[''checkname''].update(''Available'') end These examples pass and seem to achieve my objective of using the spec to drive out the required AJAX behaviour, or at least some of it. Though I suspect that this approach may have limitations for other types of AJAX functionality. At this stage, I am wondering whether it is worth trying to drive out any AJAX functionality at the point of writing RSpec view specs. Some replies seem to suggest the use of Cucumber with Culerity/Webrat/ Selenium and I read into this that one would bypass view specs for the AJAX related steps and just write the necessary view code (e.g. JavaScript or Rails Prototype helpers) to get the step to pass. Further thoughts appreciated. Thanks Lee. On 12 May, 18:47, Phlip <phlip2... at gmail.com> wrote:> David Chelimsky wrote: > > You could just say "be careful not to mock too much," which would be > > really good advice, > > Sorry; I thought I said that. This industry in general dislikes strong opinions... > > Mock on, everyone! > > ?> but instead you make a generalizing and judgmental > > > statement like this. When''s the last time you paired with someone in > > the RSpec community? > > Well it''s not for want of trying! > > -- > ? ?Phlip > ? ?http://flea.sourceforge.net/resume.html > > _______________________________________________ > rspec-users mailing list > rspec-us... at rubyforge.orghttp://rubyforge.org/mailman/listinfo/rspec-users
s.ross
2009-May-13 18:22 UTC
[rspec-users] How To Drive Out AJAX Functionality in a Rails View
Hi-- On May 13, 2009, at 12:47 AM, Lee wrote:> I found a potential solution from this blog: > http://www.rubytutorials.net/2008/02/29/small-rspec-revelations-rjs/ > > In my spec for the view in which I want to include the AJAX > functionality ("new.html.erb_spec.erb"), I have added a couple of > Examples to drive out the some of the AJAX functionality: ><snip> The one thing I would add is that Rails responds differently when it receives a post with XMLHttpHeaders than when these headers are not present. I typically put this in my spec_helper.rb and then I can include it where necessary. # spec_helper.rb module XmlHttpHelper def set_xhr_headers request.env[''HTTP_ACCEPT''] = ''application/json, text/javascript, */ *'' request.env[''HTTP_X_REQUESTED_WITH''] = ''XMLHttpRequest'' end end # things_controller_spec.rb describe ThingssController do include XmlHttpHelper it "should provide a not acceptable response if user is not appropriately related and it''s an xhr" do login_as(@unrelated_child.login, ''secret'') set_xhr_headers post :slug_collection, :name => ''bob'', :collection_name => ''my-things'' response.status.should eql(''406 Not Acceptable'') end end Just a thought...