Tag Archives: Automation

Did you know PowerShell can use Selenium?

This is sort-of a place-holder for a full-length post that I really ought to write about driving web testing from PowerShell using Selenium. I actually have a little module around for doing that with WaTiN, but honestly the Selenium project seems to be a lot more active, and has quite a bit of muscle behind it since they’ve merged with WebDriver…


Add-Type -path ~\Downloads\selenium-dotnet-2.16.0\net40\WebDriver.dll

# Navigate to google in IE (or Firefox, Chrome, Opera, etc)
$driver = New-Object OpenQA.Selenium.IE.InternetExplorerDriver
$driver.Url = "http://google.com"

# Type PowerShell into the query box, the page will update via AJAX
# Note we won't hit enter or anything
$q = $driver.FindElementByname("q")
$q.SendKeys("PowerShell")

# Use a CSS selector to find the first result link and click it
$driver.FindElementByCssSelector("li.g h3.r a").Click()
 

One Catch

The Security tab of the Internet Options dialogIf you try this with IE and you get the error Unexpected error launching Internet Explorer. Protected Mode must be set to the same value (enabled or disabled) for all zones ... it means exactly what it says. You need to open “Internet Options” from your start menu (or from IE), and go through each “zone” and set the “Enabled Protected Mode” check box to the same value for each zone (either all checked, obviously the most secure, or all unchecked). I’m not going to debate whether setting them all unprotected is a good idea … I set mine to all protected, but I don’t generally use IE anyway.

If you want more help, Selenium’s documentation is great, and there’s a section on Getting Started with Selenium WebDriver which I found quite helpful (make sure your examples are in “csharp” and you can almost just copy and paste — someone should offer to do them in PowerShell).

If you want more information about the Internet Explorer driver and this problem in particular, the short answer is that “Protected Mode” is a security boundry, so if you cross over it the COM automation object doesn’t work — thus, you need to make sure you always stay on the same side. There’s a good discussion on the mailing list archive about how it works and why, as well a weird alternative documented on the Selenium JavaDocs

Convert Twitter users into FriendFeed Imaginary Friends!

So a lot of people seem to be taking the latest missteps by Twitter’s management (and the accompanying admission of bad design) as an opportunity to try out some alternatives. Many of them seem to be coming over to FriendFeed (which has been better than Twitter for a long time, but nevermind that) ... so I thought I’d update and release a PowerShell 2.0 script I wrote to create imaginary friends out of your friends that stay on Twitter.

The first part of it is a WatiN script (that automates your browser) called New-ImaginaryFriend which takes three parameters: a name for the imaginary friend, a url for an avatar for the friend, and a HashTable… Of course, we sort-of cheat by using the HashTable … it’s basically a bunch of key-value pairs of remote services and user names. You can use it to add twitter ID’s like twitter="jsnover" or blogs like blog="http://HuddledMasses.org/" etc. You can even add multiple sources (eg: twitter + diigo, two blogs, etc) to a single new imaginary friend 8) ...

This script is done using WatiN because the FriendFeed API doesn’t support creating imaginary friends yet, and as a result it’s slow, and requires IE (and doesn’t seem to work very well with IE8 — at least, I couldn’t get it to set the avatars using IE 8 on Windows 7, so I commented out the avatar part of the next-to-last line).

The other part of the script is a pair of functions: the first is Get-FriendFeedFriends which retrieves profile information for all your friends in a slick format that includes all their services and such … you may find other uses for this later ;-) , the second is Get-TwitterFriends … Both have an -Exclude parameter so you can pass it a list of people to ignore.

When you put these three functions together, you can just import the FriendFeed module, and start creating friends (don’t forget this version of the scripts only works with IE6 or IE7 for the purpose of avatars, as WatiN can’t seem to set the file upload value in IE8 yet).


Import-Module FriendFeed
## Get any twitter friends who aren't on friendfeed
## Make sure you use FriendFeed's built in "add all your twitter friends" first
$twits = Get-TwitterFriends `
         -Nickname jaykul
         -Exclude $(Get-FriendFeedFriends jaykul | select -expand twitter)

## Add them to friend feed
foreach($twit in $twits) {
   New-ImaginaryFriend $twit.name @{twitter=$twit.screen_name} $twit.profile_image_url
}

You can download all of the required modules at once (7z), or grab the latest versions of them from PoshCode: FriendFeed, HttpRest, and WatiN … but if you do that, you’ll still need to get the binaries separately :-/

Reblog this post [with Zemanta]

Using PowerShell and WatiN (PowerWatin?)

This is an update to a previous article.

Someone asked (on Twitter) about using WatiN from PowerShell, and pointed to this old post by Scott Hanselman saying he was having the same problems … so I wrote this to help them out:

WatiN requires -STA mode

Note: WatiN requires Single Threaded Apartment mode, so you need to be using PowerShell 2.0 (currently in CTP3) in order for any of this to work, and you need to pass the -STA parameter to PowerShell. Regardless, I thought I’d throw two tips out here:

Don’t use LoadFile, use LoadFrom

I’m not 100% sure when it’s appropriate to use LoadFile in PowerShell, but I can tell you that if your assembly is in a folder with a bunch of other assemblies upon which it depends … you need to use [Reflection.Assembly]::LoadFrom( $path ) instead — because the .net loader will be able to find the dependencies.

Generate some functions to help yourself out

It’s trivial to do code-generation in PowerShell, and WatiN is not friendly to the PowerShell syntax, so you’re going to want to generate a bunch of them. To get you started, here’s a set of Find-* functions to let you find each type of element that WatiN recognizes and automates… by name, id, class, style … well, by any attribute, really:

Continue reading

PowerShell User Group Thursday (Tomorrow, Dec 4)

The PowerShell Virtual User Group meeting from November was rescheduled for this first week of December, but I’m still going to be presenting there.

Please join us on Live Meeting!

Particularly if you’re interested alternate PowerShell consoles, because not only will I be presenting my (PoshConsole), but Idera will be there to show off their latest commercial console and script editor PowerShell Plus Professional.

I’ll also be presenting some information about the PowerShell Script Repository, and about my Windows (GUI) Automation Snapin for PowerShell (WASP), and Nathan Winters will be discussing managing Exchange with PowerShell, so there’s sure to be something for everyone :-) I’d love to see more people at this event than usual, despite the repeated rescheduling, to encourage Marco Shaw (the user group organizer). After all, it’s free!

It’s tomorrow December 4th, at noon Eastern. (2008/12/04 12:00:00 PM -05:00)

Note: this is not a rescheduling of my much longer presentation about PowerShell at my local Visual Developers user group (which is coming up on December 17th), and doesn’t cover any of that content. ;)

Reblog this post [with Zemanta]

PowerShell User Group and Community News!

I keep forgetting to mention this! I’m speaking at the next PowerShell Virtual User Group this Thursday, November 13th at 12PM EST. Join us if you’re interested in any of my PowerShell CodePlex projects (PoshConsole, PoshCode, WASP). Actually, join us even if you’re not, because there’s going to be a demo of the latest version of PowerShell Plus by the folks from Idera, and Nathan Winters will be discussing managing Exchange with PowerShell.

Also, the PowerShell Community is running a survey about the possibility of a PowerShell convention, and what you’re interested in seeing at one… it’ll just take a moment :)

Window GUI Automation from PowerShell

Well, I am going to put this all on CodePlex tomorrow, but I promised a few people that I’d throw it up here for them yesterday, so I figured it’s past time to post it … without further ado. [new] The Window Automation Snapin and it’s source should be downloaded from the CodePlex project where updates can be tracked. :)

This is basically an upgrade to the Win32.Windows snapin I released a while back, the one thing that’s missing in this release that was possible in that one is using frame-set definitions to position windows. That will make it back in eventually, but in the meantime, I present some major new additions which add up to the ability to do 90% of what you’d want to do in testing or automating your winforms app’s UI.

  • Select-Window – pick windows by process name or window caption (with wildcard support)
  • Select-Control – pick controls by class and/or name and/or index (with wildcard support)
  • Send-Click – send mouse clicks (any button, with any modifier keys)
  • Send-Keys – Windows.Forms.SendKeys lets you send keys … try this: Select-Window notepad | Send-Keys "%(ea)Testing{Enter}{F5}" (and for extra fun, try it with multiple notepad windows open).
  • Set-WindowActive – yeah, just activates the window
  • Set-WindowPosition – set any one of (or all of) top, left, width, height on a window … or maximize/minimize/restore
  • Get-WindowPosition – get the position (kind-of redundant, actually, since the Window object has it’s position as a property)
  • Remove-Window – closes the specified window

There’s no help right now, so get used to using Get-Command -PSSnapin WindowAutomation and checking out the ParameterSets … hopefully you can figure it out from that for now. Oh, one other thing, there might be a few extras hiding in these:

  • [Huddled.Win32.WindowExtenders] | Get-Member -static
  • [Huddled.Win32.WindowFinder] | Get-Member -static

For now, that will have to do, it’s past time for bed. You might want to play with this and the out-voice script I posted on CodePlex awhile back, it makes things extra fun.

Control Windows from PowerShell

[New] CodePlex Project

As I announced recently I have created a Windows Automation PowerShell Snapin project to house this snapin on CodePlex, and added a bunch of features. You should head over there for the download.

Original Post

I’ve been crazy busy the last few weeks, but I’ve been really rather distracted from my main project and it’s past time I got back to it. To really feel like I’ve moved on, I need to write a bunch of articles here and publish a couple of cool apps and some source code so that I can feel like I’ve reached a release point. What I’ve been playing with in all this coding is the new technology that’s been coming out of Microsoft in the last couple months: PowerShell, .NET 3 and WPF, and Windows Vista so you may or may not actually be able to use these apps …

So yeah, anyway … I’ve been playing around with PowerShell cmdlets, and as a shell geek, I couldn’t help wondering why there wasn’t a way to enumerate windows and move them around … so I wrote one. Eventually this will show up in the PowerShell Community Extensions — but I’m posting it here for now because the powershell cmdlet process is pretty interesting.

I started off by writing a wrapper for some of the Win32 APIs, and then a PSSnapIn which provides Get-Window and Remove-Window. When you execute Get-Window, the resulting object is a Win32.Window which has methods for closing, moving, resizing, maximizing and restoring, etc. The Remove-Window cmdlet is just a wrapper to call the Close() method, but it seems to make sense in the PowerShell pipe, since you can pipe the window objects through filters etc.

I still need to finish up the Move-Window cmdlet — it’s an advanced window-organizing feature. Right now it’s only feature is that it can tile windows vertically or horizontally with percentages specified by you. The features there are a little weak, but it’s past time I show you what I mean.

What you would want to do is install the snapin and then try typing these commands one at a time (so you can see the results).


for( $i = 0; $i -lt 3; $i++){notepad}
Get-Window *notepad* > Notepad.txt
notepad Notepad.txt
Get-Window "Untitled - N*" | Move-Window "20%,30%,50%"
ps notepad | Move-Window "20%,30%,20%,30%" 0
(Get-Window *Notepad.txt*).Minimize()
$notes = Get-Window *notepad*
$notes[0].Minimize()
Get-Window | where {$_.ProcessName -eq "notepad" -and -not $_.IsMinimized} | Remove-Window
ps notepad | Remove-Window
 

A little explanation is in order:

  • Obviously the first three lines basically start up a few copies of notepad — three of them empty, one with a text file.
  • The next line shows how Get-Window works with wildcard matching on the window titles … and how Move-Window uses percentage values to organize windows.
  • Then you see that you can pipe the output of Get-Process (aliased as ps) through Move-Window. You can pipe it through Get-Window too, but the important take away here is that Remove-Window and Move-Window can both take processes as input — as long as those processes have actual windows. You’ll also notice that final parameter “0” to cause Move-Window to tile horizontally instead of vertically — “1” is the default.
  • The next three lines are examples of how you can call methods on individual Window objects.
  • And finally, the next-to-last line is just an example of how you can use Where-Object to filter windows, and the last line is just to get rid of the remaining instances of notepad.

You can download Win32.Window for PowerShell (it’s a 7-zip file, you’ll need TugZip or 7-Zip) ... it includes the source (which you can use under any of several open source licenses including Ms-PL, BSD and GPL) and the actual DLL in the bin/Release directory, along with the scripts Install.ps1 and Uninstall.ps1 ;)

Feature requests and code contributions are both welcome!