Checking Menu Item's State in Desktop Windows Applications

Applies to TestComplete 15.47, last modified on January 20, 2023

While testing menu controls, you can use specific properties and methods of the corresponding program object to perform certain actions and obtain data stored in controls. You can call these methods and properties from your keyword tests, as well as from scripts. This topic describes how to work with the needed properties and methods from your scripts. However, when testing a control from your keyword test, you can use the same methods and properties calling them from keyword test operations. For more information, see Keyword Tests Basic Operations.

Working with menu controls, you often need to check the menu items’ state. For instance, you may need to check whether an item is enabled before selecting it. To check the state of a particular menu item, use various properties of the MenuItem object that corresponds to this item. The following sections explain how to perform some common checks. Note that you can write the verification code manually, or take advantage of property checkpoints.

Verifying that the Item is Checked or Unchecked

Some menu items represent options that can be checked or unchecked which enables or disables a specific application feature. An example is Notepad’s Format | Word Wrap option. Quite often, applications provide several possibilities to toggle such options. For instance, the menu item can be duplicated on the toolbar. So, in your tests you may need to check that the menu item state corresponds to the actual application state.

To verify that a specific menu item is checked or unchecked, use the Checked property of the MenuItem object that corresponds to this item.. Below is a code snippet that checks Notepad’s Format | Word Wrap option state (Notepad must be running):

JavaScript, JScript

function Test ()
{
  var w = Sys.Process("notepad").Window("Notepad", "*");

  if (w.MainMenu.Items(2).SubMenu.Items(0).Checked)
    Log.Message ("The \"Format | Word Wrap\" option is checked.")
  else
    Log.Message ("The \"Format | Word Wrap\" option is unchecked.")
}

Python

def Test():
  w = Sys.Process("notepad").Window("Notepad", "*")

  if w.MainMenu.Items[2].SubMenu.Items[0].Checked:
    Log.Message ("The \"Format | Word Wrap\" option is checked.")
  else:
    Log.Message ("The \"Format | Word Wrap\" option is unchecked.")

VBScript

Sub Test
  Dim w
  Set w = Sys.Process("notepad").Window("Notepad", "*")

  If w.MainMenu.Items(2).SubMenu.Items(0).Checked Then
    Call Log.Message ("The ""Format | Word Wrap"" option is checked.")
  Else
    Call Log.Message ("The ""Format | Word Wrap"" option is unchecked.")
  End If
End Sub

DelphiScript

procedure Test;
var w : OleVariant;
begin
  w := Sys.Process('notepad').Window('Notepad', '*');

  if w.MainMenu.Items[2].SubMenu.Items[0].Checked then
    Log.Message ('The "Format | Word Wrap" option is checked.')
  else
    Log.Message ('The "Format | Word Wrap" option is unchecked.');
end;

C++Script, C#Script

function Test ()
{
  var w = Sys["Process"]("notepad")["Window"]("Notepad", "*");

  if (w["MainMenu"]["Items"](2)["SubMenu"]["Items"](0)["Checked"])
    Log["Message"]("The \"Format | Word Wrap\" option is checked.")
  else
    Log["Message"]("The \"Format | Word Wrap\" option is unchecked.")
}

Checking if the Item is Enabled or Disabled

Menu items can be enabled or disabled, depending on the application’s state. For example, if no text is selected in the window or control, the Cut, Copy and Delete commands are disabled. Since it is only possible to perform actions over enabled items, if you try to simulate an action over a disabled item TestComplete will post an error message in the test log. You can avoid these errors if you first check the item’s state and only simulate an action if the item is enabled.

To check whether a menu item is enabled or disabled, use the MenuItem.Enabled property. You can find an example of this property in the Example section.

Checking if the Item is a Separator

Menus can contain special separator items that are used to separate (or group) menu items according to their purpose. Separators are menu items as well, though it is impossible to perform any actions over them. If you try to simulate an action over a separator item from a test, TestComplete will post and error message to the log. To avoid these errors, you can add script instructions that will check if a menu item is a separator and if so, skip it from processing.

You can determine whether a menu item is a separator by using the MenuItem.IsSeparator property. It returns True for separator items and False for ordinary menu items. Note, that separators are always disabled (that is, they are disabled items), so their Enabled property is False.

For an example of the MenuItem.IsSeparator property usage, see the sample script in the following section.

Example

Below is an example that types text into Notepad and then “clicks” items of Notepad’s context menu one by one starting from the end of the menu. In order for the script to execute successfully, Notepad must be running.

Before clicking an item, the script checks whether the item is a separator and whether it is enabled. This check is needed, since a click on a disabled item or a separator is impossible and if performed, TestComplete posts an error message to the log.

JavaScript, JScript

function Main()
{
  var p, w, i, Cnt, MenuItem;

  // Obtain the Notepad window
  p = Sys.Process("notepad");
  w = p.Window("Notepad", "*");
  w.Activate();

  // Type text in Notepad
  w.Keys("Simple text[Enter]Simple text[Enter]Simple text![Home]");

  // Call the context menu and obtain the number of items in it
  w.Window("Edit").ClickR();
  Cnt = w.PopupMenu.Count;
  Sys.Keys("[Esc]"); // Hide the context menu

  // Go through the context menu items
  for (i = Cnt - 1; i >= 0; i--)
  {
    // Call the context menu
    w.Window("Edit").ClickR();

    // Obtain the current menu item
    MenuItem = w.PopupMenu.Items(i);
    // Check whether the item is a separator
    if (! MenuItem.IsSeparator)
    {
      // Check whether the item is enabled
      if (MenuItem.Enabled)
      {
        // Click the item
        Log.Message("The item #" + i + " (" + MenuItem.Caption + ") was selected.");
        w.PopupMenu.Click("[" + i + "]");
      }
      else
      {
        // If an item is disabled, log a message about this
        Log.Message("The item #" + i + " (" + MenuItem.Caption + ") is disabled.");
        // Hide the context menu
        Sys.Keys("[Esc]");
      }
    }
    else
    {
      // If an item is a separator, log a message about this
      Log.Message("The item #" + i + " is a separator.");
      // Hide the context menu
      Sys.Keys("[Esc]");
    }
  }
}

Python

def Main():

  # Obtain the Notepad window
  p = Sys.Process("notepad")
  w = p.Window("Notepad", "*")
  w.Activate()

  # Type text in Notepad
  w.Keys("Simple text[Enter]Simple text[Enter]Simple text![Home]")

  # Call the context menu and obtain the number of items in it
  w.Window("Edit").ClickR()
  Cnt = w.PopupMenu.Count
  Sys.Keys("[Esc]") # Hide the context menu

  # Go through the context menu items
  for i in range(0, Cnt-1):
    # Call the context menu
    w.Window("Edit").ClickR()

    # Obtain the current menu item
    MenuItem = w.PopupMenu.Items[i]
    # Check whether the item is a separator
    if not MenuItem.IsSeparator:
      
      # Check whether the item is enabled
      if MenuItem.Enabled:
        
        # Click the item
        Log.Message("The item #" + str(i) + " (" + MenuItem.Caption + ") was selected.")
        w.PopupMenu.Click("[" + str(i) + "]")
      else:
        
        # If an item is disabled, log a message about this
        Log.Message("The item #" + str(i) + " (" + MenuItem.Caption + ") is disabled.")
        # Hide the context menu
        Sys.Keys("[Esc]")
    else:
      # If an item is a separator, log a message about this
      Log.Message("The item #" + str(i) + " is a separator.")
      # Hide the context menu
      Sys.Keys("[Esc]")

VBScript

Sub Main
  Dim p, w, i, Cnt, MenuItem

  ' Obtain the Notepad process and window
  Set p = Sys.Process("notepad")
  Set w = p.Window("Notepad", "*")
  w.Activate

  ' Type text in Notepad
  w.Keys("Simple text[Enter]Simple text[Enter]Simple text![Home]")

  ' Call the context menu and obtain the number of items in it
  w.Window("Edit").ClickR
  Cnt = w.PopupMenu.Count
  Sys.Keys("[Esc]") ' Hide the context menu

  ' Go through the context menu items
  For i = Cnt - 1 To 0 Step - 1
    ' Call the context menu
    w.Window("Edit").ClickR

    ' Obtain the current menu item
    Set MenuItem = w.PopupMenu.Items(i)
    ' Check whether the item is a separator
    If Not MenuItem.IsSeparator Then
      ' Check whether the item is enabled
      If MenuItem.Enabled Then
        ' Click the item
        Log.Message("The item #" & i & " (" & MenuItem.Caption & ") was selected.")
        w.PopupMenu.Click("[" & i & "]")
      Else
        ' If an item is disabled, log a message about this
        Log.Message("The item #" & i & " (" & MenuItem.Caption & ") is disabled.")
        ' Hide the context menu
        Sys.Keys("[Esc]")
      End If
    Else
      ' If an item is a separator, log a message about this
      Log.Message("The item #" & i & " is a separator.")
      ' Hide the context menu
      Sys.Keys("[Esc]")
    End if
  Next 
End Sub

DelphiScript

procedure Main;
var
  p, w, i, Cnt, MenuItem : OleVariant;
begin
  // Obtain the Notepad process and window
  p := Sys.Process('notepad');
  w := p.Window('Notepad', '*');
  w.Activate;

  // Type text in Notepad
  w.Keys('Simple text[Enter]Simple text[Enter]Simple text![Home]');

  // Call the context menu and obtain the number of items in it
  w.Window('Edit').ClickR;
  Cnt := w.PopupMenu.Count;
  Sys.Keys('[Esc]'); // Hide the context menu

  // Go through the context menu items
  for i := Cnt - 1 downto 0 do
  begin
    // Calls the context menu
    w.Window('Edit').ClickR;

    // Obtain the current menu item
    MenuItem := w.PopupMenu.Items[i];
    // Check whether the item is a separator
    if not MenuItem.IsSeparator then 
    begin
      // Check whether the item is enabled
      if MenuItem.Enabled then 
      begin
        // Click the item
        Log.Message('The item #' + aqConvert.VarToStr(i) + ' (' + MenuItem.Caption + ') was selected.');
        w.PopupMenu.Click('[' + aqConvert.VarToStr(i) + ']');
      end
      else
      begin
        // If an item is disabled, log a message about this
        Log.Message('The item #' + aqConvert.VarToStr(i) + ' (' + MenuItem.Caption + ') is disabled.');
        // Hide the context menu
        Sys.Keys('[Esc]');
      end
    end
    else
    begin
      // If an item is a separator, log a message about this
      Log.Message('The item #' + aqConvert.VarToStr(i) + ' is a separator.');
      // Hide the context menu
      Sys.Keys('[Esc]');
    end;
  end;
end;

C++Script, C#Script

function Main()
{
  var p, w, i, Cnt, MenuItem;

  // Obtain the Notepad window
  p = Sys["Process"]("notepad");
  w = p["Window"]("Notepad", "*");
  w["Activate"]();

  // Type text in Notepad
  w["Keys"]("Simple text[Enter]Simple text[Enter]Simple text![Home]");

  // Call the context menu and obtain the number of items in it
  w["Window"]("Edit")["ClickR"]();
  Cnt = w["PopupMenu"]["Count"];
  Sys["Keys"]("[Esc]"); // Hide the context menu

  // Go through the context menu items
  for (i = Cnt - 1; i >= 0; i--)
  {
    // Call the context menu
    w["Window"]("Edit")["ClickR"]();

    // Obtain the current menu item
    MenuItem = w["PopupMenu"]["Items"](i);
    // Check whether the item is a separator
    if (! MenuItem["IsSeparator"])
    {
      // Check whether the item is enabled
      if (MenuItem["Enabled"])
      {
        // Click the item
        Log["Message"]("The item #" + i + " (" + MenuItem["Caption"] + ") was selected.");
        w["PopupMenu"]["Click"]("[" + i + "]");
      }
      else
      {
        // If an item is disabled, log a message about this
        Log["Message"]("The item #" + i + " (" + MenuItem["Caption"] + ") is disabled.");
        // Hide the context menu
        Sys["Keys"]("[Esc]");
      }
    }
    else
    {
      // If an item is a separator, log a message about this
      Log["Message"]("The item #" + i + " is a separator.");
      // Hide the context menu
      Sys["Keys"]("[Esc]");
    }
  }
}

See Also

Working With Menus in Desktop Windows Applications
MenuItem Object
Addressing Menu Items in Desktop Windows Applications
Selecting Menu Items in Desktop Windows Applications

Highlight search results