In tests, you often need to access an object that matches certain criteria. This topic describes how you can do this.
The Find and TryFind Methods
All test objects have the Find
and TryFind
methods. The methods have the following parameters:
-
The search pattern, which the sought-for test object must match.
-
The maximum level of the object hierarchy the search should reach.
The Find
method returns the sought-for object if the search is successful, and fails if the object is not found. The TryFind
method returns True and the sought-for object if the search is successful, and False and an empty object if the search fails.
The following example demonstrates how to find a button by its caption in the Replace dialog of the Notepad application:
C#
using SmartBear.TestLeft;
using SmartBear.TestLeft.TestObjects;
using SmartBear.TestLeft.TestObjects.Win;
…
[TestMethod]
public void Test()
{
// Run Notepad and get the Notepad process
IProcess notepad = Driver.Applications.Run("notepad");
// Open the Replace dialog
ITopLevelWindow wndNotepad = notepad.Find<ITopLevelWindow>(new WindowPattern()
{
WndClass = "Notepad"
});
wndNotepad.MainMenu.Click("Edit|Replace...");
// Use the Find method to get the needed object
IWinButton btnReplaceAll = notepad.Find<IWinButton>(new WindowPattern()
{
WndClass = "Button",
WndCaption = "Replace &All"
},
3);
// Simulate user actions over the found button
…
// Use the TryFind method to get the needed object
IWinButton btnReplace;
notepad.TryFind<IWinButton>(new WindowPattern()
{
WndClass = "Button",
WndCaption = "&Replace"
},
3, out btnReplace);
// If the object is found
if (btnReplace != null)
{
// Simulate user actions over the found button
…
}
…
}
Visual Basic .NET
Imports SmartBear.TestLeft
Imports SmartBear.TestLeft.TestObjects
Imports SmartBear.TestLeft.TestObjects.Win
…
<TestMethod()>
Public Sub Test()
' Run Notepad and get the Notepad process
Dim notepad As IProcess = Driver.Applications.Run("notepad")
' Open the Replace dialog
Dim wndNotepad As ITopLevelWindow = notepad.Find(Of ITopLevelWindow)(New WindowPattern() With {
.WndClass = "Notepad"
})
wndNotepad.MainMenu.Click("Edit|Replace...")
' Use the Find method to get the needed object
Dim btnReplaceAll As IWinButton = notepad.Find(Of IWinButton)(New WindowPattern() With {
.WndClass = "Button",
.WndCaption = "Replace &All"
}, 3)
' Simulate user actions over the found button
…
' Use the TryFind method to get the needed object
Dim btnReplace As IWinButton
notepad.TryFind(Of IWinButton)(New WindowPattern() With {
.WndClass = "Button",
.WndCaption = "&Replace"
}, 3, btnReplace)
' If the object is found
If btnReplace IsNot Nothing Then
' Simulate user actions over the found button
…
End If
End Sub
Java
import com.smartbear.testleft.*;
import com.smartbear.testleft.testobjects.*;
import com.smartbear.testleft.testobjects.win.*;
import com.smartbear.testleft.testobjects.WinFormsPattern;
…
@Test
public void Test() throws Exception{
// Run Notepad and get the Notepad process
TestProcess notepad = driver.getApplications().run("notepad");
// Open the Replace dialog
TopLevelWindow wndNotepad = notepad.find(TopLevelWindow.class, new WindowPattern() {{
WndClass = "Notepad";
}});
wndNotepad.getMainMenu().click("Edit|Replace...");
// Use the Find method to get the needed object
WinButton btnReplaceAll = notepad.find(WinButton.class, new WindowPattern() {{
WndClass = "Button";
WndCaption = "Replace &All";
}}, 3);
// Simulate user actions over the found button
…
// Use the TryFind method to get the needed object
WinButton btnReplace = (WinButton) notepad.tryFind(WinButton.class, new WindowPattern() {{
WndClass = "Button";
WndCaption = "&Replace";
}}, 3).get();
// If the object is found
if (btnReplace != null)
{
// Simulate user actions over the found button
… }
}
The following example demonstrates how to find a link by its address on the main page of SmartBear Software’s web site:
C#
using SmartBear.TestLeft;
using SmartBear.TestLeft.TestObjects;
using SmartBear.TestLeft.TestObjects.Web;
…
[TestMethod]
public void Test()
{
// Run the web browser and open the SmartBear Software home page
IWebPage page = Driver.Applications.RunBrowser(BrowserType.IExplorer).ToUrl("https://smartbear.com/");
// Use the Find method to get the needed object
IWebElement link = page.Find<IWebElement>(new WebElementPattern()
{
ObjectType = "Link",
href = "*testleft*"
}, 15);
// Simulate user actions over the found link
…
// Use the TryFind method to get the needed object
page.TryFind<IWebElement>(new WebElementPattern()
{
ObjectType = "Link",
href = "*testleft*"
}, 15, out link);
if (link != null)
{
// Simulate user actions over the found link
…
}
}
Visual Basic .NET
Imports SmartBear.TestLeft
Imports SmartBear.TestLeft.TestObjects
Imports SmartBear.TestLeft.TestObjects.Web
…
<TestMethod()>
Public Sub Test()
' Run the web browser and open the SmartBear Software home page
Dim page As IWebPage = Driver.Applications.RunBrowser(BrowserType.IExplorer).ToUrl("https://smartbear.com/")
' Use the Find method to get the needed object
Dim link As IWebElement = page.Find(Of IWebElement)(New WebElementPattern() With {
.ObjectType = "Link",
.href = "*testleft*"
}, 15)
' Simulate user actions over the found link
…
' Use the TryFind method to get the needed object
page.TryFind(Of IWebElement)(New WebElementPattern() With {
.ObjectType = "Link",
.href = "*testleft*"
}, 15, link)
If link IsNot Nothing Then
' Simulate user actions over the found link
…
End If
End Sub
Java
import com.smartbear.testleft.*;
import com.smartbear.testleft.testobjects.*;
import com.smartbear.testleft.testobjects.web.*;
…
@Test
public void Test() throws Exception{
// Run the web browser and open the SmartBear Software home page
WebPage page = driver.getApplications().runBrowser(BrowserType.IExplorer).toUrl("https://smartbear.com/");
// Use the Find method to get the needed object
WebElement link = page.find(WebElement.class, new WebElementPattern() {{
ObjectType = "Link";
href = "*testleft*";
}}, 15);
// Simulate user actions over the found link
…
// Use the TryFind method to get the needed object
link = (WebElement) page.tryFind(WebElement.class, new WebElementPattern() {{
ObjectType = "Link";
href = "*testleft*";
}}, 15).get();
if (link != null)
{
// Simulate user actions over the found link
…
}
}
The FindAll Method
The FindAll method searches for all the tested objects that match certain pattern and returns a sequence of all found objects.
If you use .NET, the returned sequence supports LINQ. You can use LINQ queries to sort test objects in the returned sequence, group them, filter them and so on. To learn more about LINQ and about using it to work with data, see the LINQ article in the MSDN Library.
If you use Java, you can use Lambda expressions to filter the returned sequence, sort items in it, and so on. To learn more about Lambda expressions in Java, see the Java documentation.
The following example demonstrates how to find all the buttons in the Replace dialog of the Notepad application and use LINQ queries and Lambda expressions to select only enabled buttons and sort them by their captions:
C#
using SmartBear.TestLeft;
using SmartBear.TestLeft.TestObjects;
using SmartBear.TestLeft.TestObjects.Win;
…
[TestMethod]
public void Test()
{
// Run Notepad and get the Notepad process
IProcess notepad = Driver.Applications.Run("notepad");
// Open the Replace dialog
ITopLevelWindow wndNotepad = notepad.Find<ITopLevelWindow>(new WindowPattern()
{
WndClass = "Notepad"
});
wndNotepad.MainMenu.Click("Edit|Replace...");
ITopLevelWindow dlgReplace = notepad.Find<ITopLevelWindow>(new WindowPattern()
{
WndClass = "#32770",
WndCaption = "Replace"
});
// Find all the buttons in the Replace dialog
IEnumerable<IButton> buttons = dlgReplace.FindAll<IButton>(new WindowPattern()
{
WndClass = "Button"
});
// Select all visible buttons and sort them by their captions
IEnumerable<IButton> visibleButtons = buttons.Where(b => b.Enabled).OrderBy(b => b.Cast<IWindow>().WndCaption);
foreach (IButton button in visibleButtons)
{
// Simulate user actions over each button
…
}
}
Visual Basic .NET
Imports SmartBear.TestLeft
Imports SmartBear.TestLeft.TestObjects
Imports SmartBear.TestLeft.TestObjects.Win
…
<TestMethod()>
Public Sub Test()
' Run Notepad And get the Notepad process
Dim notepad As IProcess = Driver.Applications.Run("notepad")
' Open the Replace dialog
Dim wndNotepad As ITopLevelWindow = notepad.Find(Of ITopLevelWindow)(New WindowPattern() With {
.WndClass = "Notepad"
})
wndNotepad.MainMenu.Click("Edit|Replace...")
Dim dlgReplace As ITopLevelWindow = notepad.Find(Of ITopLevelWindow)(New WindowPattern() With {
.WndClass = "#32770",
.WndCaption = "Replace"
})
' Find all the buttons in the Replace dialog
Dim buttons As IEnumerable(Of IButton) = dlgReplace.FindAll(Of IButton)(New WindowPattern() With {
.WndClass = "Button"
})
' Select all visible buttons and sort them by their captions
Dim visibleButtons As IEnumerable(Of IButton) = buttons.Where(Function(b) b.Enabled).OrderBy(Function(b) b.Cast(Of IWindow)().WndCaption)
For Each button In visibleButtons
' Simulate user actions over each button
…
Next
End Sub
Java
import com.smartbear.testleft.*;
import com.smartbear.testleft.testobjects.*;
import com.smartbear.testleft.testobjects.Button;
import com.smartbear.testleft.testobjects.Window;
…
@Test
public Test() throws Exception{
// Run Notepad And get the Notepad process
TestProcess notepad = driver.getApplications().run("notepad");
// Open the Replace dialog
TopLevelWindow wndNotepad = notepad.find(TopLevelWindow.class, new WindowPattern() {{
WndClass = "Notepad";
}});
wndNotepad.getMainMenu().click("Edit|Replace...");
TopLevelWindow dlgReplace = notepad.find(TopLevelWindow.class, new WindowPattern() {{
WndClass = "#32770";
WndCaption = "Replace";
}});
// Find all the buttons in the Replace dialog
List<Button> buttons = dlgReplace.findAll(Button.class, new WindowPattern() {{
WndClass = "Button";
}});
// Select all visible buttons and sort them by their captions
List<Button> visibleButtons = buttons.stream().filter(b -> {
try {
return b.getEnabled();
} catch (Exception e) {
return false;
}
}).collect(Collectors.toList());
visibleButtons.sort( (Button b1, Button b2) ->
{
try {
return ((Window) b1.cast(Window.class)).getWndCaption().compareTo( ((Window) b2.cast(Window.class)).getWndCaption() );
} catch (Exception e) {
return -1;
}
}
);
for (Button button : visibleButtons)
{
// Simulate user actions over each button
…
}
}
The following example demonstrates how to find all the links on the main page of SmartBear Software web site, use LINQ and Lambda expressions to select only the links that have “testleft” in their address and sort them by their text:
C#
using SmartBear.TestLeft;
using SmartBear.TestLeft.TestObjects;
using SmartBear.TestLeft.TestObjects.Web;
…
[TestMethod]
public void Test()
{
// Run the web browser and open the SmartBear Software home page
IWebPage page = Driver.Applications.RunBrowser(BrowserType.IExplorer).ToUrl("https://smartbear.com/");
// Find all the links on the web page
IEnumerable<IWebElement> links = page.FindAll<IWebElement>(new WebElementPattern()
{
ObjectType = "Link"
}, 15);
// Select all the links with the "testleft" string in their address and sort the links by their text
links = links.Where(l => l.GetProperty<string>("href").Contains("testleft")).OrderBy(l => l.contentText);
foreach (IWebElement link in links)
{
// Simulate user actions over each link
…
}
}
Visual Basic .NET
Imports SmartBear.TestLeft
Imports SmartBear.TestLeft.TestObjects
Imports SmartBear.TestLeft.TestObjects.Web
…
<TestMethod()>
Public Sub Test()
' Run the web browser and open the SmartBear Software home page
Dim page As IWebPage = Driver.Applications.RunBrowser(BrowserType.IExplorer).ToUrl("https://smartbear.com/")
' Find all the links on the web page
Dim links As IEnumerable(Of IWebElement) = page.FindAll(Of IWebElement)(New WebElementPattern() With {
.ObjectType = "Link"
}, 15)
' Select all the links with the "testleft" string in their address and sort the links by their text
links = links.Where(Function(l) l.GetProperty(Of String)("href").Contains("testleft")).OrderBy(Function(l) l.contentText)
For Each link In links
' Simulate user actions over each link
…
Next
End Sub
Java
import com.smartbear.testleft.*;
import com.smartbear.testleft.testobjects.*;
import com.smartbear.testleft.testobjects.web.*;
…
@Test
public void Test() throws Exception{
// Run the web browser and open the SmartBear Software home page
WebPage page = driver.getApplications().runBrowser(BrowserType.IExplorer).toUrl("https://smartbear.com/");
// Find all the links on the web page
List<WebElement> links = page.findAll(WebElement.class, new WebElementPattern() {{
ObjectType = "Link";
}}, 15);
// Select all the links with the "testleft" string in their address and sort the links by their text
links = links.stream().filter(l -> {
try {
return l.getProperty(String.class, "href").toString().contains("testleft");
} catch (Exception e) {
return false;
}
}).collect(Collectors.toList());
links.sort( (WebElement l1, WebElement l2) -> {
try {
return l1.getContentText().compareTo(l2.getContentText());
} catch (Exception e) {
return -1;
}
});
for (WebElement link : links)
{
// Simulate user actions over each link
…
}
}
Troubleshoot Ambiguous Matches
There could be situations when several objects match the specified search criteria. In this case, by default, the Find
and TryFind
methods return an arbitrary found object. This may cause ambiguous recognition issues when a test will use an "inappropriate" object.
To detect ambiguous recognition issues, you can –
.NET: Set the IDriver.Options.Debug.RuntimeChecks
property to AmbiguousMatches or to All.
Java: Call the driver.getOptions().getDebug().setRuntimeChecks
method with the parameter set to RuntimeChecks.AmbiguousMatches or RuntimeChecks.All.
This will make TestLeft raise an exception when several objects match the criteria.
C#
using SmartBear.TestLeft.Options;
…
public void Test()
{
// Perform additional checks during code execution
Driver.Options.Debug.RuntimeChecks = Options.RuntimeChecks.AmbiguousMatches;
// Obtain objects
…
}
Visual Basic .NET
Imports SmartBear.TestLeft.Options
…
Public Sub Test()
' Perform additional checks during code execution
Driver.Options.Debug.RuntimeChecks = Options.RuntimeChecks.AmbiguousMatches
' Obtain objects
…
End Sub
Java
import com.smartbear.testleft.testobjects.*;
import com.smartbear.testleft.options.RuntimeChecks;
…
public void Test() throws Exception{
// Perform additional checks during code execution
driver.getOptions().getDebug().setRuntimeChecks(RuntimeChecks.AmbiguousMatches);
// Obtain objects
…
}
To fix the found ambiguous matches, you will need to adjust the search pattern so that it returns only the desired object. Most search patterns allow using a combination of properties to define the sought-for object. For example, to choose a particular process object from several similar processes, you can use a combination of ProcessName
and Index
properties. Besides, you can always add any custom property to the search pattern.
See Also
Creating TestLeft Tests
Understanding Object Identification
Verifying Object Properties