<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0">
    <channel>
        <title>Web Development - Blogs at Near Infinity</title>


        <link>http://www.nearinfinity.com/blogs/</link>
        <description>Employee Blogs</description>
        <language>en</language>
        <copyright>Copyright 2010</copyright>
        <lastBuildDate>Sat, 24 Apr 2010 14:00:36 -0500</lastBuildDate>
        <generator>http://www.sixapart.com/movabletype/</generator>
        <docs>http://www.rssboard.org/rss-specification</docs>
        
        <item>
            <title>Selenium Mojo : Protoype Bindings in Selenium</title>
            <description><![CDATA[<font style="font-size: 1.25em;"><b>Introduction</b></font><br /><br />On my current project we have been involved in converting some of the hundreds of manual tests that are run by our Test Team every release into a suite of automated Selenium RC tests.<br /><br />During the course of this adventure my crew found several instances where XPath and native JavaScript were not sufficiently expressive to find elements in some of our more complicated interfaces. <br /><br />Since our web app uses the Prototype/Scriptaculous JavaScript framework we wanted to find a way to make the locating power of Prototype available within Selenium RC.<br /><br />We developed approaches for both Selenium 0.9.2 and Selenium 1.0.3 (which had better programmatic support for adding JavaScript user extensions to Selenium).<br /><br /><br /><font style="font-size: 1.25em;"><b>Selenium 0.9.2</b></font><br /><br />Selenium RC provides the capability to add "user extensions" to augment its JavaScript core. <br /><br />See <a href="http://seleniumhq.org/docs/08_user_extensions.html">http://seleniumhq.org/docs/08_user_extensions.html</a> for detailed information on how to set this up. <br /><br />We wrote the following user-extension.js file:<br /><br /><pre class="prettyprint">Selenium.prototype.setupProtoypeJS = function() {<br />&nbsp;&nbsp;&nbsp; id = selenium.browserbot.getCurrentWindow().$;<br />&nbsp;&nbsp;&nbsp; css = selenium.browserbot.getCurrentWindow().$$;<br />}</pre><br />In our code we have a base class for all our test cases. To this we added our own waitForPage() method:<br /><br /><pre class="prettyprint">public void waitForPage() {<br />&nbsp;&nbsp;&nbsp; selenium.waitForPage('60000')<br />&nbsp;&nbsp;&nbsp; proc.doCommand('setupPrototypeJS', [])<br />}</pre><br />Thus every time the page reloads (which clears the JavaScript context) we call waitForPage() and this command is re-executed. It creates two global variables (id and css) and binds them to Prototype's $ and $$ functions respectively.<br /><br /><i>Note: The reason we choose id and css instead of $ and $$ was that Groovy considers $ in Strings to be a special character and we would have had to escape it each time it was used</i>.<br /><br />The Prototype selectors can now be used in Selenium RC like this:<br /><br /><pre class="prettyprint">selenium.click("dom=id('foo')")<br />selenium.click("dom=css('.bar')")<br />selenium.click("dom=css('span.foo a.baz')")</pre><br /><i>Note: You still have to specify the dom locator type so Selenium RC will know to execute your locator string as JavaScript.&nbsp; <br /></i><br /><br /><font style="font-size: 1.25em;"><b>Selenium 1.0.3</b></font><br /><br />In more recent version of Selenium RC the project added the setExtensionJs() method. This allows you to set extension JavaScript programmatically prior to starting the selenium client:<br /><br /><pre class="prettyprint">selenium = new DefaultSelenium(...)<br />selenium.setExtensionJs('...')<br />selenium.start()</pre><br />This made it much easier to implement our Prototype bindings. The only trick was that the JavaScript seems to be executed prior to having access to a page context and is also only executed once. This required us to take a different approach.<br /><br />We created id and css as global functions instead of variables. This allowed us to defer accessing the current window until the functions were actually invoked. &nbsp; <br /><br /><pre class="prettyprint">selenium.setExtensionJs('''<br />        id = function(value) {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;    return selenium.browserbot.getCurrentWindow().$(value);<br /><div id=":w0" class="ii gt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } <br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; css = function(value) {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return selenium.browserbot.<wbr>getCurrentWindow().$$(value);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />''');</div></pre> <br /><i>Note: The above code snippet is written in Groovy which allows multiline Strings.<br /></i><br />The Prototype selectors are used in Selenium RC like before:<br /><br /><pre class="prettyprint">selenium.click("dom=id('foo')")<br />selenium.click("dom=css('.bar')")<br />selenium.click("dom=css('span.foo a.baz')")</pre><br /><br /><br />I would be interested in hearing feedback from anyone who has a chance to use this technique!<br />]]></description>
            <link>http://www.nearinfinity.com/blogs/stephen_mouring_jr/selenium_mojo_protoype_binding.html</link>
            <guid>http://www.nearinfinity.com/blogs/stephen_mouring_jr/selenium_mojo_protoype_binding.html</guid>
            
                <category domain="http://www.sixapart.com/ns/types#category">Groovy</category>
            
                <category domain="http://www.sixapart.com/ns/types#category">JavaScript</category>
            
                <category domain="http://www.sixapart.com/ns/types#category">Testing</category>
            
                <category domain="http://www.sixapart.com/ns/types#category">Web Development</category>
            
            
            <pubDate>Sat, 24 Apr 2010 14:00:36 -0500</pubDate>
        </item>
        
        <item>
            <title>Sharepoint ASP .Net Ajax Configuration</title>
            <description><![CDATA[In the world of web development, there is a little thing called ajax. Ajax is so simple because it is built in to Javascript. I like to use ajax to make web applications that look like they are not stuck in the past. Tools like jQuery make ajax so simple with its commands like:<div><pre class="prettyprint">$.get $.post $.load</pre>ASP .Net has, what they tout as ultra simple, the update panel for ajax post backs to the server. But, this tool is not as simple as it seems. While deceptively simple to stick on a page and wire up to the code behind, it takes much more to make this tool work.<div><br /><div>Like everything else in the Microsoft world, to make ASP .Net have ajax requires a dll and, through reading the documentation, a crap load of changes to the web.config file. Sure, it is easy to get the web.config all nice and set up if you have Visual Studios do it for you. Just create a new Web Site and start debugging the website. Voila, all of the configuration setting needed to use ajax are there.<br /></div><div><br /></div><div>But, for those whose have to do through code for, say, a Sharepoint web site that has to be deployed anywhere, they feel the pain of drudging through the required assembly strings and making SPWebConfigModifications. So, the first step on the path to Sharepoint ajaxiness is to go out to all the dlls and collect all the assembly strings needed:</div><div><br /><pre class="prettyprint">const string scriptResourceHandler = "System.Web.Handlers.ScriptResourceHandler,System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35";
const string scripthandlerfactory = "ScriptHandlerFactory";
const string scripthandlerfactoryappservice = "ScriptHandlerFactoryAppService";
const string scriptresource = "ScriptResource";
const string scriptModuleAssembly = "System.Web.Handlers.ScriptModule,System.Web.Extensions,Version=3.5.0.0,Culture=Neutral,PublicKeyToken=31bf3856ad364e35";
const string webScriptAssembly = "System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35";
const string webExtensionAssembly = "System.Web.Extensions,Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"</pre>After you have done that, or just copied the above assemblies, those assemblies have to be added to the web.config. That is where the SPWebConfigModification comes into play. First, you'll want to clear the modifications otherwise, modifications might appear for items that are long gone.&nbsp;</div><div><br /><pre class="prettyprint">webApp.WebConfigModifications.Clear();</pre>After that is set up, there is quite a bit to add to the WebConfigModification collection. Here OWNER, is something you set somewhere else and keep handy for when you have to remove all of the changes from the web.config.</div><div><br /><pre class="prettyprint">webApp.WebConfigModifications.Add(CreateControlSection());		webApp.WebConfigModifications.Add(CreateSafeControl(webExtensionAssembly,"System.Web.UI"));
webApp.WebConfigModifications.Add(CreateAjaxAssembly(webExtensionAssembly));			webApp.WebConfigModifications.Add(CreateHttpScriptHandler(scriptModuleAssembly,"ScriptModule"));
webApp.WebConfigModifications.Add(CreateScriptResource(scriptResourceHandler,"ScriptResource.axd","GET,HEAD"))
webApp.WebConfigModifications.Add(CreateScriptResource(webScriptAssembly,"*_AppService.axd","*"));
webApp.WebConfigModifications.Add(CreateScriptResource(webScriptAssembly,"*.asmx","*"));
webApp.WebConfigModifications.Add(CreateWebServerSection());
webApp.WebConfigModifications.Add(CreateWebServerHandlerSection());
webApp.WebConfigModifications.Add(RemoveWebServiceHandler(scripthandlerfactory));
webApp.WebConfigModifications.Add(RemoveWebServiceHandler(scripthandlerfactoryappservice));
webApp.WebConfigModifications.Add(RemoveWebServiceHandler(scriptresource));
webApp.WebConfigModifications.Add(CreateWebServiceHandler(webScriptAssembly,"*.asmx","*",scripthandlerfactory));
webApp.WebConfigModifications.Add(CreateWebServiceHandler(webScriptAssembly,"*_AppService.axd","*",scripthandlerfactoryappservice));webApp.WebConfigModifications.Add(CreateWebServiceHandler(scriptResourceHandler,"ScriptResource.axd", "GET,HEAD", scriptresource));
webApp.Farm.Services.GetValue<spwebservice>().ApplyWebConfigModifications();
webApp.Update();
/* Thus begins the many methods to add each little piece of the web.config */
private SPWebConfigModification CreateScriptResource(string assembly,string path,string verb) {
      return new SPWebConfigModification {
		Path = "configuration/system.web/httpHandlers",
		Type = SPWebConfigModification.SPWebConfigModificationType.EnsureChildNode,
		Name = string.Format(CultureInfo.InvariantCulture,"add[@verb='{2}'][@path='{1}'][@type='{0}'][@validate='false']",assembly,path,verb),
		Owner = OWNER,
		Sequence = 0,
		Value = string.Format("<add verb="{2}" path="{1}" type="{0}" validate="false">", assembly,path,verb)
	};
}

private SPWebConfigModification CreateWebServiceHandler(string assembly,string path,string verb,string name) {
	return new SPWebConfigModification {
		Path = "configuration/system.webServer/handlers",
		Type = SPWebConfigModification.SPWebConfigModificationType.EnsureChildNode,
		Name = string.Format(CultureInfo.InvariantCulture,"add[@verb='{2}'][@path='{1}'][@type='{0}'][@preCondition='integratedMode'][@name='{3}']",assembly,path,verb,name),
		Owner = OWNER,
		Sequence = 0,
		Value = string.Format("<add verb="{2}" path="{1}" type="{0}" precondition="integratedMode" name="{3}">", assembly,path,verb,name)
	};
}
private SPWebConfigModification RemoveWebServiceHandler(string name) {
	return new SPWebConfigModification {
		Path = "configuration/system.webServer/handlers",
		Type = SPWebConfigModification.SPWebConfigModificationType.EnsureChildNode,
		Name = string.Format(CultureInfo.InvariantCulture,"add[@name='{0}']",name),
		Owner = OWNER,
		Sequence = 0,
		Value = string.Format("<remove name="{0}">",name)
	};
}

private static SPWebConfigModification CreateHttpScriptHandler(string assembly,string name) {
	return new SPWebConfigModification {
		Path = "configuration/system.web/httpModules",
		Type = SPWebConfigModification.SPWebConfigModificationType.EnsureChildNode,
		Name = string.Format(CultureInfo.InvariantCulture, "add[@name='{0}'] [@type='{1}']",name, assembly),
		Owner = OWNER,
		Sequence = 0,
		Value = string.Format("<add name="{0}" type="{1}">",name, assembly)
	};
}

private static SPWebConfigModification CreateAssembly(string assembly) {
	return new SPWebConfigModification {
	        Path = "configuration/system.web/compilation/assemblies",
		Type = SPWebConfigModification.SPWebConfigModificationType.EnsureChildNode,
		Name = string.Format(CultureInfo.InvariantCulture, "add[@assembly='{0}']", assembly),
		Owner = OWNER,
		Sequence = 0,
		Value = string.Format(CultureInfo.InvariantCulture, "<add assembly="{0}">", assembly)
	};
}
private static SPWebConfigModification CreateAjaxAssembly(string assembly) {
	return new SPWebConfigModification {
		Path = "configuration/system.web/pages/controls",
		Type = SPWebConfigModification.SPWebConfigModificationType.EnsureChildNode,
		Name = string.Format(CultureInfo.InvariantCulture, "add[@tagPrefix='{0}'][@namespace='{1}'][@assembly='{2}']","asp","System.Web.UI", assembly),
		Owner = OWNER,
		Sequence = 0,
		Value = string.Format(CultureInfo.InvariantCulture, "<add tagprefix="{0}" namespace="{1}" assembly="{2}">","asp","System.Web.UI", assembly)
	};
}
private static SPWebConfigModification CreateSafeControl(string assembly, string nameSpace) {
	return new SPWebConfigModification {
		Path = "configuration/SharePoint/SafeControls",
		Type = SPWebConfigModification.SPWebConfigModificationType.EnsureChildNode,
		Name = string.Format(CultureInfo.InvariantCulture, "SafeControl[@Assembly='{0}'][@Namespace='{1}'][@TypeName='*'][@Safe='True']", assembly, nameSpace),
		Owner = OWNER,
		Sequence = 0,
		Value = string.Format(CultureInfo.InvariantCulture, "<safecontrol assembly="{0}" namespace="{1}" typename="*" safe="True">", assembly,				nameSpace)
	};
}
private static SPWebConfigModification CreateControlSection() {
	return new SPWebConfigModification {
		Path = "configuration/system.web/pages",
		Type = SPWebConfigModification.SPWebConfigModificationType.EnsureSection,
		Name = "controls",
		Value =@"<controls></controls>",
		Sequence = 0,
		Owner = OWNER
	};
}
private static SPWebConfigModification CreateWebServerSection() {
	return new SPWebConfigModification {
		Path = "configuration",
	        Type = SPWebConfigModification.SPWebConfigModificationType.EnsureSection,
		Name = "system.webServer",
		Value =@"<system.webserver></system.webserver>",
		Sequence = 0,
		Owner = OWNER
	};
}
private static SPWebConfigModification CreateWebServerHandlerSection() {
       return new SPWebConfigModification {
		Path = "configuration/system.webServer",
		Type = SPWebConfigModification.SPWebConfigModificationType.EnsureSection,
		Name = "handlers",
		Value =@"<handlers></handlers>",
		Sequence = 0,
		Owner = OWNER
	};		
}</safecontrol></add></add></add></remove></add></add></spwebservice></pre><br />So, why on earth does it take that much code to generate the xml required to use ajax in Sharepoint?</div></div></div>]]></description>
            <link>http://www.nearinfinity.com/blogs/sean_howell/sharepoint_asp_net_ajax_configuration.html</link>
            <guid>http://www.nearinfinity.com/blogs/sean_howell/sharepoint_asp_net_ajax_configuration.html</guid>
            
                <category domain="http://www.sixapart.com/ns/types#category">.NET</category>
            
                <category domain="http://www.sixapart.com/ns/types#category">Web Development</category>
            
            
            <pubDate>Tue, 02 Feb 2010 18:34:17 -0500</pubDate>
        </item>
        
        <item>
            <title>Several Must Have Firebug-Related Firefox Extensions</title>
            <description><![CDATA[ <p>Last week while doing the usual (web development stuff) I discovered a few Firefox extensions I didn't even know I was missing until I found them by accident. The "accident" happened while adding Firebug to a Firefox that was running in a VMWare Fusion Windows virtual machine on which I was testing in, gasp, Windows. I went to find add-ons and searched for Firebug. And up came not only <a href="http://getfirebug.com/">Firebug</a> but also results for <a href="http://www.softwareishard.com/blog/firecookie/">Firecookie</a>, <a href="http://robertnyman.com/firefinder/">Firefinder</a>, <a href="http://robertnyman.com/inline-code-finder/">Inline Code Finder for Firebug</a>, and <a href="http://tools.sitepoint.com/codeburner/firefox">CodeBurner for Firebug</a>.</p>

<p>Of course everyone doing web development uses Firebug (or really should anyway) since it rules. But these other extensions provide some <i>really</i> nice functionality and complement Firebug perfectly. Here's a quick run down:</p>

<h3>Firecookie</h3>

<p>Firecookie lets you see all the cookies for a site, add new ones, remove existing cookies, etc. It gives useful information about each cookie like the name, value, raw value (if URI-encoded), domain, size, path, expiration, and security. Very cool.</p>

<style type="text/css">
img.border {
   margin-bottom: 10px;
   border: 1px solid #021a40;
}
</style>

<img class="border" src="http://www.sleberknight.com/blog/sleberkn/resource/firecookie.png" alt="Firecookie Firefox Add-On" title="Firecookie Firefox Add-On"/>

<h3>Firefinder</h3> 

<p>Firefinder for Firebug lets you search for elements on a page using either CSS expressions or an XPath query. In the list of matching elements, you can expand each result, inspect the element by clicking the "Inspect" link, or click "FriendlyFire" which will copy the content you're looking at and post it up to <a href="http://jsbin.com/">JS Bin</a>. (Be careful with this one if you have code you'd rather not have going up over the wire to a different web site.) Firefinder also puts a dashed border around each matching element it found. As you hover over search results, it highlights the matching element in the page. This is really useful when you want to find all elements matching a CSS expression or when you'd like to use XPath to find specific elements. Nice.</p>

<img class="border" src="http://www.sleberknight.com/blog/sleberkn/resource/firefinder.png" alt="Firefinder Firefox Add-On" title="Firefinder Firefox Add-On"/>

<h3>Inline Code Finder for Firebug</h3>

<p>The Inline Code Finder does just that. It finds inline CSS styles, JavaScript links, and inline events, and reports the number of each of these in its results pane. Even better, it highlights each of these problems on the page  you are viewing with a thick red border, and as you hover over them it shows you what the problem is in a nicely tooltip. This is really nice to help you become less obtrusive by writing more unobtrusive JavaScript and avoiding inline styles. For older sites or sites that weren't designed with "unobtrusivity" in mind though, be warned that there might be a lot of red on the page!</p>

<img class="border" src="http://www.sleberknight.com/blog/sleberkn/resource/inlinecodefinder.png" alt="Inline Code Finder Firefox Add-On" title="Inline Code Finder Firefox Add-On"/>

<h3>CodeBurner for Firebug</h3>

<p>CodeBurner for Firebug provides an inline HTML and CSS reference within Firebug. It allows you to search for HTML elements or CSS styles and shows a definition and an example. It also provides links to the awesome <a href="http://www.sitepoint.com/">Sitepoint</a> reference and even to the Sitepoint live demos of the feature you are learning about. This is so unbelievably useful to have a HTML and CSS references directly within Firebug it isn't even funny. Thanks Sitepoint.</p>

<img class="border" src="http://www.sleberknight.com/blog/sleberkn/resource/codeburner.png" alt="CodeBurner Firefox Add-On" title="CodeBurner Firefox Add-On"/>]]></description>
            <link>http://www.nearinfinity.com/blogs/scott_leberknight/several_must_have_firebug-rela.html</link>
            <guid>http://www.nearinfinity.com/blogs/scott_leberknight/several_must_have_firebug-rela.html</guid>
            
                <category domain="http://www.sixapart.com/ns/types#category">Web Development</category>
            
            
                <category domain="http://www.sixapart.com/ns/types#tag">firefox firebug</category>
            
            <pubDate>Mon, 28 Sep 2009 12:47:51 -0500</pubDate>
        </item>
        
    </channel>
</rss>
