<div class="gmail_quote">I&#39;ve had really iffy luck with Selenium plugins in the past (selenium-on-rails, seleniumfu_rc, selenium_rc, etc.) so I&#39;ve started to write a RailsSeleniumStory. I also had to remove the ActiveRecordSafetyListener in my efforts.</div>
<div class="gmail_quote"><br></div><div class="gmail_quote">The RailsSeleniumStory is a part of the mhs_testing plugin [0] and it provides higher level helpers. For example I love how form-test-helper is used to select and submit forms:</div>
<div class="gmail_quote"><br></div><div class="gmail_quote">&nbsp;&nbsp; # option &nbsp;1</div><div class="gmail_quote">&nbsp;&nbsp; form = select_form &#39;expense_form&#39;</div><div class="gmail_quote">&nbsp;&nbsp; form.expense.amount = 12.99</div><div class="gmail_quote">
&nbsp;&nbsp; form.submit</div><div class="gmail_quote"><br></div><div class="gmail_quote">&nbsp;&nbsp; # option 2</div><div class="gmail_quote">&nbsp;&nbsp; submit_form &#39;expense_form&#39; do |form|</div><div class="gmail_quote">&nbsp;&nbsp; &nbsp; &nbsp;form.expense.amount = 12.99</div>
<div class="gmail_quote">&nbsp;&nbsp; &nbsp; &nbsp;form.expense.category_id = 2</div><div class="gmail_quote">&nbsp;&nbsp; &nbsp; &nbsp;form.expense.comments = &quot;map for trip&quot;</div><div class="gmail_quote">&nbsp;&nbsp; end</div><div class="gmail_quote"><br></div>
<div class="gmail_quote">You can use this same syntax within RailsSeleniumStories. Right now you can also use &quot;have_tag&quot; and &quot;with_tag&quot; matchers with Selenium. It supports basic matching (I wouldn&#39;t get to crazy with nesting or lots of assert-select/have-tag options), but it will be supporting more options shortly.</div>
<div class="gmail_quote"><br></div><div class="gmail_quote">So your login example could just look like:</div><div class="gmail_quote"><br></div><div class="gmail_quote">&nbsp;&nbsp; Given(&#39;log in as a admin user&#39;)</div><div class="gmail_quote">
&nbsp;&nbsp; &nbsp; &nbsp; open &quot;/admin/login&quot; &nbsp; &nbsp;&nbsp;</div><div class="gmail_quote">&nbsp;&nbsp; &nbsp; &nbsp; submit_form &quot;login_form&quot; do |form|</div><div class="gmail_quote">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;form.login = &#39;developer&#39;</div><div class="gmail_quote">
&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;form.password = &#39;test&#39;</div><div class="gmail_quote">&nbsp;&nbsp; &nbsp; &nbsp;end<br></div><div class="gmail_quote">&nbsp;&nbsp; end</div><div class="gmail_quote"><br></div><div class="gmail_quote">Which IMO I really like because if you need variations of that you can pull out a helper method like:</div>
<div class="gmail_quote">&nbsp;&nbsp;&nbsp;</div><div class="gmail_quote">&nbsp;&nbsp; def submit_login_form(user, password=&#39;test&#39;)</div><div class="gmail_quote">&nbsp;&nbsp; &nbsp; &nbsp;submit_form &quot;login_form&quot; do |form|</div><div class="gmail_quote">
&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;form.login = user.login</div><div class="gmail_quote">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;form.password = passsword</div><div class="gmail_quote">&nbsp;&nbsp; &nbsp; &nbsp;end</div><div class="gmail_quote">&nbsp;&nbsp; end</div><div class="gmail_quote"><br></div><div class="gmail_quote">
And you could push your open into a helper as well:</div><div class="gmail_quote">&nbsp;&nbsp; &nbsp;def go_to_login_page</div><div class="gmail_quote">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;open &quot;/admin/login&quot;</div><div class="gmail_quote">&nbsp;&nbsp; &nbsp;end</div><div class="gmail_quote">
<br></div><div class="gmail_quote">And now your Given could look like:</div><div class="gmail_quote"><div class="gmail_quote">&nbsp;&nbsp; Given(&#39;log in as a admin user&#39;)</div><div class="gmail_quote">&nbsp;&nbsp; &nbsp; &nbsp; go_to_login_page</div>
<div class="gmail_quote">&nbsp;&nbsp; &nbsp; &nbsp; submit_login_form @user, &#39;test&#39;</div><div class="gmail_quote">&nbsp;&nbsp; end<br></div><div class="gmail_quote"><br></div><div class="gmail_quote">Now granted submit_form and select_form both take a form&#39;s id, so each of your forms need to have one.</div>
</div><div class="gmail_quote"><br></div><div class="gmail_quote">If you are interested and have the time please check it out.&nbsp;Granted it&#39;s in its infancy and there&#39;s not a whole lot of docs right now (there is a README.Selenium for instructions on how-to setup in your project), but you can find me on GTalk or in <a href="http://irc.freenode.net">irc.freenode.net</a> (zdennis) and of course right here on the rspec ML. I am have 33 scenarios using the RailsSeleniumStory,</div>
<div class="gmail_quote"><br></div><div class="gmail_quote">ttyl,</div><div class="gmail_quote"><br></div><div class="gmail_quote">Zach</div><div class="gmail_quote"><br></div><div class="gmail_quote">0 -&nbsp;<a href="http://github.com/mvanholstyn/mhs_testing/tree/master">http://github.com/mvanholstyn/mhs_testing/tree/master</a></div>
<div class="gmail_quote"><br></div><div class="gmail_quote"><br></div><div class="gmail_quote"><br></div><div class="gmail_quote">On Thu, May 8, 2008 at 8:22 AM, Joseph Wilk &lt;<a href="mailto:lists@ruby-forum.com">lists@ruby-forum.com</a>&gt; wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">I have been using Rspec stories with Webrat feeling very productive and<br>
happy.<br>
<br>
Then I needed to do something with Selenium (Webrat could have done what<br>
I needed but it does not yet have the functionality).<br>
<br>
Selenium-core as part of a rails plugin looked nice but did not seem to<br>
fit with rspec stories. So I went the Selenium-rc route.<br>
<br>
Since Selenium uses a separate instance of rails<br>
(<a href="http://www.nabble.com/stories-with-selenium-and-the-db-td16190686.html" target="_blank">http://www.nabble.com/stories-with-selenium-and-the-db-td16190686.html</a>)<br>
I had to turn off the ActiveRecordSafetyListener used in rspec to make<br>
sure the db writes committed.<br>
<br>
Which in turn left me having to manually cleanup my selenium stories :(<br>
<br>
So that required writing a new, rather gritty scenario listener which<br>
dealt with the cleaning operation. It has to do lots of horrible things<br>
like remove all listeners for a selenium story and then re-add them all<br>
for the others stories.<br>
<br>
*Code Extract*<br>
<br>
def story_ended(title, narrative)<br>
 &nbsp;case title<br>
 &nbsp;when &#39;Edit a page&#39;<br>
<br>
 &nbsp; &nbsp;#We have finished the selenium story<br>
 &nbsp; &nbsp;$selenium_driver.stop<br>
<br>
 &nbsp; &nbsp;#Do we need to re-add some listeners<br>
 &nbsp; &nbsp;if !@listener_reloaded<br>
 &nbsp; &nbsp; &nbsp;Spec::Story::Runner.scenario_runner.add_listener(ActiveRecordSafetyListener.instance)<br>
 &nbsp; &nbsp; &nbsp; &nbsp;@listener_reloaded=true<br>
 &nbsp; &nbsp;end<br>
 &nbsp;end<br>
end<br>
<br>
<br>
I had to duplicate a lot of the story steps since now any previous<br>
post/gets did not work since they post to the test instance and not the<br>
selenium rails instance.<br>
<br>
I also needed to invoke against the selenium driver so even when the<br>
steps would work I had to duplicate them with<br>
$selenium_driver.do_something()<br>
<br>
<br>
This nice Given:<br>
<br>
 &nbsp; &nbsp;Given(&#39;log in as a admin user&#39;)<br>
 &nbsp; &nbsp; &nbsp;post &#39;/admin/sessions/create&#39;, :login =&gt; @user.login, :password =&gt;<br>
@user.password<br>
 &nbsp; &nbsp;end<br>
<br>
Being duplicated with this<br>
<br>
 &nbsp; &nbsp;Given(&#39;log in as a admin user&#39;)<br>
 &nbsp; &nbsp; &nbsp;$selenium_driver.open &#39;/admin/login&#39;<br>
 &nbsp; &nbsp; &nbsp;$selenium_driver.type &#39;login&#39;, &#39;developer&#39;<br>
 &nbsp; &nbsp; &nbsp;$selenium_driver.type &#39;password&#39;, &#39;test&#39;<br>
 &nbsp; &nbsp; &nbsp;$selenium_driver.click &#39;commit&#39;<br>
 &nbsp; &nbsp;end<br>
<br>
After some very painful testing and a lot of time I got my Selenium-rc<br>
and Webrat stories working. This experience really opened my eyes to the<br>
big void introduced by Selenium-rc running outside of the test instance.<br>
<br>
This has made me wonder whether I should have rspec stories stepping<br>
outside of the test rails instance to drive Selenium tests.<br>
<br>
Has anyone managed to make this process easier?<br>
<br>
I&#39;m hoping I&#39;m doing something silly which is making it all harder!<br>
<br>
Is it feasible to bring selenium into the test rails instances?<br>
<br>
Is it just always going to be painful?<br>
<br>
I was skipping along having a lot of fun with stories and Webrat, now<br>
I&#39;m face down in a puddle of mud, dreading that Selenium moment.<br>
<br>
--<br>
Joseph Wilk<br>
<a href="http://www.joesniff.co.uk" target="_blank">http://www.joesniff.co.uk</a><br>
<font color="#888888">--<br>
Posted via <a href="http://www.ruby-forum.com/" target="_blank">http://www.ruby-forum.com/</a>.<br>
_______________________________________________<br>
rspec-users mailing list<br>
<a href="mailto:rspec-users@rubyforge.org">rspec-users@rubyforge.org</a><br>
<a href="http://rubyforge.org/mailman/listinfo/rspec-users" target="_blank">http://rubyforge.org/mailman/listinfo/rspec-users</a><br>
</font></blockquote></div><br><br clear="all"><br>-- <br>Zach Dennis<br><a href="http://www.continuousthinking.com">http://www.continuousthinking.com</a>