--- name: thunderbird-frontend-testing-guidelines description: >- Use when writing, reviewing, or modifying Thunderbird frontend tests, especially browser mochitests, UI fixtures, chrome/content interaction, EventUtils usage, async waits, assertions, manifests, or cleanup. --- # Thunderbird Frontend Testing Guidelines ## Overview Use these conventions for Thunderbird frontend tests. Prefer nearby, recently updated Thunderbird tests as examples before copying older patterns; the tree contains both current and out-of-date styles. ## Running tests If working from the 'comm' directory, to run tests, execute: ``` $ ../mach test --headless [file paths...] ``` Do NOT include the 'comm' directory in the path in this instance. Also, note that on some systems, some tests don't execute properly in headless mode. For example, dragging on Linux will fail if run headlessly. If a test is continously failing, try running without the 'headless' flag, to see if it still fails. Confirm with the user before taking this approach. ## Test Verification When writing a new test, prove the test can fail before treating it as useful: - Break the code, fixture, or assertion in a targeted way and confirm the new test fails for the expected reason. - Restore the code and confirm the test passes again. - If you did not do this earlier, do it before finishing the test work. After the test passes normally and is in a good state, periodically run the same test with `--verify` to check for intermittent failures, race conditions, and jankiness. `--verify` can take a long time, so use it after the focused test run is already green, and confirm with the user before running. ## Local Pattern Check Before writing or reviewing a frontend test: - Inspect tests in the same directory or component first. - Prefer newer files and recently modified patterns over older examples. - Keep the test style consistent with the target directory unless this skill explicitly says to avoid an older pattern. - Add new tests to the relevant manifest and preserve existing manifest defaults. ## Reference Documentation Use the Firefox Source Docs browser chrome documentation to understand available test helpers, command flags, and recommended mochitest structure. Thunderbird tests can differ in local conventions, so use these docs as API and framework reference, then apply Thunderbird-specific guidance from this skill and nearby tests. - Browser chrome mochitests: https://firefox-source-docs.mozilla.org/testing/browser-chrome/index.html - Writing new browser mochitests: https://firefox-source-docs.mozilla.org/testing/browser-chrome/writing.html - BrowserTestUtils: https://firefox-source-docs.mozilla.org/testing/browser-chrome/ - Assert: https://firefox-source-docs.mozilla.org/testing/assert.html - TestUtils: https://firefox-source-docs.mozilla.org/testing/testutils.html - SimpleTest: https://firefox-source-docs.mozilla.org/testing/simpletest.html - EventUtils: https://firefox-source-docs.mozilla.org/testing/eventutils.html - Test Verification: https://firefox-source-docs.mozilla.org/testing/test-verification/index.html ## Browser Test Shape Browser tests usually use `browser_*.js`, `add_setup` for shared setup, and `add_task(async function test_nameCamelCase() {})` for test cases. Tests that open UI in a tab should close it in cleanup. Common tab fixture shape: ```js "use strict"; const tabmail = document.getElementById("tabmail"); let browser; let view; add_setup(async function () { const tab = tabmail.openTab("contentTab", { url: "chrome://mochitests/content/browser/comm/path/to/files/fixture.xhtml", }); await BrowserTestUtils.browserLoaded(tab.browser); tab.browser.focus(); browser = tab.browser; view = browser.contentWindow.document.querySelector("custom-element-name"); registerCleanupFunction(() => { tabmail.closeOtherTabs(tabmail.tabInfo[0]); }); }); ``` Guidelines: - Put `"use strict";` at the top of every test file, immediately after the license header and before declarations. - Use `add_setup` for shared fixture, service, or window setup. - Use named `add_task` functions. - Store stable fixture-wide references in module-level variables. - Re-query elements after rerendering, insertion, navigation, or DOM replacement. - Close opened tabs, windows, popups, dialogs, and panels in fail-safe cleanup. ## Test Naming Use names that describe the tested behavior or state transition. Use the standard `test_` prefix with lower camel case after the underscore. Apply this rule when adding or renaming tests, even if nearby older tests use snake case. Guidelines: - Use named `add_task` functions: `add_task(async function test_captureState() {})`. - Flag new or renamed snake-case test names. Do not preserve them only to match older local tests. - Name method-contract tests after the public API being exercised: `test_setState`, `test_captureState`, `test_setErrorState`. - Add the tested condition after the base behavior: `test_captureStateWithUsername`. - Use `With...` for enabled conditions or additional state: `test_captureStateWithRememberPasswordPref`. - Use `No...` for disabled or absent condition variants: `test_switchBetweenIMAPAndEWSNoPref`. - Use `ByPref` for behavior controlled by a preference: `test_graphIsEnabledByPref`. - Use `switchBetweenXAndY` for bidirectional UI transition scenarios: `test_switchBetweenIMAPAndGraph`. - Use outcome-focused names for DOM wiring, localization, and accessibility checks: `test_correctlyAppliesL10nAttributes`, `test_idsCorrectlyAppliedToElements`. - Do not repeat the component or filename context in every test name when the file already provides that scope. - Avoid `smoke` unless the test is intentionally broad contract coverage. Example renames: | Avoid | Prefer | | ------------------------------------------ | ------------------------------------- | | `test_tb_banner_loads_fixture` | `test_loadsFixture` | | `test_tb_banner_smoke_default_and_variant` | `test_defaultVariantAndUpdateVariant` | | `test_tb_banner_smoke_expand_and_collapse` | `test_expandAndCollapse` | ## Fixtures Frontend fixtures should be focused but production-like: - Use `` and the XHTML namespace for XHTML fixtures. - Include the CSS and Fluent localization links needed by the UI under test. - Import custom element modules with `