11. Debugging the Extension

Applies to TestComplete 14.93, last modified on September 27, 2021

Our custom keyword test operation is now ready. You only need to debug and package the script extension.

To test the extension, we need to change TestComplete settings to specify the extension folder and call the operation from a keyword test. Below are the steps that demonstrate how to do this.

One note before we proceed: the name of our extension coincides with the name of one of the pre-installed extensions. Before installing our extension, you should disable the TestComplete extension:

  1. Select File | Install Script Extensions from the main menu to invoke the Script Extensions dialog.

  2. In the dialog, uncheck the Log Attributes Keyword Test Operation extension.

  3. Press OK to close the dialog and save the changes.

Now we can install our script extension into TestComplete:

  1. Select the Tools | Options from the TestComplete main menu. This will invoke the Options dialog.

  2. In the dialog, select the Engines | Script Extensions node from the tree on the left of the dialog. This will open the Script Extensions Options page. Here you can specify the folders that contain script extensions.

  3. In the dialog, click Add Folder. This will invoke the standard Browse for Folder dialog.

  4. In the dialog, choose the C:\My Extension Files folder and click OK. The folder will be added to the script extensions list:

    Script Extensions Options Dialog
    We would like to note that we specified C:\My Extension Files, rather than C:\My Extension Files\LogAttrExtension. So far our script extension files are not packed in the .tcx package. When specifying the path to the unpacked extensions, you should not specify the folder that contains the description.xml file, but the folder that is one level up. This happens because TestComplete treats each item of the folders list like a folder that may contain several extensions, but not just one extension. So, unpacked files cannot reside in the root of these folders, they must be in subfolders. That is why we specified C:\My Extension Files, but not C:\My Extension Files\LogAttrExtension. If we had the packed extension (the .tcx file) in the LogAttrExtension folder, we would have specified C:\My Extension Files\LogAttrExtension.
  5. Make sure that the check box of the C:\My Extension Files item is selected in the list.

  6. Click OK to save the changes and to close the Options dialog.

After adding our extension’s path to the Script Extension Options dialog and saving the changes, TestComplete scans the folder and automatically installs the extension. To check whether the extension is installed successfully:

  • Open the Script Extensions dialog (select File | Install Script Extension from the main menu). The extension should be listed in the dialog:

    Extension name in the Install Extensions Dialog

In addition, we need to make sure that our operation appears in the keyword test operation's palette. To verify this, we need to create a keyword test and examine the Keyword Test Editor:

  • Right-click the project in the Project Explorer and select Add | New Item from the context menu. The Create New Project Item dialog will open.

  • In the dialog, select Keyword Testing and click OK.

    TestComplete will add an empty KeywordTests collection to the project.

  • Right-click the KeywordTests collection and select Add | New Item from the context menu.

  • In the dialog, specify the name of the test to create and click OK.

TestComplete will add a keyword test to the project and open it in the Keyword Test Editor.

In the Operations panel, open the Logging category and make sure that the Log Attributes operation appears in the list:

Log Attributes operation in the Operations panel

To test whether the Log Attributes operation functions properly, we will add this operation to a keyword test, specify operation settings and run it. Here are the detailed steps and description of the expected results:

  1. Add the Log Attributes to your keyword test and open the operation’s edit form.

    Expected result: TestComplete displays the operation’s edit form.

  2. In the dialog, specify the desired font style and color. For example, choose White from the Font combo box, choose Green from the Background combo box and select the Bold and Underline check boxes.

    Expected result: The appearance of the sample area at the bottom of the dialog changes according to the specified settings.

    Log Attributes operation parameters

    Click OK to save the changes and close the dialog.

  3. Examine the operation data displayed in the Keyword Test editor.

    Expected result:

    • The Item column holds “Log Attributes”.

    • The Operation column is empty.

    • The Value column displays a summary on the specified style. For instance, “Font: White, Bold, Underline; Background: Green; Remarks: Plain text”.

    • The Description column holds “Defines the font and color settings for test log items.”

  4. Select the Description cell and press F2.

    Expected result: TestComplete activates the cell’s in-place editor and selects the cell contents.

  5. Modify the operation description and press Enter to apply the changes and close the in-place editor.

    Expected result: The cell now holds a new description.

  6. Add the Log Message (or Append Log Folder, or Post Screenshot) operation right after the Log Attributes operation.

  7. Open the Operation Parameters dialog for the Log Message (or Append Folder, or Post Screenshot) operation and specify [Last Operation Result] as the Attrib parameter value:

    Log Message operation parameters
  8. (Optional). Repeat steps 1 - 7 to post multiple test log entries with different color settings.

    Your test now looks like the one in the following image:

    A sample test with the Log Attributes and Log Message operations
  9. Run the created test.

    Expected result: the messages in the test log should use the same font style and color as specified by the Log Attributes operation(s) included in the test.

    Test log with a custom-colored message

If anything is wrong, make sure the script code and description.xml file are correct and that the script file has the ANSI or UTF-8 character encoding. Also, please check that you created the operation’s edit form as it was described in the tutorial. Below are the whole contents of the laCode unit and the description.xml file.

laCode.js

// Available color names and RGB values
var ColorNames = ["Black", "Maroon", "Green", "Olive", "Navy", "Purple", "Teal", "Gray",
                   "Silver", "Red", "Lime", "Yellow", "Blue", "Fuchsia","Aqua", "White",
                   "Money Green", "Sky Blue", "Cream", "Medium Gray", "Orange", "Brown"];

var ColorValues = [0x000000, 0x000080, 0x008000, 0x008080, 0x800000, 0x800080, 0x808000, 0x808080,
                   0xC0C0C0, 0x0000FF, 0x00FF00, 0x00FFFF, 0xFF0000, 0xFF00FF, 0xFFFF00, 0xFFFFFF,
                   0xC0DCC0, 0xF0CAA6, 0xF0FBFF, 0xA4A0A0, 0x00A5FF, 0x004B96];


// This routine is executed when a new operation instance is created.
// It initializes the operation's fields.
function LogAttr_OnCreate(Data)
{
  Data.Description = "Defines the font and color settings for test log items.";
  Data.FontColor = GetColorByName("Black");
  Data.BackColor = GetColorByName("White");
  Data.Bold = false;
  Data.Italic = false;
  Data.Underline = false;
  Data.Strikeout = false;
  Data.PlainTextRemarks = true;
}

// This routine is executed when the operation is being edited.
// It displays the Operation Properties dialog.
function LogAttr_OnSetup(Data)
{
  // Customize the Operation Properties dialog
  var frm = UserForms.laEditForm;

  if (frm.cbFontColor.Properties.Items.Count == 0)
    AddColors(frm.cbFontColor);
  if (frm.cbBackColor.Properties.Items.Count == 0)
    AddColors(frm.cbBackColor);

  frm.cbFontColor.Text = GetColorName(Data.FontColor);
  frm.cbBackColor.Text = GetColorName(Data.BackColor);
  frm.chkBold.Checked = Data.Bold;
  frm.chkItalic.Checked = Data.Italic;
  frm.chkUnderline.Checked = Data.Underline;
  frm.chkStrikeout.Checked = Data.Strikeout;
  frm.cbRemarksFormat.ItemIndex = (Data.PlainTextRemarks ? 1 : 0);

  // Display the Operation Properties dialog and check the results
  if (frm.ShowModal() != mrOk)
    return false;    // No changes were made

  // Save the changes
  Data.FontColor = GetColorByName(frm.cbFontColor.Text);
  Data.BackColor = GetColorByName(frm.cbBackColor.Text);
  Data.Bold = frm.chkBold.Checked;
  Data.Italic = frm.chkItalic.Checked;
  Data.Underline = frm.chkUnderline.Checked;
  Data.Strikeout = frm.chkStrikeout.Checked;
  Data.PlainTextRemarks = (frm.cbRemarksFormat.ItemIndex == 1);

  return true;
}

// This routine is executed by the operation during the test run.
// It creates and returns a new LogAttributes object.
function LogAttr_OnExecute(Data)
{
  var attr = Log.CreateNewAttributes();

  attr.FontColor = Data.FontColor;
  attr.BackColor = Data.BackColor;
  attr.Bold = Data.Bold;
  attr.Italic = Data.Italic;
  attr.Underline = Data.Underline;
  attr.StrikeOut = Data.Strikeout;
  attr.ExtendedMessageAsPlainText = Data.PlainTextRemarks;

  return attr;
}

// Returns the text to be displayed in the Description column of the KDTest editor
function LogAttr_GetDescription(Data)
{
  return Data.Description;
}

// Returns the text to be displayed in the Value column of the KDTest editor
function LogAttr_GetValue(Data)
{
  var str = "Font: " + GetColorName(Data.FontColor);
  if (Data.Bold) str += ", Bold";
  if (Data.Italic) str += ", Italic";
  if (Data.Underline) str += ", Underline";
  if (Data.Strikeout) str += ", Strikeout";
  str += "; Background: " + GetColorName(Data.BackColor);
  str += "; Remarks: " + (Data.PlainTextRemarks ? "Plain text" : "HTML");

  return str;
}

// =====================================================================
// Event handlers for the Operation Properties dialog
// =====================================================================

// Sets the form's focused element
function laEditForm_OnShow(Sender)
{
  UserForms.laEditForm.cbFontColor.SetFocus();
}

// Applies the selected font color to the sample area
function laEditForm_cbFontColor_OnEditValueChanged(Sender)
{
  var frm = UserForms.laEditForm;
  frm.lblSample.Style.Font.Color = GetColorByName(frm.cbFontColor.Text);
}

// Applies the selected background color to the sample area
function laEditForm_cbBackColor_OnEditValueChanged(Sender)
{
  var frm = UserForms.laEditForm;
  frm.lblSample.Style.Color = GetColorByName(frm.cbBackColor.Text);
}

// Applies the specified font style to the sample area
function laEditForm_chkFontStyle_OnClick(Sender)
{
  var frm = UserForms.laEditForm;
  var style = 0;

  if (frm.chkBold.Checked) style |= 0x1;
  if (frm.chkItalic.Checked) style |= 0x2;
  if (frm.chkUnderline.Checked) style |= 0x4;
  if (frm.chkStrikeout.Checked) style |= 0x8;

  frm.lblSample.Style.Font.Style = style;
}

// Displays Help for the Log Attributes operation
function laEditForm_btnHelp_OnClick(Sender)
{
  Help.ShowContext("AQAScriptExtensions.chm", 3041);
}

// =====================================================================
// Event handlers for the in-place editor of the Description column
// =====================================================================

var EditValue;

function GetEditValue(Data)
{
  return EditValue;
}

function SetEditValue(Data, Value)
{
  EditValue = Value;
}

function LogAttr_Description_StartEditing(Data)
{
  EditValue = Data.Description;
}

function LogAttr_Description_ApplyChanges(Data)
{
  Data.Description = EditValue;
}

// =====================================================================
// Helper functions
// =====================================================================

// Populates the specified combo box with predefined color names
function AddColors(Combobox)
{
  var Items = Combobox.Properties.Items;
  Items.Clear();
  for (var i in ColorNames)
    Items.Add(ColorNames[i]);
}

// Returns the RGB value by the color name
function GetColorByName(ColorName)
{
  for (var i in ColorNames)
    if (ColorNames[i] == ColorName)
      return ColorValues[i];

  return ColorValues[0];
}

// Returns the color name by the RGB value
function GetColorName(Color)
{
  for (var i in ColorValues)
    if (ColorValues[i] == Color)
      return ColorNames[i];

  return ColorNames[0];
}

description.xml

<?xml version = "1.0" encoding = "UTF-8"?>
<ScriptExtensionGroup>
    <Category Name = "Keyword Test Operations">
        <ScriptExtension Name = "Log Attributes Keyword Test Operation" Author = "SmartBear Software" Version = "1.0 test" HomePage = "smartbear.com">
            <Description>Provides the Log Attributes keyword test operation.</Description>
            <Script Name = "laCode.js">
                <KDTOperation Name = "Log Attributes" Category = "Logging" Icon = "la-icon.bmp">
                    <Data>
                        <!-- General properties -->
                        <Field Name = "Description" />
                        <!-- Log Attributes object properties -->
                        <Field Name = "FontColor" />
                        <Field Name = "BackColor" />
                        <Field Name = "Bold" />
                        <Field Name = "Italic" />
                        <Field Name = "Underline" />
                        <Field Name = "Strikeout" />
                        <Field Name = "PlainTextRemarks" />
                    </Data>
                    <Events>
                        <Event Name = "OnCreate" Routine = "LogAttr_OnCreate"/>
                        <Event Name = "OnExecute" Routine = "LogAttr_OnExecute"/>
                        <Event Name = "OnSetup" Routine = "LogAttr_OnSetup"/>
                    </Events>
                    <Columns>
                        <Column Name = "Item" Value = "Log Attributes"/>
                        <Column Name = "Value" GetValue = "LogAttr_GetValue" />
                        <Column Name = "Description" GetValue = "LogAttr_GetDescription" Editable = "true" EditorType = "Text">
                            <Event Name = "StartEditing" Routine = "LogAttr_Description_StartEditing"/>
                            <Event Name = "GetEditValue" Routine = "GetEditValue"/>
                            <Event Name = "SetEditValue" Routine = "SetEditValue"/>
                            <Event Name = "ApplyChanges" Routine = "LogAttr_Description_ApplyChanges"/>
                        </Column>
                    </Columns>
                </KDTOperation>
            </Script>
        </ScriptExtension>
    </Category>
</ScriptExtensionGroup>

Prev     Next

See Also

Script Extensions
Debugging Script Extensions

Highlight search results