In your tests, you may need to access a portion of optically recognized text to simulate user actions on it.
Usually, you do this by using the OCR.Recognize.BlockByText(Text, SelectionPreference)
method. The method returns a text block specified by its text and (optionally) by its location in the search area (for example, at the bottom or to the right). You can find a detailed description of using the method in Get Text Block by Position.
However, there can be situations where it is not enough to get the needed text block. For example, if the specified search area contains multiple text blocks with the same text, or the position of the needed text block changes from one test run to another. In this case, you can implement your own search algorithm:
-
Use the
OCR.Recognize
method to recognize all the text in the specified area. -
Use the
OCR.Recognize.Block
andOCR.Recognize.BlockCount
properties to iterate through all text blocks. -
Check each block against expected conditions until you find the block you need. For example, you can check whether a block’s text matches a string pattern. You can also check a block’s size and location.
To get a block’s text, use the
TextBlock.Text
property. To get a block’s size and location, use theTextBlock.Bounds
property. -
When you get the block you need, you can simulate user actions on it.
In scripts
The code below contains the GetTextBlockCustom
routine that gets an onscreen object and a regular expression and returns a text block whose text matches the expression. If there is no text block whose text matches the expression, the routine returns null (null
in JavaScript, JScript, C#Script and C++Script, None
in Python, Nothing
in VBScript, nil
in DelphiScript).
The Main
routine shows how to call the GetTextBlockCustom
routine to get the needed text block and simulate user actions on it.
JavaScript, JScript
{
// Recognize the text the specified onscreen object shows
var obj = OCR.Recognize(anObject);
if (obj.FullText != "" && obj.BlockCount > 0)
{
// Iterate through text blocks
// until the one that matches the regular expression is found is found
for (var i = 0; i < obj.BlockCount; i ++)
{
var re = new RegExp(aPattern, "ig");
Matches = obj.Block(i).Text.match(re);
if (Matches != null)
{
// Return the first block that matches the regular expression
return obj.Block(i);
}
}
// If no text block matches the specified regular expression,
// return null
return null;
}
else
return null;
}
function Main()
{
// The search condition (a regular expression)
var searchPattern = "\w*[-]\w*";
// Get an onscreen object
var obj = Sys.WaitProcess("MyApp").WaitWindow("Window", "*", -1, 1000);
// Get the text block that matches the search condition
var b = GetTextBlockCustom(obj, searchPattern);
if (b != null)
{
// Simulate user actions on the text block
b.Click();
…
}
…
}
Python
import re
def GetTextBlockCustom(anObject, aPattern):
# Recognize the text the specified onscreen object shows
obj = OCR.Recognize(anObject)
if (obj.FullText != "" and obj.BlockCount > 0):
# Iterate through text blocks
# until the one that matches the regular expression is found
for i in range (0, obj.BlockCount - 1):
m = re.search(aPattern, obj.Block[i].Text)
if m is not None:
# Return the first block that matches the regular expression
return obj.Block[i]
# If no text block matches the specified regular expression,
# Return None
return None
else:
return None
def Main():
# The search condition (a regular expression)
searchPattern = "\w*-\w*"
# Get an onscreen object
obj = Sys.WaitProcess("MyApp").WaitWindow("Window", "*", -1, 1000)
# Get the text block that matches the search condition
b = GetTextBlockCustom(obj, searchPattern)
if b != None:
# Simulate user actions on the text block
b.Click()
#...
# ...
VBScript
' If no text block matches the specified regular expression,
' return Nothing
Set GetTextBlockCustom = Nothing
' Recognize the text the specified onscreen object shows
Set obj = OCR.Recognize(anObject)
If obj.FullText <> "" And obj.BlockCount > 0 Then
' Iterate through text blocks
' until the one that matches the regular expression is found
For i = 0 To obj.BlockCount - 1
Set regExpr = New RegExp
regExpr.Pattern = aPattern
regExpr.IgnoreCase = True
regExpr.Global = True
If regExpr.Test(obj.Block(i).Text) Then
' Return the first block that matches the regular expression
Set GetTextBlockCustom = obj.Block(i)
Exit For
End If
Next
End If
End Function
Sub Main()
' The search condition (a regular expression)
searchPattern = "\w*-\w*"
' Get an onscreen object
Set obj = Sys.WaitProcess("MyApp").WaitWindow("Window", "*", -1, 1000)
' Get the text block that matches the search condition
Set b = GetTextBlockCustom(obj, searchPattern)
If Not b Is Nothing Then
' Simulate user actions on the text block
b.Click
…
End If
…
End Sub
DelphiScript
var obj, i, regExpr;
begin
// If no text block matches the specified regular expression,
// return nil
result := nil;
// Recognize the text the specified onscreen object shows
obj := OCR.Recognize(anObject);
if ((obj.FullText <> '') and (obj.BlockCount > 0)) then
begin
// Iterate through text blocks
// until the one that matches the regular expression is found
for i := 0 to obj.BlockCount - 1 do
begin
regExpr := HISUtils.RegExpr;
regExpr.Expression := aPattern;
regExpr.InputString : = obj.Block[i].Text;
if regExpr.ExecPos then
begin
// Return the first block that matches the regular expression
result := obj.Block[i];
break;
end;
end;
end;
end;
procedure Main();
var searchPattern, obj, b;
begin
// The search condition (a regular expression)
searchPattern := '\w*-\w*';
// Get an onscreen object
obj := Sys.WaitProcess('MyApp').WaitWindow('Window', '*', -1, 1000);
// Get the text block that matches the search condition
b := GetTextBlockCustom(obj, searchPattern);
if b <> nil then
begin
// Simulate user actions on the text block
b.Click();
…
end;
…
end;
C++Script, C#Script
{
// Recognize the text the specified onscreen object shows
var obj = OCR["Recognize"](anObject);
if (obj["FullText"] != "" && obj["BlockCount"] > 0)
{
// Iterate through text blocks
// until the one that matches the regular expression is found
for (var i = 0; i < obj["BlockCount"]; i ++)
{
var re = new RegExp(aPattern, "ig");
Matches = obj["Block"](i)["Text"]["match"](re);
if (Matches != null)
{
// Return the first block that matches the regular expression
return obj["Block"](i);
}
}
// If no text block matches the specified regular expression,
// return null
return null;
}
else
return null;
}
function Main()
{
// The search condition (a regular expression)
var searchPattern = "\w*[-]\w*";
// Get an onscreen object
var obj = Sys["WaitProcess"]("MyApp")["WaitWindow"]("Window", "*", -1, 1000);
// Get the text block that matches the search condition
var b = GetTextBlockCustom(obj, searchPattern);
if (b != null)
{
// Simulate user actions on the text block
b["Click"]();
…
}
…
}
In keyword tests
Option 1
To iterate through text blocks, you can use the For Loop or While Loop operation. To check the block properties, you can use the If Then operation:
Option 2
-
Copy the
GetTextBlockCustom
function code from the example above to a script unit in your project in TestComplete. -
Call the function from your keyword test by using the Run Code Snippet or Run Script Routine operation.
-
Save the text block the function returns to a variable.
To learn how to get the results of a routine called from a keyword test, see Checking Operation Result. To learn how to set a variable value in a keyword test, see Keyword Test Variables.
-
Simulate the needed user actions on the returned text block in a way you find suitable. For example, by using the Run Code Snippet operation.
Option 3
-
Copy the
Main
routine from the example above to a script unit in your project in TestComplete. -
Modify the routine to work with your tested objects and to use the search conditions you need.
-
Call the routine from your keyword test by using the Run Code Snippet or the Run Script Routine operation.
See Also
About Optical Character Recognition
Regular Expressions Syntax
Checking Operation Result
Checking Conditions
Organizing Loops
Get Controls With No Text Contents