<?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:rssdatehelper="urn:rssdatehelper"><channel><title>Patrick McAndrew</title><link>http://blog.urg.name</link><pubDate></pubDate><generator>umbraco</generator><description>Techical related blog</description><language>en</language><item><title>Selenium smoke testing using sitemap</title><link>http://blog.urg.name/2011/2/17/selenium-smoke-testing-using-sitemap.aspx</link><pubDate>Thu, 17 Feb 2011 09:07:15 GMT</pubDate><guid>http://blog.urg.name/2011/2/17/selenium-smoke-testing-using-sitemap.aspx</guid><content:encoded><![CDATA[ 
<p>It seems to me that if you have a smaller sized site, its
probably useful to run selenium against all the sitemap.xml files,
just to make sure all the pages work and don't immediately come up
with errors - a very basic smoke test.</p>

<p>After spending 15 minutes googling and not finding anything
exactly what I was looking for, I thought I would jot down a bit of
code in case anyone else finds it useful.</p>

<p>&nbsp;</p>

<p>private static string baseUrl = "http://site.com";<br />
 private static string sitemapRelativeUrl =
"/google-sitemap.aspx";<br />
 private ISelenium selenium;<br />
<br />
 [TestFixtureSetUp]<br />
 public void SetupTest()<br />
 {<br />
 selenium = new DefaultSelenium("localhost", 4444, "*chrome",
baseUrl);<br />
 selenium.Start();<br />
 }<br />
<br />
 [TestFixtureTearDown]<br />
 public void TeardownTest()<br />
 {<br />
 selenium.Stop();<br />
 }<br />
<br />
 /// &lt;summary&gt;<br />
 /// Get a navigator for the sitemap<br />
 /// &lt;/summary&gt;<br />
 /// &lt;returns&gt;&lt;/returns&gt;<br />
 private XPathNavigator GetSitemapNavigator()<br />
 {<br />
 System.Xml.XmlReader xmlReader = new
System.Xml.XmlTextReader(baseUrl + sitemapRelativeUrl);<br />
 System.Xml.XPath.XPathDocument doc = new
System.Xml.XPath.XPathDocument(xmlReader);<br />
 var nav = doc.CreateNavigator();<br />
 return nav;<br />
 }<br />
<br />
 /// &lt;summary&gt;<br />
 /// Get a namespace manager for the sitemap<br />
 /// &lt;/summary&gt;<br />
 /// &lt;param name="namespaceAlias"&gt;&lt;/param&gt;<br />
 /// &lt;returns&gt;&lt;/returns&gt;<br />
 private XmlNamespaceManager GetSitemapManager(XPathNavigator nav,
string namespaceAlias)<br />
 {<br />
 XmlNamespaceManager manager = new
XmlNamespaceManager(nav.NameTable);<br />
 manager.AddNamespace(namespaceAlias,
"http://www.sitemaps.org/schemas/sitemap/0.9");<br />
 return manager;<br />
 }<br />
<br />
/// &lt;summary&gt;<br />
 /// Make sure that the sitemap can be loaded and has entries<br />
 /// &lt;/summary&gt;<br />
 [Test]<br />
 public void LoadSitemapAndCheckQuery()<br />
 {<br />
 var nav = GetSitemapNavigator();<br />
 var manager = GetSitemapManager(nav, "sitemap");<br />
 Assert.IsTrue(nav.Select("//sitemap:loc", manager).Count &gt;
0);<br />
 }<br />
<br />
 /// &lt;summary&gt;<br />
 /// Load up each of the sitemap pages<br />
 /// &lt;/summary&gt;<br />
 [Test]<br />
 public void LoadAllSitemapPages()<br />
 {<br />
<br />
 List&lt;string&gt; ExpectedRedirects = new
List&lt;string&gt;();<br />
 ExpectedRedirects.Add(string.Format("{0}/url.aspx",
baseUrl));<br />
<br />
 var nav = GetSitemapNavigator();<br />
 var manager = GetSitemapManager(nav, "sitemap");<br />
 XPathNodeIterator iterator = nav.Select("//sitemap:loc",
manager);<br />
 if (iterator.Count &gt; 0)<br />
 {<br />
 Uri url = null;<br />
 while (iterator.MoveNext())<br />
 {<br />
 try<br />
 {<br />
 if (Uri.TryCreate(iterator.Current.InnerXml,
UriKind.RelativeOrAbsolute, out url))<br />
 {<br />
 selenium.Open(url.ToString());<br />
 string currentBodyText = selenium.GetBodyText();<br />
<br />
 Assert.IsFalse(currentBodyText.IndexOf("Error parsing XSLT file:")
&gt;= 0, string.Format("Error parsing XSLT File url: {0}",
url));<br />
 Assert.IsFalse(currentBodyText.IndexOf("Error reading XSLT file:")
&gt;= 0, string.Format("Error reading XSLT File url: {0}",
url));<br />
 Assert.IsFalse(currentBodyText.IndexOf("Server Error in '/'
Application.") &gt;= 0, string.Format("Server error url: {0}",
url));<br />
<br />
 // Unless we are expecting the page to redirect, throw an error if
it does<br />
 if (!ExpectedRedirects.Contains(url.ToString()))<br />
 Assert.AreEqual(url.ToString().Replace("'", "%27"),
selenium.GetLocation(), "{0} was redirected to {1}",
url.ToString(), selenium.GetLocation());<br />
 }<br />
 }<br />
 catch (Exception ex)<br />
 {<br />
 Assert.Fail(string.Format("Exception found. Last url: {0}
Exception: {1}", url, ex));<br />
 }<br />
 }<br />
 }<br />
 }</p>
]]></content:encoded></item><item><title>Umbraco deeplinking (aka loading content node on login)</title><link>http://blog.urg.name/2011/1/21/umbraco-deeplinking-(aka-loading-content-node-on-login).aspx</link><pubDate>Fri, 21 Jan 2011 14:31:00 GMT</pubDate><guid>http://blog.urg.name/2011/1/21/umbraco-deeplinking-(aka-loading-content-node-on-login).aspx</guid><content:encoded><![CDATA[ 
<p>I spent at least 10 minutes googling without an answer, since I
didn't know the keyword 'deeplinking', so in case anyone else is
interested:</p>

<p>How do you load a content node in Umbraco via a url?</p>

<p>
/umbraco/umbraco.aspx?app=content&amp;rightAction=editContent&amp;id={nodeId}</p>

<p>Seems like this syntax can be used for accessing anything in the
umbraco cms.&nbsp; Quite useful!</p>
]]></content:encoded></item><item><title>Deploying to Umbraco</title><link>http://blog.urg.name/2011/1/21/deploying-to-umbraco.aspx</link><pubDate>Fri, 21 Jan 2011 14:12:55 GMT</pubDate><guid>http://blog.urg.name/2011/1/21/deploying-to-umbraco.aspx</guid><content:encoded><![CDATA[ 
<p>How do you deploy Umbraco?</p>

<p>&nbsp;</p>

<p>Up until this point, I was either working on the occasional file
which could just be copied or just working via the cms
website.&nbsp; But when you have a larger deployment, the ordering
of items becomes important.&nbsp; So here's my initial
checklist.&nbsp; Now to figure out how to automate more of
this.</p>

<p>&nbsp;</p>

<p>Standard Deployment steps:<br />
<br />
 1) Backup files from environment<br />
<br />
 2) Create any new Relation Types in Umbraco CMS<br />
<br />
 3) Create any new Data Types in Umbraco CMS<br />
<br />
 4) Create any new masterpages in Umbraco CMS<br />
<br />
 5) Import any new Doc Types in Umbraco CMS (order is
important)<br />
<br />
 6) Create any Dictionary Items<br />
<br />
 7) Alter Doc Types to allow for updated Templates /
Structure<br />
<br />
 8) Copy files to environment<br />
<br />
9) Create Macros<br />
<br />
10) Create nodes<br />
<br />
11) Update nodes</p>
]]></content:encoded></item><item><title>Trac &amp; Milestones</title><link>http://blog.urg.name/2010/11/7/trac--milestones.aspx</link><pubDate>Sun, 07 Nov 2010 13:45:18 GMT</pubDate><guid>http://blog.urg.name/2010/11/7/trac--milestones.aspx</guid><content:encoded><![CDATA[ 
<p>From my understanding, with Agile, you want very small
iterations.&nbsp; Release often and frequently.</p>

<p>However, there is always a bit of admin to do beforehand.&nbsp;
Dev environments need to be setup, some type of project plan is
usually required, etc.</p>

<p>Most of my development setup is complete, I have a workstation
with Visual Studio &amp; Sql Server and I have a server with
SVN.&nbsp; I did have to install Trac on my linux server, which
although wasn't very complicated, still took 1/2 hour to get
everything correct.</p>

<p>I don't want to overdue the project management, rather just a
basic area to keep track of how things are progessing and a place
to organise future enhancements.</p>

<p>In keeping it simple, I have the following milestones setup:</p>

<ul>
<li>Intial Website where the user should be able to create an
account, login, upload their laugher</li>

<li>Better Website Features where the user can rate other people's
laughter and play a guessing game</li>

<li>Basic Facebook integration - as I don't know much about
facebook integration, I will fill this in later, but its enough for
now to know reach is needed</li>

<li>Improved website design - I'm focusing on funcationality first
as design is usually easy to plug in later on.&nbsp; I'm not a
designer, so even an improved design will still be a bit crap, but
I should be able to at least get it looking clean and simple.</li>

<li>IOS application - again, I don't know much about this, so will
leave it to later</li>
</ul>

<p>So now the focus is to enter in the tickets for the first
milestone and creating a basic website.</p>

<p>I know that my BDD is very weak, so research on that as well as
research on Azure will be the first tasks.</p>

<p>Project planning complete for now.&nbsp; Once research is done,
I should be able to flesh out the tickets a bit more and put some
times down.</p>
]]></content:encoded></item><item><title>#devchallenge Announcement</title><link>http://blog.urg.name/2010/11/7/#devchallenge-announcement.aspx</link><pubDate>Sun, 07 Nov 2010 13:25:07 GMT</pubDate><guid>http://blog.urg.name/2010/11/7/#devchallenge-announcement.aspx</guid><content:encoded><![CDATA[ 
<p>With about a month to spare, I have decided to set myself a bit
of a challenge and launch a site laughterbank.com that I've been
meaning to do for awhile.</p>

<p>Laugherbank will be a simple website to upload your laughter
(mp3 type recording), listen to other people's laughter and rate
them (on the funniness scale).</p>

<p>To make it interesting, I want to upgrade my skillset a bit and
learn some new technoogies that I've been meaning to pick up.&nbsp;
So I plan on using/doing the following:</p>

<ul>
<li>I'm finally going to try using twitter (#devchallenge) and see
if there's any use in it.&nbsp; Also, will finally use my blog
beyond just technical notes for myself.</li>

<li>Asp.Net MVC - v3 beta is out, so it appears to be the future.
Time to get onboard.</li>

<li>TDD - I've created and used unit tests, but its always been
after the fact.&nbsp; Time to see how creating the test beforehand
actually works in a project.</li>

<li>BDD - I've never used it before - lets see how it works.</li>

<li>Continous build - I've used it before and its good, so its
about time to have it running in my environment.</li>

<li>Azure hosting - Its the new thing.&nbsp; I'm sure the scability
is good, but I've heard there are some tricks to get a site running
with low costs.&nbsp; Lets see how feasibile this is.&nbsp; If its
too expensive, then I'll host it on my windows vps and perhaps move
it to amazon aws if the traffic ramps up.</li>

<li>Agile Development - With myself as the only team member, I
don't think daily scrums are necessary, but there can definitely be
apsects of scum applied even to a personal project.&nbsp; I'll be
using trac to manage this project.</li>

<li>IOS - I signed up to the apple developer network about a year
ago.&nbsp; Its finally time to get an app out there.</li>

<li>Facebook App - I'm about 5 years late on this one, but its a
good way to get lots of traffice for a social network
application.</li>

<li>And if time, a Windows 7 mobile app and Android app would be
good as well.</li>
</ul>

<p>So, off I go.&nbsp; Wish me luck and hope to hear some
comments.</p>
]]></content:encoded></item><item><title>Remote Debugging</title><link>http://blog.urg.name/2010/4/13/remote-debugging.aspx</link><pubDate>Tue, 13 Apr 2010 15:38:32 GMT</pubDate><guid>http://blog.urg.name/2010/4/13/remote-debugging.aspx</guid><content:encoded><![CDATA[ 
<p>There always seems to be a bit of confusion setting up remote
debugging in a cross domain environment.&nbsp; In my current
contract, there is the domain we log into (domain1), and then the
development domain (domain2) which we have control over. Perhaps
not all of these items are required and it is definitely not a
secure method, but if they are set, then it should work.</p>

<p>Domain1</p>

<p>==</p>

<p>LM1 (Local machine)</p>

<p>User1 (your login account)</p>

<p>&nbsp;</p>

<p>Domain2</p>

<p>==</p>

<p>RM1 (Remote machine to be debugged)</p>

<p>&nbsp;</p>

<p>* On RM1, create local account RM1\User1&nbsp; Assign to local
administrators group.</p>

<p>* Make sure that Domain2\Administrator has the same password as
LM1\Administrator.&nbsp; Also, neither account should be locked
out.</p>

<p>* Turn off firewalls on both machines (make sure to do in the
windows firewall setting - the service still needs to run)</p>

<p>* Login to RM1 as Domain2\Administrator</p>

<p>* Start (install in necessary) the Remote Debug Monitor (run as
an app, not as a service).</p>

<p>** Tools/Permissions, Add RM1\User1 with Debug permissions.</p>

<p>** Tools/Options, set server name to: RM1\User1@RM1</p>

<p>* On LM1, Visual Studio, Attach to Process, Transport Default,
Qualifier = RM1\User1@RM1.&nbsp; Note that @RM1 can be replaced by
@RM1_IPAddress, however, it's better to add RM1 to the hosts
file.</p>
]]></content:encoded></item><item><title>WinMerge Settings</title><link>http://blog.urg.name/2010/2/5/winmerge-settings.aspx</link><pubDate>Fri, 05 Feb 2010 14:54:10 GMT</pubDate><guid>http://blog.urg.name/2010/2/5/winmerge-settings.aspx</guid><content:encoded><![CDATA[ 
<div>
<p><a href="http://winmerge.org/">WinMerge</a> is a great diff
tool.<br />
 A few options to change (Edit/Options)</p>

<p>Compare: Ignore Carriage Return Differences<br />
 System: Add to explorer context Menu + Enable advanced menu +
Include subfolders by default<br />
 External editor: C:\Program Files\Notepad++\notepad++.exe<br />
 Backup File: Untick File Backup</p>
</div>
]]></content:encoded></item><item><title>Tortoise</title><link>http://blog.urg.name/2010/2/5/tortoise.aspx</link><pubDate>Fri, 05 Feb 2010 14:53:54 GMT</pubDate><guid>http://blog.urg.name/2010/2/5/tortoise.aspx</guid><content:encoded><![CDATA[ 
<div>
<p><a href="http://tortoisesvn.tigris.org/">Tortoise</a> has a few
settings that will improve performance and useability.</p>

<p>The first is to only use the icon overlay in a specific folder
(and subfolders). I put all my local files under c:\Working
Docs.<br />
 Go to the settings menu, Look And Feel, Icon Overlays and under
include path type in something like c:\Working Docs\*</p>

<p>I also tend to use Diff quite a bit, so under settings, Look and
Feel, untick Diff, and it will now show up in the main context menu
instead of the sub-context menu.</p>

<p>Finally, I find WinMerge a much easier app to use than
TortosieMerge. Provided WinMerge is installed, go to
Settings/External Programs, Select External and type in C:\Program
Files\WinMerge\WinMergeU.exe (or the relivent path).</p>
</div>
]]></content:encoded></item><item><title>Accessing Underlying Data in DataBound Event</title><link>http://blog.urg.name/2010/2/5/accessing-underlying-data-in-databound-event.aspx</link><pubDate>Fri, 05 Feb 2010 14:53:28 GMT</pubDate><guid>http://blog.urg.name/2010/2/5/accessing-underlying-data-in-databound-event.aspx</guid><content:encoded><![CDATA[ 
<div>
<p>I always forget how to access the underlying data in a DataBind
Event. Example:</p>

<p>protected void userListItem_Bound(Object sender,
GridViewRowEventArgs e)<br />
 {<br />
 if (e.Row.RowType == DataControlRowType.DataRow)<br />
 {<br />
 DataRowView currentRow = (DataRowView)e.Row.DataItem;<br />
 string currentUser = (string)currentRow["Username"];<br />
 }<br />
 }</p>
</div>
]]></content:encoded></item><item><title>FindControlR</title><link>http://blog.urg.name/2010/2/5/findcontrolr.aspx</link><pubDate>Fri, 05 Feb 2010 14:53:09 GMT</pubDate><guid>http://blog.urg.name/2010/2/5/findcontrolr.aspx</guid><content:encoded><![CDATA[ 
<p><a
href="http://www.extensionmethod.net/Details.aspx?ID=129">FindControlR</a>
is a very useful method to include in an Asp.Net project. If you
don't know which control holds a control, you can use a parent
control (such as form) to find it.</p>
]]></content:encoded></item></channel></rss>

