Category Archives: SePSX tutorial

Turned a year!


Just remembered that the¬†PowerShell testing suite turned a year. As it believed, approx. on November 28th, 2011, the result of a programming mistake, of course (a piece of code didn’t work in PowerShell, just a usage mistake), the decision to write up C#-cmdlets has been made. ūüôā

Since then, our frameworks have changed significantly. It was only UIAutomation which was the root of the suite. Now, there are several frameworks published and several versions upcoming.

Shortly, I’d drop a word about the Software Testing Using PowerShell team plans. From the features that are almost ready to those that are only in mind. What will the upcoming winter bring to us?

UIAutomation:

  • on fail, the Invoke-UIA[ControlType]Click cmdlets will try Win32 click by default. This behavior (the user wants it click and it clicks) is most awaiting (thanks to JohnQuest for the idea).
  • the Set-UIA[ControlType]Text cmdlets will check the result and try to use SendKeys on a failure
  • the Set-UIAControlKeys cmdlet will try several times to put text into the input field, checking the result
  • UIAutomationSpy are going to produce more useful code. Moreover, the code produced is¬†going to be faster. How? When possible, UIAutomationSpy will set the -Win32 parameter, what, in certain situations, accelerates tests significantly (working with controls near grids and listviews is slow; this can be healed by using Win32 handles).
  • UIAutomationSpy will finally check code that it generates (sometimes what can be got by hovering over is not the same that can be got by searching in the Automation tree).
  • at least ten pages of documentation as what is published is like a mad mix
  • setup for the module
  • Java Access Brigde (that has not been tried yet)
  • we will try to use UIA2 if it’s possible to combine two UI Automation technologies

SePSX:

  • support for ChromeOptions, InternetExplorerOptions and FirefoxProfile
  • fast-working ‘named’ cmdlets Get-Se[TagName]
  • cmdlets for working with tables
  • SeleniumSpy
  • in a perspective, support for other browsers

TMX:

  • TestLink add-in (missing functionality)
  • TFS add-in
  • working with test cases in SQLite, TestLink, various files

AWSPSX:

  • EC2 and S3 cmdlets to allow automated test lab deployment and execution

ESXiMgmt:

  • a small set of cmdlets allowing us to start/stop/suspend/snapshot guests

Internals:

  • these days we are working on harnessing a Dependency Injection framework. By now, SePSX is partially sitting on Autofac 2.6 and we are also experimenting with NInject 3 in other projects. TLAddin has benefited from using Moq. The reasons we are working on not a business-understood features are such:
  1. the number of tests is growing and the testing cycle should be running every several minutes. Hundreds of tests we already have are for daily framework verification (they take twenty minutes or more, what is critical for us). On the opposite, a hundred of unit tests we have already had take less than five seconds (and around seventeen seconds does Gallio take to get the consciousness at the start of testing)
  2. we need more through-out testing of our code
Advertisements

Web automation: even more PowerShell for getting a WebElement


Yesterday, we worked on a translation of the sample from SeleniumHQ to PowerShell. One of the great PowerShell advantages is the ability to use .NET objects in code similarly to what C# programmers do. I’m speaking about the following piece of code:

$ff01 = Start-SeFirefox;
$searchBox = ($ff01 | Enter-SeURL -URL "http://www.google.com/" | Get-SeWebElement -Name "q");
$searchBox.SendKeys("Cheese");
$searchBox.Submit();
sleep -Seconds 3; # to observe the result
$ff01.Title;
$ff01 | Stop-SeFirefox;

We have been using two variables here, $ff01 for a browser instance (the driver) and $searchBox for the prominent Google search text box. Using methods .SendKeys(text), .Submit() and properties like .Title is what is considered by purists as the ‘CSharp style’. The purists (they are also known for the abbreviation MVP. I really don’t know how they managed to shorten the word ‘purist’ to ‘MVP’ :)) state that the only right way of using PowerShell is end-to-end pipelining. Okay, today’s our efforts are put in this direction:

$ff01 = Start-SeFirefox;
$searchBox = ($ff01 | `
 Enter-SeURL -URL "http://www.google.com/" | `
 Get-SeWebElement -Name "q" | `
 Set-SeWebElementKeys -Text "Cheese" | `
 Submit-SeWebElement);

Write-Host "Text:";
$searchBox | Read-SeWebElementText
Write-Host "Enabled:";
$searchBox | Read-SeWebElementEnabled
Write-Host "Displayed:";
$searchBox | Read-SeWebElementDisplayed
Write-Host "Selected:";
$searchBox | Read-SeWebElementSelected
Write-Host "TagName:";
$searchBox | Read-SeWebElementTagName
Write-Host "Size:";
$searchBox | Read-SeWebElementSize
Write-Host "Location:";
$searchBox | Read-SeWebElementLocation

sleep -Seconds 3; # to observe the result
$ff01.Title;
$ff01 | Stop-SeFirefox;

This time, all the code working with an WebElement is put through the pipeline.

Web automation: starting a browser and getting an element


Testing of web sites always required a lot of small tests. UI Automation is not good there due to the following flaws:

  • it’s slow. The more windows, tabs or elements are given, the slower UI Automation is
  • it can’t get a range of elements. The¬†UIA COM wrapper can more, but for now it is not good at patterns
  • it is not cross-browser. Whereas Internet Explorer and Firefox are seen as a set of UI Automation controls, WebKit browsers are often sets of tabs in a window.

These problems usually led testers to using such instruments as Selenium or watir.

Nonetheless, things are not so bad for PowerShell testers as it seems to! There is no strict need to write all the test code in CSharp-like style, on the contrary, continue using pipelines:

$ff01 = Start-SeFirefox;
$searchBox = ($ff01 | Enter-SeURL -URL "http://www.google.com/" | Get-SeWebElement -Name "q");
$searchBox.SendKeys("Cheese");
$searchBox.Submit();
sleep -Seconds 3; # to observe the result
$ff01.Title;
$ff01 | Stop-SeFirefox;

This is nothing else than the sample the Selenium project provides:

using OpenQA.Selenium;
using OpenQA.Selenium.Firefox;

// Requires reference to WebDriver.Support.dll
using OpenQA.Selenium.Support.UI;

class GoogleSuggest
{
    static void Main(string[] args)
    {
        // Create a new instance of the Firefox driver.

        // Notice that the remainder of the code relies on the interface,
        // not the implementation.

        // Further note that other drivers (InternetExplorerDriver,
        // ChromeDriver, etc.) will require further configuration
        // before this example will work. See the wiki pages for the
        // individual drivers at http://code.google.com/p/selenium/wiki
        // for further information.
        IWebDriver driver = new FirefoxDriver();

        //Notice navigation is slightly different than the Java version
        //This is because 'get' is a keyword in C#
        driver.Navigate().GoToUrl("http://www.google.com/");

        // Find the text input element by its name
        IWebElement query = driver.FindElement(By.Name("q"));

        // Enter something to search for
        query.SendKeys("Cheese");

        // Now submit the form. WebDriver will find the form for us from the element
        query.Submit();

        // Google's search is rendered dynamically with JavaScript.
        // Wait for the page to load, timeout after 10 seconds
        WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10));
        wait.Until((d) => { return d.Title.ToLower().StartsWith("cheese"); });

        // Should see: "Cheese - Google Search"
        System.Console.WriteLine("Page title is: " + driver.Title);

        //Close the browser
        driver.Quit();
    }
}

Not surprisingly, the PowerShell code is shorter, prettier and looks comprehensible. Need to port to another browser? It’s easy (enough). The code below does the same in three browsers and, moreover, in two search engines:

$ff01 = Start-SeFirefox;
$searchBox = ($ff01 | Enter-SeURL -URL "http://www.google.com/" | Get-SeWebElement -Name "q");
$searchBox.SendKeys("Cheese");
$searchBox.Submit();
sleep -Seconds 3; # to observe the result
$ff01.Title;
$ff01 | Stop-SeFirefox;

$ch01 = Start-SeChrome;
$searchBox = ($ch01 | Enter-SeURL -URL "http://www.google.com/" | Get-SeWebElement -Name "q");
$searchBox.SendKeys("Cheese");
$searchBox.Submit();
sleep -Seconds 3; # to observe the result
$ch01.Title;
$ch01 | Stop-SeChrome;

$ie01 = Start-SeInternetExplorer;
$searchBox = ($ie01 | Enter-SeURL -URL "http://www.google.com/" | Get-SeWebElement -Name "q");
$searchBox.SendKeys("Cheese");
$searchBox.Submit();
sleep -Seconds 3; # to observe the result
$ie01.Title;
$ie01 | Stop-SeInternetExplorer;

$ff01 = Start-SeFirefox;
$searchBox = ($ff01 | Enter-SeURL -URL "http://www.yandex.ru/" | Get-SeWebElement -Id "text");
$searchBox.SendKeys("Cheese");
$searchBox.Submit();
sleep -Seconds 3; # to observe the result
$ff01.Title;
$ff01 | Stop-SeFirefox;

Test web sites with pleasure!

%d bloggers like this: