Search code examples
c#user-interfacerevit-apirevit

How to simulate a click on a pushbutton?


I have a PushButton in a revit API ribbon and would like to simulate a press on it in order to do some tests (I need a ExternalCommandData object from the currently active document). However I cannot seem to find anything like a PushButton.Click() function.

var panel = Application.CreateRibbonPanel("a", "b")
var buttonData = new PushButtonData(name, name, ApplicationInfo.AddInPath, "TestZone.Commands." + "DefaultCommand");
var button = panel.AddItem(buttonData) as PushButton;

With Application being of course the default UIControlledApplication on the OnStartup function. Anyway to know simulate a button click so that I can obtain an ExternalCommandData object of the currently opened document (In the final version there will be checks to ensure that a document is already open ext.) Or is there another way to obtain an externalCommandData?

Note that this question may require you to know the revit API, I doubt that just knowledge of c# will be enough to answer this.


Solution

  • I had many of the same issues with unit testing Revit - and the other users are right, there is no way to get an ExternalCommandData object without running a command. Fortunately, there's a framework that makes a lot of this possible by automating the startup and running of Revit externally. https://github.com/DynamoDS/RevitTestFramework

    The Dynamo group built this framework to automate their tests, and it offers a lot of great functionality.

    Most pertinently for you, it actually exposes a valid ExternalCommandData object

    Here is some example code from their framework.

    /// <summary>
    /// Using the TestModel parameter, you can specify a Revit model
    /// to be opened prior to executing the test. The model path specified
    /// in this attribute is relative to the working directory.
    /// </summary>
    [Test]
    [TestModel(@"./bricks.rfa")]
    public void ModelHasTheCorrectNumberOfBricks()
    {
        var doc = RevitTestExecutive.CommandData.Application.ActiveUIDocument.Document;
    
        var fec = new FilteredElementCollector(doc);
        fec.OfClass(typeof(FamilyInstance));
    
        var bricks = fec.ToElements()
            .Cast<FamilyInstance>()
            .Where(fi => fi.Symbol.Family.Name == "brick");
    
        Assert.AreEqual(bricks.Count(), 4);
    }
    

    RevitTestExecutive.CommandData offers the ExternalCommandData you are looking for.

    Note that there's an issue with installing the RTF as an admin on your machine. I recommend installing it to a local directory as a local user so you don't run into Windows UAC issues.