<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>maxheapsize.com &#187; selenium ide</title>
	<atom:link href="http://maxheapsize.com/tag/selenium-ide/feed/" rel="self" type="application/rss+xml" />
	<link>http://maxheapsize.com</link>
	<description>Oliver Wehrens on Programming and Agile</description>
	<lastBuildDate>Tue, 14 Jun 2011 20:41:41 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.1.2</generator>
		<item>
		<title>Using Selenium2 for web testing (and not Selenium IDE)</title>
		<link>http://maxheapsize.com/2010/01/04/using-selenium-2-for-web-testing/</link>
		<comments>http://maxheapsize.com/2010/01/04/using-selenium-2-for-web-testing/#comments</comments>
		<pubDate>Mon, 04 Jan 2010 05:38:15 +0000</pubDate>
		<dc:creator>Oliver Wehrens</dc:creator>
				<category><![CDATA[Web]]></category>
		<category><![CDATA[selenium]]></category>
		<category><![CDATA[selenium ide]]></category>
		<category><![CDATA[selenium2]]></category>
		<category><![CDATA[test]]></category>
		<category><![CDATA[webdriver]]></category>

		<guid isPermaLink="false">http://maxheapsize.com/?p=393</guid>
		<description><![CDATA[Selenium IDE Selenium is well know for automatic testing web pages. It does support many browsers, operating systems and languages. A Selenium IDE exists to aid you creating automated tests. It is possible to write extensions in JavaScript to have data driven tests. If you organize your selenium tests in a way that you split [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fmaxheapsize.com%2F2010%2F01%2F04%2Fusing-selenium-2-for-web-testing%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fmaxheapsize.com%2F2010%2F01%2F04%2Fusing-selenium-2-for-web-testing%2F&amp;source=owehrens&amp;style=normal&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<h3>Selenium IDE</h3>
<p><a href="http://seleniumhq.org">Selenium</a> is well know for automatic testing web pages. It does support many <a href="http://seleniumhq.org/about/platforms.htm">browsers, operating systems and languages<a/>. A <a href="http://seleniumhq.org/projects/ide/">Selenium IDE</a> exists to aid you creating automated tests. </p>
<div class="wp-caption alignleft" style="width: 313px"><img alt="Selenium" src="http://maxheapsize.com/static/selenium.png" title="Selenium IDE" width="303" height="177" /><p class="wp-caption-text">Selenium IDE</p></div>
<p>It is possible to write extensions in JavaScript to have data driven tests. If you organize your selenium tests in a way that you split  the pages and forms in components, you can  load up new data for the tests (written in xml) to fill out forms differently for each use case. The Selenium IDE will be of a great help here since you start develop the tests in the IDE and later &#8216;just&#8217; parametrize the pages. With a couple of more javascript magic you can run these as well in <a href="http://seleniumhq.org/projects/remote-control/">Selenium Remote Control</a> (Selenium RC for short). This even works for running  the tests in continuous integration systems like Hudson or Teamcity.</p>
<p>Great Stuff.</p>
<h3>The problem.</h3>
<p>The drawback coding up your tests with the Selenium IDE is: <b>HTML</b>.  </p>
<p>You will end up with some test suites including many test scenarios. It will be one big ball of </p>
<pre class="brush: xml; title: ;">
&lt;tr&gt;
  &lt;td&gt;type&lt;/td&gt;
  &lt;td&gt;accountnumber:Value&lt;/td&gt;
  &lt;td&gt;82892892811&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
  &lt;td&gt;type&lt;/td&gt;
  &lt;td&gt;accountAmount:Value&lt;/td&gt;
  &lt;td&gt;2345.33&lt;/td&gt;
&lt;/tr&gt;
</pre>
<p>You will build components and you will end up with GotoIf and Label statements. Back to Basic programming from the 80ties. Without more javascript extensions you also can&#8217;t reuse combinations of scenarios. </p>
<p>While this works pretty ok: I&#8217;m a programmer and do have a <strong>problem</strong> with the <strong>quality of the produced code</strong>. It&#8217;s <strong>easy to mess up</strong>. It&#8217;s <strong>not safe for refactoring</strong>. To extend functionality you need to have javascript knowledge. Depending on your company profile (e.g. java shop) , this might be a problem.  Having a dedicated tester on the team certainly helps to overcome these obstacles, but if everybody in the team just once in a while looks into the Selenium IDE tests, the quality and the reliability of the code will not improve. Not to mention all the <strong>copy and paste</strong>. Been there, done that.</p>
<h3>Selenium 2</h3>
<p>A much nicer approach for me would be something like this:</p>
<pre class="brush: java; title: ;">
WebDriver driver  = new FirefoxDriver();
AppWebTest test = new AppWebTest(driver, &quot;http://myapp.com/login&quot;);
LoggedInUser user = test.login(&quot;user&quot;, &quot;password&quot;);
Account account = user.createNewAccount(&quot;DemoAccount&quot;);
account.addPerson(PersonFactory.createPersonWithNoIncome());
...
account.verify();
</pre>
<p>This would log in a user, creates an account and assigns a person to it. Everybody could <strong>read and understand</strong> it. Furthermore you can easily reuse components and logic. I would imagine that creating a DSL, matchers and finders is everything one would need to have a very nice test scenario.</p>
<p>All that is already possible with Selenium 1 and the language bindings (more or less). </p>
<p>Just with the release of the first alpha of Selenium 2 mid december 2009 it became just a little bit easier.</p>
<p>Selenium 2 is the <strong>combined effort</strong> of Google&#8217;s Webdriver and Selenium. Webdriver tries to <a href="http://google-opensource.blogspot.com/2009/05/introducing-webdriver.html">tackle</a> Seleniums problems with Javascript and the security model as well as the complex Selenium RC API. </p>
<blockquote><p>
Selenium is written in JavaScript which causes a significant weakness: browsers impose a pretty strict security model on any JavaScript that they execute in order to protect a user from malicious scripts.<br />
&#8230;<br />
Additionally, being a mature product, the API for Selenium RC has grown over time, and as it has done so it has become harder to understand how best to use it. For example, it&#8217;s not immediately obvious whether you should be using &#8220;type&#8221; instead of &#8220;typeKeys&#8221; to enter text into a form control. Although it&#8217;s a question of aesthetics, some find the large API intimidating and difficult to navigate.
</p></blockquote>
<p>Webdriver does not use JavaScript to control the web browser but <strong>uses native controls</strong>, e.g. an extension for Firefox or the native automation extensions of IE. Furthermore it introduces an object based API instead of following Seleniums directory based approach.</p>
<p>So given the above example the login method would look something like this:</p>
<pre class="brush: java; title: ;">
 public LoggedInUser login(String userName, String password) {
    driver.get(url);
    driver.findElement(By.id(&quot;user&quot;)).sendKeys(userName);
    driver.findElement(By.id(&quot;password&quot;)).sendKeys(password);
    driver.findElement(By.id(&quot;login&quot;)).click();

    LoggedInUser user = new LoggedInUser(driver);

    WebElement startPage = driver.findElement(By.id(&quot;startPage&quot;));

    assertThat(startPage().getText()).isEqualTo(&quot;Start&quot;);
    return user;
  }
</pre>
<p>You can take this to any level. It took me just a few hours to model the above use case with componentized input elements. </p>
<p>With a bit more abstraction addPerson looks something like the following code. Whatever is needed to add a person to an account will be replayed. This is what Selenium IDE would normally do.</p>
<pre class="brush: java; title: ;">
public void addPerson(Person person) {
    jumpToAccountOverView();
    clickOnLink(&quot;menu:Overview&quot;);
    clickOnLink(&quot;table_personTable:link_newPerson&quot;);

    inputGuiElement(person.getTitle());
    inputGuiElement(person.getLastName());
...
    clickSave();
</pre>
<p>And now for the best part. You <strong>don&#8217;t really need a real web browser</strong>. Selenium 2 supports 4 WebDriver: </p>
<ul>
<li>Firefox</li>
<li>Chrome</li>
<li>Internet Explorer (on Windows)</li>
<li>HtmlUnit</li>
</ul>
<h3>HtmlUnit</h3>
<p>With enabled JavaScript on HtmlUnit (it uses Rhino, so not all JavaScript tricks might work, could be a drawback depending on your scenario) I can run my test as <strong>TestNG or JUnit</strong> test case. No need for a Selenium RC anymore. <strong>No  browsers running locally</strong> or on remote machine listing to ports to execute tests and transmitting results back. </p>
<p>It is very useful to have the Selenium RC take screen shots during it&#8217;s run. Selenium 2 can&#8217;t do this right now (and with HtmlUnit never can). But by simply integrating some logging in the components and elements and you know right away where things went wrong.<br />
Developing with the <strong>Selenium IDE</strong> might seem like a must, but during the work on my prototype all I needed was Firebug and a XPath Searcher. I <strong>did not miss it</strong> at all. To do integration tests you could test all components independently and one at a time. Once these work, chain them together and let them run as unit tests. Did I mention <strong>HtmlUnit is fast</strong> ? </p>
<h3>Conclusion</h3>
<p>I barely dug into the webdriver code, I played around with it for a couple of hours and I&#8217;m sure there more is stuff (and bugs) to find. Given that Selenium 2 is in alpha 1 stage right now I expect very nice things coming out of it. It certainly looks like the way to go. </p>
<p>Another strong contender is <a href="http://webtest.canoo.com/webtest/manual/WebTestHome.html">Canoo WebTest</a>. I will have a look at this one in another post.</p>
<p><strong>Update Ajax and HtmlUnit</strong> 1/5/2010 </p>
<p>It does not seem to work. You need a real browser to get dynamically content re-rendered through Ajax. </p>
<p>A method waiting for an id to be rendered (or timeout after x seconds) could look like this:</p>
<pre class="brush: java; title: ;">
  public void waitForElementOrTimeout(String idToWaitFor, int timeout) {
    long end = System.currentTimeMillis() + timeout * 1000;
    RenderedWebElement resultsDiv = null;
    while (System.currentTimeMillis() &lt; end) {
      try {
        resultsDiv = (RenderedWebElement) driver.findElement(By.id(idToWaitFor));
      }
      catch (NoSuchElementException e) {
        //
      }
      if (resultsDiv != null &amp;&amp; resultsDiv.isDisplayed()) {
        break;
      }
    }
    assertThat(resultsDiv).isNotNull();
  }
</pre>
<p>This will either find the element specified or throw an assertion (updated example from the selenium 2 page).</p>
<div class="google_plusone_widget"><g:plusone 
      count="true" href="http://maxheapsize.com/2010/01/04/using-selenium-2-for-web-testing/" size="medium"></g:plusone></div><!-- Social Bookmarks BEGIN -->
<div class="social_bookmark">
<br />
<div class="d">
<br />
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://del.icio.us/post?url=http://maxheapsize.com/2010/01/04/using-selenium-2-for-web-testing/&amp;title=Using+Selenium2+for+web+testing+%28and+not+Selenium+IDE%29" rel="nofollow" title="Add to&nbsp;Del.icio.us"><img class="social_img" src="http://maxheapsize.com/wp-content/plugins/social-bookmarks/images/delicious.png" title="Add to&nbsp;Del.icio.us" alt="Add to&nbsp;Del.icio.us" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://digg.com/submit?phase=2&amp;url=http://maxheapsize.com/2010/01/04/using-selenium-2-for-web-testing/&amp;title=Using+Selenium2+for+web+testing+%28and+not+Selenium+IDE%29" rel="nofollow" title="Add to&nbsp;digg"><img class="social_img" src="http://maxheapsize.com/wp-content/plugins/social-bookmarks/images/digg.png" title="Add to&nbsp;digg" alt="Add to&nbsp;digg" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.dzone.com/links/add.html?description=Using+Selenium2+for+web+testing+%28and+not+Selenium+IDE%29&amp;url=http://maxheapsize.com/2010/01/04/using-selenium-2-for-web-testing/&amp;title=Using+Selenium2+for+web+testing+%28and+not+Selenium+IDE%29" rel="nofollow" title="Add to&nbsp;DZone"><img class="social_img" src="http://maxheapsize.com/wp-content/plugins/social-bookmarks/images/dzone.png" title="Add to&nbsp;DZone" alt="Add to&nbsp;DZone" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.facebook.com/sharer.php?u=http://maxheapsize.com/2010/01/04/using-selenium-2-for-web-testing/" rel="nofollow" title="Add to&nbsp;Facebook"><img class="social_img" src="http://maxheapsize.com/wp-content/plugins/social-bookmarks/images/facebook.png" title="Add to&nbsp;Facebook" alt="Add to&nbsp;Facebook" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.google.com/bookmarks/mark?op=edit&amp;output=popup&amp;bkmk=http://maxheapsize.com/2010/01/04/using-selenium-2-for-web-testing/&amp;title=Using+Selenium2+for+web+testing+%28and+not+Selenium+IDE%29" rel="nofollow" title="Add to&nbsp;Google Bookmarks"><img class="social_img" src="http://maxheapsize.com/wp-content/plugins/social-bookmarks/images/google.png" title="Add to&nbsp;Google Bookmarks" alt="Add to&nbsp;Google Bookmarks" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.mister-wong.com/index.php?action=addurl&amp;bm_url=http://maxheapsize.com/2010/01/04/using-selenium-2-for-web-testing/&amp;bm_description=Using+Selenium2+for+web+testing+%28and+not+Selenium+IDE%29" rel="nofollow" title="Add to&nbsp;Mister Wong"><img class="social_img" src="http://maxheapsize.com/wp-content/plugins/social-bookmarks/images/misterwong.png" title="Add to&nbsp;Mister Wong" alt="Add to&nbsp;Mister Wong" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://reddit.com/submit?url=http://maxheapsize.com/2010/01/04/using-selenium-2-for-web-testing/&amp;title=Using+Selenium2+for+web+testing+%28and+not+Selenium+IDE%29" rel="nofollow" title="Add to&nbsp;reddit"><img class="social_img" src="http://maxheapsize.com/wp-content/plugins/social-bookmarks/images/reddit.png" title="Add to&nbsp;reddit" alt="Add to&nbsp;reddit" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.stumbleupon.com/submit.php?url=http://maxheapsize.com/2010/01/04/using-selenium-2-for-web-testing/&amp;title=Using+Selenium2+for+web+testing+%28and+not+Selenium+IDE%29" rel="nofollow" title="Add to&nbsp;Stumble Upon"><img class="social_img" src="http://maxheapsize.com/wp-content/plugins/social-bookmarks/images/stumbleupon.png" title="Add to&nbsp;Stumble Upon" alt="Add to&nbsp;Stumble Upon" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.sphere.com/sphereit/http://maxheapsize.com/2010/01/04/using-selenium-2-for-web-testing/" rel="nofollow" title="Add to&nbsp;SphereIt"><img class="social_img" src="http://maxheapsize.com/wp-content/plugins/social-bookmarks/images/sphereit.png" title="Add to&nbsp;SphereIt" alt="Add to&nbsp;SphereIt" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.spurl.net/spurl.php?url=http://maxheapsize.com/2010/01/04/using-selenium-2-for-web-testing/&amp;title=Using+Selenium2+for+web+testing+%28and+not+Selenium+IDE%29" rel="nofollow" title="Add to&nbsp;Spurl"><img class="social_img" src="http://maxheapsize.com/wp-content/plugins/social-bookmarks/images/spurl.png" title="Add to&nbsp;Spurl" alt="Add to&nbsp;Spurl" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.technorati.com/faves?add=http://maxheapsize.com/2010/01/04/using-selenium-2-for-web-testing/" rel="nofollow" title="Add to&nbsp;Technorati"><img class="social_img" src="http://maxheapsize.com/wp-content/plugins/social-bookmarks/images/technorati.png" title="Add to&nbsp;Technorati" alt="Add to&nbsp;Technorati" /></a>
<a onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://twitter.com/home/?status=Check+out+Using+Selenium2+for+web+testing+%28and+not+Selenium+IDE%29+@+http://maxheapsize.com/2010/01/04/using-selenium-2-for-web-testing/" rel="nofollow" title="Add to&nbsp;Twitter"><img class="social_img" src="http://maxheapsize.com/wp-content/plugins/social-bookmarks/images/twitter.png" title="Add to&nbsp;Twitter" alt="Add to&nbsp;Twitter" /></a>
<br />
</div>
</div>
<!-- Social Bookmarks END -->
]]></content:encoded>
			<wfw:commentRss>http://maxheapsize.com/2010/01/04/using-selenium-2-for-web-testing/feed/</wfw:commentRss>
		<slash:comments>16</slash:comments>
		</item>
	</channel>
</rss>

