As a unit testing addict, I’ve recently started to use the wonderful SWTBot framwork, for testing the interface part of Eclipse plugins and applications.

When it came to test the text of the StatusLine (e.g., after selecting something on a tree, the status line should show the string for the selected element), I found some problems, not strictly related to SWTBot, but to the fact that the IStatusLineManager interface has a method for setting the text, but none for getting the current text.

I found a post which was suggesting a “Nasty” way to access the current text, by relying of the internal implementation of the StatusLineManager; relying on an internal implementation is actually a bad thing, especially because in new versions such implementation is likely to change, and your code will stop working. However, in a unit test, I guess it is admissible… afterall, if the internal implementation changes, your test will break, and tests are (also) there for that reason 😉

So here’s how I managed to test the current status line text

protected void assertStatusLine(final String expectedStatusLineText) {
    Display.getDefault().syncExec(new Runnable() {
        public void run() {
            IWorkbenchPartSite site = PlatformUI.getWorkbench()
                    .getActiveWorkbenchWindow().getActivePage()
                    .getActivePart().getSite();

            if (site instanceof IViewSite) {
                assertStatusLine(expectedStatusLineText,
                        ((IViewSite) site).getActionBars());
            } else if (site instanceof IEditorSite) {
                assertStatusLine(expectedStatusLineText,
                        ((IEditorSite) site).getActionBars());
            } else {
                fail("unknown site: " + site);
            }
        }

        protected void assertStatusLine(
                final String expectedStatusLineText, IActionBars actionBars) {
            IStatusLineManager statusLineManager = actionBars
                    .getStatusLineManager();

            // this is a terrible hack to read the current text of the
            // status line manager as suggested here:
            // http://stackoverflow.com/questions/5173838/reading-eclipse-status-line
            SubStatusLineManager subStatusLineManager = (SubStatusLineManager) statusLineManager;
            Control control = ((StatusLineManager) subStatusLineManager
                    .getParent()).getControl();
            Control[] children = ((Composite) control).getChildren();

            for (Control child : children) {
                if (child instanceof CLabel) {
                    assertEquals(expectedStatusLineText,
                            ((CLabel) child).getText());
                    return;
                }
            }

            // if we're here we failed
            fail("could not find the text of the status line");
        }
    });
}

Note, that first, we need to get the IStatusLineManager from the current site (either a view site, or an editor site), and then we do the nasty thing, by getting the internal CLabel which shows the text in the status line and simply retrieve its text.

Hope this helps some tester out there 🙂