One of the first pieces of feedback we got on MozMill was that there didn’t seem to be any way to click on system menus.
System menus are defined in XUL using a special set of elements. Those are then displayed differently on every operating system and as such we can’t use tools like the MozMill Inspector to get repeatable elements to click on.
After digging in to this problem a bit I figured out that the elements defining menus can be traversed and that they even respond properly to .click(). I then wrote thin API around the elements so that they can be easily looked up by name the way they are displayed in the menus. You can see the full documentation here.
var mozmill = {}; Components.utils.import('resource://mozmill/modules/mozmill.js', mozmill); var elementslib = {}; Components.utils.import('resource://mozmill/modules/elementslib.js', elementslib); var setupModule = function (module) { module.controller = mozmill.getBrowserController(); } var testMenu = function () { // Example 1: Click menus without testing the click controller.menus.File["New Tab"].click(); controller.menus.View.Sidebar.Bookmarks.click(); controller.menus.View["Page Style"]["No Style"].click(); // Example 2: Click menus and test the click controller.click(new elementslib.Elem(controller.menus.File["New Tab"])); controller.click(new elementslib.Elem(controller.menus.View.Sidebar.Bookmarks)); controller.click(new elementslib.Elem(controller.menus.View["Page Style"]["No Style"])); }
As you can see the API is a simple chain of objects by name cascading down the different sub menus until a menu element is reached. Attribute access is just plain old JavaScript so you only need to use ["name"] syntax when looking up menus with names that contain spaces. The API is most definitely case sensitive.










This sounds completely useless. What happens in a localized Firefox?
The menu is created by looking up elements by name, so in a localized Firefox the names should be localized.
I’d welcome APIs to either refer to menu items by position or by id, for the same reasons that Sebastian mentioned.
I have a testing extension that opens all menu items one by one, and being able to do that in a cross platform manner would be cool. But I’d need to have it in a way that’s independent of the localization used.
Same would go for testing localized extensions, something I’m thinking about as well.
This menu API is intended for functional test developers to have an easy way to simulate menu usage in their tests. Doing them by name is the simplest API for that use case.
If the localization testers want a different API then we can write one specifically for that use case, but having the default API for functional test developers be by position or id requires them to know more about the menu definition internals than any of our functional testers know.
Not having an abstraction API like this one for your specific needs doesn’t block you from testing the menu’s the way you would like, you’ll just need to pull out the elements on your own. You can look at the menu API code to get you on your feet;
http://code.google.com/p/mozmill/source/browse/trunk/mozmill/extension/resource/modules/controller.js#115
http://code.google.com/p/mozmill/source/browse/trunk/mozmill/extension/resource/modules/controller.js#141