Search code examples
angularjestjsangular-testing-library

angular-testing-library: getByRole query works only with hidden: true option


I am just trying out this library and seem to be unable to access elements by their ARIA role.

I use angular 10.0.6, jest 26.2.1 together with jest-preset-angular 8.2.1 and @testing-library/angular 10.0.1. I believe to have set the project up as described in https://www.npmjs.com/package/jest-preset-angular and https://testing-library.com/docs/angular-testing-library/intro

here's my component I am trying to test:

<h1>{{title}}</h1>
<img src="../assets/chuck-norris-logo.jpg" alt="Chuck Norris Approves!">
<p role="status">{{jokeText}}</p>
<button (click)="refreshJoke()">Refresh</button>

and the relevant part of some test:

test('refreshes joke on click', async () => {
    const component = await render(AppComponent);

    const button = component.getByRole('button');
    fireEvent.click(button);
  });

However, I get an error message that the role could not be found.

TestingLibraryElementError: Unable to find an accessible element with the role "button"

There are no accessible roles. But there might be some inaccessible roles. If you wish to access them, then set the `hidden` option to `true`. Learn more about this here: https://testing-library.com/docs/dom-testing-library/api-queries#byrole

<div
  id="root1"
  ng-version="10.0.6"
>
  <h1>
    Chuck Norris
  </h1>
  <img
    alt="Chuck Norris Approves!"
    src="../assets/chuck-norris-logo.jpg"
  />
  <p
    role="status"
  >
    Chuck Norris uses canvas in IE.
  </p>
  <button>
    Refresh
  </button>
</div>

I can circumvent that by setting the hidden option to true.

import {configure} from '@testing-library/dom';

configure({
  defaultHidden: true
});

As the other query functions I tried work (such as getByText and getByTestId) work fine and I never encountered similar problems with react, I guess I messed up my configuration somehow.

this is my complete package.json

{
  "name": "chuck-norris-ng",
  "version": "0.0.0",
  "scripts": {
    "ng": "ng",
    "start": "ng serve",
    "build": "ng build",
    "test": "jest",
    "test:watch": "jest --watch",
    "lint": "ng lint",
    "e2e": "ng e2e"
  },
  "private": true,
  "dependencies": {
    "@angular/animations": "~10.0.6",
    "@angular/common": "~10.0.6",
    "@angular/compiler": "~10.0.6",
    "@angular/core": "~10.0.6",
    "@angular/forms": "~10.0.6",
    "@angular/platform-browser": "~10.0.6",
    "@angular/platform-browser-dynamic": "~10.0.6",
    "@angular/router": "~10.0.6",
    "rxjs": "~6.6.0",
    "tslib": "^2.0.0",
    "zone.js": "~0.10.2"
  },
  "devDependencies": {
    "@angular-devkit/build-angular": "~0.1000.4",
    "@angular/cli": "~10.0.4",
    "@angular/compiler-cli": "~10.0.6",
    "@testing-library/angular": "^10.0.1",
    "@testing-library/jest-dom": "^5.11.2",
    "@types/jest": "^26.0.7",
    "@types/node": "^12.11.1",
    "codelyzer": "^6.0.0",
    "jest": "^26.2.1",
    "jest-preset-angular": "^8.2.1",
    "protractor": "~7.0.0",
    "ts-node": "~8.3.0",
    "tslint": "~6.1.0",
    "typescript": "~3.9.7"
  },
  "jest": {
    "preset": "jest-preset-angular",
    "setupFilesAfterEnv": [
      "<rootDir>/src/setup-jest.ts"
    ]
  }
}

I've uploaded my repo to GitHub. What did I wrong?


Solution

  • I ran into same issue and I resolved my issue by removing a portion of the jest browser mocks that was referenced in the 'Usage' section for https://www.npmjs.com/package/jest-preset-angular#usage:

    I deleted the following from the jest-global-mocks.ts file:

    Object.defineProperty(window, 'getComputedStyle', {
       value: () => {
          return {
             display: 'none',
             appearance: ['-webkit-appearance'],
          };
       },
    });
    

    I've seen similar global mocks referenced from articles like https://www.amadousall.com/how-to-set-up-angular-unit-testing-with-jest/ <-- this article says "Mock some properties and functions of the global window object to make sure our tests can run in a JSDOM environment." but I don't know enough to understand whether removing this is a good idea when using the angular-testing-library (I am also using https://www.npmjs.com/package/@testing-library/jest-dom). Maybe someone else can help explain the use case in more detail, but right now I'm just glad I can use getByRole() again.