Category Archives: Windows 7

Daily automation: dumping control’s genealogy


This is a new edition of the old post.

Note: this post is deprecated, please refer to my comment below.

One more way to find out where in the Automation tree a control resides is to use the Get-UIAControlAncestors cmdlet. We are told that TreeScope.Parent and TreeScope.Ancestors used as filter for search will call the functionality that is not yet implemented? However, the cmdlet does perform the search from the very bottom of the hierarchy to the topmost window. Let’s take Calculator and dump the control hierarchy:

Task: demonstrate using the search to the top cmdlet.

Requirements: perform search that consumes a part of control’s name and retrieve all the ancestors of the search result.

Solution: the following code prints out all the hierarchy in reverse order:

Set-StrictMode -Version Latest;

ipmo [path]\UIAutomation.dll;

# here we are searching for all the element whose names start with 'a'

Start-Process calc -PassThru | Get-UIAWindow | Search-UIAControl -Name A* | `

%{Write-Host "===========================================================";

Write-Host "@{Name='$($_.Current.Name)';
AutomaitonId='$($_.Current.AutomaitonId);
ControlType='$($_.Current.ControlType.ProgrammaticName)'}";
$_ | Get-UIAControlAncestors | `

%{Write-Host "@{Name='$($_.Current.Name)';
AutomaitonId='$($_.Current.AutomaitonId);
ControlType='$($_.Current.ControlType.ProgrammaticName)'}";}};

Daily automation: a few windows in parallel


At work, an interesting question was raised: is it possible to work with several windows in parallel if their processes are run under various users? Yes, it surely is.

Task: use UIAutomation to get windows of AUTs that are run under various users.

Requirements: demonstrate how to use the technique and how to determine which window might cause a problem.

Solution: the first example is simple and demonstrates how to handle several windows:

Set-StrictMode -Version Latest;
ipmo [path]\UIAutomation.dll
Start-Process calc;
Start-Process calc;
Start-Process calc;
Start-Process calc;
Get-UIAWindow -ProcessName calc | Get-UIAButton -Name 1 | Invoke-UIAButtonClick | Read-UIAControlName
Get-UIAWindow -ProcessName calc | Get-UIAMenuItem -n vi* | Invoke-UIAMenuItemExpand | Get-UIAMenuItem -n scien* | Invoke-UIAMenuItemClick

The sample starts the foursome of calculators, gets them all, clicks the 1 button and changes application mode to the Scientific one.

There is no difficulty with windows run under several user accounts while your test process (i.e., powershell) is running with at least equal or higher privileges.

Now, we’ll start calc under two different user accounts (credentials are not provided to the public domain just for you not locking your accounts ;):

Set-StrictMode -Version Latest;
ipmo [path]\UIAutomation.dll;
(Start-Process calc -Credential (Get-Credential) -PassThru).Id
(Start-Process calc -Credential (Get-Credential) -PassThru).Id
# Here, we are writing up numbers to a paper
Get-UIAWindow -ProcessId 5924,6076 | Get-UIAMenuItem -Name vi* | Invoke-UIAMenuItemExpand | Get-UIAMenuItem -Name scien* | Invoke-UIAMenuItemClick

This works, but the sample is not friendly to use: you need to store process ids. Okay, below is a better one-liner:

Set-StrictMode -Version Latest;
ipmo [path]\UIAutomation.dll;
@((Start-Process calc -Credential (Get-Credential) -PassThru).Id; (Start-Process calc -Credential (Get-Credential) -PassThru).Id) | %{ Get-UIAWindow -ProcessId $_ | Get-UIAMenuItem -Name vi* | Invoke-UIAMenuItemExpand | Get-UIAMenuItem -Name stat* | Invoke-UIAMenuItemClick; }

Finally, how to learn which window failed? For example, by defining a counting variable that will increment every window and point to an element of the windows array.

Daily automation: eliminating the fragility of tests. Part 3


Many of us faced the situation when a window is gone and a testing tool hits the air for long time. The testing tool tries to get a control, a next control, and so on. Every attempt takes time.

UIAutomation had the remedy for the problem for relatively long time. This feature has never been widely known, so that it’s time to tell you what it is and how it works.

Task: minimize the time that UIAutomation spends on controls of a window that failed to appear.

Requirements: demonstrate how to use the technique with default settings.

Solution: you don’t need to do anything to benefit from this technique in case if a window of your interest is gone:

ipmo [path]\UIAutomation.dll
Start-Process calc -PassThru | Get-UIAWindow;
[UIAutomation.Preferences]::Timeout
[UIAutomation.Preferences]::AfterFailTurboTimeout
Get-UIAWindow -Name calc1 # non-existing window
[UIAutomation.Preferences]::Timeout
[UIAutomation.Preferences]::AfterFailTurboTimeout
Get-UIAWindow -Name calc* # this call get a window
[UIAutomation.Preferences]::Timeout
[UIAutomation.Preferences]::AfterFailTurboTimeout

After we ran this sample, we have the following output:
5000 – the default timeout
2000 – the AfterFailTurboTimeout
2000 – the timeout equals to AfterFailTurboTimeout. This is because calc1 has not been caught and the default timeout was considered as too long to wait for nothing
2000 – the AfterFailTurboTimeout
5000 – the default timeout was restored after the test have got a window
2000 – the AfterFailTurboTimeout
Note: this funcitonality has been broken in 0.8.0 Preview 4 (more accurately, 0.8.0P4 was released despite the fact that several unit tests have not been fixed. Just because this functionality is not widely known and never used explicitly).

Internally, UIAutomation checks that [UIAutomation.CurrentData]::CurrentWindow is $null and [UIAutomation.CurrentData]::LastResult also is $null.

Well, what about controls? Imagine the case you have a window and a child window or a control failed to appear.

This problem is not so obvious as the ‘no such window’ problem. ‘One control is gone’ is a typical case during the development cycle. Nonetheless, some controls are vital for the whole test. For this, a new parameter is here: -IsCritical. Let’s see how it works:

ipmo [path]\UIAutomation.dll
Start-Process calc -PassThru | Get-UIAWindow | Get-UIAButton -Name 1
[UIAutomation.Preferences]::Timeout
Start-Process calc -PassThru | Get-UIAWindow | Get-UIAButton -Name 10
[UIAutomation.Preferences]::Timeout
Start-Process calc -PassThru | Get-UIAWindow | Get-UIAButton -Name 10 -IsCritical
[UIAutomation.Preferences]::Timeout
[UIAutomation.CurrentData]::LastResult
Start-Process calc -PassThru | Get-UIAWindow | Get-UIAButton -Name 1
[UIAutomation.Preferences]::Timeout
Start-Process calc -PassThru | Get-UIAWindow | Get-UIAButton -Name 1 -IsCritical
[UIAutomation.Preferences]::Timeout

Below is the output:
5000 – the default timeout
5000 – the default timeout as the -IsCritical parameter has not been used
2000 – the turbo timeout (thanks to the -IsCritical parameter)
5000 – the default timeout (after the first control that has been caught successfully)
5000 – IsCritical does nothing if there wasn’t a problem

The general rule is to use the -IsCritical parameter for child windows, default buttons and controls like combo boxes and radio buttons if their state blocks you from going forward.

Metro automation: navigating to a certain page


A typical Metro UI application is a set of pages. One is main, and there are several pages where we can go from the main page.

A Metro UI app is unlikely to a traditional app, which often starts from some starting point. A Metro UI app starts for the first time with its main page, but further is may start from wherever page the user left the app.

In our sample, we’ll be using the *Wizard* cmdlets. What are they?

1. the New-UIAWizard cmdlet creates a wizard object, provides it with name and contains a code to start the AUT (application under test), for example. Some initial code.

2. the Add-UIAWizardStep cmdlet creates a step, provides the step with a name, takes a wizard object as an input.

First action we should do on a step is to examine the step. The -SearchCriteria parameter does exactly this task.

After that, we run code for this step. There are two actions we can use, for forward movement and for backward. In out Metro UI app we will be using only forward steps for simplicity sake.

3. the Invoke-UIAWizard cmdlets runs the wizard (in fact, the code we added to the New-UIAWizard cmdlet). It’s usually used for starting the AUT. For purposes of Metro UI testing, we will use this action to show the Start screen and to open the app window.

4. the Step-UIAWizard cmdlet checks the -SearchCriteria (i.e., checks that controls are here and we are on the right page) and runs the step code.


Set-StrictMode -Version Latest

[UIAutomation.Preferences]::Timeout = 10000;
[UIAutomation.Preferences]::EveryCmdletAsTestResult = $true;
[UIAutomation.Preferences]::OnSuccessDelay = 300;

# names of the pages and buttons in the app menu
[string]$constPageMain = 'Home';
[string]$constPageFeaturedDestinations = 'Featured Destinations';
[string]$constPageDestinations = 'Destinations';
[string]$constPageFlights = 'Flights';
[string]$constPageHotels = 'Hotels';
[string]$constPageBestOfWeb = 'Best Of Web';

# names of wizard steps
[string]$constWizardName = 'TravelWizard';
[string]$constWizardStepHome = 'Home';
[string]$constWizardStepDestinations = 'Destinations';
[string]$constWizardStepFlights = 'Flights';
[string]$constWizardStepHotels = 'Hotels';
[string]$constWizardStepBestOfWeb = 'BestOfWeb';

# we need to clear the collection of wizards or delete
# the wizard we are playing with.
# Otherwise, the next run will throw an exception
# 'Wizard already exists'
[UIAutomation.WizardCollection]::Wizards.Clear();

# Creating a new wizard
New-UIAWizard -Name $constWizardName `
 -StartAction {
 # setting the Metro Start screen
 Get-UIADesktop;
 Show-UIAMetroStartScreen;

# clicking on the tile of the AUT
 Get-UIAListItem -Name 'Travel' | `
 Invoke-UIAListItemClick;

# the loading screen (if happened)
 try {
 Get-UIAWindow -Name 'Travel' | `
 Get-UIAProgressBar;
 #sleep -Seconds 5; # the app is loading
 }
 catch {}

 # start our tests from the Main page
 Show-UIAMetroMenu;
 Get-UIAWindow -Name 'Travel' | `
 Get-UIAMenuBar -Name 'App Bar' | `
 Get-UIAHyperlink -Name $constPageMain | `
 Invoke-UIAControlClick;
 } | `
 Add-UIAWizardStep -Name $constWizardStepHome `
 -SearchCriteria @{ControlType="Text";Name='Bing Travel'} `
 -StepForwardAction {
 #[System.Windows.Forms.MessageBox]::Show("StepHome");
 "<<<<<<<<<< On the Home page >>>>>>>>>>";
 try {
 Get-UIAText -Name 'Bing Travel';
 Close-TMXTestResult -Name "<<<<<<<<<< Navigating to the Home page >>>>>>>>>>" -TestPassed;
 }
 catch {
 Close-TMXTestResult -Name "<<<<<<<<<< Navigating to the Home page >>>>>>>>>>";
 }
 } -PassThru | `
 Add-UIAWizardStep -Name $constWizardStepDestinations `
 -SearchCriteria @{ControlType="Text";Name='Destinations'},@{ControlType="Text";Name='Region'} `
 -StepForwardAction {
 #[System.Windows.Forms.MessageBox]::Show("StepDestinations");
 "<<<<<<<<<< On the Destinations page >>>>>>>>>>";
 try {
 Get-UIAText -Name 'Destinations';
 Get-UIAText -Name 'Region';
 Close-TMXTestResult -Name "<<<<<<<<<< Navigating to the Destinations page >>>>>>>>>>" -TestPassed;
 }
 catch {
 Close-TMXTestResult -Name "<<<<<<<<<< Navigating to the Destinations page >>>>>>>>>>";
 }
 } -PassThru | `
 Add-UIAWizardStep -Name $constWizardStepFlights `
 -SearchCriteria @{ControlType="Text";Name='Flights'},@{ControlType="Text";Name='Schedule'} `
 -StepForwardAction {
 #[System.Windows.Forms.MessageBox]::Show("StepFlights");
 "<<<<<<<<<< On the Flights page >>>>>>>>>>";
 try {
 Get-UIAText -Name 'Flights';
 Get-UIAText -Name 'Schedule';
 Close-TMXTestResult -Name "<<<<<<<<<< Navigating to the Flights page >>>>>>>>>>" -TestPassed;
 }
 catch {
 Close-TMXTestResult -Name "<<<<<<<<<< Navigating to the Flights page >>>>>>>>>>";
 }
 } -PassThru | `
 Add-UIAWizardStep -Name $constWizardStepHotels `
 -SearchCriteria @{ControlType="Text";Name='Hotels'},@{ControlType="Text";Name='Check-in'} `
 -StepForwardAction {
 #[System.Windows.Forms.MessageBox]::Show("StepHotels");
 "<<<<<<<<<< On the Hotels page >>>>>>>>>>";
 try {
 Get-UIAText -Name 'Hotels';
 Get-UIAText -Name 'Check-in';
 Close-TMXTestResult -Name "<<<<<<<<<< Navigating to the Hotels page >>>>>>>>>>" -TestPassed;
 }
 catch {
 Close-TMXTestResult -Name "<<<<<<<<<< Navigating to the Hotels page >>>>>>>>>>";
 }
 } -PassThru | `
 Add-UIAWizardStep -Name $constWizardStepBestOfWeb `
 -SearchCriteria @{ControlType="Text";Name='Travel'},@{ControlType="Text";Name='Explore'},@{ControlType="Text";Name='Plan a Trip'} `
 -StepForwardAction {
 #[System.Windows.Forms.MessageBox]::Show("Best Of Web");
 "<<<<<<<<<< On the 'Best Of Web' page >>>>>>>>>>";
 try {
 Get-UIAText -Name 'Travel';
 Get-UIAText -Name 'Explore';
 Get-UIAText -Name 'Plan a Trip';
 Close-TMXTestResult -Name "<<<<<<<<<< Navigating to the 'Best Of Web' page >>>>>>>>>>" -TestPassed;
 }
 catch {
 Close-TMXTestResult -Name "<<<<<<<<<< Navigating to the 'Best Of Web' page >>>>>>>>>>";
 }
 };

# Start the wizard
[UIAutomation.Wizard]$wizard = Invoke-UIAWizard -Name $constWizardName;

# Click on the Destinations button in the app menu
Show-UIAMetroMenu;
Get-UIAWindow -Name 'Travel' | `
 Get-UIAMenuBar -Name 'App Bar' | `
 Get-UIAHyperlink -Name $constPageDestinations | `
 Invoke-UIAControlClick;

# Check that this is the Destinations page and run code (in the future sample)
$wizard | Step-UIAWizard -Name $constWizardStepDestinations

# Click on the Flights button in the app menu
Show-UIAMetroMenu;
Get-UIAWindow -Name 'Travel' | `
 Get-UIAMenuBar -Name 'App Bar' | `
 Get-UIAHyperlink -Name $constPageFlights | `
 Invoke-UIAControlClick;

# Check that this is the Flights page and run code (in the future sample)
$wizard | Step-UIAWizard -Name $constWizardStepFlights;

# Click on the Hotels button in the app menu
Show-UIAMetroMenu;
Get-UIAWindow -Name 'Travel' | `
 Get-UIAMenuBar -Name 'App Bar' | `
 Get-UIAHyperlink -Name $constPageHotels | `
 Invoke-UIAControlClick;

# Check that this is the Hotels page and run code (in the future sample)
$wizard | Step-UIAWizard -Name $constWizardStepHotels;

# Click on the 'Best Of Web' button in the app menu
Show-UIAMetroMenu;
Get-UIAWindow -Name 'Travel' | `
 Get-UIAMenuBar -Name 'App Bar' | `
 Get-UIAHyperlink -Name $constPageBestOfWeb | `
 Invoke-UIAControlClick;

# Check that this is the 'Best Of Web' page and run code (in the future sample)
$wizard | Step-UIAWizard -Name $constWizardStepBestOfWeb;

The dubious piece of code is getting a progress bar on loading the application. Sometimes, it is shown. Sometimes, there is no progress bar.

0.8.0 Preview 2: wanted richer output?


Again and again, it’s not going to end. People ask me ‘why Metro UI testing doesn’t work from PowerShell ISE?’

PowerShell ISE and powershell.exe are Microsoft’s tools, they have no relation to Metro UI testing. Technically, Microsoft guys can build ISE and powershell.exe to make them uiAccess’ible. However, don’t wait this: why should they build a host for my cmdlets? To help compete with their Coded UI? I sooner believe that they will write their own UI cmdlets in v3 or v4 (as they usually answer to PowerGUI features, for example), than they do something specific for 3rd party cmdlets.

The other side of coin is that I’m not going to write one more code editor with debugging capabilities. I’d like to, but this is a time-consuming task. Not to say that an editor of appropriate quality is not so easy to write up.

That’s a dilemma: we can run PowerShell over Metro UI, but we can’t work deeply with variables and output.

0.8.0 Preview 2 solves this partly. Now, output is partially supported. The list of what is supported:

  • string output (code: “string”)
  • string output for objects (code: (Get-UIAWindow 0n calc*).Current | Out-String)

Write- cmdlets are not supported in this version. Possibly, they will be supported later.

Here is a sample:

[UIAutomation.Preferences]::EveryCmdletAsTestResult=$true
[UIAutomation.Preferences]::OnSuccessDelay = 0;

Start-Process calc
Get-UIAWindow -n calc* | Get-UIAButton -n 1 | Invoke-UIAButtonClick;
(Get-UIAButton -n add | Invoke-UIAButtonClick).Current.AutomationId;
(Get-UIAButton -n 1 | Invoke-UIAButtonClick).Current | Out-String;
Get-UIAWindow -n calc* | Get-UIAButton | Set-UIAFocus | Set-UIAControlKeys -Text "1{+}1{=}"
'Get-UIAWindow -n calc* | Out-String; ->'
Get-UIAWindow -n calc* | Out-String;
'(Get-UIAWindow -n calc*).Current | Out-String;'
(Get-UIAWindow -n calc*).Current | Out-String;

"now test should fail"
Get-UIAWindow -n "non-existing window" -Seconds 2
Get-UIAWindow -n calc* | Get-UIAButton -n 10 | Invoke-UIAButtonClick;

Output is shown as light-blue lines. It returns:

  • the button 1 (Invoke-UIAButtonClick returns)
  • the automation id of the button Add (again, the same cmdlet returns)
  • AutomationElementInfo (i.e., .Current). This is the button 1 again.
  • further, after an empty string, there are string lines to help you compare what means to put an AutomationElement and an AutomationElementInfo to the Out-String cmdlet.

It’s not proper way to debug your scripts, though it’s the only way for now.

0.8.0 Preview 2: double squares help to visualize controls better


Controls belong to a big hierarchy. What may be the reason to highlight only two levels of controls if, in practice, there might be ten or twenty levels in the hierarchy?

The pictures show what the double-highlighting is. The inner square is over the control of interest, whereas the circumscribing one is over its parent.

However, things suddenly change when you put the cursor over WPF applications, its (WPF’s) derivatives and HTML:

This is a rather typical case: we are seeing a button or a link and, at the same time, the topmost control is a text.

The same story in Metro UI applications:

Here it is seen even better:

and here too:

The name of the button is not ‘Permissions’ as we could think, the name is ‘Back’.

At the end, there is a brilliant example:

There are TWO things on top of the button! This is the out-of-the-box Mail application.

0.8.0 Preview 1: UIARunner, UIAutomationSpy, and modules are published


Even though with some bugs and ugly-looking (it never was our intent to write GUI tools besides modules:)), UIARunner is published. As far as I know, this is the first GUI wrapper for PowerShell that looks like a software testing tool. 🙂

This preliminary version supports:

  • running one script at a time
  • using the UIARunner.ps1 file (in the application’s folder) as a configuration file
  • generating test report on the fly (in the GUI)
  • generating test report on the fly as a CSV file (both GUI and command-line versions produce such output)
  • unattended runs
  • the GUI version also shows how many test results are passed, failed and the velocity in newly introduced measures called ‘test results per second’ (trps)
  • of course, it supports basic sorting in the grid.

Known issues are numerous (again, this project lacks of professional GUI programmers :)):

  • bad multithreading
  • poor informing about what happened at the PowerShell level
  • and many, many lesser bugs.

Anyway, this version is worth experimenting with. Each package includes several simple scripts to try the runner. Scripts work similarly to other PowerShell hosts, note, however, that you need to use try/catch blocks to avoid terminating errors.

0.8.0 Preview 1: UIARunner as a graphical test tool


Today’s Preview 1 brings to us a new test runner: UIARunner for testing Metro UI and Windows UI.

This version, even though not a release, already can run a script and display test results. The current version supports only test results, i.e., events generated by the Close-TMXTestResult cmdlet or closed automatically through the parameter [UIAutomation.Preferences]::EveryCmdletAsTestResult set to $true.

The figure below shows how it works:

 

The picture was taken when UIARunner was working on a performance test: it should calculate the results of expressions 1 + 1 and 2 + 2 a thousand times, and thousand times try to find the 10 button (it’s a flaw that Microsoft didn’t manage to find more space to put this useful button on the form).

To obtain such a visual report, you need no more than start the application with default settings, open a script through the File -> Open menu item (or by pressing Ctrl+O) and run the script by clicking on the menu item Script -> Run or by pressing F5.

The application is not smooth and cool for its first version. Nonetheless, it already can be used for gathering script results.

Speaking about future improvements, the features that are planned to implement are:

  •  supporting hierarchical reports based on test suites, test scenarios and test results and shown in a grouped list view
  • probably, pausing the script
  • maybe, some events or alerts on conditions like ‘too many failures’ or ‘global timeout interrupted the script’.

 

Daily automaiton: how to deal with windows?


On the project forum, questions about windows have been posted today. I think, the community is interesting in he answers.

Question:

Please, give some examples how to wait for new window with unpredictable Name value(it can be various error or notify messages)?; how to enumerate all opened windows? I want to remove windows to clean desktop after unsuccessful run of application.

Answer:

1) how to wait for a new window with random Name?

first of all, there are ways to take a window by its ProcessId/pid, ProcessName/pn and its process object. If you issue the process, all the following would work:

# you've set a name for process somewhere in the code
$processName = "calc";

# get the window by its process id
Get-UIAWindow -pid (Start-Process $processName -PassThru).Id

# get the window by its process name
Get-UIAWindow -pn (Start-Process $processName -PassThru).ProcessName

second, you also can use a part of its name (supposing that some part of a name is uncahngeble from run to run);

Start-Process calc; Get-UIAWindow -n *lato*

Note that rare windows that are not seen by MS Automation and could be found by using FindWindow, still don’t support wild cards (it will be done relatively soon). I know only one such an example: on a 64-bit OS, a 32-bit MMC snap-in that is not shown in the TaskBar, runs its own window instead of the main MMC window (It’s really rare case).
 

2) Which opened windows do you want to enumerate?

2.1) window with known to you a part of name:

Start-Process calc; Start-Process calc; Start-Process calc;
Get-UIADesktop | Get-UIAControlChildren -ControlType Window | ?{$_.Current.Name.Contains("alcu")}

2.2) if you need to collect all the dialog of the application under test, there is search down the Automaiton tree

# you should run PowerShell as Asministrator to reproduce this test
Start-Process services.msc -PassThru | Get-UIAWindow | Get-UIAMenuItem -Name File | Invoke-UIAMenuItemClick | Get-UIAMenuItem -Name Opt* | Invoke-UIAMenuItemClick;

# now we have several windows in the process mmc: the main window, the Options window 
# and one or more internal frames of mmc itself
# as mmc has windows called snap-ins (or possibly even more windows I'm not aware of)

# in the code below, you don't need to use the Get-UIAWindow cmdlet
# because the last window you've successfully gotten
# stored in the [UIAutomation.CurrentData]::CurrentWindow variable
Get-UIAControlDescendants -ControlType Window | %{$_.Current.Name;}

# in this case, we have gotten only two windows, both with names
# in more complicated cases, you need to use several properties to select a window
Get-UIAControlDescendants -ControlType Window | %{Write-Host "$($_.Current.Name)`t$($_.Current.AutomaitonId)`t$($_.Current.ClassName)";}

there also are Search- cmdlets, but these are considered legacy as they use TreeWalker what means more cross-process callc during the test:

# the search for a specified window
Search-UIAControl -Name Options -ControlType Window
# the code assumes that you already have the main window
# and the same as the code:
[UIAutomation.CurrentData]::CurrentWindow | Search-UIAControl -Name Options -ControlType Window

As can be seen, the Search-UIAControl cmdlet is more specific (like every good search), whereas Get-UIAControlDescendants returns all that is of type specified.

2.3) if you need to catch inexplicable windows like a dialog in the process of the application under test, use the Register-UIAWindowsOpenedEvent cmdlet (it’s recommended to use also the Unregister-UIAEvent cmdlet from time to time during the test suite):

Start-Process services.msc -PassThru | Get-UIAWindow | Register-UIAWindowOpenedEvent -EventAction {param($src, $e) [System.Windows.Forms.MessageBox]::Show("A new window is open: $($src.Cached.Name)");};
Get-UIAMenuItem -Name File | Invoke-UIAMenuItemClick | Get-UIAMenuItem -Name Opt* | Invoke-UIAMenuItemClick;

2.4) finally, if you need to catch a windows of another process that appears during the test, use the standard Register-WMIObjectEvent cmdlet (there are a lot of ways to write the code as parameters of the cmdlet can be used in various combinaitons):

the smaple from Richard Siddaway’s Blog: http://msmvps.com/blogs/richardsiddaway/archive/2009/11/07/powershell-wmi-events.aspx

3) you can eliminate processes, it’s the best choise in many situations

Start-Process calc; Start-Process calc; Start-Process calc;
Stop-Process -Name calc

However, some applications should save their data or close connections before exiting, so that you need to use something like in the item 2.1 (Get-UIADesktop | Get-UIAControlChildren: main windows are always children of the desktop) to get all of them to perform exit via main menu or hitting the Close button…

 

Quality report: a great success of PowerShell in testing


Yesterday’s build of a commercial application we are working on was reported as “with a bug”. An annoying dialog appeared here and there after a relatively long time of uninterruptible work of the application’s console. Need to say that reproduction of such bugs (“the console got tired and a dialog appears after an hour or more…”) is not a piece of cake. At least, no one wants to await the dialog in the debugger for an hour or two.

Now, the serious part of the product is being tested with PowerShell. Whereas the system part is being tested with C# (the ‘system team’ prefers writing code what I call ‘writing own bugs’), the UI including simple interactions like selecting users from a domain is done in PowerShell. The majority of the code exploits UIAutomation and TMX modules.

Below is the yesterday’s report (a TMX results report):

Suites:31 Passed:19 Failed:9 Not tested:3
Scenarios:227 Passed:206 Failed:21 Not tested:0
Test cases:2682 Passed:2479 Failed:161 Not tested:42 Time spent:8005 seconds

As can be seen, the average time of a test case is 8005/(2682-42)=3,03 seconds.

The fail/pass rate is 161/2682=6%.

Data is nothing if you have none to compare. Below is a report done a week ago (test cases number varies from run to run as the autotest developer and maintainer switches test cases on or off due to changes in the UI or for analysis and making amendments to the test suite):

Suites:31 Passed:19 Failed:8 Not tested:4
Scenarios:197 Passed:188 Failed:9 Not tested:0
Test cases:2251 Passed:2204 Failed:12 Not tested:35 Time spent:4623 seconds

The ‘happy’ run has 0,5% fail/pass rate (0.0% fail/pass rate is hardly achievable during the time the product’s UI is being changed).

The average time is better than in a normal case and counted as 4623/(2251-35)=2,08 seconds per test case, and there is still room for further improvements. Preferably, that fail-run increments were bound to 20%, not 50%.

Anyway, the red peak of 6% of the height of a percent chart seems appropriate. Isn’t it a success of using PowerShell in software testing?

%d bloggers like this: