Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix defect in calling code when building the ElementRoleMap #555

Merged
merged 2 commits into from
Jul 8, 2024

Conversation

samccone
Copy link
Contributor

@samccone samccone commented Jul 4, 2024

As discovered in #554

Address the defect introduced f7f6120#r143856081

This now exercises all of the code:
Screenshot 2024-07-04 at 12 19 06 PM

Yet now multiple tests are failing in a fixture file used for testing that has been updated since this defect was introduced. I am not sure what the correct state of these fixtures should be

Copy link

codesandbox-ci bot commented Jul 4, 2024

This pull request is automatically built and testable in CodeSandbox.

To see build info of the built libraries, click here or the icon next to each commit SHA.

@samccone
Copy link
Contributor Author

samccone commented Jul 4, 2024

@jlp-craigmorten I think you might be in the best spot to provide some guidance on what to do with the fixture failures - as I am not sure how to audit what is correct or not.

@jlp-craigmorten
Copy link
Contributor

jlp-craigmorten commented Jul 5, 2024

Hey @samccone 👋

Sure will pull your branch and take a look to see if can make sense of it.

Be interesting to understand what the impact of this is, the pertinent PR #447 was merged back in 2022 with no issues raised for it since. Makes you wonder if could consider it YAGNI and just remove 🤔 but depends what value this could potentially bring, or if consumers of this package have been unknowingly incorrect for 2 years and would benefit from this being reinstated.

@samccone
Copy link
Contributor Author

samccone commented Jul 5, 2024

I agree @jlp-craigmorten - to test this I went back and fixed the original code change at f7f6120#r143856081

with

diff --git a/src/elementRoleMap.js b/src/elementRoleMap.js
index 35a2233..bbff1b6 100644
--- a/src/elementRoleMap.js
+++ b/src/elementRoleMap.js
@@ -24,7 +24,7 @@ for (let i = 0; i < keys.length; i++) {
       if (relation.module === 'HTML') {
         const concept = relation.concept;
         if (concept) {
-          const elementRoleRelation: ?ElementARIARoleRelationTuple = elementRoles.find(relation => deepEqual(relation, concept));
+          const elementRoleRelation: ?ElementARIARoleRelationTuple = elementRoles.find(relation => deepEqual(relation[0], concept));
           let roles: RoleSet;
           
           if (elementRoleRelation) {

Running the tests with this patch at that state of the tree resulted in failures. 😢

``` Test Suites: 1 failed, 6 passed, 7 total Tests: 48 failed, 5086 passed, 5134 total Snapshots: 0 total Time: 3.446 s ```

I am thinking this may have been broken since this original change - and or the fixture test files were not snapped to the correct state. Wondering if you have any ideas.


Browserslist: caniuse-lite is outdated. Please run:
  npx update-browserslist-db@latest
  Why you should do it regularly: https://github.com/browserslist/update-db#readme
Browserslist: caniuse-lite is outdated. Please run:
  npx update-browserslist-db@latest
  Why you should do it regularly: https://github.com/browserslist/update-db#readme
Browserslist: caniuse-lite is outdated. Please run:
  npx update-browserslist-db@latest
  Why you should do it regularly: https://github.com/browserslist/update-db#readme
Browserslist: caniuse-lite is outdated. Please run:
  npx update-browserslist-db@latest
  Why you should do it regularly: https://github.com/browserslist/update-db#readme
Browserslist: caniuse-lite is outdated. Please run:
  npx update-browserslist-db@latest
  Why you should do it regularly: https://github.com/browserslist/update-db#readme
Browserslist: caniuse-lite is outdated. Please run:
  npx update-browserslist-db@latest
  Why you should do it regularly: https://github.com/browserslist/update-db#readme
 PASS  __tests__/src/util/iteratorProxy-test.js
Browserslist: caniuse-lite is outdated. Please run:
  npx update-browserslist-db@latest
  Why you should do it regularly: https://github.com/browserslist/update-db#readme
Browserslist: caniuse-lite is outdated. Please run:
  npx update-browserslist-db@latest
  Why you should do it regularly: https://github.com/browserslist/update-db#readme
 PASS  __tests__/src/util/iterationDecorator-test.js
 PASS  __tests__/src/ariaPropsMaps-test.js
 PASS  __tests__/src/roleElementMap-test.js
 PASS  __tests__/src/domMap-test.js
 PASS  __tests__/src/rolesMap-test.js
 FAIL  __tests__/src/elementRoleMap-test.js
  ● elementRoleMap API › entries() › Testing element: {
  attributes: [ { name: 'aria-label' }, [length]: 1 ],
  name: 'section'
}

    expect(received).toEqual(expected) // deep equality

    Expected: ArrayContaining [[{"attributes": [{"name": "aria-label"}], "name": "section"}, ["section", "region"]]]
    Received: [[{"name": "article"}, ["article"]], [{"constraints": ["scoped to the body element"], "name": "header"}, ["banner"]], [{"name": "blockquote"}, ["blockquote"]], [{"attributes": [{"name": "type", "value": "button"}], "name": "input"}, ["button"]], [{"attributes": [{"name": "type", "value": "image"}], "name": "input"}, ["button"]], [{"attributes": [{"name": "type", "value": "reset"}], "name": "input"}, ["button"]], [{"attributes": [{"name": "type", "value": "submit"}], "name": "input"}, ["button"]], [{"name": "button"}, ["button"]], [{"name": "caption"}, ["caption"]], [{"constraints": ["ancestor table element has table role"], "name": "td"}, ["cell"]], …]

      125 |   describe('entries()', function () {
      126 |     test.each(elementRoleMap.entries())('Testing element: %o', (obj, roles) => {
    > 127 |       expect(entriesList).toEqual(
          |                           ^
      128 |         expect.arrayContaining([[obj, roles]]),
      129 |       );
      130 |     });

      at toEqual (__tests__/src/elementRoleMap-test.js:127:27)

  ● elementRoleMap API › entries() › Testing element: {
  attributes: [ { name: 'aria-labelledby' }, [length]: 1 ],
  name: 'section'
}

    expect(received).toEqual(expected) // deep equality

    Expected: ArrayContaining [[{"attributes": [{"name": "aria-labelledby"}], "name": "section"}, ["section", "region"]]]
    Received: [[{"name": "article"}, ["article"]], [{"constraints": ["scoped to the body element"], "name": "header"}, ["banner"]], [{"name": "blockquote"}, ["blockquote"]], [{"attributes": [{"name": "type", "value": "button"}], "name": "input"}, ["button"]], [{"attributes": [{"name": "type", "value": "image"}], "name": "input"}, ["button"]], [{"attributes": [{"name": "type", "value": "reset"}], "name": "input"}, ["button"]], [{"attributes": [{"name": "type", "value": "submit"}], "name": "input"}, ["button"]], [{"name": "button"}, ["button"]], [{"name": "caption"}, ["caption"]], [{"constraints": ["ancestor table element has table role"], "name": "td"}, ["cell"]], …]

      125 |   describe('entries()', function () {
      126 |     test.each(elementRoleMap.entries())('Testing element: %o', (obj, roles) => {
    > 127 |       expect(entriesList).toEqual(
          |                           ^
      128 |         expect.arrayContaining([[obj, roles]]),
      129 |       );
      130 |     });

      at toEqual (__tests__/src/elementRoleMap-test.js:127:27)

  ● elementRoleMap API › entries() › Testing element: { name: 'aside' }

    expect(received).toEqual(expected) // deep equality

    Expected: ArrayContaining [[{"name": "aside"}, ["complementary", "generic"]]]
    Received: [[{"name": "article"}, ["article"]], [{"constraints": ["scoped to the body element"], "name": "header"}, ["banner"]], [{"name": "blockquote"}, ["blockquote"]], [{"attributes": [{"name": "type", "value": "button"}], "name": "input"}, ["button"]], [{"attributes": [{"name": "type", "value": "image"}], "name": "input"}, ["button"]], [{"attributes": [{"name": "type", "value": "reset"}], "name": "input"}, ["button"]], [{"attributes": [{"name": "type", "value": "submit"}], "name": "input"}, ["button"]], [{"name": "button"}, ["button"]], [{"name": "caption"}, ["caption"]], [{"constraints": ["ancestor table element has table role"], "name": "td"}, ["cell"]], …]

      125 |   describe('entries()', function () {
      126 |     test.each(elementRoleMap.entries())('Testing element: %o', (obj, roles) => {
    > 127 |       expect(entriesList).toEqual(
          |                           ^
      128 |         expect.arrayContaining([[obj, roles]]),
      129 |       );
      130 |     });

      at toEqual (__tests__/src/elementRoleMap-test.js:127:27)

  ● elementRoleMap API › entries() › Testing element: { name: 'aside' }

    expect(received).toEqual(expected) // deep equality

    Expected: ArrayContaining [[{"name": "aside"}, ["complementary", "generic"]]]
    Received: [[{"name": "article"}, ["article"]], [{"constraints": ["scoped to the body element"], "name": "header"}, ["banner"]], [{"name": "blockquote"}, ["blockquote"]], [{"attributes": [{"name": "type", "value": "button"}], "name": "input"}, ["button"]], [{"attributes": [{"name": "type", "value": "image"}], "name": "input"}, ["button"]], [{"attributes": [{"name": "type", "value": "reset"}], "name": "input"}, ["button"]], [{"attributes": [{"name": "type", "value": "submit"}], "name": "input"}, ["button"]], [{"name": "button"}, ["button"]], [{"name": "caption"}, ["caption"]], [{"constraints": ["ancestor table element has table role"], "name": "td"}, ["cell"]], …]

      125 |   describe('entries()', function () {
      126 |     test.each(elementRoleMap.entries())('Testing element: %o', (obj, roles) => {
    > 127 |       expect(entriesList).toEqual(
          |                           ^
      128 |         expect.arrayContaining([[obj, roles]]),
      129 |       );
      130 |     });

      at toEqual (__tests__/src/elementRoleMap-test.js:127:27)

  ● elementRoleMap API › entries() › Testing element: {
  attributes: [ { name: 'aria-label' }, [length]: 1 ],
  name: 'section'
}

    expect(received).toEqual(expected) // deep equality

    Expected: ArrayContaining [[{"attributes": [{"name": "aria-label"}], "name": "section"}, ["section", "region"]]]
    Received: [[{"name": "article"}, ["article"]], [{"constraints": ["scoped to the body element"], "name": "header"}, ["banner"]], [{"name": "blockquote"}, ["blockquote"]], [{"attributes": [{"name": "type", "value": "button"}], "name": "input"}, ["button"]], [{"attributes": [{"name": "type", "value": "image"}], "name": "input"}, ["button"]], [{"attributes": [{"name": "type", "value": "reset"}], "name": "input"}, ["button"]], [{"attributes": [{"name": "type", "value": "submit"}], "name": "input"}, ["button"]], [{"name": "button"}, ["button"]], [{"name": "caption"}, ["caption"]], [{"constraints": ["ancestor table element has table role"], "name": "td"}, ["cell"]], …]

      125 |   describe('entries()', function () {
      126 |     test.each(elementRoleMap.entries())('Testing element: %o', (obj, roles) => {
    > 127 |       expect(entriesList).toEqual(
          |                           ^
      128 |         expect.arrayContaining([[obj, roles]]),
      129 |       );
      130 |     });

      at toEqual (__tests__/src/elementRoleMap-test.js:127:27)

  ● elementRoleMap API › entries() › Testing element: {
  attributes: [ { name: 'aria-labelledby' }, [length]: 1 ],
  name: 'section'
}

    expect(received).toEqual(expected) // deep equality

    Expected: ArrayContaining [[{"attributes": [{"name": "aria-labelledby"}], "name": "section"}, ["section", "region"]]]
    Received: [[{"name": "article"}, ["article"]], [{"constraints": ["scoped to the body element"], "name": "header"}, ["banner"]], [{"name": "blockquote"}, ["blockquote"]], [{"attributes": [{"name": "type", "value": "button"}], "name": "input"}, ["button"]], [{"attributes": [{"name": "type", "value": "image"}], "name": "input"}, ["button"]], [{"attributes": [{"name": "type", "value": "reset"}], "name": "input"}, ["button"]], [{"attributes": [{"name": "type", "value": "submit"}], "name": "input"}, ["button"]], [{"name": "button"}, ["button"]], [{"name": "caption"}, ["caption"]], [{"constraints": ["ancestor table element has table role"], "name": "td"}, ["cell"]], …]

      125 |   describe('entries()', function () {
      126 |     test.each(elementRoleMap.entries())('Testing element: %o', (obj, roles) => {
    > 127 |       expect(entriesList).toEqual(
          |                           ^
      128 |         expect.arrayContaining([[obj, roles]]),
      129 |       );
      130 |     });

      at toEqual (__tests__/src/elementRoleMap-test.js:127:27)

  ● elementRoleMap API › entries() › Testing element: {
  attributes: [ { name: 'aria-label' }, [length]: 1 ],
  name: 'section'
}

    expect(received).toEqual(expected) // deep equality

    Expected: ArrayContaining [[{"attributes": [{"name": "aria-label"}], "name": "section"}, ["section", "region"]]]
    Received: [[{"name": "article"}, ["article"]], [{"constraints": ["scoped to the body element"], "name": "header"}, ["banner"]], [{"name": "blockquote"}, ["blockquote"]], [{"attributes": [{"name": "type", "value": "button"}], "name": "input"}, ["button"]], [{"attributes": [{"name": "type", "value": "image"}], "name": "input"}, ["button"]], [{"attributes": [{"name": "type", "value": "reset"}], "name": "input"}, ["button"]], [{"attributes": [{"name": "type", "value": "submit"}], "name": "input"}, ["button"]], [{"name": "button"}, ["button"]], [{"name": "caption"}, ["caption"]], [{"constraints": ["ancestor table element has table role"], "name": "td"}, ["cell"]], …]

      130 |     });
      131 |     test.each([...elementRoleMap.entries()])('Testing element: %o', (obj, roles) => {
    > 132 |       expect(entriesList).toEqual(
          |                           ^
      133 |         expect.arrayContaining([[obj, roles]]),
      134 |       );
      135 |     });

      at toEqual (__tests__/src/elementRoleMap-test.js:132:27)

  ● elementRoleMap API › entries() › Testing element: {
  attributes: [ { name: 'aria-labelledby' }, [length]: 1 ],
  name: 'section'
}

    expect(received).toEqual(expected) // deep equality

    Expected: ArrayContaining [[{"attributes": [{"name": "aria-labelledby"}], "name": "section"}, ["section", "region"]]]
    Received: [[{"name": "article"}, ["article"]], [{"constraints": ["scoped to the body element"], "name": "header"}, ["banner"]], [{"name": "blockquote"}, ["blockquote"]], [{"attributes": [{"name": "type", "value": "button"}], "name": "input"}, ["button"]], [{"attributes": [{"name": "type", "value": "image"}], "name": "input"}, ["button"]], [{"attributes": [{"name": "type", "value": "reset"}], "name": "input"}, ["button"]], [{"attributes": [{"name": "type", "value": "submit"}], "name": "input"}, ["button"]], [{"name": "button"}, ["button"]], [{"name": "caption"}, ["caption"]], [{"constraints": ["ancestor table element has table role"], "name": "td"}, ["cell"]], …]

      130 |     });
      131 |     test.each([...elementRoleMap.entries()])('Testing element: %o', (obj, roles) => {
    > 132 |       expect(entriesList).toEqual(
          |                           ^
      133 |         expect.arrayContaining([[obj, roles]]),
      134 |       );
      135 |     });

      at toEqual (__tests__/src/elementRoleMap-test.js:132:27)

  ● elementRoleMap API › entries() › Testing element: { name: 'aside' }

    expect(received).toEqual(expected) // deep equality

    Expected: ArrayContaining [[{"name": "aside"}, ["complementary", "generic"]]]
    Received: [[{"name": "article"}, ["article"]], [{"constraints": ["scoped to the body element"], "name": "header"}, ["banner"]], [{"name": "blockquote"}, ["blockquote"]], [{"attributes": [{"name": "type", "value": "button"}], "name": "input"}, ["button"]], [{"attributes": [{"name": "type", "value": "image"}], "name": "input"}, ["button"]], [{"attributes": [{"name": "type", "value": "reset"}], "name": "input"}, ["button"]], [{"attributes": [{"name": "type", "value": "submit"}], "name": "input"}, ["button"]], [{"name": "button"}, ["button"]], [{"name": "caption"}, ["caption"]], [{"constraints": ["ancestor table element has table role"], "name": "td"}, ["cell"]], …]

      130 |     });
      131 |     test.each([...elementRoleMap.entries()])('Testing element: %o', (obj, roles) => {
    > 132 |       expect(entriesList).toEqual(
          |                           ^
      133 |         expect.arrayContaining([[obj, roles]]),
      134 |       );
      135 |     });

      at toEqual (__tests__/src/elementRoleMap-test.js:132:27)

  ● elementRoleMap API › entries() › Testing element: { name: 'aside' }

    expect(received).toEqual(expected) // deep equality

    Expected: ArrayContaining [[{"name": "aside"}, ["complementary", "generic"]]]
    Received: [[{"name": "article"}, ["article"]], [{"constraints": ["scoped to the body element"], "name": "header"}, ["banner"]], [{"name": "blockquote"}, ["blockquote"]], [{"attributes": [{"name": "type", "value": "button"}], "name": "input"}, ["button"]], [{"attributes": [{"name": "type", "value": "image"}], "name": "input"}, ["button"]], [{"attributes": [{"name": "type", "value": "reset"}], "name": "input"}, ["button"]], [{"attributes": [{"name": "type", "value": "submit"}], "name": "input"}, ["button"]], [{"name": "button"}, ["button"]], [{"name": "caption"}, ["caption"]], [{"constraints": ["ancestor table element has table role"], "name": "td"}, ["cell"]], …]

      130 |     });
      131 |     test.each([...elementRoleMap.entries()])('Testing element: %o', (obj, roles) => {
    > 132 |       expect(entriesList).toEqual(
          |                           ^
      133 |         expect.arrayContaining([[obj, roles]]),
      134 |       );
      135 |     });

      at toEqual (__tests__/src/elementRoleMap-test.js:132:27)

  ● elementRoleMap API › entries() › Testing element: {
  attributes: [ { name: 'aria-label' }, [length]: 1 ],
  name: 'section'
}

    expect(received).toEqual(expected) // deep equality

    Expected: ArrayContaining [[{"attributes": [{"name": "aria-label"}], "name": "section"}, ["section", "region"]]]
    Received: [[{"name": "article"}, ["article"]], [{"constraints": ["scoped to the body element"], "name": "header"}, ["banner"]], [{"name": "blockquote"}, ["blockquote"]], [{"attributes": [{"name": "type", "value": "button"}], "name": "input"}, ["button"]], [{"attributes": [{"name": "type", "value": "image"}], "name": "input"}, ["button"]], [{"attributes": [{"name": "type", "value": "reset"}], "name": "input"}, ["button"]], [{"attributes": [{"name": "type", "value": "submit"}], "name": "input"}, ["button"]], [{"name": "button"}, ["button"]], [{"name": "caption"}, ["caption"]], [{"constraints": ["ancestor table element has table role"], "name": "td"}, ["cell"]], …]

      130 |     });
      131 |     test.each([...elementRoleMap.entries()])('Testing element: %o', (obj, roles) => {
    > 132 |       expect(entriesList).toEqual(
          |                           ^
      133 |         expect.arrayContaining([[obj, roles]]),
      134 |       );
      135 |     });

      at toEqual (__tests__/src/elementRoleMap-test.js:132:27)

  ● elementRoleMap API › entries() › Testing element: {
  attributes: [ { name: 'aria-labelledby' }, [length]: 1 ],
  name: 'section'
}

    expect(received).toEqual(expected) // deep equality

    Expected: ArrayContaining [[{"attributes": [{"name": "aria-labelledby"}], "name": "section"}, ["section", "region"]]]
    Received: [[{"name": "article"}, ["article"]], [{"constraints": ["scoped to the body element"], "name": "header"}, ["banner"]], [{"name": "blockquote"}, ["blockquote"]], [{"attributes": [{"name": "type", "value": "button"}], "name": "input"}, ["button"]], [{"attributes": [{"name": "type", "value": "image"}], "name": "input"}, ["button"]], [{"attributes": [{"name": "type", "value": "reset"}], "name": "input"}, ["button"]], [{"attributes": [{"name": "type", "value": "submit"}], "name": "input"}, ["button"]], [{"name": "button"}, ["button"]], [{"name": "caption"}, ["caption"]], [{"constraints": ["ancestor table element has table role"], "name": "td"}, ["cell"]], …]

      130 |     });
      131 |     test.each([...elementRoleMap.entries()])('Testing element: %o', (obj, roles) => {
    > 132 |       expect(entriesList).toEqual(
          |                           ^
      133 |         expect.arrayContaining([[obj, roles]]),
      134 |       );
      135 |     });

      at toEqual (__tests__/src/elementRoleMap-test.js:132:27)

  ● elementRoleMap API › forEach() › Testing element: {
  attributes: [ { name: 'aria-label' }, [length]: 1 ],
  name: 'section'
}

    expect(received).toEqual(expected) // deep equality

    Expected: ArrayContaining [[{"attributes": [{"name": "aria-label"}], "name": "section"}, ["section", "region"]]]
    Received: [[{"name": "article"}, ["article"]], [{"constraints": ["scoped to the body element"], "name": "header"}, ["banner"]], [{"name": "blockquote"}, ["blockquote"]], [{"attributes": [{"name": "type", "value": "button"}], "name": "input"}, ["button"]], [{"attributes": [{"name": "type", "value": "image"}], "name": "input"}, ["button"]], [{"attributes": [{"name": "type", "value": "reset"}], "name": "input"}, ["button"]], [{"attributes": [{"name": "type", "value": "submit"}], "name": "input"}, ["button"]], [{"name": "button"}, ["button"]], [{"name": "caption"}, ["caption"]], [{"constraints": ["ancestor table element has table role"], "name": "td"}, ["cell"]], …]

      145 |     });
      146 |     test.each(output)('Testing element: %o', (obj, roles) => {
    > 147 |       expect(entriesList).toEqual(
          |                           ^
      148 |         expect.arrayContaining([[obj, roles]]),
      149 |       );
      150 |     });

      at toEqual (__tests__/src/elementRoleMap-test.js:147:27)

  ● elementRoleMap API › forEach() › Testing element: {
  attributes: [ { name: 'aria-labelledby' }, [length]: 1 ],
  name: 'section'
}

    expect(received).toEqual(expected) // deep equality

    Expected: ArrayContaining [[{"attributes": [{"name": "aria-labelledby"}], "name": "section"}, ["section", "region"]]]
    Received: [[{"name": "article"}, ["article"]], [{"constraints": ["scoped to the body element"], "name": "header"}, ["banner"]], [{"name": "blockquote"}, ["blockquote"]], [{"attributes": [{"name": "type", "value": "button"}], "name": "input"}, ["button"]], [{"attributes": [{"name": "type", "value": "image"}], "name": "input"}, ["button"]], [{"attributes": [{"name": "type", "value": "reset"}], "name": "input"}, ["button"]], [{"attributes": [{"name": "type", "value": "submit"}], "name": "input"}, ["button"]], [{"name": "button"}, ["button"]], [{"name": "caption"}, ["caption"]], [{"constraints": ["ancestor table element has table role"], "name": "td"}, ["cell"]], …]

      145 |     });
      146 |     test.each(output)('Testing element: %o', (obj, roles) => {
    > 147 |       expect(entriesList).toEqual(
          |                           ^
      148 |         expect.arrayContaining([[obj, roles]]),
      149 |       );
      150 |     });

      at toEqual (__tests__/src/elementRoleMap-test.js:147:27)

  ● elementRoleMap API › forEach() › Testing element: { name: 'aside' }

    expect(received).toEqual(expected) // deep equality

    Expected: ArrayContaining [[{"name": "aside"}, ["complementary", "generic"]]]
    Received: [[{"name": "article"}, ["article"]], [{"constraints": ["scoped to the body element"], "name": "header"}, ["banner"]], [{"name": "blockquote"}, ["blockquote"]], [{"attributes": [{"name": "type", "value": "button"}], "name": "input"}, ["button"]], [{"attributes": [{"name": "type", "value": "image"}], "name": "input"}, ["button"]], [{"attributes": [{"name": "type", "value": "reset"}], "name": "input"}, ["button"]], [{"attributes": [{"name": "type", "value": "submit"}], "name": "input"}, ["button"]], [{"name": "button"}, ["button"]], [{"name": "caption"}, ["caption"]], [{"constraints": ["ancestor table element has table role"], "name": "td"}, ["cell"]], …]

      145 |     });
      146 |     test.each(output)('Testing element: %o', (obj, roles) => {
    > 147 |       expect(entriesList).toEqual(
          |                           ^
      148 |         expect.arrayContaining([[obj, roles]]),
      149 |       );
      150 |     });

      at toEqual (__tests__/src/elementRoleMap-test.js:147:27)

  ● elementRoleMap API › forEach() › Testing element: { name: 'aside' }

    expect(received).toEqual(expected) // deep equality

    Expected: ArrayContaining [[{"name": "aside"}, ["complementary", "generic"]]]
    Received: [[{"name": "article"}, ["article"]], [{"constraints": ["scoped to the body element"], "name": "header"}, ["banner"]], [{"name": "blockquote"}, ["blockquote"]], [{"attributes": [{"name": "type", "value": "button"}], "name": "input"}, ["button"]], [{"attributes": [{"name": "type", "value": "image"}], "name": "input"}, ["button"]], [{"attributes": [{"name": "type", "value": "reset"}], "name": "input"}, ["button"]], [{"attributes": [{"name": "type", "value": "submit"}], "name": "input"}, ["button"]], [{"name": "button"}, ["button"]], [{"name": "caption"}, ["caption"]], [{"constraints": ["ancestor table element has table role"], "name": "td"}, ["cell"]], …]

      145 |     });
      146 |     test.each(output)('Testing element: %o', (obj, roles) => {
    > 147 |       expect(entriesList).toEqual(
          |                           ^
      148 |         expect.arrayContaining([[obj, roles]]),
      149 |       );
      150 |     });

      at toEqual (__tests__/src/elementRoleMap-test.js:147:27)

  ● elementRoleMap API › forEach() › Testing element: {
  attributes: [ { name: 'aria-label' }, [length]: 1 ],
  name: 'section'
}

    expect(received).toEqual(expected) // deep equality

    Expected: ArrayContaining [[{"attributes": [{"name": "aria-label"}], "name": "section"}, ["section", "region"]]]
    Received: [[{"name": "article"}, ["article"]], [{"constraints": ["scoped to the body element"], "name": "header"}, ["banner"]], [{"name": "blockquote"}, ["blockquote"]], [{"attributes": [{"name": "type", "value": "button"}], "name": "input"}, ["button"]], [{"attributes": [{"name": "type", "value": "image"}], "name": "input"}, ["button"]], [{"attributes": [{"name": "type", "value": "reset"}], "name": "input"}, ["button"]], [{"attributes": [{"name": "type", "value": "submit"}], "name": "input"}, ["button"]], [{"name": "button"}, ["button"]], [{"name": "caption"}, ["caption"]], [{"constraints": ["ancestor table element has table role"], "name": "td"}, ["cell"]], …]

      145 |     });
      146 |     test.each(output)('Testing element: %o', (obj, roles) => {
    > 147 |       expect(entriesList).toEqual(
          |                           ^
      148 |         expect.arrayContaining([[obj, roles]]),
      149 |       );
      150 |     });

      at toEqual (__tests__/src/elementRoleMap-test.js:147:27)

  ● elementRoleMap API › forEach() › Testing element: {
  attributes: [ { name: 'aria-labelledby' }, [length]: 1 ],
  name: 'section'
}

    expect(received).toEqual(expected) // deep equality

    Expected: ArrayContaining [[{"attributes": [{"name": "aria-labelledby"}], "name": "section"}, ["section", "region"]]]
    Received: [[{"name": "article"}, ["article"]], [{"constraints": ["scoped to the body element"], "name": "header"}, ["banner"]], [{"name": "blockquote"}, ["blockquote"]], [{"attributes": [{"name": "type", "value": "button"}], "name": "input"}, ["button"]], [{"attributes": [{"name": "type", "value": "image"}], "name": "input"}, ["button"]], [{"attributes": [{"name": "type", "value": "reset"}], "name": "input"}, ["button"]], [{"attributes": [{"name": "type", "value": "submit"}], "name": "input"}, ["button"]], [{"name": "button"}, ["button"]], [{"name": "caption"}, ["caption"]], [{"constraints": ["ancestor table element has table role"], "name": "td"}, ["cell"]], …]

      145 |     });
      146 |     test.each(output)('Testing element: %o', (obj, roles) => {
    > 147 |       expect(entriesList).toEqual(
          |                           ^
      148 |         expect.arrayContaining([[obj, roles]]),
      149 |       );
      150 |     });

      at toEqual (__tests__/src/elementRoleMap-test.js:147:27)

  ● elementRoleMap API › forEach() › Testing element: {
  attributes: [ { name: 'aria-label' }, [length]: 1 ],
  name: 'section'
}

    expect(received).toEqual(expected) // deep equality

    Expected: ArrayContaining [[{"attributes": [{"name": "aria-label"}], "name": "section"}, ["section", "region"]]]
    Received: [[{"name": "article"}, ["article"]], [{"constraints": ["scoped to the body element"], "name": "header"}, ["banner"]], [{"name": "blockquote"}, ["blockquote"]], [{"attributes": [{"name": "type", "value": "button"}], "name": "input"}, ["button"]], [{"attributes": [{"name": "type", "value": "image"}], "name": "input"}, ["button"]], [{"attributes": [{"name": "type", "value": "reset"}], "name": "input"}, ["button"]], [{"attributes": [{"name": "type", "value": "submit"}], "name": "input"}, ["button"]], [{"name": "button"}, ["button"]], [{"name": "caption"}, ["caption"]], [{"constraints": ["ancestor table element has table role"], "name": "td"}, ["cell"]], …]

      150 |     });
      151 |     test.each(context)('Testing element: %o', (obj, roles) => {
    > 152 |       expect(entriesList).toEqual(
          |                           ^
      153 |         expect.arrayContaining([[obj, roles]]),
      154 |       );
      155 |     });

      at toEqual (__tests__/src/elementRoleMap-test.js:152:27)

  ● elementRoleMap API › forEach() › Testing element: {
  attributes: [ { name: 'aria-labelledby' }, [length]: 1 ],
  name: 'section'
}

    expect(received).toEqual(expected) // deep equality

    Expected: ArrayContaining [[{"attributes": [{"name": "aria-labelledby"}], "name": "section"}, ["section", "region"]]]
    Received: [[{"name": "article"}, ["article"]], [{"constraints": ["scoped to the body element"], "name": "header"}, ["banner"]], [{"name": "blockquote"}, ["blockquote"]], [{"attributes": [{"name": "type", "value": "button"}], "name": "input"}, ["button"]], [{"attributes": [{"name": "type", "value": "image"}], "name": "input"}, ["button"]], [{"attributes": [{"name": "type", "value": "reset"}], "name": "input"}, ["button"]], [{"attributes": [{"name": "type", "value": "submit"}], "name": "input"}, ["button"]], [{"name": "button"}, ["button"]], [{"name": "caption"}, ["caption"]], [{"constraints": ["ancestor table element has table role"], "name": "td"}, ["cell"]], …]

      150 |     });
      151 |     test.each(context)('Testing element: %o', (obj, roles) => {
    > 152 |       expect(entriesList).toEqual(
          |                           ^
      153 |         expect.arrayContaining([[obj, roles]]),
      154 |       );
      155 |     });

      at toEqual (__tests__/src/elementRoleMap-test.js:152:27)

  ● elementRoleMap API › forEach() › Testing element: { name: 'aside' }

    expect(received).toEqual(expected) // deep equality

    Expected: ArrayContaining [[{"name": "aside"}, ["complementary", "generic"]]]
    Received: [[{"name": "article"}, ["article"]], [{"constraints": ["scoped to the body element"], "name": "header"}, ["banner"]], [{"name": "blockquote"}, ["blockquote"]], [{"attributes": [{"name": "type", "value": "button"}], "name": "input"}, ["button"]], [{"attributes": [{"name": "type", "value": "image"}], "name": "input"}, ["button"]], [{"attributes": [{"name": "type", "value": "reset"}], "name": "input"}, ["button"]], [{"attributes": [{"name": "type", "value": "submit"}], "name": "input"}, ["button"]], [{"name": "button"}, ["button"]], [{"name": "caption"}, ["caption"]], [{"constraints": ["ancestor table element has table role"], "name": "td"}, ["cell"]], …]

      150 |     });
      151 |     test.each(context)('Testing element: %o', (obj, roles) => {
    > 152 |       expect(entriesList).toEqual(
          |                           ^
      153 |         expect.arrayContaining([[obj, roles]]),
      154 |       );
      155 |     });

      at toEqual (__tests__/src/elementRoleMap-test.js:152:27)

  ● elementRoleMap API › forEach() › Testing element: { name: 'aside' }

    expect(received).toEqual(expected) // deep equality

    Expected: ArrayContaining [[{"name": "aside"}, ["complementary", "generic"]]]
    Received: [[{"name": "article"}, ["article"]], [{"constraints": ["scoped to the body element"], "name": "header"}, ["banner"]], [{"name": "blockquote"}, ["blockquote"]], [{"attributes": [{"name": "type", "value": "button"}], "name": "input"}, ["button"]], [{"attributes": [{"name": "type", "value": "image"}], "name": "input"}, ["button"]], [{"attributes": [{"name": "type", "value": "reset"}], "name": "input"}, ["button"]], [{"attributes": [{"name": "type", "value": "submit"}], "name": "input"}, ["button"]], [{"name": "button"}, ["button"]], [{"name": "caption"}, ["caption"]], [{"constraints": ["ancestor table element has table role"], "name": "td"}, ["cell"]], …]

      150 |     });
      151 |     test.each(context)('Testing element: %o', (obj, roles) => {
    > 152 |       expect(entriesList).toEqual(
          |                           ^
      153 |         expect.arrayContaining([[obj, roles]]),
      154 |       );
      155 |     });

      at toEqual (__tests__/src/elementRoleMap-test.js:152:27)

  ● elementRoleMap API › forEach() › Testing element: {
  attributes: [ { name: 'aria-label' }, [length]: 1 ],
  name: 'section'
}

    expect(received).toEqual(expected) // deep equality

    Expected: ArrayContaining [[{"attributes": [{"name": "aria-label"}], "name": "section"}, ["section", "region"]]]
    Received: [[{"name": "article"}, ["article"]], [{"constraints": ["scoped to the body element"], "name": "header"}, ["banner"]], [{"name": "blockquote"}, ["blockquote"]], [{"attributes": [{"name": "type", "value": "button"}], "name": "input"}, ["button"]], [{"attributes": [{"name": "type", "value": "image"}], "name": "input"}, ["button"]], [{"attributes": [{"name": "type", "value": "reset"}], "name": "input"}, ["button"]], [{"attributes": [{"name": "type", "value": "submit"}], "name": "input"}, ["button"]], [{"name": "button"}, ["button"]], [{"name": "caption"}, ["caption"]], [{"constraints": ["ancestor table element has table role"], "name": "td"}, ["cell"]], …]

      150 |     });
      151 |     test.each(context)('Testing element: %o', (obj, roles) => {
    > 152 |       expect(entriesList).toEqual(
          |                           ^
      153 |         expect.arrayContaining([[obj, roles]]),
      154 |       );
      155 |     });

      at toEqual (__tests__/src/elementRoleMap-test.js:152:27)

  ● elementRoleMap API › forEach() › Testing element: {
  attributes: [ { name: 'aria-labelledby' }, [length]: 1 ],
  name: 'section'
}

    expect(received).toEqual(expected) // deep equality

    Expected: ArrayContaining [[{"attributes": [{"name": "aria-labelledby"}], "name": "section"}, ["section", "region"]]]
    Received: [[{"name": "article"}, ["article"]], [{"constraints": ["scoped to the body element"], "name": "header"}, ["banner"]], [{"name": "blockquote"}, ["blockquote"]], [{"attributes": [{"name": "type", "value": "button"}], "name": "input"}, ["button"]], [{"attributes": [{"name": "type", "value": "image"}], "name": "input"}, ["button"]], [{"attributes": [{"name": "type", "value": "reset"}], "name": "input"}, ["button"]], [{"attributes": [{"name": "type", "value": "submit"}], "name": "input"}, ["button"]], [{"name": "button"}, ["button"]], [{"name": "caption"}, ["caption"]], [{"constraints": ["ancestor table element has table role"], "name": "td"}, ["cell"]], …]

      150 |     });
      151 |     test.each(context)('Testing element: %o', (obj, roles) => {
    > 152 |       expect(entriesList).toEqual(
          |                           ^
      153 |         expect.arrayContaining([[obj, roles]]),
      154 |       );
      155 |     });

      at toEqual (__tests__/src/elementRoleMap-test.js:152:27)

  ● elementRoleMap API › values() › Testing value: [ 'section', 'region', [length]: 2 ]

    expect(received).toEqual(expected) // deep equality

    Expected: ArrayContaining [["section", "region"]]
    Received: [["article"], ["banner"], ["blockquote"], ["button"], ["button"], ["button"], ["button"], ["button"], ["caption"], ["cell"], …]

      211 |     const entriesValues = entriesList.map(entry => entry[1]);
      212 |     test.each(elementRoleMap.values().map(value => [value]))('Testing value: %o', (value) => {
    > 213 |       expect(entriesValues).toEqual(
          |                             ^
      214 |         expect.arrayContaining([value]),
      215 |       );
      216 |     });

      at toEqual (__tests__/src/elementRoleMap-test.js:213:29)

  ● elementRoleMap API › values() › Testing value: [ 'section', 'region', [length]: 2 ]

    expect(received).toEqual(expected) // deep equality

    Expected: ArrayContaining [["section", "region"]]
    Received: [["article"], ["banner"], ["blockquote"], ["button"], ["button"], ["button"], ["button"], ["button"], ["caption"], ["cell"], …]

      211 |     const entriesValues = entriesList.map(entry => entry[1]);
      212 |     test.each(elementRoleMap.values().map(value => [value]))('Testing value: %o', (value) => {
    > 213 |       expect(entriesValues).toEqual(
          |                             ^
      214 |         expect.arrayContaining([value]),
      215 |       );
      216 |     });

      at toEqual (__tests__/src/elementRoleMap-test.js:213:29)

  ● elementRoleMap API › values() › Testing value: [ 'complementary', 'generic', [length]: 2 ]

    expect(received).toEqual(expected) // deep equality

    Expected: ArrayContaining [["complementary", "generic"]]
    Received: [["article"], ["banner"], ["blockquote"], ["button"], ["button"], ["button"], ["button"], ["button"], ["caption"], ["cell"], …]

      211 |     const entriesValues = entriesList.map(entry => entry[1]);
      212 |     test.each(elementRoleMap.values().map(value => [value]))('Testing value: %o', (value) => {
    > 213 |       expect(entriesValues).toEqual(
          |                             ^
      214 |         expect.arrayContaining([value]),
      215 |       );
      216 |     });

      at toEqual (__tests__/src/elementRoleMap-test.js:213:29)

  ● elementRoleMap API › values() › Testing value: [ 'complementary', 'generic', [length]: 2 ]

    expect(received).toEqual(expected) // deep equality

    Expected: ArrayContaining [["complementary", "generic"]]
    Received: [["article"], ["banner"], ["blockquote"], ["button"], ["button"], ["button"], ["button"], ["button"], ["caption"], ["cell"], …]

      211 |     const entriesValues = entriesList.map(entry => entry[1]);
      212 |     test.each(elementRoleMap.values().map(value => [value]))('Testing value: %o', (value) => {
    > 213 |       expect(entriesValues).toEqual(
          |                             ^
      214 |         expect.arrayContaining([value]),
      215 |       );
      216 |     });

      at toEqual (__tests__/src/elementRoleMap-test.js:213:29)

  ● elementRoleMap API › values() › Testing value: [ 'section', 'region', [length]: 2 ]

    expect(received).toEqual(expected) // deep equality

    Expected: ArrayContaining [["section", "region"]]
    Received: [["article"], ["banner"], ["blockquote"], ["button"], ["button"], ["button"], ["button"], ["button"], ["caption"], ["cell"], …]

      211 |     const entriesValues = entriesList.map(entry => entry[1]);
      212 |     test.each(elementRoleMap.values().map(value => [value]))('Testing value: %o', (value) => {
    > 213 |       expect(entriesValues).toEqual(
          |                             ^
      214 |         expect.arrayContaining([value]),
      215 |       );
      216 |     });

      at toEqual (__tests__/src/elementRoleMap-test.js:213:29)

  ● elementRoleMap API › values() › Testing value: [ 'section', 'region', [length]: 2 ]

    expect(received).toEqual(expected) // deep equality

    Expected: ArrayContaining [["section", "region"]]
    Received: [["article"], ["banner"], ["blockquote"], ["button"], ["button"], ["button"], ["button"], ["button"], ["caption"], ["cell"], …]

      211 |     const entriesValues = entriesList.map(entry => entry[1]);
      212 |     test.each(elementRoleMap.values().map(value => [value]))('Testing value: %o', (value) => {
    > 213 |       expect(entriesValues).toEqual(
          |                             ^
      214 |         expect.arrayContaining([value]),
      215 |       );
      216 |     });

      at toEqual (__tests__/src/elementRoleMap-test.js:213:29)

  ● elementRoleMap API › values() › Testing value: [ 'section', 'region', [length]: 2 ]

    expect(received).toEqual(expected) // deep equality

    Expected: ArrayContaining [["section", "region"]]
    Received: [["article"], ["banner"], ["blockquote"], ["button"], ["button"], ["button"], ["button"], ["button"], ["caption"], ["cell"], …]

      216 |     });
      217 |     test.each([...elementRoleMap.values()].map(value => [value]))('Testing value: %o', (value) => {
    > 218 |       expect(entriesValues).toEqual(
          |                             ^
      219 |         expect.arrayContaining([value]),
      220 |       );
      221 |     });

      at toEqual (__tests__/src/elementRoleMap-test.js:218:29)

  ● elementRoleMap API › values() › Testing value: [ 'section', 'region', [length]: 2 ]

    expect(received).toEqual(expected) // deep equality

    Expected: ArrayContaining [["section", "region"]]
    Received: [["article"], ["banner"], ["blockquote"], ["button"], ["button"], ["button"], ["button"], ["button"], ["caption"], ["cell"], …]

      216 |     });
      217 |     test.each([...elementRoleMap.values()].map(value => [value]))('Testing value: %o', (value) => {
    > 218 |       expect(entriesValues).toEqual(
          |                             ^
      219 |         expect.arrayContaining([value]),
      220 |       );
      221 |     });

      at toEqual (__tests__/src/elementRoleMap-test.js:218:29)

  ● elementRoleMap API › values() › Testing value: [ 'complementary', 'generic', [length]: 2 ]

    expect(received).toEqual(expected) // deep equality

    Expected: ArrayContaining [["complementary", "generic"]]
    Received: [["article"], ["banner"], ["blockquote"], ["button"], ["button"], ["button"], ["button"], ["button"], ["caption"], ["cell"], …]

      216 |     });
      217 |     test.each([...elementRoleMap.values()].map(value => [value]))('Testing value: %o', (value) => {
    > 218 |       expect(entriesValues).toEqual(
          |                             ^
      219 |         expect.arrayContaining([value]),
      220 |       );
      221 |     });

      at toEqual (__tests__/src/elementRoleMap-test.js:218:29)

  ● elementRoleMap API › values() › Testing value: [ 'complementary', 'generic', [length]: 2 ]

    expect(received).toEqual(expected) // deep equality

    Expected: ArrayContaining [["complementary", "generic"]]
    Received: [["article"], ["banner"], ["blockquote"], ["button"], ["button"], ["button"], ["button"], ["button"], ["caption"], ["cell"], …]

      216 |     });
      217 |     test.each([...elementRoleMap.values()].map(value => [value]))('Testing value: %o', (value) => {
    > 218 |       expect(entriesValues).toEqual(
          |                             ^
      219 |         expect.arrayContaining([value]),
      220 |       );
      221 |     });

      at toEqual (__tests__/src/elementRoleMap-test.js:218:29)

  ● elementRoleMap API › values() › Testing value: [ 'section', 'region', [length]: 2 ]

    expect(received).toEqual(expected) // deep equality

    Expected: ArrayContaining [["section", "region"]]
    Received: [["article"], ["banner"], ["blockquote"], ["button"], ["button"], ["button"], ["button"], ["button"], ["caption"], ["cell"], …]

      216 |     });
      217 |     test.each([...elementRoleMap.values()].map(value => [value]))('Testing value: %o', (value) => {
    > 218 |       expect(entriesValues).toEqual(
          |                             ^
      219 |         expect.arrayContaining([value]),
      220 |       );
      221 |     });

      at toEqual (__tests__/src/elementRoleMap-test.js:218:29)

  ● elementRoleMap API › values() › Testing value: [ 'section', 'region', [length]: 2 ]

    expect(received).toEqual(expected) // deep equality

    Expected: ArrayContaining [["section", "region"]]
    Received: [["article"], ["banner"], ["blockquote"], ["button"], ["button"], ["button"], ["button"], ["button"], ["caption"], ["cell"], …]

      216 |     });
      217 |     test.each([...elementRoleMap.values()].map(value => [value]))('Testing value: %o', (value) => {
    > 218 |       expect(entriesValues).toEqual(
          |                             ^
      219 |         expect.arrayContaining([value]),
      220 |       );
      221 |     });

      at toEqual (__tests__/src/elementRoleMap-test.js:218:29)

  ● elementRolesMap › iteration › spread operator › Testing element: {
  attributes: [ { name: 'aria-label' }, [length]: 1 ],
  name: 'section'
}

    expect(received).toEqual(expected) // deep equality

    Expected: ArrayContaining [[{"attributes": [{"name": "aria-label"}], "name": "section"}, ["section", "region"]]]
    Received: [[{"name": "article"}, ["article"]], [{"constraints": ["scoped to the body element"], "name": "header"}, ["banner"]], [{"name": "blockquote"}, ["blockquote"]], [{"attributes": [{"name": "type", "value": "button"}], "name": "input"}, ["button"]], [{"attributes": [{"name": "type", "value": "image"}], "name": "input"}, ["button"]], [{"attributes": [{"name": "type", "value": "reset"}], "name": "input"}, ["button"]], [{"attributes": [{"name": "type", "value": "submit"}], "name": "input"}, ["button"]], [{"name": "button"}, ["button"]], [{"name": "caption"}, ["caption"]], [{"constraints": ["ancestor table element has table role"], "name": "td"}, ["cell"]], …]

      233 |       });
      234 |       test.each([...elementRoleMap])('Testing element: %o', (obj, roles) => {
    > 235 |         expect(entriesList).toEqual(
          |                             ^
      236 |           expect.arrayContaining([[obj, roles]]),
      237 |         );
      238 |       });

      at toEqual (__tests__/src/elementRoleMap-test.js:235:29)

  ● elementRolesMap › iteration › spread operator › Testing element: {
  attributes: [ { name: 'aria-labelledby' }, [length]: 1 ],
  name: 'section'
}

    expect(received).toEqual(expected) // deep equality

    Expected: ArrayContaining [[{"attributes": [{"name": "aria-labelledby"}], "name": "section"}, ["section", "region"]]]
    Received: [[{"name": "article"}, ["article"]], [{"constraints": ["scoped to the body element"], "name": "header"}, ["banner"]], [{"name": "blockquote"}, ["blockquote"]], [{"attributes": [{"name": "type", "value": "button"}], "name": "input"}, ["button"]], [{"attributes": [{"name": "type", "value": "image"}], "name": "input"}, ["button"]], [{"attributes": [{"name": "type", "value": "reset"}], "name": "input"}, ["button"]], [{"attributes": [{"name": "type", "value": "submit"}], "name": "input"}, ["button"]], [{"name": "button"}, ["button"]], [{"name": "caption"}, ["caption"]], [{"constraints": ["ancestor table element has table role"], "name": "td"}, ["cell"]], …]

      233 |       });
      234 |       test.each([...elementRoleMap])('Testing element: %o', (obj, roles) => {
    > 235 |         expect(entriesList).toEqual(
          |                             ^
      236 |           expect.arrayContaining([[obj, roles]]),
      237 |         );
      238 |       });

      at toEqual (__tests__/src/elementRoleMap-test.js:235:29)

  ● elementRolesMap › iteration › spread operator › Testing element: { name: 'aside' }

    expect(received).toEqual(expected) // deep equality

    Expected: ArrayContaining [[{"name": "aside"}, ["complementary", "generic"]]]
    Received: [[{"name": "article"}, ["article"]], [{"constraints": ["scoped to the body element"], "name": "header"}, ["banner"]], [{"name": "blockquote"}, ["blockquote"]], [{"attributes": [{"name": "type", "value": "button"}], "name": "input"}, ["button"]], [{"attributes": [{"name": "type", "value": "image"}], "name": "input"}, ["button"]], [{"attributes": [{"name": "type", "value": "reset"}], "name": "input"}, ["button"]], [{"attributes": [{"name": "type", "value": "submit"}], "name": "input"}, ["button"]], [{"name": "button"}, ["button"]], [{"name": "caption"}, ["caption"]], [{"constraints": ["ancestor table element has table role"], "name": "td"}, ["cell"]], …]

      233 |       });
      234 |       test.each([...elementRoleMap])('Testing element: %o', (obj, roles) => {
    > 235 |         expect(entriesList).toEqual(
          |                             ^
      236 |           expect.arrayContaining([[obj, roles]]),
      237 |         );
      238 |       });

      at toEqual (__tests__/src/elementRoleMap-test.js:235:29)

  ● elementRolesMap › iteration › spread operator › Testing element: { name: 'aside' }

    expect(received).toEqual(expected) // deep equality

    Expected: ArrayContaining [[{"name": "aside"}, ["complementary", "generic"]]]
    Received: [[{"name": "article"}, ["article"]], [{"constraints": ["scoped to the body element"], "name": "header"}, ["banner"]], [{"name": "blockquote"}, ["blockquote"]], [{"attributes": [{"name": "type", "value": "button"}], "name": "input"}, ["button"]], [{"attributes": [{"name": "type", "value": "image"}], "name": "input"}, ["button"]], [{"attributes": [{"name": "type", "value": "reset"}], "name": "input"}, ["button"]], [{"attributes": [{"name": "type", "value": "submit"}], "name": "input"}, ["button"]], [{"name": "button"}, ["button"]], [{"name": "caption"}, ["caption"]], [{"constraints": ["ancestor table element has table role"], "name": "td"}, ["cell"]], …]

      233 |       });
      234 |       test.each([...elementRoleMap])('Testing element: %o', (obj, roles) => {
    > 235 |         expect(entriesList).toEqual(
          |                             ^
      236 |           expect.arrayContaining([[obj, roles]]),
      237 |         );
      238 |       });

      at toEqual (__tests__/src/elementRoleMap-test.js:235:29)

  ● elementRolesMap › iteration › spread operator › Testing element: {
  attributes: [ { name: 'aria-label' }, [length]: 1 ],
  name: 'section'
}

    expect(received).toEqual(expected) // deep equality

    Expected: ArrayContaining [[{"attributes": [{"name": "aria-label"}], "name": "section"}, ["section", "region"]]]
    Received: [[{"name": "article"}, ["article"]], [{"constraints": ["scoped to the body element"], "name": "header"}, ["banner"]], [{"name": "blockquote"}, ["blockquote"]], [{"attributes": [{"name": "type", "value": "button"}], "name": "input"}, ["button"]], [{"attributes": [{"name": "type", "value": "image"}], "name": "input"}, ["button"]], [{"attributes": [{"name": "type", "value": "reset"}], "name": "input"}, ["button"]], [{"attributes": [{"name": "type", "value": "submit"}], "name": "input"}, ["button"]], [{"name": "button"}, ["button"]], [{"name": "caption"}, ["caption"]], [{"constraints": ["ancestor table element has table role"], "name": "td"}, ["cell"]], …]

      233 |       });
      234 |       test.each([...elementRoleMap])('Testing element: %o', (obj, roles) => {
    > 235 |         expect(entriesList).toEqual(
          |                             ^
      236 |           expect.arrayContaining([[obj, roles]]),
      237 |         );
      238 |       });

      at toEqual (__tests__/src/elementRoleMap-test.js:235:29)

  ● elementRolesMap › iteration › spread operator › Testing element: {
  attributes: [ { name: 'aria-labelledby' }, [length]: 1 ],
  name: 'section'
}

    expect(received).toEqual(expected) // deep equality

    Expected: ArrayContaining [[{"attributes": [{"name": "aria-labelledby"}], "name": "section"}, ["section", "region"]]]
    Received: [[{"name": "article"}, ["article"]], [{"constraints": ["scoped to the body element"], "name": "header"}, ["banner"]], [{"name": "blockquote"}, ["blockquote"]], [{"attributes": [{"name": "type", "value": "button"}], "name": "input"}, ["button"]], [{"attributes": [{"name": "type", "value": "image"}], "name": "input"}, ["button"]], [{"attributes": [{"name": "type", "value": "reset"}], "name": "input"}, ["button"]], [{"attributes": [{"name": "type", "value": "submit"}], "name": "input"}, ["button"]], [{"name": "button"}, ["button"]], [{"name": "caption"}, ["caption"]], [{"constraints": ["ancestor table element has table role"], "name": "td"}, ["cell"]], …]

      233 |       });
      234 |       test.each([...elementRoleMap])('Testing element: %o', (obj, roles) => {
    > 235 |         expect(entriesList).toEqual(
          |                             ^
      236 |           expect.arrayContaining([[obj, roles]]),
      237 |         );
      238 |       });

      at toEqual (__tests__/src/elementRoleMap-test.js:235:29)

  ● elementRolesMap › iteration › for..of pattern › Testing element: {
  attributes: [ { name: 'aria-label' }, [length]: 1 ],
  name: 'section'
}

    expect(received).toEqual(expected) // deep equality

    Expected: ArrayContaining [[{"attributes": [{"name": "aria-label"}], "name": "section"}, ["section", "region"]]]
    Received: [[{"name": "article"}, ["article"]], [{"constraints": ["scoped to the body element"], "name": "header"}, ["banner"]], [{"name": "blockquote"}, ["blockquote"]], [{"attributes": [{"name": "type", "value": "button"}], "name": "input"}, ["button"]], [{"attributes": [{"name": "type", "value": "image"}], "name": "input"}, ["button"]], [{"attributes": [{"name": "type", "value": "reset"}], "name": "input"}, ["button"]], [{"attributes": [{"name": "type", "value": "submit"}], "name": "input"}, ["button"]], [{"name": "button"}, ["button"]], [{"name": "caption"}, ["caption"]], [{"constraints": ["ancestor table element has table role"], "name": "td"}, ["cell"]], …]

      244 |       }
      245 |       test.each(output)('Testing element: %o', (obj, roles) => {
    > 246 |         expect(entriesList).toEqual(
          |                             ^
      247 |           expect.arrayContaining([[obj, roles]]),
      248 |         );
      249 |       });

      at toEqual (__tests__/src/elementRoleMap-test.js:246:29)

  ● elementRolesMap › iteration › for..of pattern › Testing element: {
  attributes: [ { name: 'aria-labelledby' }, [length]: 1 ],
  name: 'section'
}

    expect(received).toEqual(expected) // deep equality

    Expected: ArrayContaining [[{"attributes": [{"name": "aria-labelledby"}], "name": "section"}, ["section", "region"]]]
    Received: [[{"name": "article"}, ["article"]], [{"constraints": ["scoped to the body element"], "name": "header"}, ["banner"]], [{"name": "blockquote"}, ["blockquote"]], [{"attributes": [{"name": "type", "value": "button"}], "name": "input"}, ["button"]], [{"attributes": [{"name": "type", "value": "image"}], "name": "input"}, ["button"]], [{"attributes": [{"name": "type", "value": "reset"}], "name": "input"}, ["button"]], [{"attributes": [{"name": "type", "value": "submit"}], "name": "input"}, ["button"]], [{"name": "button"}, ["button"]], [{"name": "caption"}, ["caption"]], [{"constraints": ["ancestor table element has table role"], "name": "td"}, ["cell"]], …]

      244 |       }
      245 |       test.each(output)('Testing element: %o', (obj, roles) => {
    > 246 |         expect(entriesList).toEqual(
          |                             ^
      247 |           expect.arrayContaining([[obj, roles]]),
      248 |         );
      249 |       });

      at toEqual (__tests__/src/elementRoleMap-test.js:246:29)

  ● elementRolesMap › iteration › for..of pattern › Testing element: { name: 'aside' }

    expect(received).toEqual(expected) // deep equality

    Expected: ArrayContaining [[{"name": "aside"}, ["complementary", "generic"]]]
    Received: [[{"name": "article"}, ["article"]], [{"constraints": ["scoped to the body element"], "name": "header"}, ["banner"]], [{"name": "blockquote"}, ["blockquote"]], [{"attributes": [{"name": "type", "value": "button"}], "name": "input"}, ["button"]], [{"attributes": [{"name": "type", "value": "image"}], "name": "input"}, ["button"]], [{"attributes": [{"name": "type", "value": "reset"}], "name": "input"}, ["button"]], [{"attributes": [{"name": "type", "value": "submit"}], "name": "input"}, ["button"]], [{"name": "button"}, ["button"]], [{"name": "caption"}, ["caption"]], [{"constraints": ["ancestor table element has table role"], "name": "td"}, ["cell"]], …]

      244 |       }
      245 |       test.each(output)('Testing element: %o', (obj, roles) => {
    > 246 |         expect(entriesList).toEqual(
          |                             ^
      247 |           expect.arrayContaining([[obj, roles]]),
      248 |         );
      249 |       });

      at toEqual (__tests__/src/elementRoleMap-test.js:246:29)

  ● elementRolesMap › iteration › for..of pattern › Testing element: { name: 'aside' }

    expect(received).toEqual(expected) // deep equality

    Expected: ArrayContaining [[{"name": "aside"}, ["complementary", "generic"]]]
    Received: [[{"name": "article"}, ["article"]], [{"constraints": ["scoped to the body element"], "name": "header"}, ["banner"]], [{"name": "blockquote"}, ["blockquote"]], [{"attributes": [{"name": "type", "value": "button"}], "name": "input"}, ["button"]], [{"attributes": [{"name": "type", "value": "image"}], "name": "input"}, ["button"]], [{"attributes": [{"name": "type", "value": "reset"}], "name": "input"}, ["button"]], [{"attributes": [{"name": "type", "value": "submit"}], "name": "input"}, ["button"]], [{"name": "button"}, ["button"]], [{"name": "caption"}, ["caption"]], [{"constraints": ["ancestor table element has table role"], "name": "td"}, ["cell"]], …]

      244 |       }
      245 |       test.each(output)('Testing element: %o', (obj, roles) => {
    > 246 |         expect(entriesList).toEqual(
          |                             ^
      247 |           expect.arrayContaining([[obj, roles]]),
      248 |         );
      249 |       });

      at toEqual (__tests__/src/elementRoleMap-test.js:246:29)

  ● elementRolesMap › iteration › for..of pattern › Testing element: {
  attributes: [ { name: 'aria-label' }, [length]: 1 ],
  name: 'section'
}

    expect(received).toEqual(expected) // deep equality

    Expected: ArrayContaining [[{"attributes": [{"name": "aria-label"}], "name": "section"}, ["section", "region"]]]
    Received: [[{"name": "article"}, ["article"]], [{"constraints": ["scoped to the body element"], "name": "header"}, ["banner"]], [{"name": "blockquote"}, ["blockquote"]], [{"attributes": [{"name": "type", "value": "button"}], "name": "input"}, ["button"]], [{"attributes": [{"name": "type", "value": "image"}], "name": "input"}, ["button"]], [{"attributes": [{"name": "type", "value": "reset"}], "name": "input"}, ["button"]], [{"attributes": [{"name": "type", "value": "submit"}], "name": "input"}, ["button"]], [{"name": "button"}, ["button"]], [{"name": "caption"}, ["caption"]], [{"constraints": ["ancestor table element has table role"], "name": "td"}, ["cell"]], …]

      244 |       }
      245 |       test.each(output)('Testing element: %o', (obj, roles) => {
    > 246 |         expect(entriesList).toEqual(
          |                             ^
      247 |           expect.arrayContaining([[obj, roles]]),
      248 |         );
      249 |       });

      at toEqual (__tests__/src/elementRoleMap-test.js:246:29)

  ● elementRolesMap › iteration › for..of pattern › Testing element: {
  attributes: [ { name: 'aria-labelledby' }, [length]: 1 ],
  name: 'section'
}

    expect(received).toEqual(expected) // deep equality

    Expected: ArrayContaining [[{"attributes": [{"name": "aria-labelledby"}], "name": "section"}, ["section", "region"]]]
    Received: [[{"name": "article"}, ["article"]], [{"constraints": ["scoped to the body element"], "name": "header"}, ["banner"]], [{"name": "blockquote"}, ["blockquote"]], [{"attributes": [{"name": "type", "value": "button"}], "name": "input"}, ["button"]], [{"attributes": [{"name": "type", "value": "image"}], "name": "input"}, ["button"]], [{"attributes": [{"name": "type", "value": "reset"}], "name": "input"}, ["button"]], [{"attributes": [{"name": "type", "value": "submit"}], "name": "input"}, ["button"]], [{"name": "button"}, ["button"]], [{"name": "caption"}, ["caption"]], [{"constraints": ["ancestor table element has table role"], "name": "td"}, ["cell"]], …]

      244 |       }
      245 |       test.each(output)('Testing element: %o', (obj, roles) => {
    > 246 |         expect(entriesList).toEqual(
          |                             ^
      247 |           expect.arrayContaining([[obj, roles]]),
      248 |         );
      249 |       });

      at toEqual (__tests__/src/elementRoleMap-test.js:246:29)

Test Suites: 1 failed, 6 passed, 7 total
Tests:       48 failed, 5086 passed, 5134 total
Snapshots:   0 total
Time:        2.326 s
Ran all test suites matching /__tests__\/src\/ariaPropsMaps-test.js|__tests__\/src\/domMap-test.js|__tests__\/src\/elementRoleMap-test.js|__tests__\/src\/roleElementMap-test.js|__tests__\/src\/rolesMap-test.js|__tests__\/src\/util/i.

@ljharb
Copy link
Collaborator

ljharb commented Jul 5, 2024

@jlp-craigmorten i think that for a11y in particular, we can't assume that something's "good enough" just because nobody's complained; devs rely on a11y tools to do the right thing even for smaller groups of people, so if we need to make a change to make things more correct, I think that'd be a good thing to do.

@cmorten
Copy link
Contributor

cmorten commented Jul 6, 2024

Ok think have this grok’d. Lemme try and poorly talk through:

It is feasible that an element can be assigned more than one role (under relevant spec WAI-ARIA and HTML-AAM).

It is rare and specs generally change to remove ambiguity by providing additional context (or constraints as referred to by this project) which can be added to the fixtures in this project, but it can happen. E.g. the role for img with empty alt is none or presentation without explicitly stating a preference.

REFs:

The section of code in scope for this change is responsible for backsearching through previously generated element to role entries to see if we’re in such a case and make sure roles are correctly applied.

As stands in the code today this impacts a single element, namely aside which currently has two identical concepts in the complementary and generic role fixtures. This code ensures that both entries for aside element in the elementRoleMap contain both roles.

Coincidentally the concepts for the aside element matching is actually a bug, see #526 where we are missing a constraints entry for the complementary role usage. This change accentuates the issue somewhat.

Where we should see this code have an impact is for the likes of alias roles of presentation/none and the upcoming ARIA 1.3 image/img, but this is behind other PRs, namely #551 (because img with empty alt is presentational but not listed for none role) and #557 for the image alias role.

Interestingly, even these could be debated as none is implied to be the canonical implicit role for user-agents by WAI-ARIA, but none of the specs state it explicitly. In WAI-ARIA 1.3 image is stated to be preferred over img more explicitly. (FWIW if we were to take the opinionated stance that the presentation and soon to be img roles are never the implicit role for an element, then we could consider leaving this code removed as element:role would be 1:1).

Curiously, this appears to result in duplicate entries in the map where the only difference is the ordering of the roles in the value - open question whether this should be de-duped as not sure what value that has? I think this is a bug and suspect we could add logic such that if we’re in a duplicate case we simply update the existing entry and avoid the final elementRoles.push([concept, roles]) to avoid multiple entries.

Adding this de-dupe logic could be seen as a breaking change, except:

  1. The only case this currently applies to is actually incorrect (the aside element)
  2. The only case it should apply to isn’t coded in this project yet (the none role)

So no-one should be relying on there being multiple entries afaik.

As an aside I seem to get different test failures when trying the old usage of dequal vs the new comparison function (unless I’ve messed up…), perhaps one to dbl check that they are equivalent?

if (isUnique) {
roles.push(key);
}
elementRoles.push([concept, roles]);
Copy link
Contributor

@cmorten cmorten Jul 6, 2024

Choose a reason for hiding this comment

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

Per my other comment, I think we could consider something like:

Suggested change
elementRoles.push([concept, roles]);
if (!elementRoleRelation) {
elementRoles.push([concept, roles]);
}

This would mean the map only ever has a single entry per unique concept (aka element + constraints) rather than multiple (in the case of elements that exhibit an alias role)

@@ -23,7 +23,25 @@ for (let i = 0; i < keys.length; i++) {
if (relation.module === 'HTML') {
const concept = relation.concept;
if (concept) {
elementRoles.push([concept, [key]]);
const elementRoleRelation: ?ElementARIARoleRelationTuple = elementRoles.find(relation => ariaRoleRelationConceptAttributeEquals(relation[0], concept));
Copy link
Contributor

@cmorten cmorten Jul 6, 2024

Choose a reason for hiding this comment

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

Suggested change
const elementRoleRelation: ?ElementARIARoleRelationTuple = elementRoles.find(relation => ariaRoleRelationConceptAttributeEquals(relation[0], concept));
const elementRoleRelation: ?ElementARIARoleRelationTuple = elementRoles.find(relation => ariaRoleRelationConceptEquals(relation[0], concept));

Care needed here - I think you’ve been working off the wrong type(s).

The relation[0] and concept are of type ARIARoleRelationConcept not ARIARoleRelationConceptAttribute which I think explains why your test case failure count is so high.

The comparison function needs to be amended to take the full concept into account.

Once amended the only failures should relate to the aside element (pending a fix for separate issues)

@samccone
Copy link
Contributor Author

samccone commented Jul 7, 2024

Thanks @cmorten I agree with your analysis - and I appreciate you taking a look - I have applied your patch from #558 and now can confirm all tests are passing.

ljharb and others added 2 commits July 7, 2024 21:15
As discovered in A11yance#554

Address the defect introduced f7f6120#r143856081

This change depends on A11yance#558 which when applied (as in this PR makes the teset cases pass)
@coveralls
Copy link

coveralls commented Jul 8, 2024

Pull Request Test Coverage Report for Build 9833491688

Details

  • 25 of 25 (100.0%) changed or added relevant lines in 1 file are covered.
  • No unchanged relevant lines lost coverage.
  • Overall coverage increased (+1.7%) to 96.474%

Totals Coverage Status
Change from base Build 9833362227: 1.7%
Covered Lines: 283
Relevant Lines: 287

💛 - Coveralls

src/elementRoleMap.js Outdated Show resolved Hide resolved
Copy link
Contributor

@cmorten cmorten left a comment

Choose a reason for hiding this comment

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

LGTM

Copy link
Collaborator

@ljharb ljharb left a comment

Choose a reason for hiding this comment

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

Thanks to you both for all of your help here!

@ljharb ljharb merged commit 037e621 into A11yance:main Jul 8, 2024
7 checks passed
@samccone samccone deleted the impossible branch July 10, 2024 16:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants