When you need a red CI for exactly the purpose: a11y dialog coverage in Collabora Online

What happened

A patch enabled a new dialog page for JSDialog rendering: “jsdialog: enable missing Conditions tab in styles dialog”. In Collabora Online, dialogs described by GTK .ui files are rendered as interactive HTML in the browser rather than drawn server-side. Enabling the Condition tab of the paragraph style dialog (conditionpage.ui) means that tab now renders as a real HTML sub-dialog for the user.

Shortly after, the CI turned red in the Writer accessibility dialog tests due to the following cryptic message:

“after all” hook for “Settings dialog”:

AssertionError: used .ui files: .empty was passed non-string primitive undefined

And that was the message, because the dialog that started shipping in Collabora Online was not being opened by any of the tests, thus there was no a11y coverage of it in the application.

Why that test exists

The accessibility dialog tests were introduced by Caolán McNamara. There are two parts in them:

1. Core part: With the tracking enabled, the document engine logs every .ui file that gets instantiated by the app (getUsedUIList), and maintains lists of every .ui file that can be rendered as a JSDialog in that app (for example SwriterDialogList in vcl/jsdialog/enabled.cxx)

2. Test part: Cypress opens all dialogs from the list, does the A11yValidator checks on every dialog (unlabeled controls, non-native buttons, images without alternative text etc.), and queries core to give it the set of .ui files that were never used in the run. Then it asserts that the set is empty (CompleteWriterDialogCoverage, CompleteCommonDialogCoverage).

That is the tripwire. As soon as a new dialog is enabled in core without being added to the test opening the dialog, the set is no longer empty and the CI fails

Why the red was a good sign

Tripwire worked perfectly fine and triggered twice over

1. It detected that the new dialog was not tested and not covered with a11y

2. When we added the test opening that Conditions tab, the A11yValidator reported a problem that combobox in it lacked a label

Without tripwire the tab would have gone out into the world unlabeled and untested. Red CI is cheaper than the regression in the release.

How it was fixed

Two commits:

1. 2fdff461 added a label with use-underline and mnemonic-widget attributes to the “Style Group” combobox of the conditionpage.ui

2. 57d4c5a8 made the Coverage test open one of the conditional paragraphs (“Body Text”) to exercise and validate conditionpage.ui

If you enable a new .ui file, here is how to keep CI green

1. Red CI is expected, as adding a .ui to a dialog list in vcl/jsdialog/enabled.cxx enables it to be rendered by JSDialog and adds to the set of dialogs that have to be opened. CI will fail until a test opens it. This is the intended behavior, not a surprise

2. Understand how the dialog is opened in the product: with which UNO command, which parent dialog and tab it is nested under, what the preconditions are. Some pages may only show up in certain conditions (Conditions page of the Paragraph style dialog only appears for conditional paragraph)

3. Add it to the appropriate coverage list:

– Writer dialogs: allWriterDialogs in desktop/writer1/a11y_dialog_spec.js

– Common dialogs: allCommonDialogs in common/a11y_helper.js

– Calc and Impress have their own equivalent lists

– For a page nested under a tab, there is nothing special to do, just open the parent dialog in the appropriate state to get the tab open

– See a11y_helper handleDialog for the sub-dialogs that opened via button

4. Test it locally: make -C cypress_test check-desktop spec=writer1/a11y_dialog_spec.js

5. If the A11y validator throws exception, that is an a11y gap in the .ui. Fix the .ui, do not ignore it

6. Make sure A11y cypress passes locally and CI goes green.

Leave a Reply