Ranorex code examples

This chapter contains a collection of code examples which explain how to use the Ranorex API to write code modules and extend recording modules with user-specific code.

In this chapter

    Using repository in code

    [TestModule("D451F1D1-C347-4B58-939F-F6187642EB56", ModuleType.UserCode, 1)] 
    public class UsingRepository : ITestModule 
    { 
     // Repository object to access UI elements 
     MyFirstTestProjectRepository repo = MyFirstTestProjectRepository.Instance; 
     
     /// <summary> 
     /// Constructs a new instance. 
     /// </summary> 
     public UsingRepository() 
     { 
     // Do not delete - a parameterless constructor is required! 
     } 
     
     void ITestModule.Run() 
     { 
     Mouse.DefaultMoveTime = 300; 
     Keyboard.DefaultKeyPressTime = 100; 
     Delay.SpeedFactor = 1.0; 
     
     // Using Ranorex.Form adapter represented by 'MyApp' 
     // 'MyApp' is used as a folder within the repository; 
     // the 'Self' property returns an object of type Ranorex.Form 
     
     // Activates application 
     repo.MyApp.Self.Activate(); 
     // Log 'Active' state 
     Report.Info(repo.MyApp.Self.Active.ToString()); 
     // Maximize, Minimize and Restore 
     repo.MyApp.Self.Maximize(); 
     repo.MyApp.Self.Minimize(); 
     repo.MyApp.Self.Restore(); 
     // Closes application 
     repo.MyApp.Self.Close(); 
     
     
     // Using Ranorex.Button adapter represented by 'ButtonAdd' 
     // Read and log value of 'Text' attribute 
     Report.Info(repo.MyApp.Buttons.ButtonAdd.Text); 
     
     // Press button 
     repo.MyApp.Buttons.ButtonAdd.Press(); 
     // Read and log value of 'Enabled' attribute 
     Report.Info(repo.MyApp.Buttons.ButtonAdd.Enabled.ToString()); 
     
     // Using Ranorex.RadioButton adapter 
     // represented by 'GenderOption' 
     
     // Select radio button 
     repo.MyApp.GenderOption.Select(); 
     
     // Accessing listitems of Ranorex.List adapter 
     // represented by 'CategoryList' 
     IList<ranorex.listitem> listItems = repo.MyApp.CategoryList.Items; 
     foreach ( Ranorex.ListItem item in listItems ) 
     { 
     Report.Info(item.Text + " is member of CategoryList"); 
     } 
     
     // Using Ranorex.MenuItem to open 'File' menu 
     repo.MyApp.MenuItemFile.Select(); 
     // Selecting sub menu item 'Connect' 
     repo.FileMenu.Connect.Select(); 
     // Read and log 'Enabled' state of menu item 'Connect' 
     Report.Info(repo.FileMenu.Connect.Enabled.ToString()); 
     } 
    }
    Public Class UsingRepository 
     Implements ITestModule 
     ' Repository object to access UI elements 
     Private repo As MyFirstTestProjectRepository = MyFirstTestProjectRepository.Instance 
     
     ''' <summary> 
     ''' Constructs a new instance. 
     ''' </summary> 
     ' Do not delete - a parameterless constructor is required! 
     Public Sub New() 
     End Sub 
     
     ''' <summary> 
     ''' Performs the playback of actions in this module. 
     ''' </summary> 
     ''' <remarks>You should not call this method directly, instead pass the module 
     ''' instance to the <see cref="TestModuleRunner.Run(ITestModule)"> method 
     ''' that will in turn invoke this method.</see></remarks> 
     Private Sub ITestModule_Run() Implements ITestModule.Run 
     Mouse.DefaultMoveTime = 300 
     Keyboard.DefaultKeyPressTime = 100 
     Delay.SpeedFactor = 1.0 
     ' Using Ranorex.Form adapter represented by 'MyApp' 
     ' 'MyApp' is used as a folder within the repository; 
     ' the 'Self' property returns a Ranorex.Form object 
     
     ' Activates application 
     repo.MyApp.Self.Activate() 
     ' Log 'Active' state 
     Report.Info(repo.MyApp.Self.Active.ToString()) 
     ' Maximize, Minimize and Restore 
     repo.MyApp.Self.Maximize() 
     repo.MyApp.Self.Minimize() 
     repo.MyApp.Self.Restore() 
     ' Closes application 
     repo.MyApp.Self.Close() 
     
     
     ' Using Ranorex.Button adapter represented by ButtonAdd' 
     ' Read and log value of 'Text' attribute 
     Report.Info(repo.MyApp.Buttons.ButtonAdd.Text) 
     
     ' Press button 
     repo.MyApp.Buttons.ButtonAdd.Press() 
     ' Read and log value of 'Enabled' attribute 
     Report.Info(repo.MyApp.Buttons.ButtonAdd.Enabled.ToString()) 
     
     ' Using Ranorex.RadioButton adapter 
     ' represented by 'GenderOption' 
     
     ' Select radio button 
     repo.MyApp.GenderOption.[Select]() 
     ' Accessing listitems of Ranorex.List adapter 
     ' represented by 'CategoryList' 
     Dim listItems As IList(Of Ranorex.ListItem) = repo.MyApp.CategoryList.Items 
     For Each item As Ranorex.ListItem In listItems 
     Report.Info(item.Text & " is member of CategoryList") 
     Next 
     
     ' Using Ranorex.MenuItem to open 'File' menu 
     repo.MyApp.MenuItemFile.[Select]() 
     ' Selecting sub menu item 'Connect' 
     repo.FileMenu.Connect.[Select]() 
     ' Read and log 'Enabled' state of menu item 'Connect' 
     Report.Info(repo.FileMenu.Connect.Enabled.ToString()) 
     End Sub 
    End Class

    Wait for UI elements using repository

    Each item and each folder type provides an additional object item declared with ‘Info’. It is used to access item related attributes without accessing the UI element directly in order to prevent Ranorex from throwing exceptions. The info object is mainly used to check whether an item or a folder path is valid or not. In combination with the timeout set for the item, you can use it to wait for UI elements like dialogs, text values and web content.

    // Use the 'Info' object to check existence of the 
    // 'SaveDialog' item; Method 'Exists' uses the timeout 
    // specified for the 'SaveDialog' in the repository 
    Report.Info("Exists = " + repo.SaveDialog.SelfInfo.Exists().ToString()); 
     
    // Use the 'Info' object to check existence of the 
    // 'TextOnline' item which uses the following RXPath: 
    // statusbar/text[@accessiblename='Online'] 
    // This way you can wait with the timeout specified for 
    // the item within the repository for the text 'Online' 
    bool statusTextConnected = repo.MyApp.TextOnlineInfo.Exists(); 
     
    // Using 'Info' objects for validation 
    // Throws a Ranorex.ValidationException if validation 
    // fails. Automatically reports success or failed message 
    // to log file 
    Validate.Exists(repo.SaveDialog.ButtonOKInfo); 
     
    // Validates the existence of the repository item, 
    // but does not throw any exception 
    Validate.Exists(repo.SaveDialog.ButtonOKInfo,"Check Object '{0}'",false);
    ' Use the 'Info' object to check existence of the 
    ' 'SaveDialog' item; Method 'Exists' uses the timeout 
    ' specified for the 'SaveDialog' in the repository 
    Report.Info("Exists = " & repo.SaveDialog.SelfInfo.Exists().ToString()) 
     
    ' Use the 'Info' object to check existence of the 
    ' 'TextOnline' item which uses the following RXPath: 
    ' statusbar/text[@accessiblename='Online'] 
    ' This way you can wait with the timeout specified for 
    ' the item within the repository for the text 'Online' 
    Dim statusTextConnected As Boolean = repo.MyApp.TextOnlineInfo.Exists() 
     
    ' Using 'Info' objects for validation 
    ' Throws a Ranorex.ValidationException if validation 
    ' fails. Automatically reports success or failed message 
    ' to log file 
    Validate.Exists(repo.SaveDialog.ButtonOKInfo) 
     
    ' Validates the existence of the repository item, 
    ' but does not throw any exception 
    Validate.Exists(repo.SaveDialog.ButtonOKInfo, "Check Object '{0}'", False)

    Create adapters to access more properties and methods

    If you analyze the VIP Database application form with Ranorex Spy, you see that that the application window provides three adapters (Form, Control and NativeWindow). The Ranorex.Form adapter with all attributes and methods is directly available using the repository’s application folder ‘MyApp’. If you want to access properties like ‘ProcessName’ or invoke methods exposed by a .NET WinForms control you need to convert the Form adapter to NativeWindow or Control. As you can see in the code section below the ‘…Info’ object is used to create the desired adapter.

    Note icon

    Note

    In order to access properties or methods exposed by a WinForms control you need to know their names. If you’re not familiar with the control’s API ask the developer of your application for assistance.

    // Creating adapter of type 'NativeWindow' using the "...Info" object 
    Ranorex.NativeWindow nativeWnd = repo.MyApp.SelfInfo.CreateAdapter<Ranorex.NativeWindow>(false); 
    // ... and read value of attribute 'ProcessName' 
    Report.Info("Process name of VIP Database: " + nativeWnd.ProcessName); 
     
    // Using Control Adapter to access properties and methods of 
    // .NET WinForms control 
    Ranorex.Control winFormsControl = repo.MyApp.SelfInfo.CreateAdapter<Ranorex.Control>(false); 
    // Set background color of VIP application to Color.Black using the 
    // exposed property 'BackColor' 
    winFormsControl.SetPropertyValue("BackColor",Color.Black); 
     
    // Report screenshot after changing the background color 
    Report.Screenshot(repo.MyApp.Self); 
    // Closes VIP Database by invoking the 'Close' method 
    // exposed by the System.Windows.Forms.Form class 
    winFormsControl.InvokeMethod("Close");
    ' Creating adapter of type 'NativeWindow' using the "...Info" object 
    Dim nativeWnd As Ranorex.NativeWindow = repo.MyApp.SelfInfo.CreateAdapter(Of Ranorex.NativeWindow)(False) 
    ' ... and read value of attribute 'ProcessName' 
    Report.Info("Process name of VIP Database: " & nativeWnd.ProcessName) 
     
    ' Using Control Adapter to access properties and methods of 
    ' .NET WinForms control 
    Dim winFormsControl As Ranorex.Control = repo.MyApp.SelfInfo.CreateAdapter(Of Ranorex.Control)(False) 
    ' Set background color of VIP application to Color.Black using the 
    ' exposed property 'BackColor' 
    winFormsControl.SetPropertyValue("BackColor", Color.Black) 
     
    ' Report screenshot after changing the background color 
    Report.Screenshot(repo.MyApp.Self) 
    ' Closes VIP Database by invoking the 'Close' method 
    ' exposed by the System.Windows.Forms.Form class 
    winFormsControl.InvokeMethod("Close")

    Create a list of adapters from a repository element

    If multiple elements match a RanoreXPath of a single repository item use the CreateAdapters method to create a list of adapters.

    Learn more about how to create repository items delivering multiple elements here: ⇢ Adding Repository Items

    // Create a list of adapters using the "Info" object 
    IList<Ranorex.Button> buttonList = 
     repo.MyApp.EnabledButtonsInfo.CreateAdapters<Ranorex.Button>(); 
     
    // Move the mouse pointer to each button of the list 
    // and add a screenshot for each to the report 
    foreach (Ranorex.Button button in buttonList ) 
    { 
     button.MoveTo(); 
     Report.Screenshot(button); 
    }
    ' Create a list of adapters using the "Info" object 
    Dim buttonList As IList(Of Ranorex.Button) = 
     repo.MyApp.EnabledButtonsInfo.CreateAdapters(Of Ranorex.Button)() 
     
    ' Move the mouse pointer to each button of the list 
    ' and add a screenshot for each to the report 
    For Each button As Ranorex.Button In buttonList 
     button.MoveTo() 
     Report.Screenshot(button) 
    Next

    Using the Validate class

    The Ranorex.Validate class is used to check values from UI elements, but it can also be used to simply compare non UI related objects in code. In comparison to a simple IF statement the methods provided automatically log fail or success messages to the report.

    Note icon

    Note

    Each method provided by the Validate class allows to suppress exceptions thrown in case of a failed validation. The code snippet above uses only a few validation methods. For further and more detailed explanation of the Ranorex.Validate class see the API documentation.

    // Validate for Existence 
     
    // Using 'Info' objects for validation 
    // Throws a Ranorex.ValidationException if validation 
    // fails. Automatically reports success or failed message 
    // to log file 
    Validate.Exists(repo.SaveDialog.ButtonOKInfo); 
     
    // Validates the existence of the repository item, 
    // but does not throw any exception 
    bool exists = Validate.Exists(repo.SaveDialog.ButtonOKInfo,"Check Object '{0}'",false); 
     
    // Check whether an application form exists using a RanoreXPath 
    Validate.Exists("/form[@controlname='formVipApplication']"); 
     
    // Check whether an application does not exists 
    // for the time specified as timeout for the given repository item 
    Validate.NotExists(repo.MyApp.SelfInfo); 
     
    // Validate 'Enabled' attribute of button 'Delete' 
    Validate.Attribute(repo.MyApp.Buttons.ButtonDeleteInfo,"Enabled",false);
    ' Validate for Existence 
     
    ' Using 'Info' objects for validation 
    ' Throws a Ranorex.ValidationException if validation 
    ' fails. Automatically reports success or failed message 
    ' to log file 
    Validate.Exists(repo.SaveDialog.ButtonOKInfo) 
     
    ' Validates the existence of the repository item, 
    ' but does not throw any exception 
    Dim exists As Boolean = Validate.Exists(repo.SaveDialog.ButtonOKInfo,"Check Object '{0}'",false) 
     
    ' Check whether an application form exists using a RanoreXPath 
    Validate.Exists("/form[@controlname='formVipApplication']") 
     
    ' Check whether an application does not exists 
    ' for the time specified as timeout for the given repository item 
    Validate.NotExists(repo.MyApp.SelfInfo) 
     
    ' Validate 'Enabled' attribute of button 'Delete' 
    Validate.Attribute(repo.MyApp.Buttons.ButtonDeleteInfo,"Enabled",false)

    Forcing a test case to fail using the Validate class

    As described above you can use the Validate class to compare values from UI and non UI related objects bringing a test to fail or success. Additional to this, you can force a test case to fail without comparing using the Validate class.

    Ranorex.Cell cellObject = null; 
    // Try to find a cell object 
    bool found=false; 
    found = Host.Local.TryFindSingle<Ranorex.Cell>("/form//table/row/cell[3]", 2000, out cellObject); 
    // If the expressions does not return an object 
    // call Validate.Fail and the test case fails 
    if (!found) Validate.Fail("RanoreXPath with no return");
    Dim cellObject As Ranorex.Cell = Nothing 
    ' Try to find a cell object 
    Dim found As Boolean = False 
    found = Host.Local.TryFindSingle(Of Ranorex.Cell)("/form//table/row/cell[3]", 2000, cellObject) 
    ' If the expressions does not return an object 
    ' call Validate.Fail and the test case fails 
    If Not found Then 
     Validate.Fail("RanoreXPath with no return") 
    End If

    Forcing a test case to fail using exceptions

    Ranorex uses exception handling to determine whether a test case run failed or succeeded. As long as no exception is thrown by any of the Ranorex methods (e.g Ranorex.Validate method or use of not valid repository item) the test run will be successful. If you want to prevent Ranorex from throwing exceptions but at the same time decide on your own whether a test case fails or not, you need to throw Ranorex exceptions programmatically.

    Ranorex.Cell cellObject = null; 
    // Try to find a cell object using two 
    // different RanoreXPath expressions 
    bool found=false; 
    found = Host.Local.TryFindSingle<Ranorex.Cell>("/form//table/row/cell[3]", 2000, out cellObject); 
    found = found || Host.Local.TryFindSingle<Ranorex.cell>("/form//table/row/cell[4]", 2000, out cellObject); 
    // If none of the expressions returns an object 
    // throw new 'ElementNotFoundException' and test case fails 
    if (!found) 
    { 
     throw new Ranorex.ElementNotFoundException("Both RanoreXPath with no return", null); 
    } 
    else 
    { 
     // If the value of attribute 'Text' does not equal to the expected value 
     // throw new 'ValidationException' to break the test case 
     if ( cellObject.Text == "MyExpectedTextValue" ) 
     { 
     Report.Success("User Specific Validation","Text validation of cell object succeeded"); 
     } 
     else 
     { 
     throw new Ranorex.ValidationException("Text validation of cell object succeeded failed"); 
     } 
    } 
    </ranorex.cell></ranorex.cell> 
    Dim cellObject As Ranorex.Cell = Nothing 
    ' Try to find a cell object using two 
    ' different RanoreXPath expressions 
    Dim found As Boolean = Host.Local.TryFindSingle(Of Ranorex.Cell)("/form//table/row/cell[3]", 2000, cellObject) 
    found = found OrElse Host.Local.TryFindSingle(Of Ranorex.Cell)("/form//table/row/cell[4]", 2000, cellObject) 
    ' If none of the expressions returns an object 
    ' throw new 'ElementNotFoundException' and test case fails 
    If Not found Then 
     Throw New Ranorex.ElementNotFoundException("Both RanoreXPath with no return", Nothing) 
    Else 
     ' If the value of attribute 'Text' does not equal to the expected value 
     ' throw new 'ValidationException' to break the test case 
     If cellObject.Text = "MyExpectedTextValue" Then 
     Report.Success("User Specific Validation", "Text validation of cell object succeeded") 
     Else 
     Throw New Ranorex.ValidationException("Text validation of cell object succeeded failed") 
     End If 
    End If

    Set up automation speed

    You can optionally specify and change the automation speed at any time in the code. The code generated by a recording uses the same properties to define replay speed as used within a code module. A newly created code module already contains three lines of code specifying the automation speed in the ‘Run’ method.

    void ITestModule.Run() 
    { 
     Mouse.DefaultMoveTime = 300; 
     Keyboard.DefaultKeyPressTime = 100; 
     Delay.SpeedFactor = 1.0; 
    }
    Private Sub ITestModule_Run() Implements ITestModule.Run 
     Mouse.DefaultMoveTime = 300 
     Keyboard.DefaultKeyPressTime = 100 
     Delay.SpeedFactor = 1.0 
    End Sub

    Accessing test case and test suite context

    Sometimes it’s necessary to forward values read from the UI in a code module or recording to the module executed next in the scope of a test case. The example code shown below uses the module variables varDialogTextA (Code Module A) and varDialogTextB (Code Module B) which are both bound to a parameter specified within the test case’s data binding dialog to transfer data within a test case.

    // ----------------- Code Block used by Code Module A ----------------- 
     
    // Click 'Save' button to open 'SaveDialog' 
    repo.MyApp.Buttons.ButtonSave.Click(); 
    // Read text message shown with 'SaveDialog' 
    // and assign it to the variable 'varDialogTextA' bound to a test case parameter 
    varDialogTextA = repo.SaveDialog.TextMessage.TextValue; 
     
     
     
    // -------- Code Block used by User Code Action of recording B -------- 
     
    // Read value of module variable 'varDialogTextB' in other code module 
    // or recording module using a user code action 
    Report.Info(varDialogTextB); 
     
    // Get the current data context and log 
    // the current row index of a data driven run 
    Report.Info(TestCase.Current.DataContext.CurrentRowIndex.ToString());
    ' ----------------- Code Block used by Code Module A ----------------- 
     
    ' Click 'Save' button to open 'SaveDialog' 
    repo.MyApp.Buttons.ButtonSave.Click() 
    ' Read text message shown with 'SaveDialog' 
    ' and assign it to the variable 'varDialogTextA' bound to a test case parameter 
    varDialogTextA = repo.SaveDialog.TextMessage.TextValue 
     
    ' -------- Code Block used by User Code Action of recording B -------- 
     
    ' Read value of module variable 'varDialogTextB' in other code module 
    ' or recording module using a user code action 
    Report.Info(varDialogTextB) 
     
    ' Get the current data context and log 
    ' the current row index of a data driven run 
    Report.Info(TestCase.Current.DataContext.CurrentRowIndex.ToString())

    Advanced code examples

    You can also use RanoreXPath expressions directly in code in order to search for items using different ‘Find’ methods offered by the API. Start searching for elements directly at the root level using ‘Host.Local’ or reuse existing adapters like repository items to start searching from there.

    // Create Ranorex.Button adapter using 'FindSingle' method 
    // from Host.Local (starting at root node) with absolute RanoreXPath 
    // Note: ElementNotFound exception is thrown if item is not found within 
    // the specified timeout of 2000 ms. 
    Ranorex.Button addButtonVar1 = Host.Local.FindSingle<Ranorex.Button>("/form[@controlname='formVipApplication']/button[@controlname='btAdd']",2000); 
    addButtonVar1.MoveTo(); 
     
    // Alternatively you can use the 'TryFindSingle' method to prevent 
    // a test case from failing because of an exception thrown if 
    // the element is not found within the specified timeout of 2000 ms 
    Ranorex.Button addButtonVar2 = null; 
    bool found = Host.Local.TryFindSingle<Ranorex.Button>("/form[@controlname='formVipApplication']/button[@controlname='btAdd']", 2000, out addButtonVar2); 
    // Move mouse pointer to button 
    addButtonVar2.MoveTo(); 
     
    // Request a list of buttons shown from the VIP Database application 
    // and create a screenshot for each button in the report file 
    IList<Ranorex.Button> buttonList = Host.Local.Find<Ranorex.Button>("/form[@controlname='formVipApplication']/button",500); 
    foreach (Ranorex.Button bt in buttonList) 
    { 
     Report.Screenshot(bt); 
    } 
     
    // Using find methods in combination with existing Ranorex repository items 
    Ranorex.Button btAdd = repo.MyApp.Self.FindSingle<Ranorex.Button>("button[@controlname='btAdd']",2000);
    ' Create Ranorex.Button adapter using 'FindSingle' method 
    ' from Host.Local (starting at root node) with absolute RanoreXPath 
    ' Note: ElementNotFound exception is thrown if item is not found within 
    ' the specified timeout of 2000 ms. 
    Dim addButtonVar1 As Ranorex.Button = Host.Local.FindSingle(Of Ranorex.Button)("/form[@controlname='formVipApplication']/button[@controlname='btAdd']", 2000) 
    addButtonVar1.MoveTo() 
     
    ' Alternatively you can use 'TryFindSingle' method to prevent 
    ' a test case from failing because of an exception thrown if 
    ' the element is not found within the specified timeout of 2000 ms 
    Dim addButtonVar2 As Ranorex.Button = Nothing 
    Dim found As Boolean = Host.Local.TryFindSingle(Of Ranorex.Button)("/form[@controlname='formVipApplication']/button[@controlname='btAdd']", 2000, addButtonVar2) 
    ' Move mouse pointer to button 
    addButtonVar2.MoveTo() 
     
    ' Request a list of buttons from the VIP Database application 
    ' and create a screenshot for each button in the report file 
    Dim buttonList As IList(Of Ranorex.Button) = Host.Local.Find(Of Ranorex.Button)("/form[@controlname='formVipApplication']/button", 500) 
    For Each bt As Ranorex.Button In buttonList 
     Report.Screenshot(bt) 
    Next 
     
    ' Using find methods in combination with existing Ranorex repository items 
    Dim btAdd As Ranorex.Button = repo.MyApp.Self.FindSingle(Of Ranorex.Button)("button[@controlname='btAdd']", 2000)

    How to do image-based automation

    If Ranorex is not able to clearly identify some of your GUI elements, it may be helpful to automate them using the implicit image search mechanism of the ‘Click’ method.

    // Create bitmap to search for 
    // within application form and 
    // click it 
    Bitmap bmp = Ranorex.Imaging.Load( 
     @"....Green Sea Turtle Small.bmp"); 
    // Performs a right click on the image found 
    // within the application window based on 
    // the image location 
    myRepo.WinFormsApp.Self.Click(MouseButtons.Right,bmp); 
     
    // You can also search for images that are slightly different to the 
    // loaded image by specifying the minimum Similarity for a match (95% = 0.95). 
    myRepo.WinFormsApp.Self.Click(new Location(bmp, new Imaging.FindOptions(0.95))); 
     
    // OR Set the default Similarity value for all following image operations 
    Imaging.FindOptions.Default.Similarity = 0.95; 
    myRepo.WinFormsApp.Self.Click(bmp); 
     
    Report.Success("Image found and clicked successfully");
    ' Create bitmap to search for 
    ' within application form and 
    ' click it 
    Dim bmp As Bitmap = Ranorex.Imaging.Load("....Green Sea Turtle Small.bmp") 
    ' Performs a right click on the image found 
    ' within the application window based 
    ' on the image location 
    myRepo.WinFormsApp.Self.Click(MouseButtons.Right, bmp) 
     
    ' You can also search for images that are slightly different to the 
    ' loaded image by specifying the minimum Similarity for a match (95% = 0.95). 
    myRepo.WinFormsApp.Self.Click(new Location(bmp, new Imaging.FindOptions(0.95))) 
     
    ' OR Set the default Similarity value for all following image operations 
    Imaging.FindOptions.Default.Similarity = 0.95 
    myRepo.WinFormsApp.Self.Click(bmp) 
     
    Report.Success("Image displayed successfully")

    How to find and compare images

    To compare an image simply search for it within an existing Ranorex element using the ‘Contains’ method.

    tipp icon

    Hint

    Both examples load an uncompressed file (BMP or PNG format) in order to carry out a one-to-one comparison. Use the FindOptions class to configure similarity, preprocessing and other search settings.

    // Create bitmap 
    Bitmap bmp = Ranorex.Imaging.Load( 
     @"....Green Sea Turtle Small.bmp"); 
     
    // Search for it within the application window 
    if (Ranorex.Imaging.Contains(myRepo.WinFormsApp.Self,bmp) == true) 
    { 
     Report.Success("Image found within WinForms application"); 
    }
    ' Create bitmap 
    Dim bmp As Bitmap = Ranorex.Imaging.Load("....Green Sea Turtle Small.bmp") 
    ' Search for it within the application window 
    If Imaging.Contains(myRepo.WinFormsApp.Self,bmp Then 
     Report.Success("Image found within WinForms application") 
    End If

    Handling unexpected dialogs

    A common problem in UI testing is the appearance of an unexpected dialog – e.g. the Update-Check dialog in KeePass.

    To overcome this issue, you can use the PopupWatcher class. Using this class you can add watches for each dialog which might pop up during test execution. In these watches you can specify a RanoreXPath or a Repository item the PopupWatcher should keep watching for, as well as a method which should be triggered or a repository item which should be clicked.

     

    void ITestModule.Run() 
    { 
     
     // Create PopupWatcher 
     PopupWatcher myPopupWatcher = new PopupWatcher(); 
     
     // Add a Watch using a RanoreXPath and triggering the Method CloseUpdateCheckDialog 
     myPopupWatcher.Watch("/form[@controlname='UpdateCheckForm']/button[@controlname='m_btnClose']", CloseUpdateCheckDialog); 
     
     // Add a Watch using the info object of a button and triggering the Method CloseUpdateCheckDialog 
     // myPopupWatcher.Watch(repo.UpdateCheckDialog.btCloseInfo, CloseUpdateCheckDialog); 
     
     // Add a Watch using the info object of the dialog and the info object of the button to click 
     // myPopupWatcher.WatchAndClick(repo.UpdateCheckDialog.SelfInfo, repo.UpdateCheckDialog.btCloseInfo); 
     
     // Add a Watch using a repository folder object and the info object of the button to click 
     // myPopupWatcher.WatchAndClick(repo.UpdateCheckDialog, repo.UpdateCheckDialog.btCloseInfo); 
     
     // Start PopupWatcher 
     myPopupWatcher.Start(); 
     
    } 
     
    public static void CloseUpdateCheckDialog(Ranorex.Core.Repository.RepoItemInfo myInfo, Ranorex.Core.Element myElement) 
    { 
     myElement.As<Ranorex.Button>().Click(); 
    } 
     
    public static void CloseUpdateCheckDialog(Ranorex.Core.RxPath myPath, Ranorex.Core.Element myElement) 
    { 
     myElement.As<Ranorex.Button>().Click(); 
    }
    Private Sub ITestModule_Run() Implements ITestModule.Run 
     
     ' Create PopupWatcher 
     Dim myPopupWatcher As New PopupWatcher() 
     
     ' Add a Watch using a RanoreXPath and triggering the Method CloseUpdateCheckDialog 
     myPopupWatcher.Watch("/form[@controlname='UpdateCheckForm']/button[@controlname='m_btnClose']", AddressOf CloseUpdateCheckDialog) 
     
     ' Add a Watch using the info object of a button and triggering the Method CloseUpdateCheckDialog 
     ' myPopupWatcher.Watch(repo.UpdateCheckDialog.btCloseInfo, CloseUpdateCheckDialog); 
     
     ' Add a Watch using the info object of the dialog and the info object of the button to click 
     ' myPopupWatcher.WatchAndClick(repo.UpdateCheckDialog.SelfInfo, repo.UpdateCheckDialog.btCloseInfo); 
     
     ' Add a Watch using a repository folder object and the info object of the button to click 
     ' myPopupWatcher.WatchAndClick(repo.UpdateCheckDialog, repo.UpdateCheckDialog.btCloseInfo); 
     
     ' Start PopupWatcher 
     myPopupWatcher.Start() 
     
    End Sub 
     
    Public Shared Sub CloseUpdateCheckDialog(myInfo As Ranorex.Core.Repository.RepoItemInfo, myElement As Ranorex.Core.Element) 
     myElement.[As](Of Ranorex.Button)().Click() 
    End Sub 
     
    Public Shared Sub CloseUpdateCheckDialog(myPath As Ranorex.Core.RxPath, myElement As Ranorex.Core.Element) 
     myElement.[As](Of Ranorex.Button)().Click() 
    End Sub

    Creating and using a WebDriver (incl. configuration) in code

    // Create endpoint management factory
    var fac = new RemoteEndpointFactory();
    
    // Use existing endpoints
    var existing = fac.GetAll();
    Report.Log(ReportLevel.Info, string.Format("Endpoints: {0}", existing.Count()));
    
    foreach (var e in existing)
    {
     Report.Log(ReportLevel.Info, string.Format("Name: {0}", e.DisplayName));
    }
    
    // Get WebDriver endpoints form the existing ones (no equivalent for mobile currently)
    var webDriverEndpoints = fac.GetAllWebDriverEndpoints();
    Report.Log(ReportLevel.Info, string.Format("There are '{0}' WebDriver endpoints", webDriverEndpoints.Count()));
    
    // Create user process endpoint
    var ep = fac.CreateTransientWebDriverEndpoint(new WebDriverEndpointInfo("tempEp", "http://localhost:4444/wd/hub"));
    
    var cfg = WebDriverConfiguration.FromJson("{}");
    cfg.Name = "MyConfig1";
    cfg.Description = "Code sample Config";
    
    ep.ActivateConfiguration(cfg);
    
    ep.ConnectAsync()
     .ContinueWith(_ => ep.MakeCurrentHostAsync())
     .Wait();
    
    var b = ep.StartBrowser("firefox", "https://support.ranorex.com");
    

    Advanced validation – clipboard

    This sample shows how the current content of the clipboard can be validated against a given reference value.

    public void Validate_ClipboardContentEqual(string compareText, string customLogMessage) 
    { 
     // check if content of clipboard is text 
     if (System.Windows.Forms.Clipboard.ContainsText()) 
     { 
     // Get text from clipboard 
     string clipboardtext = System.Windows.Forms.Clipboard.GetText(); 
     
     // prepare log message if the log-parameter is empty 
     if (string.IsNullOrEmpty(clipboardtext)) 
     { 
     customLogMessage = "Comparing content of clipboard with given text: ({0} vs. {1})"; ; 
     } 
     
     // Validate if given text (compareText) is equal to current text in clipboard 
     Ranorex.Validate.AreEqual(clipboardtext, compareText, customLogMessage); 
     } 
     else 
     { 
     throw new Ranorex.RanorexException("There is not text on the clipboard that can be compared"); 
     } 
    }
    Public Sub Validate_ClipboardContentEqual(compareText As String, customLogMessage As String) 
     ' check if content of clipboard is text 
     If System.Windows.Forms.Clipboard.ContainsText() Then 
     ' Get text from clipboard 
     Dim clipboardtext As String = System.Windows.Forms.Clipboard.GetText() 
     
     ' prepare log message if the log-parameter is empty 
     If String.IsNullOrEmpty(clipboardtext) Then 
     customLogMessage = "Comparing content of clipboard with given text: ({0} vs. {1})" 
     
     
     End If 
     
     ' Validate if given text (compareText) is equal to current text in clipboard 
     Ranorex.Validate.AreEqual(clipboardtext, compareText, customLogMessage) 
     Else 
     Throw New Ranorex.RanorexException("There is not text on the clipboard that can be compared") 
     End If 
    End Sub

    Advanced validation – entire table

    This sample shows how the content of a whole table (UI control) can be validated at once. Therefore the table has to be passed as a parameter. Additionally the filename of a Ranorex Snapshot needs to be provided which will act as a reference and defines the expected content of the table.

    Note icon

    Note

    The referencing snapshot has to be created before calling this advanced validation function. Simply select the table in the tree view in Ranorex Spy, right-click and choose “Save as Snapshot” in the context menu. More information on creating snapshots can be found here: ⇢ Creating Ranorex Snapshots.

    public void Validate_TableContentEqual(Ranorex.Adapter repoItem, string filename_ReferenceTableSnapshot, string customLogMessageOverall, string customLogMessageDetail) 
    { 
     
     // check if snapshot file exists 
     const string fileNotExists = "The given file does not exist: {0}"; 
     if (!System.IO.File.Exists(filename_ReferenceTableSnapshot)) 
     { 
     throw new Ranorex.ValidationException(string.Format(fileNotExists, filename_ReferenceTableSnapshot)); 
     } 
     
     ElementSnapshot snap = null; 
     try 
     { 
     snap = Ranorex.Core.ElementSnapshot.CreateFromFile (filename_ReferenceTableSnapshot); // ElementSnapshot.CreateFromFile is available starting with Ranorex 5.4.2 
     } 
     catch 
     { 
     throw new Ranorex.ValidationException("Snapshot could not be loaded from file"); 
     } 
     
     // restore table from snapshot 
     Ranorex.Table refTable; 
     try 
     { 
     refTable = snap.Element; 
     } 
     catch 
     { 
     throw new Ranorex.ValidationException("Table could not be created from snapshot"); 
     } 
     var tableAdapter = repoItem.As <Ranorex.Table>(); 
     if (tableAdapter==null) 
     { 
     throw new Ranorex.ValidationException("Repo-item could not be accessed"); 
     } 
     
     // check if rowcount is identical 
     if (tableAdapter.Rows.Count != refTable.Rows.Count) 
     { 
     throw new Ranorex.ValidationException(String.Format ("Tables do not have same number of rows ({0} vs. {1})", tableAdapter.Rows.Count, refTable.Rows.Count)); 
     } 
     
     // run through table-rows 
     for (int iRow = 0; iRow <= tableAdapter.Rows.Count - 1; iRow++) 
     { 
     int cellCountCur = tableAdapter.Rows[iRow].Cells.Count; 
     int cellCountRef = refTable.Rows[iRow].Cells.Count; 
     
     // check if number of cells is identical in current row 
     if (cellCountCur != cellCountRef) 
     { 
     throw new Ranorex.ValidationException(String.Format("Table-Rows do not have same number of cells ({0} vs. {1})", cellCountCur, cellCountRef)); 
     } 
     
     // run through cells in current row 
     for (int iCol = 0; iCol <= cellCountCur - 1; iCol++) 
     { 
     string aCurText = tableAdapter.Rows[iRow].Cells[iCol].As<Ranorex.Cell>().Text; 
     string aRefText = refTable.Rows[iRow].Cells[iCol].As<Ranorex.Cell>().Text; 
     
     string validationMessage = string.Empty; 
     if (string.IsNullOrEmpty(customLogMessageDetail)) 
     { 
     validationMessage = String.Format ("Comparing content of cell ({2}/{3}) (found:'{0}', expected: '{1}')", aCurText, aRefText, iRow,iCol); 
     } 
     else 
     { 
     validationMessage = customLogMessageDetail; 
     } 
     
     // validate whether current text and expected text are identical 
     Ranorex.Validate.AreEqual (aCurText, aRefText, validationMessage); 
     } 
     } 
     // Log overall success 
     if (string.IsNullOrEmpty(customLogMessageOverall)) 
     customLogMessageOverall = "Successfully completed content-validation of table with provided snapshot of table (reference)"; 
     Ranorex.Report.Log (ReportLevel.Success, customLogMessageOverall); 
    }
    public Sub Validate_TableContentEqual(repoItem As Ranorex.Adapter, filename_ReferenceTableSnapshot As String, customLogMessageOverall As String, customLogMessageDetail As String) 
     
     ' check if snapshot file exists 
     Const fileNotExists As String = "The given file does not exist: {0}" 
     If Not System.IO.File.Exists(filename_ReferenceTableSnapshot) Then 
     Throw New Ranorex.ValidationException(String.Format(fileNotExists, filename_ReferenceTableSnapshot)) 
     End If 
     
     Dim snap As ElementSnapshot = Nothing 
     Try 
     snap = Ranorex.Core.ElementSnapshot.CreateFromFile(filename_ReferenceTableSnapshot) 'ElementSnapshot.CreateFromFile is available starting with Ranorex 5.4.2 
     Catch 
     Throw New Ranorex.ValidationException("Snapshot could not be loaded from file") 
     End Try 
     
     ' restore table from snapshot 
     Dim refTable As Ranorex.Table 
     Try 
     refTable = snap.Element 
     Catch 
     Throw New Ranorex.ValidationException("Table could not be created from snapshot") 
     End Try 
     Dim tableAdapter = repoItem.[As](Of Ranorex.Table)() 
     If tableAdapter Is Nothing Then 
     Throw New Ranorex.ValidationException("Repo-item could not be accessed") 
     End If 
     
     ' check if rowcount is identical 
     If tableAdapter.Rows.Count <> refTable.Rows.Count Then 
     Throw New Ranorex.ValidationException([String].Format("Tables do not have same number of rows ({0} vs. {1})", tableAdapter.Rows.Count, refTable.Rows.Count)) 
     End If 
     
     ' run through table-rows 
     For iRow As Integer = 0 To tableAdapter.Rows.Count - 1 
     Dim cellCountCur As Integer = tableAdapter.Rows(iRow).Cells.Count 
     Dim cellCountRef As Integer = refTable.Rows(iRow).Cells.Count 
     
     ' check if number of cells is identical in current row 
     If cellCountCur <> cellCountRef Then 
     Throw New Ranorex.ValidationException([String].Format("Table-Rows do not have same number of cells ({0} vs. {1})", cellCountCur, cellCountRef)) 
     End If 
     
     ' run through cells in current row 
     For iCol As Integer = 0 To cellCountCur - 1 
     Dim aCurText As String = tableAdapter.Rows(iRow).Cells(iCol).[As](Of Ranorex.Cell)().Text 
     Dim aRefText As String = refTable.Rows(iRow).Cells(iCol).[As](Of Ranorex.Cell)().Text 
     
     Dim validationMessage As String = String.Empty 
     If String.IsNullOrEmpty(customLogMessageDetail) Then 
     validationMessage = [String].Format("Comparing content of cell ({2}/{3}) (found:'{0}', expected: '{1}')", aCurText, aRefText, iRow, iCol) 
     Else 
     validationMessage = customLogMessageDetail 
     End If 
     
     ' validate whether current text and expected text are identical 
     Ranorex.Validate.AreEqual(aCurText, aRefText, validationMessage) 
     Next 
     Next 
     ' Log overall success 
     If String.IsNullOrEmpty(customLogMessageOverall) Then 
     customLogMessageOverall = "Successfully completed content-validation of table with provided snapshot of table (reference)" 
     End If 
     Ranorex.Report.Log(ReportLevel.Success, customLogMessageOverall) 
    End Sub

    Advanced validation – entire table in web

    This sample shows how the content of a whole web table (HTML tag table) can be validated at once. Therefore the table has to be passed as a parameter. Additionally the filename of a Ranorex Snapshot needs to be provided which will act as a reference and defines the expected content of the web table.

    Note icon

    Note

    The referencing snapshot has to be created before calling this advanced validation function. Simply select the table in the tree view in Ranorex Spy, right-click and choose “Save as Snapshot” in the context menu. More information on creating snapshots can be found here: ⇢ Creating Ranorex Snapshots.

    public void Validate_WebTableContentEqual(Ranorex.Adapter repoItem, string filename_ReferenceTableSnapshot, string customLogMessageOverall, string customLogMessageDetail) 
    { 
     // check if snapshot file exists 
     Ranorex.Validate.IsTrue (System.IO.File.Exists (filename_ReferenceTableSnapshot), string.Format("Checking existence of snapshot file: {0}",filename_ReferenceTableSnapshot )); 
     
     ElementSnapshot snap; 
     try 
     { 
     snap = Ranorex.Core.ElementSnapshot.CreateFromFile (filename_ReferenceTableSnapshot); // ElementSnapshot.CreateFromFile is available starting with Ranorex 5.4.2 
     } 
     catch 
     { 
     throw new Ranorex.ValidationException ("Snapshot could not be loaded from file"); 
     } 
     
     // restore table from snapshot 
     Ranorex.TableTag refTable; 
     try 
     { 
     refTable = snap.Element; 
     } 
     catch (Exception e) 
     { 
     throw new Ranorex.ValidationException("Table could not be created from snapshot.", e); 
     } 
     
     Ranorex.TableTag tableAdapter = repoItem.As <Ranorex.TableTag>(); 
     if (tableAdapter==null) 
     { 
     throw new Ranorex.ValidationException("Repo-item could not be accessed."); 
     } 
     
     IList<TrTag> actTableRows = tableAdapter.FindDescendants<TrTag>(); 
     int rowCntAct = actTableRows.Count; 
     IList<TrTag> refTableRows = refTable.FindDescendants<TrTag>(); 
     int rowCntRef = refTableRows.Count; 
     
     // check if rowcount is identical 
     Ranorex.Validate.AreEqual (rowCntAct, rowCntRef, "Comparing number of rows ({0} vs. {1})"); 
     
     // run through table-rows 
     for (int iRow = 0; iRow <= actTableRows.Count - 1; iRow++) 
     { 
     IList<Ranorex.WebElement> cellsInActRow = actTableRows[iRow].FindChildren<Ranorex.WebElement>(); 
     IList<Ranorex.WebElement> cellsInRefRow = refTableRows[iRow].FindChildren<Ranorex.WebElement>(); 
     
     // check if number of cells is identical in current row 
     Ranorex.Validate.AreEqual (cellsInActRow.Count, cellsInRefRow.Count, "Comparing number of cells in current row ({0} vs. {1})"); 
     
     // run through cells in current row 
     for (int iCol = 0; iCol <= cellsInActRow.Count - 1; iCol++) 
     { 
     string aCurText = new WebElement(cellsInActRow[iCol]).InnerText; 
     string aRefText = new WebElement(cellsInRefRow[iCol]).InnerText; 
     
     string validationMessage = string.Empty; 
     if (string.IsNullOrEmpty(customLogMessageDetail)) 
     { 
     validationMessage = String.Format ("Comparing content of cell ({2}/{3}) (found:'{0}', expected: '{1}')", aCurText, aRefText, iRow,iCol); 
     } 
     else 
     { 
     validationMessage = customLogMessageDetail; 
     } 
     
     // validate whether current text and expected text are identical 
     Ranorex.Validate.AreEqual (aCurText, aRefText, validationMessage); 
     } 
     } 
     
     // Log overall success 
     if (string.IsNullOrEmpty(customLogMessageOverall)) 
     customLogMessageOverall = "Successfully completed content-validation of web-table with provided snapshot of web-table (reference)"; 
     Ranorex.Report.Log (ReportLevel.Success, customLogMessageOverall); 
    }
    Public Sub Validate_WebTableContentEqual(repoItem As Ranorex.Adapter, filename_ReferenceTableSnapshot As String, customLogMessageOverall As String, customLogMessageDetail As String) 
     ' check if snapshot file exists 
     Ranorex.Validate.IsTrue(System.IO.File.Exists(filename_ReferenceTableSnapshot), String.Format("Checking existence of snapshot file: {0}", filename_ReferenceTableSnapshot)) 
     
     Dim snap As ElementSnapshot 
     Try 
     ' ElementSnapshot.CreateFromFile is available starting with Ranorex 5.4.2 
     snap = Ranorex.Core.ElementSnapshot.CreateFromFile(filename_ReferenceTableSnapshot) 
     Catch 
     Throw New Ranorex.ValidationException("Snapshot could not be loaded from file") 
     End Try 
     
     ' restore table from snapshot 
     Dim refTable As Ranorex.TableTag 
     Try 
     refTable = snap.Element 
     Catch e As Exception 
     Throw New Ranorex.ValidationException("Table could not be created from snapshot.", e) 
     End Try 
     
     Dim tableAdapter As Ranorex.TableTag = repoItem.[As](Of Ranorex.TableTag)() 
     If tableAdapter Is Nothing Then 
     Throw New Ranorex.ValidationException("Repo-item could not be accessed.") 
     End If 
     
     Dim actTableRows As IList(Of TrTag) = tableAdapter.FindDescendants(Of TrTag)() 
     Dim rowCntAct As Integer = actTableRows.Count 
     Dim refTableRows As IList(Of TrTag) = refTable.FindDescendants(Of TrTag)() 
     Dim rowCntRef As Integer = refTableRows.Count 
     
     ' check if rowcount is identical 
     Ranorex.Validate.AreEqual(rowCntAct, rowCntRef, "Comparing number of rows ({0} vs. {1})") 
     
     ' run through table-rows 
     For iRow As Integer = 0 To actTableRows.Count - 1 
     Dim cellsInActRow As IList(Of Ranorex.WebElement) = actTableRows(iRow).FindChildren(Of Ranorex.WebElement)() 
     Dim cellsInRefRow As IList(Of Ranorex.WebElement) = refTableRows(iRow).FindChildren(Of Ranorex.WebElement)() 
     
     ' check if number of cells is identical in current row 
     Ranorex.Validate.AreEqual(cellsInActRow.Count, cellsInRefRow.Count, "Comparing number of cells in current row ({0} vs. {1})") 
     
     ' run through cells in current row 
     For iCol As Integer = 0 To cellsInActRow.Count - 1 
     Dim aCurText As String = New WebElement(cellsInActRow(iCol)).InnerText 
     Dim aRefText As String = New WebElement(cellsInRefRow(iCol)).InnerText 
     
     Dim validationMessage As String = String.Empty 
     If String.IsNullOrEmpty(customLogMessageDetail) Then 
     validationMessage = [String].Format("Comparing content of cell ({2}/{3}) (found:'{0}', expected: '{1}')", aCurText, aRefText, iRow, iCol) 
     Else 
     validationMessage = customLogMessageDetail 
     End If 
     
     ' validate whether current text and expected text are identical 
     Ranorex.Validate.AreEqual(aCurText, aRefText, validationMessage) 
     Next 
     Next 
     
     ' Log overall success 
     If String.IsNullOrEmpty(customLogMessageOverall) Then 
     customLogMessageOverall = "Successfully completed content-validation of web-table with provided snapshot of web-table (reference)" 
     End If 
     Ranorex.Report.Log(ReportLevel.Success, customLogMessageOverall) 
    End Sub

    Advanced validation – file (text-based)

    This sample shows how the content of a text-based file can be validated. The content of the file will be compared with the content of a reference-file. Therefore the filename of the file to validate needs to be provided as well as the filename of a reference-file.

    public void Validate_FileTextEqual(string filePath_Expected, string filePath_Current, string customLogMessage) 
    { 
     // prepare log messages 
     const string fileNotFoundMessage = "File not found for comparison in Validate_FileContentEqual: {0}"; 
     const string logMessage = "Comparing content of files ({0} vs. {1})"; 
     if (string.IsNullOrEmpty(customLogMessage)) 
     { 
     customLogMessage = string.Format(logMessage, filePath_Expected, filePath_Current); 
     } 
     
     // check if file exists 
     if (!System.IO.File.Exists(filePath_Current)) 
     { 
     throw new Ranorex.RanorexException(string.Format(fileNotFoundMessage, filePath_Current)); 
     } 
     
     // check if referencing file exists 
     if (!System.IO.File.Exists(filePath_Expected)) 
     { 
     throw new Ranorex.RanorexException(string.Format(fileNotFoundMessage, filePath_Expected)); 
     } 
     
     // check if filenames are identical 
     if (filePath_Expected.Equals(filePath_Current)) 
     { 
     Ranorex.Validate.IsTrue(true, customLogMessage); 
     } 
     else 
     { 
     string current = System.IO.File.ReadAllText(filePath_Current); 
     string expected = System.IO.File.ReadAllText(filePath_Expected); 
     // validate whether expected value equals to current value 
     Ranorex.Validate.AreEqual(current, expected, customLogMessage); 
     } 
    }
    Public Sub Validate_FileTextEqual(filePath_Expected As String, filePath_Current As String, customLogMessage As String) 
     ' prepare log messages 
     Const fileNotFoundMessage As String = "File not found for comparison in Validate_FileContentEqual: {0}" 
     Const logMessage As String = "Comparing content of files ({0} vs. {1})" 
     If String.IsNullOrEmpty(customLogMessage) Then 
     customLogMessage = String.Format(logMessage, filePath_Expected, filePath_Current) 
     End If 
     
     ' check if file exists 
     If Not System.IO.File.Exists(filePath_Current) Then 
     Throw New Ranorex.RanorexException(String.Format(fileNotFoundMessage, filePath_Current)) 
     End If 
     
     ' check if referencing file exists 
     If Not System.IO.File.Exists(filePath_Expected) Then 
     Throw New Ranorex.RanorexException(String.Format(fileNotFoundMessage, filePath_Expected)) 
     End If 
     
     ' check if filenames are identical 
     If filePath_Expected.Equals(filePath_Current) Then 
     Ranorex.Validate.IsTrue(True, customLogMessage) 
     Else 
     Dim current As String = System.IO.File.ReadAllText(filePath_Current) 
     Dim expected As String = System.IO.File.ReadAllText(filePath_Expected) 
     ' validate whether expected value equals to current value 
     Ranorex.Validate.AreEqual(current, expected, customLogMessage) 
     End If 
    End Sub

    Advanced validation – file (not-text-based, binary)

    This sample shows how a non text-based file (binary file) can be validated. The content of the file will be compared with the content of a reference-file. Therefore the filename of the file to validate needs to be provided as well as the filename of a reference-file.

    public void Validate_FileBinaryContentEqual(string filePath_Expected, string filePath_Current, string customLogMessage) 
    { 
     // prepare log messages 
     const string fileNotFoundMessage = "File not found for comparison in Validate_FileContentEqual: {0}"; 
     const string logMessage = "Comparing content of files ({0} vs. {1})"; 
     if (string.IsNullOrEmpty(customLogMessage)) 
     { 
     customLogMessage = string.Format(logMessage, filePath_Expected, filePath_Current); 
     } 
     
     // check if file exists 
     if (!System.IO.File.Exists(filePath_Current)) 
     { 
     throw new Ranorex.ValidationException (string.Format(fileNotFoundMessage, filePath_Current)); 
     } 
     
     // check if referencing file exists 
     if (!System.IO.File.Exists(filePath_Expected)) 
     { 
     throw new Ranorex.ValidationException(string.Format(fileNotFoundMessage, filePath_Expected)); 
     } 
     
     
     // check if filenames are identical 
     if (filePath_Expected.Equals(filePath_Current)) 
     { 
     Ranorex.Validate.IsTrue(true, customLogMessage); 
     } 
     else 
     { 
     using (var file1 = new System.IO.FileStream(filePath_Current, System.IO.FileMode.Open)) 
     using (var file2 = new System.IO.FileStream(filePath_Expected, System.IO.FileMode.Open)) 
     // Check whether files are equal 
     Ranorex.Validate.IsTrue(StreamEquals(file1, file2), customLogMessage); 
     } 
    } 
     
    // compare file-streams 
    private static bool StreamEquals(System.IO.Stream stream1, System.IO.Stream stream2) 
    { 
     const int bufferSize = 2048; 
     byte[] buffer1 = new byte[bufferSize]; 
     byte[] buffer2 = new byte[bufferSize]; 
     while (true) 
     { 
     int count1 = stream1.Read(buffer1, 0, bufferSize); 
     int count2 = stream2.Read(buffer2, 0, bufferSize); 
     
     if (count1 != count2) 
     return false; 
     
     if (count1 == 0) 
     return true; 
     
     for (int i = 0; i < count1; i++) 
     { 
     if (buffer1[i] != buffer2[i]) 
     { 
     return false; 
     } 
     } 
     } 
    } 
    
    Public Sub Validate_FileBinaryContentEqual(filePath_Expected As String, filePath_Current As String, customLogMessage As String) 
     ' prepare log messages 
     Const fileNotFoundMessage As String = "File not found for comparison in Validate_FileContentEqual: {0}" 
     Const logMessage As String = "Comparing content of files ({0} vs. {1})" 
     If String.IsNullOrEmpty(customLogMessage) Then 
     customLogMessage = String.Format(logMessage, filePath_Expected, filePath_Current) 
     End If 
     
     ' check if file exists 
     If Not System.IO.File.Exists(filePath_Current) Then 
     Throw New Ranorex.ValidationException(String.Format(fileNotFoundMessage, filePath_Current)) 
     End If 
     
     ' check if referencing file exists 
     If Not System.IO.File.Exists(filePath_Expected) Then 
     Throw New Ranorex.ValidationException(String.Format(fileNotFoundMessage, filePath_Expected)) 
     End If 
     
     
     ' check if filenames are identical 
     If filePath_Expected.Equals(filePath_Current) Then 
     Ranorex.Validate.IsTrue(True, customLogMessage) 
     Else 
     Using file1 = New System.IO.FileStream(filePath_Current, System.IO.FileMode.Open) 
     Using file2 = New System.IO.FileStream(filePath_Expected, System.IO.FileMode.Open) 
     ' Check whether files are equal 
     Ranorex.Validate.IsTrue(StreamEquals(file1, file2), customLogMessage) 
     End Using 
     End Using 
     End If 
    End Sub 
     
    ' compare file-streams 
    Private Shared Function StreamEquals(stream1 As System.IO.Stream, stream2 As System.IO.Stream) As Boolean 
     Const bufferSize As Integer = 2048 
     Dim buffer1 As Byte() = New Byte(bufferSize - 1) {} 
     Dim buffer2 As Byte() = New Byte(bufferSize - 1) {} 
     While True 
     Dim count1 As Integer = stream1.Read(buffer1, 0, bufferSize) 
     Dim count2 As Integer = stream2.Read(buffer2, 0, bufferSize) 
     
     If count1 <> count2 Then 
     Return False 
     End If 
     
     If count1 = 0 Then 
     Return True 
     End If 
     
     For i As Integer = 0 To count1 - 1 
     If buffer1(i) <> buffer2(i) Then 
     Return False 
     End If 
     Next 
     End While 
    End Function

    Advanced validation – database (single field)

    This sample shows how a database-field can be validated against a given text value. To access the database, a valid connection string needs to be provided as well as a valid SQL Statement. Please see the MSDN for more information on the OLE database connection.

    Note icon

    Note

    For performance reasons, do not use this method in a series. If you want to access an entire table and/or SQL results, use the method after this one.

    public void Validate_DatabaseFieldWithQuery(string OLEConnectionString, string SQLQuery, string expectedValue, string customLogMessage) 
    { 
     
     // check is connection string is empty 
     if (string.IsNullOrEmpty(OLEConnectionString)) 
     { 
     throw new Ranorex.RanorexException("ConnectionString is empty"); 
     } 
     
     // check if SQL statement is empty 
     if (SQLQuery.Trim().Equals(string.Empty)) 
     { 
     throw new Ranorex.RanorexException("SQLQuery is empty"); 
     } 
     
     // establish connection to database 
     using (System.Data.OleDb.OleDbConnection connection = new System.Data.OleDb.OleDbConnection(@OLEConnectionString)) 
     { 
     connection.Open(); 
     
     System.Data.OleDb.OleDbCommand command = null; 
     System.Data.OleDb.OleDbDataReader SQLReader = null; 
     try 
     { 
     // set SQL statement and execute search 
     command = new System.Data.OleDb.OleDbCommand(SQLQuery, connection); 
     SQLReader = command.ExecuteReader(); 
     
     SQLReader.Read(); 
     
     // check if there is a result 
     if (SQLReader.FieldCount > 0) 
     { 
     
     // retrieve single result from SQL database 
     var actualValue = SQLReader.GetString(0); 
     
     // prepare log message 
     if (customLogMessage.Trim().Equals(string.Empty)) 
     { 
     customLogMessage = "Actual value = '{0}', expected value = '{1}' (database query = " + SQLQuery + ")"; 
     } 
     
     // compare retrieved value with expected value 
     Ranorex.Validate.AreEqual(actualValue, expectedValue, customLogMessage); 
     } 
     else 
     { 
     throw new Ranorex.RanorexException(string.Format("SQL statement did not return any results: {0}", SQLQuery)); 
     } 
     } 
     finally 
     { 
     command.Dispose(); 
     SQLReader.Dispose(); 
     } 
     } 
    }
    Public Sub Validate_DatabaseFieldWithQuery(OLEConnectionString As String, SQLQuery As String, expectedValue As String, customLogMessage As String) 
     
     ' check is connection string is empty 
     If String.IsNullOrEmpty(OLEConnectionString) Then 
     Throw New Ranorex.RanorexException("ConnectionString is empty") 
     End If 
     
     ' check if SQL statement is empty 
     If SQLQuery.Trim().Equals(String.Empty) Then 
     Throw New Ranorex.RanorexException("SQLQuery is empty") 
     End If 
     
     ' establish connection to database 
     Using connection As New System.Data.OleDb.OleDbConnection(OLEConnectionString) 
     connection.Open() 
     
     Dim command As System.Data.OleDb.OleDbCommand = Nothing 
     Dim SQLReader As System.Data.OleDb.OleDbDataReader = Nothing 
     Try 
     ' set SQL statement and execute search 
     command = New System.Data.OleDb.OleDbCommand(SQLQuery, connection) 
     SQLReader = command.ExecuteReader() 
     
     SQLReader.Read() 
     
     ' check if there is a result 
     If SQLReader.FieldCount > 0 Then 
     
     ' retrieve single result from SQL database 
     Dim actualValue = SQLReader.GetString(0) 
     
     ' prepare log message 
     If customLogMessage.Trim().Equals(String.Empty) Then 
     customLogMessage = "Actual value = '{0}', expected value = '{1}' (database query = " & SQLQuery & ")" 
     End If 
     
     ' compare retrieved value with expected value 
     Ranorex.Validate.AreEqual(actualValue, expectedValue, customLogMessage) 
     Else 
     Throw New Ranorex.RanorexException(String.Format("SQL statement did not return any results: {0}", SQLQuery)) 
     End If 
     Finally 
     command.Dispose() 
     SQLReader.Dispose() 
     End Try 
     End Using 
    End Sub

    Advanced validation – database (entire table)

    This sample shows how the content of a database can be validated. Using it you can check against an entire table, a database view or against every result of an SQL statement. Thus a valid SQL statement as well as a valid connection string has to be provided to allow access to the database. Please see the MSDN for more information on establishing an OLE database connection.

    Additionally, the filename of a csv-file needs to be passed in as a parameter. This file is acts as a reference and should contain the expected values. If the values in the file are separated differently than using the semicolon (“;”), please use the parameter “csvSeparator” to pass it in.

    Note icon

    Note

    The reference file (csv-file) needs to be created in forefront of calling this method. Every text editor can be used for creating this reference-file.

     public void Validate_DatabaseTableWithQuery(string OLEConnectionString, string SQLQuery, string referenceCSVTable, string csvSeparator, string customLogMessageOverall, string customLogMessageDetail) 
    { 
     
     // check if reference file exists 
     if (!System.IO.File.Exists(referenceCSVTable)) 
     { 
     throw new Ranorex.RanorexException(string.Format("File does not exist: {0}", referenceCSVTable)); 
     } 
     
     // check if connection string is empty 
     if (OLEConnectionString.Trim().Equals(string.Empty)) 
     { 
     throw new Ranorex.RanorexException("ConnectionString is empty"); 
     } 
     
     // check if SQL statement is empty 
     if (SQLQuery.Trim().Equals(string.Empty)) 
     { 
     throw new Ranorex.RanorexException("SQLQuery is empty"); 
     } 
     
     // prepare separator for csv file (if not passed in) 
     char separator; 
     if (string.IsNullOrEmpty(csvSeparator)) 
     { 
     separator = ';'; 
     } 
     else 
     { 
     separator = csvSeparator[0]; 
     } 
     
     // establish database connection 
     using (System.Data.OleDb.OleDbConnection connection = new System.Data.OleDb.OleDbConnection(@OLEConnectionString)) 
     { 
     connection.Open(); 
     
     System.Data.OleDb.OleDbCommand command = null; 
     System.Data.OleDb.OleDbDataReader SQLReader = null; 
     System.IO.StreamReader CSVReader = null; 
     
     try 
     { 
     // set SQL statement and execute search 
     command = new System.Data.OleDb.OleDbCommand(SQLQuery, connection); 
     SQLReader = command.ExecuteReader(); 
     
     // open csv file (reference file) 
     CSVReader = new System.IO.StreamReader(System.IO.File.OpenRead(@referenceCSVTable)); 
     
     // run through every line in file 
     int iRow = 0; 
     while ((SQLReader.Read()) && (!CSVReader.EndOfStream)) 
     { 
     
     // read line from csv file 
     var line = CSVReader.ReadLine(); 
     
     // split line into array of values 
     var values = line.Split(separator); 
     
     // check if number of values equals (in current row of csv file and in SQL result) 
     if (values.Length != SQLReader.FieldCount) 
     { 
     throw new Ranorex.RanorexException(string.Format("Number of fields in SQL query and reference-file does not match ({0} vs. {1})", values.Length + 1, SQLReader.FieldCount)); 
     } 
     
     
     // run through every field in SQL result 
     for (int iFields = 0; iFields <= SQLReader.FieldCount - 1; iFields++) 
     { 
     
     var expectedValue = values[iFields]; 
     var actualValue = SQLReader[iFields].ToString(); 
     
     // prepare log message 
     string validationMessage = string.Empty; 
     if (string.IsNullOrEmpty(customLogMessageDetail)) 
     { 
     validationMessage = String.Format("Comparing content of cell ({2}/{3}) (found:'{0}', expected: '{1}')", actualValue, expectedValue, iRow, iFields); 
     } 
     else 
     { 
     validationMessage = customLogMessageDetail; 
     } 
     // validate if actual value and expected value are equal 
     Ranorex.Validate.AreEqual(actualValue, expectedValue, customLogMessageDetail); 
     
     } 
     iRow++; 
     } 
     if (string.IsNullOrEmpty(customLogMessageOverall)) 
     { 
     customLogMessageOverall = "Successfully validated SQL Table with given SQL-Statement against content of given CSV file"; 
     } 
     // Log success 
     Ranorex.Report.Log(Ranorex.ReportLevel.Success, customLogMessageOverall); 
     
     } 
     finally 
     { 
     command.Dispose(); 
     SQLReader.Dispose(); 
     CSVReader.Dispose(); 
     } 
     } 
    } 
    
    Public Sub Validate_DatabaseTableWithQuery(OLEConnectionString As String, SQLQuery As String, referenceCSVTable As String, csvSeparator As String, customLogMessageOverall As String, customLogMessageDetail As String) 
     
     ' check if reference file exists 
     If Not System.IO.File.Exists(referenceCSVTable) Then 
     Throw New Ranorex.RanorexException(String.Format("File does not exist: {0}", referenceCSVTable)) 
     End If 
     
     ' check if connection string is empty 
     If OLEConnectionString.Trim().Equals(String.Empty) Then 
     Throw New Ranorex.RanorexException("ConnectionString is empty") 
     End If 
     
     ' check if SQL statement is empty 
     If SQLQuery.Trim().Equals(String.Empty) Then 
     Throw New Ranorex.RanorexException("SQLQuery is empty") 
     End If 
     
     ' prepare separator for csv file (if not passed in) 
     Dim separator As Char 
     If String.IsNullOrEmpty(csvSeparator) Then 
     separator = ";"C 
     Else 
     separator = csvSeparator(0) 
     End If 
     
     ' establish database connection 
     Using connection As New System.Data.OleDb.OleDbConnection(OLEConnectionString) 
     connection.Open() 
     
     Dim command As System.Data.OleDb.OleDbCommand = Nothing 
     Dim SQLReader As System.Data.OleDb.OleDbDataReader = Nothing 
     Dim CSVReader As System.IO.StreamReader = Nothing 
     
     Try 
     ' set SQL statement and execute search 
     command = New System.Data.OleDb.OleDbCommand(SQLQuery, connection) 
     SQLReader = command.ExecuteReader() 
     
     ' open csv file (reference file) 
     CSVReader = New System.IO.StreamReader(System.IO.File.OpenRead(referenceCSVTable)) 
     
     ' run through every line in file 
     Dim iRow As Integer = 0 
     While (SQLReader.Read()) AndAlso (Not CSVReader.EndOfStream) 
     
     ' read line from csv file 
     Dim line = CSVReader.ReadLine() 
     
     ' split line into array of values 
     Dim values = line.Split(separator) 
     
     ' check if number of values equals (in current row of csv file and in SQL result) 
     If values.Length <> SQLReader.FieldCount Then 
     Throw New Ranorex.RanorexException(String.Format("Number of fields in SQL query and reference-file does not match ({0} vs. {1})", values.Length + 1, SQLReader.FieldCount)) 
     End If 
     
     
     ' run through every field in SQL result 
     For iFields As Integer = 0 To SQLReader.FieldCount - 1 
     
     Dim expectedValue = values(iFields) 
     Dim actualValue = SQLReader(iFields).ToString() 
     
     ' prepare log message 
     Dim validationMessage As String = String.Empty 
     If String.IsNullOrEmpty(customLogMessageDetail) Then 
     validationMessage = [String].Format("Comparing content of cell ({2}/{3}) (found:'{0}', expected: '{1}')", actualValue, expectedValue, iRow, iFields) 
     Else 
     validationMessage = customLogMessageDetail 
     End If 
     ' validate if actual value and expected value are equal 
     
     Ranorex.Validate.AreEqual(actualValue, expectedValue, customLogMessageDetail) 
     Next 
     iRow += 1 
     End While 
     If String.IsNullOrEmpty(customLogMessageOverall) Then 
     customLogMessageOverall = "Successfully validated SQL Table with given SQL-Statement against content of given CSV file" 
     End If 
     ' Log success 
     
     Ranorex.Report.Log(Ranorex.ReportLevel.Success, customLogMessageOverall) 
     Finally 
     command.Dispose() 
     SQLReader.Dispose() 
     CSVReader.Dispose() 
     End Try 
     End Using 
    End Sub

    Advanced validation – XML code

    This sample shows how XML code can be validated with Ranorex. The method below awaits the XML code snippet as a parameter and an XPath expression in the parameter ‘node’. This XPath expression selects the node to validate. Please provide the expected value as well in the parameter ‘expectedValue’.

    Use case and example: This method might be useful to validate the result of a web service in XML format. Assuming an online library provides a web service allowing to gather detailed information of books when submitting a unique ISBN. The result from the web service is in XML format and contains information like author, title, year of publication and more of the found book. The XML result (see sample XML code further below) can now be validated using the code method with the following call:

    // call method to validate xml code 
    Validate_XMLResponse(xml, "books/book/@title", "Ranorex Test Automation Guide", "Validating result of web service request ({0} vs. {1})");
    ' call method to validate xml code 
    Validate_XMLResponse(xml, "books/book/@title", "Ranorex Test Automation Guide", "Validating result of web service request ({0} vs. {1})")
    Note icon

    Note

    This method can also be called from the recorder’s action table. Therefore the usercode file needs to provide this method (directly or derived from a base class).

    public void Validate_XMLResponse(string xmlContent, string node, string expectedValue, string customLogMessage) 
    { 
     string actualValue = string.Empty; 
     
     // check if xml content is empty 
     if (string.IsNullOrEmpty(xmlContent)) 
     { 
     throw new Ranorex.ValidationException ("Parameter 'xmlContent' is empty"); 
     } 
     
     // check if node (XPath) is empty 
     if (string.IsNullOrEmpty(node)) 
     { 
     throw new Ranorex.ValidationException("Parameter 'node' is empty"); 
     } 
     
     // check if expected value is empty 
     if (string.IsNullOrEmpty(expectedValue)) 
     { 
     throw new Ranorex.ValidationException("Parameter 'expectedValue' is empty"); 
     } 
     
     System.Xml.XmlDocument document = new System.Xml.XmlDocument(); 
     try 
     { 
     // load XML from text in xml file 
     document.LoadXml(xmlContent); 
     
     //select the node with given argument (XPath) 
     System.Xml.XmlNode desiredNode = document.SelectSingleNode(node); 
     
     if (desiredNode != null) 
     { 
     actualValue = desiredNode.InnerText; 
     } 
     else 
     { 
     throw new Ranorex.ValidationException(string.Format("No node found with XPath '{0}'!", node)); 
     } 
     
     } 
     catch (System.Xml.XmlException) 
     { 
     throw new Ranorex.ValidationException("Unable to load valid XML string!"); 
     } 
     
     
     // prepare log file 
     if (string.IsNullOrEmpty(customLogMessage)) 
     { 
     customLogMessage = "Comparing XML response ({0} vs. {1})"; 
     } 
     
     // validate if expected value and actual value are equal 
     Ranorex.Validate.AreEqual(expectedValue, actualValue, customLogMessage); 
    }
    Public Sub Validate_XMLResponse(xmlContent As String, node As String, expectedValue As String, customLogMessage As String) 
     Dim actualValue As String = String.Empty 
     
     ' check if xml content is empty 
     If String.IsNullOrEmpty(xmlContent) Then 
     Throw New Ranorex.ValidationException("Parameter 'xmlContent' is empty") 
     End If 
     
     ' check if node (XPath) is empty 
     If String.IsNullOrEmpty(node) Then 
     Throw New Ranorex.ValidationException("Parameter 'node' is empty") 
     End If 
     
     ' check if expected value is empty 
     If String.IsNullOrEmpty(expectedValue) Then 
     Throw New Ranorex.ValidationException("Parameter 'expectedValue' is empty") 
     End If 
     
     Dim document As New System.Xml.XmlDocument() 
     Try 
     ' load XML from text in xml file 
     document.LoadXml(xmlContent) 
     
     'select the node with given argument (XPath) 
     Dim desiredNode As System.Xml.XmlNode = document.SelectSingleNode(node) 
     
     If desiredNode IsNot Nothing Then 
     actualValue = desiredNode.InnerText 
     Else 
     Throw New Ranorex.ValidationException(String.Format("No node found with XPath '{0}'!", node)) 
     
     End If 
     Catch generatedExceptionName As System.Xml.XmlException 
     Throw New Ranorex.ValidationException("Unable to load valid XML string!") 
     End Try 
     
     
     ' prepare log file 
     If String.IsNullOrEmpty(customLogMessage) Then 
     customLogMessage = "Comparing XML response ({0} vs. {1})" 
     End If 
     
     ' validate if expected value and actual value are equal 
     Ranorex.Validate.AreEqual(expectedValue, actualValue, customLogMessage) 
    End Sub

    Sample XML code

    This sample XML code allows you to implement the sample from above.

    <books> 
     <book title="Ranorex Test Automation Guide" author="Ranorex" year="2014"> 
     </book>