tag:www.rhnh.net,2008:/webrat
Webrat - Xavier Shay's Blog
2009-09-17T17:08:26Z
Enki
Xavier Shay
notreal@rhnh.net
tag:www.rhnh.net,2008:Post/797
2009-05-18T16:30:00Z
2009-09-17T17:08:26Z
Selenium, webrat and the firefox beta
<p>*UPDATE: * Latest version of webrat (0.5.3, maybe earlier) includes a fixed version of selenium, so you shouldn’t need this hack.</p>
<p>I needed a few hacks to get selenium running with webrat.</p>
<p>First, make sure you are running at least 0.4.4 of webrat. Don’t make the same mistake I did and upgrade your gem version, but not the plugin installed in vendor/plugins.</p><table class="CodeRay"><tr>
<td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"><pre>1<tt>
</tt>2<tt>
</tt>3<tt>
</tt></pre></td>
<td class="code"><pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }">gem install webrat<tt>
</tt>gem install selenium-client<tt>
</tt>gem install bmabey-database_cleaner --source=http://gems.github.com<tt>
</tt></pre></td>
</tr></table>
<p>There is a trick to get Firefox 3.5 beta working. The selenium server package with webrat 0.4.4 only supports <span class="caps">FF 3</span>.0.*. Follow these instructions, patching the jar that is packaged with webrat (vendor/selenium-server.jar) so that the extensions that selenium uses will be valid for the new FF.</p><table class="CodeRay"><tr>
<td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"><pre>1<tt>
</tt>2<tt>
</tt>3<tt>
</tt>4<tt>
</tt>5<tt>
</tt>6<tt>
</tt>7<tt>
</tt>8<tt>
</tt>9<tt>
</tt><strong>10</strong><tt>
</tt>11<tt>
</tt>12<tt>
</tt>13<tt>
</tt>14<tt>
</tt>15<tt>
</tt>16<tt>
</tt>17<tt>
</tt>18<tt>
</tt>19<tt>
</tt><strong>20</strong><tt>
</tt>21<tt>
</tt>22<tt>
</tt>23<tt>
</tt>24<tt>
</tt></pre></td>
<td class="code"><pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }">cd vendor/ # In webrat dir<tt>
</tt>jar xf selenium-server.jar \<tt>
</tt>customProfileDirCUSTFFCHROME/extensions/readystate@openqa.org/install.rdf<tt>
</tt>jar xf selenium-server.jar \<tt>
</tt>customProfileDirCUSTFFCHROME/extensions/{538F0036-F358-4f84-A764-89FB437166B4}/install.rdf<tt>
</tt>jar xf selenium-server.jar \<tt>
</tt>customProfileDirCUSTFFCHROME/extensions/\{503A0CD4-EDC8-489b-853B-19E0BAA8F0A4\}/install.rdf <tt>
</tt>jar xf selenium-server.jar \<tt>
</tt>customProfileDirCUSTFF/extensions/readystate\@openqa.org/install.rdf <tt>
</tt>jar xf selenium-server.jar \<tt>
</tt>customProfileDirCUSTFF/extensions/\{538F0036-F358-4f84-A764-89FB437166B4\}/install.rdf<tt>
</tt><tt>
</tt>replace "3.0.*" "3.*" -- `find . | grep rdf`<tt>
</tt><tt>
</tt>jar uf selenium-server.jar \<tt>
</tt>customProfileDirCUSTFFCHROME/extensions/readystate@openqa.org/install.rdf<tt>
</tt>jar uf selenium-server.jar \<tt>
</tt>customProfileDirCUSTFFCHROME/extensions/{538F0036-F358-4f84-A764-89FB437166B4}/install.rdf<tt>
</tt>jar uf selenium-server.jar \<tt>
</tt>customProfileDirCUSTFFCHROME/extensions/\{503A0CD4-EDC8-489b-853B-19E0BAA8F0A4\}/install.rdf <tt>
</tt>jar uf selenium-server.jar \<tt>
</tt>customProfileDirCUSTFF/extensions/readystate\@openqa.org/install.rdf <tt>
</tt>jar uf selenium-server.jar \<tt>
</tt>customProfileDirCUSTFF/extensions/\{538F0036-F358-4f84-A764-89FB437166B4\}/install.rdf<tt>
</tt></pre></td>
</tr></table>
<p>(hat tip to <a href="http://www.spacevatican.org/2008/9/27/selenium-and-firefox-3">space vatican</a>)</p>
<p>I haven’t been able to get Safari working yet.</p>
<p>I want to run selenium tests besides normal webrat tests, so I created a new environment “acceptance” that I can run tests under. Modify your test helper file:</p><table class="CodeRay"><tr>
<td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"><pre>1<tt>
</tt>2<tt>
</tt>3<tt>
</tt>4<tt>
</tt>5<tt>
</tt>6<tt>
</tt>7<tt>
</tt>8<tt>
</tt></pre></td>
<td class="code"><pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"><span class="c"># test/test_helper.rb</span><tt>
</tt><span class="co">ENV</span>[<span class="s"><span class="dl">"</span><span class="k">RAILS_ENV</span><span class="dl">"</span></span>] ||= <span class="s"><span class="dl">"</span><span class="k">test</span><span class="dl">"</span></span><tt>
</tt>raise <span class="s"><span class="dl">"</span><span class="k">Can't run tests in </span><span class="il"><span class="idl">#{</span><span class="co">ENV</span>[<span class="s"><span class="dl">'</span><span class="k">RAILS_ENV</span><span class="dl">'</span></span>]<span class="idl">}</span></span><span class="k"> environment</span><span class="dl">"</span></span> <span class="r">unless</span> <span class="s"><span class="dl">%w(</span><span class="k">test acceptance</span><span class="dl">)</span></span>.include?(<span class="co">ENV</span>[<span class="s"><span class="dl">"</span><span class="k">RAILS_ENV</span><span class="dl">"</span></span>])<tt>
</tt><tt>
</tt>require <span class="s"><span class="dl">'</span><span class="k">webrat</span><span class="dl">'</span></span><tt>
</tt>require <span class="s"><span class="dl">"</span><span class="k">test/env/</span><span class="il"><span class="idl">#{</span><span class="co">ENV</span>[<span class="s"><span class="dl">"</span><span class="k">RAILS_ENV</span><span class="dl">"</span></span>]<span class="idl">}</span></span><span class="dl">"</span></span><tt>
</tt><tt>
</tt><span class="c"># ...</span><tt>
</tt></pre></td>
</tr></table>
<table class="CodeRay"><tr>
<td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"><pre>1<tt>
</tt>2<tt>
</tt>3<tt>
</tt>4<tt>
</tt>5<tt>
</tt>6<tt>
</tt>7<tt>
</tt></pre></td>
<td class="code"><pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"><span class="c"># test/env/test.rb</span><tt>
</tt>require <span class="s"><span class="dl">'</span><span class="k">webrat/rails</span><span class="dl">'</span></span><tt>
</tt><tt>
</tt><span class="co">Webrat</span>.configure <span class="r">do</span> |config|<tt>
</tt> config.mode = <span class="sy">:rails</span><tt>
</tt> config.open_error_files = <span class="pc">false</span><tt>
</tt><span class="r">end</span><tt>
</tt></pre></td>
</tr></table>
<table class="CodeRay"><tr>
<td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"><pre>1<tt>
</tt>2<tt>
</tt>3<tt>
</tt>4<tt>
</tt>5<tt>
</tt>6<tt>
</tt>7<tt>
</tt>8<tt>
</tt>9<tt>
</tt><strong>10</strong><tt>
</tt>11<tt>
</tt>12<tt>
</tt>13<tt>
</tt>14<tt>
</tt>15<tt>
</tt>16<tt>
</tt>17<tt>
</tt>18<tt>
</tt>19<tt>
</tt><strong>20</strong><tt>
</tt>21<tt>
</tt>22<tt>
</tt>23<tt>
</tt>24<tt>
</tt>25<tt>
</tt>26<tt>
</tt>27<tt>
</tt>28<tt>
</tt>29<tt>
</tt><strong>30</strong><tt>
</tt>31<tt>
</tt>32<tt>
</tt>33<tt>
</tt></pre></td>
<td class="code"><pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"><span class="c"># test/env/acceptance.rb</span><tt>
</tt>require <span class="s"><span class="dl">'</span><span class="k">webrat/selenium/silence_stream</span><span class="dl">'</span></span><tt>
</tt>require <span class="s"><span class="dl">'</span><span class="k">webrat/selenium</span><span class="dl">'</span></span><tt>
</tt>require <span class="s"><span class="dl">'</span><span class="k">test/selenium_helpers</span><span class="dl">'</span></span><tt>
</tt>require <span class="s"><span class="dl">'</span><span class="k">test/element_helpers</span><span class="dl">'</span></span><tt>
</tt><tt>
</tt><span class="c"># Required because we aren't isolating tests inside a transaction</span><tt>
</tt>require <span class="s"><span class="dl">'</span><span class="k">database_cleaner</span><span class="dl">'</span></span><tt>
</tt><span class="co">DatabaseCleaner</span>.strategy = <span class="sy">:truncation</span><tt>
</tt><tt>
</tt><span class="co">Webrat</span>.configure <span class="r">do</span> |config|<tt>
</tt> config.mode = <span class="sy">:selenium</span><tt>
</tt><span class="r">end</span><tt>
</tt><tt>
</tt><span class="r">class</span> <span class="cl">ActionController::IntegrationTest</span><tt>
</tt> <span class="pc">self</span>.use_transactional_fixtures = <span class="pc">false</span> <span class="c"># Necessary, otherwise selenium will never see any changes!</span><tt>
</tt><tt>
</tt> setup <span class="r">do</span> |session|<tt>
</tt> session.host! <span class="s"><span class="dl">"</span><span class="k">localhost:3001</span><span class="dl">"</span></span><tt>
</tt> <span class="r">end</span><tt>
</tt><tt>
</tt> teardown <span class="r">do</span><tt>
</tt> <span class="co">DatabaseCleaner</span>.clean<tt>
</tt> <span class="r">end</span><tt>
</tt><span class="r">end</span><tt>
</tt><tt>
</tt><span class="c"># Hack: webrat requires this, even though we're not using rspec</span><tt>
</tt><span class="r">module</span> <span class="cl">Spec</span><tt>
</tt> <span class="r">module</span> <span class="cl">Expectations</span><tt>
</tt> <span class="r">class</span> <span class="cl">ExpectationNotMetError</span> < <span class="co">Exception</span><tt>
</tt> <span class="r">end</span><tt>
</tt> <span class="r">end</span><tt>
</tt><span class="r">end</span><tt>
</tt></pre></td>
</tr></table>
<table class="CodeRay"><tr>
<td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"><pre>1<tt>
</tt>2<tt>
</tt>3<tt>
</tt>4<tt>
</tt>5<tt>
</tt>6<tt>
</tt>7<tt>
</tt>8<tt>
</tt>9<tt>
</tt><strong>10</strong><tt>
</tt>11<tt>
</tt></pre></td>
<td class="code"><pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"><span class="c"># lib/tasks/test.rake</span><tt>
</tt>namespace <span class="sy">:test</span> <span class="r">do</span><tt>
</tt> task <span class="sy">:force_acceptance</span> <span class="r">do</span><tt>
</tt> <span class="co">ENV</span>[<span class="s"><span class="dl">"</span><span class="k">RAILS_ENV</span><span class="dl">"</span></span>] = <span class="s"><span class="dl">'</span><span class="k">acceptance</span><span class="dl">'</span></span><tt>
</tt> <span class="r">end</span><tt>
</tt><tt>
</tt> <span class="co">Rake</span>::<span class="co">TestTask</span>.new(<span class="sy">:acceptance</span> => <span class="sy">:force_acceptance</span>) <span class="r">do</span> |t|<tt>
</tt> t.test_files = <span class="co">FileList</span>[<span class="s"><span class="dl">'</span><span class="k">test/acceptance/*_test.rb</span><span class="dl">'</span></span>]<tt>
</tt> t.verbose = <span class="pc">true</span><tt>
</tt> <span class="r">end</span><tt>
</tt><span class="r">end</span><tt>
</tt></pre></td>
</tr></table>
<p>Notes</p>
<ul>
<li>selenium and javascript helpers are from <a href="http://pivotallabs.com/users/patn/blog/articles/717-run-javascript-in-selenium-tests-easily">pivotallabs pat</a>, they’re really handy for testing visibilty of <span class="caps">DOM</span> elements</li>
<li>there’s some magic in webrat to conditionally require <code>silence_stream</code> based on something in active_support. I don’t understand it quite enough, but requiring it explicitly was necessary to get things running for me</li>
<li>webrat/selenium assumes some classes are loaded that only happens if you’re using rspec. I’m not, so stubbed out the ExpectationNotMetError (it is only referred to in a rescue block).</li>
<li><code>rake test:acceptance</code> runs the selenium tests. Running acceptance tests directly as a ruby script runs them using normal webrat – this is actually handy when writing tests because you get a quicker turnaround.</li>
<li>to pause selenium mid test run (to see wtf is going on), just add <code>gets</code> at the appropriate line in your test</li>
</ul>