<?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>Gojko Adzic &#187; ajax</title>
	<atom:link href="http://gojko.net/tag/ajax/feed/" rel="self" type="application/rss+xml" />
	<link>http://gojko.net</link>
	<description>Building software that matters</description>
	<lastBuildDate>Wed, 04 Aug 2010 11:38:56 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Opensource .NET talks schedule</title>
		<link>http://gojko.net/2008/08/27/opensource-net-talks-schedule/</link>
		<comments>http://gojko.net/2008/08/27/opensource-net-talks-schedule/#comments</comments>
		<pubDate>Wed, 27 Aug 2008 20:51:12 +0000</pubDate>
		<dc:creator>gojko</dc:creator>
				<category><![CDATA[news]]></category>
		<category><![CDATA[.net]]></category>
		<category><![CDATA[ajax]]></category>
		<category><![CDATA[alt.net]]></category>
		<category><![CDATA[castle]]></category>
		<category><![CDATA[gwt]]></category>
		<category><![CDATA[nservicebus]]></category>
		<category><![CDATA[script#]]></category>
		<category><![CDATA[skills matter]]></category>
		<category><![CDATA[tdd]]></category>
		<category><![CDATA[windsor]]></category>

		<guid isPermaLink="false">http://gojko.net/?p=315</guid>
		<description><![CDATA[We have worked out the schedule for opensource .NET talks at Skills Matter in London for the next few months. Here are the dates to note in your calendar &#8211; more detail on sessions will follow: 25th September: Script #, .NET response to Google Web Toolkit. Registration is now open 23rd October: Dependency injection with [...]]]></description>
			<content:encoded><![CDATA[<p>We have worked out the schedule for opensource .NET talks at <a target="_blank" href="http://skillsmatter.com/go/open-source-dot-net">Skills Matter</a> in London for the next few months. Here are the dates to note in your calendar &#8211; more detail on sessions will follow:</p>
<ul>
<li>25th September: Script #, .NET response to Google Web Toolkit.<br />
<a target="_blank" href="http://skillsmatter.com/event/open-source-dot-net/script-the-dot-net-response-to-the-google-web-toolkit">Registration is now open</a></li>
<li>23rd October: Dependency injection with Castle Windsor</li>
<li>27th November: Asynchronous enterprise .NET applications with NServiceBus</li>
<li>17th December: Test driven development in .NET</li>
</ul>
<p>We will probably do another Alt.NET evening in January like the one this July. This time we&#8217;ll have more time and hopefully a bigger venue. At the moment, we have a slot on 13th Jan available for this. If you attended the July talks, please let me know what you thought of the way that we organised it, what you liked, what you disliked, and what we could do to make it better next time.</p>
]]></content:encoded>
			<wfw:commentRss>http://gojko.net/2008/08/27/opensource-net-talks-schedule/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Video: Developing Ajax Web Applications with Castle Monorail</title>
		<link>http://gojko.net/2008/07/18/video-developing-ajax-web-applications-with-castle-monorail/</link>
		<comments>http://gojko.net/2008/07/18/video-developing-ajax-web-applications-with-castle-monorail/#comments</comments>
		<pubDate>Fri, 18 Jul 2008 20:11:57 +0000</pubDate>
		<dc:creator>gojko</dc:creator>
				<category><![CDATA[presentations]]></category>
		<category><![CDATA[tutorials]]></category>
		<category><![CDATA[.net]]></category>
		<category><![CDATA[ajax]]></category>
		<category><![CDATA[alt.net]]></category>
		<category><![CDATA[castle]]></category>
		<category><![CDATA[monorail]]></category>
		<category><![CDATA[web 2.0]]></category>

		<guid isPermaLink="false">http://gojko.net/?p=152</guid>
		<description><![CDATA[Here&#8217;s the video from the talk that Dave and I did last month at Skills Matter on developing Ajax Web applications with Castle Monorail. You can download slides and find links from the talk here. (if the video does not load in the embedded player, see it on google video)]]></description>
			<content:encoded><![CDATA[<p><embed id="VideoPlayback" style="width:400px;height:326px;float:left;margin:5px 5px 5px 5px; border: 1px solid black" allowFullScreen="true" src="http://video.google.com/googleplayer.swf?docid=-383418991140556188&#038;hl=en&#038;fs=true" type="application/x-shockwave-flash"></embed>Here&#8217;s the video from the talk that Dave and I did last month at <a href="http://www.skillsmatter.com">Skills Matter</a> on developing Ajax Web applications with Castle Monorail.  You can download slides and find links from the talk <a href="http://gojko.net/2008/06/13/slides-links-and-source-from-the-ajax-monorail-talk/">here</a>. (if the video does not load in the embedded player, see it on <a href="http://video.google.com/videoplay?docid=-383418991140556188" target="_blank">google video</a>)</p>
]]></content:encoded>
			<wfw:commentRss>http://gojko.net/2008/07/18/video-developing-ajax-web-applications-with-castle-monorail/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Slides, links and source from the Ajax Monorail talk</title>
		<link>http://gojko.net/2008/06/13/slides-links-and-source-from-the-ajax-monorail-talk/</link>
		<comments>http://gojko.net/2008/06/13/slides-links-and-source-from-the-ajax-monorail-talk/#comments</comments>
		<pubDate>Fri, 13 Jun 2008 09:57:15 +0000</pubDate>
		<dc:creator>gojko</dc:creator>
				<category><![CDATA[presentations]]></category>
		<category><![CDATA[.net]]></category>
		<category><![CDATA[ajax]]></category>
		<category><![CDATA[alt.net]]></category>
		<category><![CDATA[castle]]></category>
		<category><![CDATA[monorail]]></category>

		<guid isPermaLink="false">http://gojko.net/?p=138</guid>
		<description><![CDATA[I really enjoyed talking about Developing Ajax web applications with Castle Monorail yesterday at Skills Matter. It was great to see so many familiar faces &#8212; thanks for coming again and I hope that you enjoyed it as well. Here are the downloads and links that Dave and I promised to put online: Downloads PPT [...]]]></description>
			<content:encoded><![CDATA[<p>I really enjoyed talking about <a target="_blank" href="http://skillsmatter.com/podcast/open-source-dot-net/developing-ajax-web-applications-with-castle-monorail">Developing Ajax web applications with Castle Monorail</a> yesterday at Skills Matter. It was great to see so many familiar faces &mdash; thanks for coming again and I hope that you enjoyed it as well. Here are the downloads and links that Dave and I promised to put online:<span id="more-138"></span></p>
<h2>Downloads</h2>
<ul>
<li><a href="/resources/monorail-ajax-20080612.ppt">PPT slides</a></li>
<li><a href="/resources/monorail-ajax-20080612-superpowers.zip">Source code for the SuperPowers app</a> (drag &#038; drop, scriptaculous and prototype effects demo) </li>
<li><a href="/resources/monorail-ajax-20080612-jsondemo.zip">Source code for the JSonDemo app</a> (comparing the three options for ajax with monorail; requires castle trunk DLLs)</li>
</ul>
<h2>Links with more details on the stuff from our talk</h2>
<ul>
<li>Hammett&#8217;s post about <a href="http://hammett.castleproject.org/?p=97" target="_blank">Generating JS commands from actions </a> (option #1 from the PPT). For all available functions in $page helper, see the source code of  <a target="_blank" href='http://svn.castleproject.org:8080/svn/castle/trunk/MonoRail/Castle.MonoRail.Framework/JSGeneration/Prototype/PrototypeGenerator.cs'>PrototypeGenerator.cs</a> and <a target="_blank" href='http://svn.castleproject.org:8080/svn/castle/trunk/MonoRail/Castle.MonoRail.Framework/JSGeneration/Prototype/PrototypeElementGenerator.cs'>PrototypeElementGenerator.cs</a> classes.
</li>
<li>Hammett&#8217;s post on <a target="_blank" href="http://hammett.castleproject.org/?p=247">JSON return binders</a> (option #3 from the PPT)</li>
<li><a href="http://skillsmatter.com/podcast/open-source-dot-net/agile-web-development-with-the-castle-framework">Video </a>, <a href="http://gojko.net/2008/05/15/links-and-slides-from-the-castle-talk/">links and slides</a> from my earlier talk on agile web development with Castle and Monorail</li>
<li><a href="http://gojko.net/tag/castle/">Castle-related articles on this web site</a> including the demo app that explains how to develop monorail controllers and how to unit test them.</li>
</ul>
<h2>Some general links</h2>
<ul>
<li><a target="_blank" href="http://www.castleproject.org/MonoRail">Monorail web site</a>
</li>
<li><a target="_blank" href="http://hammett.castleproject.org">Hammett&#8217;s blog</a> and <a target="_blank" href="http://www.ayende.com/blog">Ayende&#8217;s blog</a> are excellent resources for all stuff about Castle.</li>
<li><a target="_blank" href="http://www.prototypejs.org">Prototype JS library docs</a>
</li>
<li><a target="_blank" href="http://script.aculo.us">Scriptaculous JS library docs</a>
</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://gojko.net/2008/06/13/slides-links-and-source-from-the-ajax-monorail-talk/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>The wrong way to do a shopping cart</title>
		<link>http://gojko.net/2008/02/18/the-wrong-way-to-do-a-shopping-cart/</link>
		<comments>http://gojko.net/2008/02/18/the-wrong-way-to-do-a-shopping-cart/#comments</comments>
		<pubDate>Mon, 18 Feb 2008 18:39:19 +0000</pubDate>
		<dc:creator>gojko</dc:creator>
				<category><![CDATA[articles]]></category>
		<category><![CDATA[ajax]]></category>
		<category><![CDATA[best practices]]></category>
		<category><![CDATA[usability]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://gojko.net/2008/02/18/the-wrong-way-to-do-a-shopping-cart/</guid>
		<description><![CDATA[The print-on-demand service that I&#8217;ve chosen for my book has a fairly nice web user interface with lots of Ajax code. Generally, that web application is one of the best aspects of doing business with them. That&#8217;s why I was surprised to find a rather amateurish flaw in their shopping cart. Here is the screenshot: [...]]]></description>
			<content:encoded><![CDATA[<p>The print-on-demand service that I&#8217;ve chosen for <a href="/fitnesse/book">my book</a> has a fairly nice web user interface with lots of Ajax code. Generally, that web application is one of the best aspects of doing business with them. That&#8217;s why I was surprised to find a rather amateurish flaw in their shopping cart. Here is the screenshot:</p>
<p><center><img src="/images/donotclick.png" style="border:1px solid black; margin:5px 5px 5px 5px;"/></center></p>
<p>Notice the &#8220;do not click Place Order more than once&#8221; message. Someone has obviously identified that customers have been clicking more times than needed, but offering a warning message is not the way to solve the issue. In fact, such a message is a <a href="http://gojko.net/2007/06/14/dont-deal-with-problems-like-gaggia/"> huge warning signal that something is wrong</a>.</p>
<p>I&#8217;m pointing out this case in particular because it is one of the <a href="http://gojko.net/2007/03/22/breaking-the-web/">most frequent problems I&#8217;ve seen in Ajax sites</a>, and one so easy to avoid. The proper solution is incredibly simple: <i>always disable the form as the first step of asynchronous processing</i>. It is very easy to block the &#8220;Place Order&#8221; button before an Ajax call goes out to the server, and doing so would technically prevent anyone using a proper browser to place the same order twice. For high volume sites, like this one, I always recommend implementing some sort of double-order analytics on the server just in case, because exceptions do happen, but just a simple JavaScript command to disable that button would save everyone a lot of trouble.</p>
]]></content:encoded>
			<wfw:commentRss>http://gojko.net/2008/02/18/the-wrong-way-to-do-a-shopping-cart/feed/</wfw:commentRss>
		<slash:comments>18</slash:comments>
		</item>
		<item>
		<title>How to test AJAX sites with FitNesse and Selenium RC</title>
		<link>http://gojko.net/2008/02/14/ajax-selenium-fitnesse/</link>
		<comments>http://gojko.net/2008/02/14/ajax-selenium-fitnesse/#comments</comments>
		<pubDate>Thu, 14 Feb 2008 00:21:30 +0000</pubDate>
		<dc:creator>gojko</dc:creator>
				<category><![CDATA[fitnesse]]></category>
		<category><![CDATA[.net]]></category>
		<category><![CDATA[ajax]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[selenium]]></category>
		<category><![CDATA[tdd]]></category>
		<category><![CDATA[webtest]]></category>

		<guid isPermaLink="false">http://gojko.net/2008/02/14/ajax-selenium-fitnesse/</guid>
		<description><![CDATA[It&#8217;s been almost a year since I wrote Automating web tests with FitNesse and Selenium, offering an idea how FitNesse can be used to implement a nice customer-friendly mini-language for user interface testing. Since then, that article has been one of the most popular, if not the single most popular, article on this web site. [...]]]></description>
			<content:encoded><![CDATA[<p><img src="/images/684719_test_me.jpg" style="border:1px solid black;margin:5px 5px 5px 5px; float:left" />It&#8217;s been almost a year since I wrote <a href="http://gojko.net/2007/05/20/automating-web-tests-with-fitnesse-and-selenium/">Automating web tests with FitNesse and Selenium</a>, offering an idea how FitNesse can be used to implement a nice customer-friendly mini-language for user interface testing. Since then, that article has been one of the most popular, if not the single most popular, article on this web site. I have helped several clients improve and integrate their UI testing based on the ideas in that article, expanding and improving the mini-language, especially for AJAX testing. Here is what I&#8217;ve learned about that in the last  year.<span id="more-101"></span></p>
<p><i>Quick note before we continue: FIT fixtures described in this article can be downloaded from <a href="http://fitnesse.info/webtest">fitnesse.info/webtest</a>. Both Java and .NET are supported and the fixtures are released under GPL. To learn how to set everything up, read the <a href="http://gojko.net/2007/05/20/automating-web-tests-with-fitnesse-and-selenium/">original article</a>.</i></p>
<h2>Effective AJAX testing with selenium.Wait</h2>
<p>In the original article, I have suggested using <i>WaitForCondition</i> and <i>selenium.browserbot.getCurrentWindow()</i> to dynamically evaluate JavaScript expressions and block until they become fulfilled. Although this did the trick, the code was very ugly and error-prone, mixing JavaScript evaluations with Java/.NET expressions. <b>It turned out that it was much better to poll browser a few times per second through Selenium RC API.</b> This way, the code is much more consistent, and waiting conditions are much easier to write. Polling, in theory, causes unnecessary delay, but this case Selenium RC and UI testing itself introduce a lot of latency, so the polling does not really make things any worse. In fact, the Java version of Selenium Remote Control has API support for that: <i>Wait</i> class in <i>com.thoughtworks.selenium</i> package. The official <a href="http://release.openqa.org/selenium-remote-control/0.9.2/doc/java/">JavaDoc</a> for that class is a bit wrong and misleading, but with a bit of experimenting that class is very easy to use, and quite powerful. The official documentation suggests this usage pattern:</p>
<pre>
new Wait("Couldn't find close button!") {
    boolean until() {
        return selenium.isElementPresent("button_Close");
    }
};
</pre>
<p>Yet this code will not even compile with Selenium RC 9.2, because no such constructor exists. Instead, the error message should be passed while calling the blocking <i>wait</i> method later. Here is an example that blocks until some text appears on the page:</p>
<pre>
  // private class of WebTest fixture
  private class WaitForTextToAppear extends Wait{
    private String text;
    public  WaitForTextToAppear(String  text){
      this.text= text;
    }
    public boolean until(){
       return WebTest.this.pageContainsText(text);
    }
  }
 // method of WebTest Fixture
 public boolean waitSecondsForTextToAppear(int timeout, String text){
   Wait x=new WaitForTextToAppear(text);
   x.wait("Cannot find text " +text+ " after "+timeout+" seconds",timeout*1000);
   return true;
 }
</pre>
<h3>Waiting In mini-language</h3>
<p>In FitNesse, this would be used as:</p>
<pre>
|wait|5|seconds for text|Hello World|to appear|
</pre>
<p>This line would block the execution of the page up to five seconds, waiting for <i>Hello World</i> to appear anywhere in the page. If that text does not appear after five seconds, the test breaks. Using this pattern, it is very easy to implement any kind of asynchronous waiting without manually checking for JavaScript expressions and worrying about Selenium-to-application page DOM conversions. So far, I have implemented the following waiting methods for the testing mini-language:</p>
<pre>
|wait|5|seconds for element|username|to appear|

|wait|5|seconds for element|username|to disappear|

|wait|5|seconds for text|Hello World|to appear|

|wait|5|seconds for text|Hello World|to disappear|

|wait|5|seconds for field|username|to contain text|Hello World|

|wait|5|seconds for element|username_label|to contain text|Please enter username|
</pre>
<p>the difference between &#8220;wait for field to contain text&#8221; and &#8220;wait for elelement to contain text&#8221; is that the first method checks for the current value of an INPUT field (&lt;input type=&#8221;text&#8221; name=&#8221;username&#8221; value=&#8221;Hello World&#8221;/&gt;), and the second checks for text inside a dom element (&lt;span id=&#8221;username_label&#8221;&gt;Please enter username&lt;/span&gt;). .NET Selenium RC API does not have this class, but it was not hard to implement, so the .NET fixture also supports this in the mini-language.</p>
<h2>Locator lookup takes too long</h2>
<p>Selenium uses &#8220;locators&#8221; to point to DOM elements that you want to automate. In the original article, I suggested a complex scheme of mapping user-friendly descriptions to locators so that we can use button captions, labels and similar visible text and labels to point to page elements. Under this scheme, the FitNesse-Selenium glue code tried out locators from an array until it found a match. This turned out to be such a performance penalty that I no longer suggest it. Each attempt to discover whether an element was present or not went through the full cycle of FitNesse, Selenium Remote Console, Browser, Selenium and back. In average, that increased the time for a UI test to execute by 500-600 percent. It turned out that, with a bit of care in naming, DOM element IDs can be used in all cases so that test pages are still descriptive enough, and indirect locator lookup can be avoided. <b>So now I suggest using DOM element IDs directly, not using labels or captions.</b></p>
<h3>Effective locators in mini-language</h3>
<p>I have introduced a new parameter to control whether the lookup is performed or not. It is still on by default, but if you put this table into your page:</p>
<pre>
|set locator lookup|false|
</pre>
<p>tests will execute much much faster. This will require you, however, to use DOM element IDs exclusively to point to all page elements. Even with lookup turned on, tests should now run faster if you use DOM element IDs, because I&#8217;ve moved IDs to the top of lookup arrays for all element types.</p>
<h2>Element type safety is not really important</h2>
<p>In the original article, I suggested checking whether something is a button, input field or a link when doing methods like <i>click</i>, so that something like:</p>
<pre>
|user clicks on|save|button|
</pre>
<p>would fail if <i>save</i> was a link identifier. I thought that would introduce one more level of safety and avoid problems because of ambiguous definitions. Since trying out all those locators works really slow, I gave up on checking for the type of element, and use that only in special cases (such as radio buttons, which should be selectable by value as well as name). This did not, in practice, make tests any less effective. So I now suggest avoiding such complex checks.</p>
<h3>Direct element access in mini-language</h3>
<p>The WebFixture mini-language now supports a bunch of methods for generic elements, which are located using the DOM element ID or element name, without checking the exact type. So you can write something like:</p>
<pre>
|user clicks on|save|
</pre>
<p>and that is going to work for buttons, labels, text elements and anything you can click on.</p>
<h2>Don&#8217;t pause, wait for specific events</h2>
<p>In the original article, I introduced a few methods that blocked until the whole page loaded correctly. With AJAX testing, those methods are no longer applicable. To allow an asynchronous operation to complete before continuing with the test, lots of people used the &#8216;pause&#8217; function. This caused more harm than good, so I&#8217;m now thinking of effectively removing that function or throwing an exception on the end of the pause to print a warning that the test should be rewritten. Pause is makes tests error prone and very brittle. If, for example, you pause for 5 seconds to wait for a form to load, then when you run the tests on different hardware or over network, the test itself might break because of longer latency (so the code implementation is still correct, but the test fails, which is a very dangerous anti-pattern). This gets solved by extending the pause to be long enough, so your tests are no longer running for 10 seconds but a minute&#8230; once the test suite starts running for longer than a minute people are no longer running tests before committing, and that makes the feedback loop even longer, reducing the effectiveness of tests.</p>
<p><b>It&#8217;s much better, if you can, to block and wait for a specific event.</b> So instead of pausing, use one of the wait functions as described in the beginning of this article. Those functions still allow you to specify the ultimate timeout period, so that if the event does not happen after 10-15 seconds the test breaks. A very important difference is that, in normal case, the execution will continue straight after the event does happen. So you&#8217;ll wait exactly as long as you need to, and not a second longer.</p>
<h2>DOM events don&#8217;t always fire automatically</h2>
<p>When you type stuff in with Selenium, DOM elements such as <i>onFocus</i>, <i>onBlur</i> and <i>onChange</i> don&#8217;t fire automatically (not to mention <i>onKeyUp</i> and <i>onKeyDown</i>). Lots of AJAX code is built around those events, and tests fail if the code relies on events. Selenium allows you to triggers the events manually using <i>fireEvent</i> method. <b>So, if your site behaves differently under test and when you play with it manually, missing events should be your first suspect</b>. </p>
<h3>Firing events manually in the mini-language</h3>
<p>I have changed the <i>UserTypesIntoField</i> method to fire events as well, in the appropriate order. You can fire an event explicitly using the <i>fire event for</i> method:<br />
<code><br />
|fire event|blur|for|username|<br />
</code> </p>
<p>To fire events, don&#8217;t put the leading <i>on</i> &mdash; use <i>click</i> instead of <i>onclick</i>.</p>
<h2>Some people prefer click-and-record</h2>
<p>Although I&#8217;ve tried to introduce a customer-friendly mini-language for testing, some people liked the idea of using FitNesse to wrap Selenium tests more because it UI tests could then be integrated into automated integration testing and because they could prepare and verify their database during Selenium tests. But they still preferred using Selenium IDE to record tests, without having to manually write them. I have introduced a new fixture class, <i>webfixture.PlainSeleniumTest</i>, that more or less just forwards the commands to Selenium RC. So you can use a Selenium test table, paste it in FitNesse, change it just a bit, and run the test using Selenium Remote Control. The only changes required are deleting the test name (first row of the table) and optionally changing the <i>open</i> command to include a relative URL instead of an absolute one. That allows you to record tests using Selenium IDE, but still integrate them into Cruise Control and control the database or talk to your domain objects during tests.</p>
<p>Selenium tests can be stored as HTML files, and you can use HTML directly in FitNesse without converting it to the Wiki syntax. Just paste  the table anywhere in the page, but put the HTML code between <i>!-</i> and <i>-!</i> to tell FitNesse to display the contents raw, without special formatting.</p>
<p>Originally, I thought that I could just get away by wrapping a Selenium RC instance into a Sequence Fixture as the system under test, and pass all commands to it. But Selenium RC API and browser-based Selenium scripts differ in some parts, especially for the waiting methods and verification methods. For example, <i>verifyVisible</i> in Selenium is called <i>isVisible</i> in Selenium RC. So I wrote a bunch of wrappers for <i>verifyXXX</i> and <i>assertXXX</i> methods to make tests run without changing.</p>
<p>The next problem was that the resulting Selenium test tables may have one additional empty cell if the method only has one argument, such as <i>open url</i>. Because of that additional argument, FitNesse will try to map the row to the method <i>open(String, String)</i> and fail because it could not find such a method. Because of that, I also wrote a bunch of wrappers for single-parameter methods that have a second string argument, which is just ignored. For example:</p>
<pre>
public void open (String url, String ignore){
  open(url);
}
public void click(String what, String ignore){
  instance.click(what);
}
</pre>
<p>With that, Selenium tests started working more or less out of the box. I occasionally have to add another method for one of the reasons mentioned above, but that is fairly quick and straightforward.</p>
<p>There&#8217;s one more trick related to this. Selenium scripts, especially those recorded, can be quite lengthy. FitNesse will flush output after each table, so if you leave the test as one big table, it will look like FitNesse is not doing anything for a while and then you&#8217;ll get all results at once. I&#8217;ve found it much better to just split the big table into several smaller tables, so that I can track progress while the test is running.  </p>
<h2>Use browser names instead of browser codes</h2>
<p><a href="http://www.cornetdesign.com" target="_blank">Cory Foy</a> suggested that we should not use browser codes like <i>*iehta</i>, but make tests even more user friendly by using descriptive browser names. I like that idea very much, so the <i>start browser</i> now supports both codes and names like <i>IE</i> and <i>Firefox</i>. It will map the name to the appropriate browser code for you.</p>
<h2>Plenty of new methods</h2>
<p>I have also added quite a few new methods to the mini-language for UI tests that check alerts, click on confirmations, inspect options available in SELECT elements, check whether elements are enabled or disabled and work with checkboxes and radio buttons. See the full list of supported methods in <a href="http://fitnesse.info/webtest">fitnesse.info/webtest</a>.</p>
<h2>Summary</h2>
<p>On the end, here is a summary of lessons learned:</p>
<ul>
<li>Poll browser a few times per second through Selenium RC API using the <i>Wait</i> class to check for asynchronous events.</li>
<li>Use DOM element IDs directly, don&#8217;t look for elements using xpath locators, labels or captions.</li>
<li>Don&#8217;t use a generic pause. If you can, block and wait for a specific event.</li>
<li>If your site behaves differently under test and when you play with it manually, missing events should be your first suspect. Fire events manually in that case.</li>
</ul>
<p>FIT fixtures that implement the testing mini-language for .NET and Java can be downloaded from <a href="http://fitnesse.info/webtest">fitnesse.info/webtest</a>. The code is released under GPL, so you can edit and experiment with it. If you add any new useful methods, please send them so that they can be included in the next version of this library&#8230;</p>
<p>Image credits: <a href="http://www.sxc.hu/profile/cancsajn" target="_blank">Timi az en vaok</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://gojko.net/2008/02/14/ajax-selenium-fitnesse/feed/</wfw:commentRss>
		<slash:comments>33</slash:comments>
		</item>
	</channel>
</rss>
