Skip to content

fix no speech when role="math" on a non-math element#17327

Merged
seanbudd merged 5 commits into
nvaccess:masterfrom
NSoiffer:role-math
Nov 14, 2024
Merged

fix no speech when role="math" on a non-math element#17327
seanbudd merged 5 commits into
nvaccess:masterfrom
NSoiffer:role-math

Conversation

@NSoiffer

@NSoiffer NSoiffer commented Oct 27, 2024

Copy link
Copy Markdown
Contributor

Link to issue number:

This fixes #15058.

Summary of the issue:

When someone has something like

            <span role="math">
                <math>
                    <msqrt>
                        <mn>4</mn>
                    </msqrt>
                </math>
            </span>

The math is not spoken (nothing is spoken).

This construct happens in real life math (see #15058 for more details).

Description of user facing changes

Web content such as the above will now be spoken as if the span (or other elements) are not present. This is what should have always happened.

Description of development approach

The fix (which is a bit of a hueristic) is to look inside the span (or other element with role="math" and see if exactly one of the children is math. If so, then we recursively call the code to get the MathML for it.

If there isn't exactly one math element, we fall through and raise a LookupError (which is what happened before adding this check).

Testing strategy:

Known issues with pull request:

It only deals with one scenario where role="math" occurs. If there are multiple math children or if the math is not MathML, nothing is done. Potentially there are better things that might be done (such as speaking the leaf content) rather than being silent.

Code Review Checklist:

  • Documentation:
    • Change log entry
    • User Documentation
    • Developer / Technical Documentation
    • Context sensitive help for GUI changes
  • Testing:
    • Unit tests
    • System (end to end) tests
    • Manual testing
  • UX of all users considered:
    • Speech
    • Braille
    • Low Vision
    • Different web browsers
    • Localization in other languages / culture than English
  • API is compatible with existing add-ons.
  • Security precautions taken.

@coderabbitai summary

The fix (which is a bit of a hueristic) is to look inside the `span` (or other element with `role="math"` and see if exactly one of the children is `math`. If so, then we recursively call the code to get the MathML for it.

If there isn't exactly one math element, we fall through and raise a LookupError (which is what happened before adding this check).
@NSoiffer

Copy link
Copy Markdown
Contributor Author

Any suggestions for how to write a unit or system test for this?

It seems like I should be able to provide some HTML, call some function, and then make sure the MathML is returned from this call. I looked at the existing tests and nothing struck me as similar, although I could have easily overlooked a similar test. There is tests/system/robot/chromeTests.py, but I think they all depend on speech and since MathML is not currently packaged with NVDA (hopefully that will change in the next month or so), I can't do a test that relies on speech generation.

If testing this is not currently an option, then this will be ready for review.

@AppVeyorBot

Copy link
Copy Markdown
  • PASS: Translation comments check.
  • PASS: License check.
  • PASS: Unit tests.
  • PASS: Lint check.
  • FAIL: System tests (tags: installer NVDA). See test results for more information.
  • Build (for testing PR): https://ci.appveyor.com/api/buildjobs/4swpw4lbjogsmiq2/artifacts/output/l10nUtil.exe nvda_snapshot_pr17327-34422,9e2ac7cc.exe
  • CI timing (mins):
    INIT 0.0,
    INSTALL_START 1.3,
    INSTALL_END 0.8,
    BUILD_START 0.0,
    BUILD_END 22.1,
    TESTSETUP_START 0.0,
    TESTSETUP_END 0.3,
    TEST_START 0.0,
    TEST_END 18.2,
    FINISH_END 0.2

See test results for failed build of commit 9e2ac7ccde

@XLTechie

XLTechie commented Oct 27, 2024 via email

Copy link
Copy Markdown
Collaborator

@NSoiffer NSoiffer marked this pull request as ready for review October 27, 2024 18:27
@NSoiffer NSoiffer requested a review from a team as a code owner October 27, 2024 18:27
@NSoiffer NSoiffer requested a review from seanbudd October 27, 2024 18:27
@NSoiffer

Copy link
Copy Markdown
Contributor Author

@coderabbitai: as per @XLTechie, any suggestions for a test?

@coderabbitai

coderabbitai Bot commented Oct 27, 2024

Copy link
Copy Markdown
Contributor

Tip

For best results, initiate chat on the files or code changes.

@NSoiffer: I'd be happy to suggest a unit test for this fix.

Since the issue involves elements with role="math" wrapping a <math> element, we can write a unit test to ensure that the MathML is correctly retrieved and processed. Here's an example of how you might write such a test:

import unittest
from some_module import getMathMlFromNode
from some_parser import parseHtmlToNode

class TestMathRoleSpan(unittest.TestCase):
    def test_math_role_span_with_single_math_child(self):
        # HTML content with role="math" wrapping a <math> element
        html_content = '''
            <span role="math">
                <math>
                    <msqrt>
                        <mn>4</mn>
                    </msqrt>
                </math>
            </span>
        '''
        # Parse the HTML content into a node
        node = parseHtmlToNode(html_content)
        # Call the function that retrieves MathML from the node
        mathml = getMathMlFromNode(node)
        # Expected MathML output
        expected_mathml = '''
            <math>
                <msqrt>
                    <mn>4</mn>
                </msqrt>
            </math>
        '''
        # Assert that the retrieved MathML matches the expected output
        self.assertEqual(mathml.strip(), expected_mathml.strip())

if __name__ == '__main__':
    unittest.main()

In this test:

  • html_content simulates the HTML snippet where a <span> with role="math" wraps a <math> element.
  • parseHtmlToNode is a hypothetical function that parses the HTML string into a node object usable by your processing functions. You might already have a similar function in your test utilities.
  • getMathMlFromNode is the function you've modified to handle this case. Replace some_module with the actual module name where this function is defined.
  • The test checks that the MathML extracted from the node matches the expected MathML.

If your codebase uses different parsing or testing utilities, you can adjust the above code accordingly. Additionally, if there's an existing test class for MathML processing, you can add this test method to that class.

I hope this helps!

@seanbudd seanbudd added the conceptApproved Similar 'triaged' for issues, PR accepted in theory, implementation needs review. label Oct 28, 2024

@seanbudd seanbudd left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @NSoiffer

Comment thread source/NVDAObjects/IAccessible/ia2Web.py Outdated
Comment thread user_docs/en/changes.md Outdated
@seanbudd

seanbudd commented Nov 4, 2024

Copy link
Copy Markdown
Member

For testing, you will probably have to create a chrome test in the system test framework

@seanbudd

seanbudd commented Nov 4, 2024

Copy link
Copy Markdown
Member

However since we don't have mathML support bundled in NVDA yet, I don't think this can be tested

@AppVeyorBot

Copy link
Copy Markdown
  • PASS: Translation comments check.
  • PASS: License check.
  • PASS: Unit tests.
  • FAIL: Lint check. See test results and lint artifacts for more information.
  • PASS: System tests (tags: installer NVDA).
  • Build (for testing PR): https://ci.appveyor.com/api/buildjobs/rfdx0n7r50uysb00/artifacts/output/l10nUtil.exe nvda_snapshot_pr17327-34579,d298d88a.exe
  • CI timing (mins):
    INIT 0.0,
    INSTALL_START 1.5,
    INSTALL_END 1.0,
    BUILD_START 0.0,
    BUILD_END 27.5,
    TESTSETUP_START 0.0,
    TESTSETUP_END 0.4,
    TEST_START 0.0,
    TEST_END 18.9,
    FINISH_END 0.2

See test results for failed build of commit d298d88a12

Comment thread source/NVDAObjects/IAccessible/ia2Web.py Outdated
@seanbudd seanbudd merged commit 32245d4 into nvaccess:master Nov 14, 2024
@github-actions github-actions Bot added this to the 2025.1 milestone Nov 14, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

conceptApproved Similar 'triaged' for issues, PR accepted in theory, implementation needs review.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

When role="math" is present, MathCAT isn't called

4 participants