Scott Hanselman

WATIR for .NET - WatiN approaches 0.8 release and automating IE from PowerShell

August 18, '06 Comments [7] Posted in ASP.NET | PowerShell | Ruby | Watir
Sponsored By

I'm a big fan of WATIR (pronounced "Water"). However many folks have said they wish they could have a similar tool in .NET. WatiN may be that tool. Looks like they'll be releasing 0.8.0 around September 1st with these changes:

  • An even more Watir like syntax to access an element. There's no need anymore to use MainDocument to access, for example, a TextField. You will now write code like:
    ie.TextField("textfieldid).Text 
  •  Support for finding matching element attribute values by using regular expressions.
  • Out of the box support for finding images by their Src attribute (no need to create your own AttributeValue class for this anymore).
  • Updated documentation.

Looks like a pretty nice, pretty clean implementation of an IE abstraction layer for .NET that will be getting even cleaner very soon. 

Aside: Another great .NET-based IE Automator is Alex Furman's SWExplorerAutomation. Here's an example of integrating SWEA with NUnit.

Back on the Watir side, one of the coolest things about Watir is "putting IE on a string" from the Interactive RuBy shell, or IRB. Leon has a great 3 mins to Watir tutorial that uses the IRB with Watir to interactively poke around at a site. Many folks find this more useful and interesting than using a recorder tool.

For example, assuming you've installed Ruby with the Windows Ruby Installer, open up a cmd.exe prompt and run

gem install Watir

to get Watir. Then run IRB.exe (Interactive Ruby) and do this:

irb(main):001:0> require 'watir'
irb(main):002:0> include Watir
irb(main):003:0> ie = Watir::IE.new
irb(main):004:0> ie.goto("
http://google.com")
irb(main):005:0> ie.text_field(:name, "q").set("Scott Hanselman")
irb(main):006:0> ie.button(:name, "btnG").click

And that's interactive Watir, right? Yay.

So, if I take a look at this WatiN (pronounced WHAT'n as in What'n'tha'heck maybe?) using the only interactive .NET Shell I have available to me...could I do Watir/IRB style interactive work using PowerShell?

PS[1] C:\WatiN-0.7.0.4000\bin
> [System.Reflection.Assembly]::LoadFile((get-item WatiN.Core.dll).FullName)

GAC    Version        Location
---    -------        --------
False  v1.1.4322      C:\WatiN-0.7.0...

PS[2] C:\WatiN-0.7.0.4000\bin
> $ie = new-object WatiN.Core.IE("
http://www.google.com")
New-Object : Exception calling ".ctor" with "1" argument(s): "Could not load fi
le or assembly 'Interop.SHDocVw, Version=1.1.0.0, Culture=neutral, PublicKeyTok
en=null' or one of its dependencies. The system cannot find the file specified.
"
At line:1 char:17
+ $ie = new-object  <<<< WatiN.Core.IE("
http://www.google.com")

Looks like since he's using an unsigned IE interop assembly it can't load it from the current application directory. That's c:/Program Files/Windows PowerShell/v1.0/, not the current directory. At this point I have two choices. I can copy the unsigned intern assembly Interop.SHDocVw.dll to the PowerShell folder, or I can rebuild the project against a Signed Primary Interop Assembly for IE. I'll copy it over for now.

PS[1] C:\WatiN-0.7.0.4000\bin
> [System.Reflection.Assembly]::LoadFile((get-item WatiN.Core.dll).FullName)

GAC    Version        Location
---    -------        --------
False  v1.1.4322      C:\WatiN-0.7.0...

PS[2] C:\WatiN-0.7.0.4000\bin
> $ie = new-object WatiN.Core.IE("
http://www.google.com")
New-Object : Exception calling ".ctor" with "1" argument(s): "Specified cast is
 not valid."
At line:1 char:17
+ $ie = new-object  <<<< WatiN.Core.IE("
http://www.google.com")

Yikes. Looks like folks are pissed off; so pissed off this forcibly closed PowerShell also.

Ok, so WatiN is doing something tricky that PowerShell doesn't like. Well, since PowerShell has its own concept of how .NET and COM should interact. Let's cut out the middle man (WatiN in this case) and go direct to IE from PowerShell .

PS[1]>$psie = new-object -com InternetExplorer.Application
PS[2]>$psie.Navigate("
http://www.google.com")
PS[3]>$q = ($psie.Document.GetElementsByTagname("input") | where { $_.Name -eq "q" } #get the input box called "q"
PS[4]>$q.value = "Scott Hanselman"
PS[5]>$search = $psie.Document.GetElementsByTagname("input") | where { $_.Name -eq "btnG" }
PS[6]>$search.click()

Gross, not easy, but shows potential. You know, a weekend, some UpdateType-Data action and a few functions and one could get a WatiPSH (!?) prototype running that would be very PowerShelly...I wonder if the PowerShell type extension stuff works as nicely with COM objects...

If the WatiN team considers PowerShell in their use cases, their abstraction layer might make a suitable interface for PowerShell scripting. Or, perhaps a few well written PowerShell scripts could give Watir-like syntax on PowerShell. Either way, WatiN has the potential to be pretty useful, particularly within NUnit if you find the Watir NUnit Integration distasteful (some do, I don't, I started it).

For now, I'll stick with the simplicity and IJW of Watir, but I'm keeping my eye on WatiN.

Now playing: Stephen Lynch - Superhero

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook twitter subscribe
About   Newsletter
Sponsored By
Hosting By
Dedicated Windows Server Hosting by SherWeb

AnkhSVN: Using Subversion within Visual Studio

August 17, '06 Comments [9] Posted in Musings | Tools
Sponsored By

Ankh1rc2Congrats to Arild for releasing AhknSVN RC2. If you're looking to use Subversion within Visual Studio, perhaps at work or perhaps you're working on an Open Source project at SourceForge, this is the tool for you.

NOTE: If you do use TortoiseSVN at the same time as Ankh, do note that they are linked to Subversion 1.4, so they will upgrade your local SVN working copies. Make sure you upgrade both at the same time.

To be clear:

IMPORTANT NOTE: TortoiseSVN 1.4.0-RC1 is linked with the Subversion 1.4.0-RC4 libraries. Due to various improvements made to the working copy library, the working copy format has changed. Using TortoiseSVN 1.4.0-rc1 on any working copy created by previous versions of Subversion/TSVN will TRANSPARENTLY upgrade your working copy, which means that production-ready versions of Subversion/TSVN (1.3.x and earlier) will no longer be able to read it! Please be careful, if you use other Subversion clients (eg. the 1.3.x command line client), not to use the TortoiseSVN 1.4.x release candidate on a production working copy.

As with all things, YMMV and back up your life.

ADDITIONAL NOTE: If you get "Unable to retrieve folder information from the server" when using VS2003 in a Web Project, you may need to go into your TortoiseSVN settings and set "use ASP.NET Hack" which tells Tortoise to use folders name "_svn" to store details rather than folders named ".svn".

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook twitter subscribe
About   Newsletter
Sponsored By
Hosting By
Dedicated Windows Server Hosting by SherWeb

Hanselminutes Podcast 29 - Dynamic vs Compiled Languages

August 16, '06 Comments [9] Posted in Podcast | Programming
Sponsored By

My twenty-ninth Podcast is up. This episode is about disruptive technologies like Ruby on Rails, the rise of dynamic languages and what it means to the average .NET developer.

We're listed in the iTunes Podcast Directory, so I encourage you to subscribe with a single click (two in Firefox) with the button below. For those of you on slower connections there are lo-fi and torrent-based versions as well.

This show was FULL of links, so here they are again. They are also always on the show site. Do also remember the archives are always up and they have PDF Transcripts, a little known feature.

Links from the Show

BLINQ (heg)
ARSTechnica on BLINQ (hej)
Castle (hen)
LINQ (heh)
Ruby on Rails (hel)
ActiveRecord (hem)
C# 3.0 (hei)
FTP Online Tutorial on BLINQ (hek)

Subscribe to my Podcast in iTunes

NEW COUPON CODE EXCLUSIVELY FOR HANSELMINUTES LISTENERS: The folks at XCeed are giving Hanselminutes listeners that is Coupon Code "hm-20-20." It'll work on their online shop or over the phone. This is an amazing deal, and I encourage you to check our their stuff. The coupon is good for 20% off any component or suite, with or without subscription, for 1 developer all the way up to a site license.

Our sponsors are XCeed, CodeSmith Tools, PeterBlum and the .NET Dev Journal. There's a $100 off CodeSmith coupon for Hanselminutes listeners - it's coupon code HM100. Spread the word, now's the time to buy.

As I've said before this show comes to you with the audio expertise and stewardship of Carl Franklin. The name comes from Travis Illig, but the goal of the show is simple. Avoid wasting the listener's time. (and make the commute less boring)

  • The basic MP3 feed is here, and the iPod friendly one is here. There's a number of other ways you can get it (streaming, straight download, etc) that are all up on the site just below the fold. I use iTunes, myself, to listen to most podcasts, but I also use FeedDemon and it's built in support.
  • Note that for now, because of bandwidth constraints, the feeds always have just the current show. If you want to get an old show (and because many Podcasting Clients aren't smart enough to not download the file more than once) you can always find them at http://www.hanselminutes.com.
  • I have, and will, also include the enclosures to this feed you're reading, so if you're already subscribed to ComputerZen and you're not interested in cluttering your life with another feed, you have the choice to get the 'cast as well.
  • If there's a topic you'd like to hear, perhaps one that is better spoken than presented on a blog, or a great tool you can't live without, contact me and I'll get it in the queue!

Enjoy. Who knows what'll happen in the next show?

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook twitter subscribe
About   Newsletter
Sponsored By
Hosting By
Dedicated Windows Server Hosting by SherWeb

Enabling Evil - Overriding System.DateTime's default ToString

August 15, '06 Comments [5] Posted in Internationalization | Musings
Sponsored By

Had an interesting back and forth with Tom Wayson today. He wanted to be able to "modify the default behavior of DateTime.ToString()."

So, pushing aside issues of localization and the questions of "why would you want to do that?" let's look at the problem.

He has an intranet application and doesn't need to localize it. He wants to 'enforce' a specific date/time format and wants to avoid writing DateTime.Now.ToString("MM/dd/yy HH:mm:ss") everytime. He also doesn't want to explicitly set the system-wide settings in Control Panel | Regional Settings.

He noted that the output of DateTime.Now.ToString on a standard en-us machine in the states gave this output:

8/15/2006 3:27:27 PM

It looks like the output of ToString is the combination of the DateTimeFormatInfo.ShortDatePattern and DateTimeFormatInfo.ShortTimePattern. So, he: 

Imports System

Imports System.Globalization

 

Public Module MyModule

    Sub Main()

        Dim customCulture As CultureInfo = New CultureInfo("en-US")

        customCulture.DateTimeFormat.ShortDatePattern = "MM/dd/yy"

        'HH means 24 hour time, while hh means 12 hour time
        customCulture.DateTimeFormat.ShortTimePattern = "HH:mm:ss"

 

        System.Threading.Thread.CurrentThread.CurrentCulture = customCulture

        System.Threading.Thread.CurrentThread.CurrentUICulture = customCulture

 

        WL(DateTime.Now.ToString())

        WL(DateTime.Now.ToShortDateString())

        WL(DateTime.Now.ToShortTimeString())

    End Sub

 

    Sub WL(ByVal text As Object)

        Console.WriteLine(text)

    End Sub

End Module 

But the output was still 12 hour time:

8/15/06 3:28:34 PM

Ah...a little Reflectoring shows us that the default format string for System.DateTime is "G" as in System.DateTime.ToString("G") where G is one of the presets.

From PowerShell we see:

PS>C:\Documents and Settings\shanselm\Desktop
[DateTime]::Now.ToString("g")
8/15/2006 3:28 PM
PS>C:\Documents and Settings\shanselm\Desktop
[DateTime]::Now.ToString("G")
8/15/2006 3:28:02 PM
PS>C:\Documents and Settings\shanselm\Desktop
[DateTime]::Now.ToString()
8/15/2006 3:28:15 PM

So we add:

Imports System

Imports System.Globalization

 

Public Module MyModule

    Sub Main()

        Dim customCulture As CultureInfo = New CultureInfo("en-US")

        customCulture.DateTimeFormat.ShortDatePattern = "MM/dd/yy"

        'HH means 24 hour time, while hh means 12 hour time
        customCulture.DateTimeFormat.ShortTimePattern = "HH:mm:ss"       
        customCulture.DateTimeFormat.LongTimePattern = "HH:mm:ss"

 

        System.Threading.Thread.CurrentThread.CurrentCulture = customCulture

        System.Threading.Thread.CurrentThread.CurrentUICulture = customCulture

 

        WL(DateTime.Now.ToString())

        WL(DateTime.Now.ToShortDateString())

        WL(DateTime.Now.ToShortTimeString())

    End Sub

 

    Sub WL(ByVal text As Object)

        Console.WriteLine(text)

    End Sub

End Module 

And gets the output he expects, indicating that "G" is the combination of a ShortDate and a LongTime.

8/15/2006 15:28:57

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook twitter subscribe
About   Newsletter
Sponsored By
Hosting By
Dedicated Windows Server Hosting by SherWeb

A Day in the Z - Mischief and Mayhem 1

August 15, '06 Comments [12] Posted in Movies | Musings | Parenting | Z
Sponsored By

ZmischiefthumbWARNING: This post has nothing technical going on. Maybe a little because of the MP4 compressed video, but that's a stretch at best. If you don't have young kids, or perhaps you hate pets and/or small children, ignore this post.

My good friend Eli told me after the birth of his lovely young daughter:

Kids go through three phases, Plant, Pet, Person. My daughter (A month old at this point) is currently a Plant. We feed her, she water us, and she sits for long periods. Z is now in the Pet stage. He'll follow you anywhere and smiles when he sees you.

God help us when they become People. Because with People come Opinions.

Z is eight and a half months old and he's unstoppable. He's a biscuit away from walking and he roams the house ruling with an iron, if slightly moist, fist. This is an obnoxiously long video with no audio of my pride and joy roaming the house.

A few notes and disclaimers. The kitchen is being remodelled so that's why we have no countertops. Z is in the "decoy drawer" that I've setup for him that includes old remote controls and random safe stuff for him to 'discover.'

This video is an MP4. If you have trouble viewing it, try Quicktime, a newer Windows Media Player, or the amazing-give-it-to-your-famly VLC Player.

File Attachment: ZMischief.mp4 (5882 KB)

We'll be back in tech tommorow.

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook twitter subscribe
About   Newsletter
Sponsored By
Hosting By
Dedicated Windows Server Hosting by SherWeb

Disclaimer: The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.