# All files / src/queries role.ts

100% Statements 31/31
100% Branches 21/21
100% Functions 12/12
100% Lines 30/30

Press n or j to go to the next uncovered block, b, p or k for the previous block.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133

    48x

    111x

    33x
    33x

    48x

    154x

    48x

    122x

    48x

    597x
    213x

    1814x

    48x
    118x

    118x
    6x

    118x
    590x
    5x

    118x
    472x
    9x

    118x

    48x
    22x

    48x
    96x

    48x

    48x

    386x

     import type { ReactTestInstance } from 'react-test-renderer';
    import {
      accessibilityStateKeys,
      accessiblityValueKeys,
      isAccessibilityElement,
    } from '../helpers/accessiblity';
    import { findAll } from '../helpers/findAll';
    import {
      AccessibilityStateMatcher,
      matchAccessibilityState,
    } from '../helpers/matchers/accessibilityState';
    import {
      AccessibilityValueMatcher,
      matchAccessibilityValue,
    } from '../helpers/matchers/accessibilityValue';
    import { matchStringProp } from '../helpers/matchers/matchStringProp';
    import type { TextMatch } from '../matches';
    import { getQueriesForElement } from '../within';
    import { makeQueries } from './makeQueries';
    import type {
      FindAllByQuery,
      FindByQuery,
      GetAllByQuery,
      GetByQuery,
      QueryAllByQuery,
      QueryByQuery,
    } from './makeQueries';
    import { CommonQueryOptions } from './options';

    type ByRoleOptions = CommonQueryOptions &
      AccessibilityStateMatcher & {
        name?: TextMatch;
        value?: AccessibilityValueMatcher;
      };

    const matchAccessibleNameIfNeeded = (
      node: ReactTestInstance,
      name?: TextMatch
    ) => {
      if (name == null) return true;

      const { queryAllByText, queryAllByLabelText } = getQueriesForElement(node);
      return (
        queryAllByText(name).length > 0 || queryAllByLabelText(name).length > 0
      );
    };

    const matchAccessibleStateIfNeeded = (
      node: ReactTestInstance,
      options?: ByRoleOptions
    ) => {
      return options != null ? matchAccessibilityState(node, options) : true;
    };

    const matchAccessibilityValueIfNeeded = (
      node: ReactTestInstance,
      value?: AccessibilityValueMatcher
    ) => {
      return value != null ? matchAccessibilityValue(node, value) : true;
    };

    const queryAllByRole = (
      instance: ReactTestInstance
    ): ((role: TextMatch, options?: ByRoleOptions) => Array<ReactTestInstance>) =>
      function queryAllByRoleFn(role, options) {
        return findAll(
          instance,
          (node) =>
            // run the cheapest checks first, and early exit to avoid unneeded computations
            typeof node.type === 'string' &&
            isAccessibilityElement(node) &&
            matchStringProp(node.props.accessibilityRole, role) &&
            matchAccessibleStateIfNeeded(node, options) &&
            matchAccessibilityValueIfNeeded(node, options?.value) &&
            matchAccessibleNameIfNeeded(node, options?.name),
          options
        );
      };

    const formatQueryParams = (role: TextMatch, options: ByRoleOptions = {}) => {
      const params = [`role: "${String(role)}"`];

      if (options.name) {
        params.push(`name: "${String(options.name)}"`);
      }

      accessibilityStateKeys.forEach((stateKey) => {
        if (options[stateKey] !== undefined) {
          params.push(`${stateKey} state: ${options[stateKey]}`);
        }
      });

      accessiblityValueKeys.forEach((valueKey) => {
        if (options?.value?.[valueKey] !== undefined) {
          params.push(`${valueKey} value: ${options?.value?.[valueKey]}`);
        }
      });

      return params.join(', ');
    };

    const getMultipleError = (role: TextMatch, options?: ByRoleOptions) =>
      `Found multiple elements with ${formatQueryParams(role, options)}`;

    const getMissingError = (role: TextMatch, options?: ByRoleOptions) =>
      `Unable to find an element with ${formatQueryParams(role, options)}`;

    const { getBy, getAllBy, queryBy, queryAllBy, findBy, findAllBy } = makeQueries(
      queryAllByRole,
      getMissingError,
      getMultipleError
    );

    export type ByRoleQueries = {
      getByRole: GetByQuery<TextMatch, ByRoleOptions>;
      getAllByRole: GetAllByQuery<TextMatch, ByRoleOptions>;
      queryByRole: QueryByQuery<TextMatch, ByRoleOptions>;
      queryAllByRole: QueryAllByQuery<TextMatch, ByRoleOptions>;
      findByRole: FindByQuery<TextMatch, ByRoleOptions>;
      findAllByRole: FindAllByQuery<TextMatch, ByRoleOptions>;
    };

    export const bindByRoleQueries = (
      instance: ReactTestInstance
    ): ByRoleQueries => ({
      getByRole: getBy(instance),
      getAllByRole: getAllBy(instance),
      queryByRole: queryBy(instance),
      queryAllByRole: queryAllBy(instance),
      findByRole: findBy(instance),
      findAllByRole: findAllBy(instance),
    });