From 90052334c1ffa6f92ee4af24418f95b3b2652179 Mon Sep 17 00:00:00 2001 From: Spencer Miskoviak Date: Sun, 9 Aug 2020 16:50:01 -0700 Subject: [PATCH] feat: add support for multiple test id attributes --- docs/rules/consistent-data-testid.md | 19 +++++-- lib/rules/consistent-data-testid.ts | 32 +++++++++-- .../lib/rules/consistent-data-testid.test.ts | 57 +++++++++++++++++++ 3 files changed, 99 insertions(+), 9 deletions(-) diff --git a/docs/rules/consistent-data-testid.md b/docs/rules/consistent-data-testid.md index b39a297d..de58f52b 100644 --- a/docs/rules/consistent-data-testid.md +++ b/docs/rules/consistent-data-testid.md @@ -24,10 +24,10 @@ const baz = props =>
...
; ## Options -| Option | Required | Default | Details | Example | -| ----------------- | -------- | ------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------- | -| `testIdPattern` | Yes | None | A regex used to validate the format of the `data-testid` value. `{fileName}` can optionally be used as a placeholder and will be substituted with the name of the file OR the name of the files parent directory in the case when the file name is `index.js` | `^{fileName}(\_\_([A-Z]+[a-z]_?)+)_\$` | -| `testIdAttribute` | No | `data-testid` | A string used to specify the attribute used for querying by ID. This is only required if data-testid has been explicitly overridden in the [RTL configuration](https://testing-library.com/docs/dom-testing-library/api-queries#overriding-data-testid) | `data-my-test-attribute` | +| Option | Required | Default | Details | Example | +| ----------------- | -------- | ------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------- | +| `testIdPattern` | Yes | None | A regex used to validate the format of the `data-testid` value. `{fileName}` can optionally be used as a placeholder and will be substituted with the name of the file OR the name of the files parent directory in the case when the file name is `index.js` | `^{fileName}(\_\_([A-Z]+[a-z]_?)+)_\$` | +| `testIdAttribute` | No | `data-testid` | A string (or array of strings) used to specify the attribute used for querying by ID. This is only required if data-testid has been explicitly overridden in the [RTL configuration](https://testing-library.com/docs/dom-testing-library/api-queries#overriding-data-testid) | `data-my-test-attribute`, `["data-testid", "testId"]` | ## Example @@ -41,3 +41,14 @@ const baz = props =>
...
; ] } ``` + +```json +{ + "testing-library/consistent-data-testid": [ + 2, + { + "testIdAttribute": ["data-testid", "testId"] + } + ] +} +``` diff --git a/lib/rules/consistent-data-testid.ts b/lib/rules/consistent-data-testid.ts index a408a68f..eb872b76 100644 --- a/lib/rules/consistent-data-testid.ts +++ b/lib/rules/consistent-data-testid.ts @@ -7,7 +7,7 @@ export type MessageIds = 'invalidTestId'; type Options = [ { testIdPattern: string; - testIdAttribute: string; + testIdAttribute?: string | string[]; } ]; @@ -37,8 +37,18 @@ export default ESLintUtils.RuleCreator(getDocsUrl)({ type: 'string', }, testIdAttribute: { - type: 'string', default: 'data-testid', + oneOf: [ + { + type: 'string', + }, + { + type: 'array', + items: { + type: 'string', + }, + }, + ], }, }, }, @@ -70,9 +80,21 @@ export default ESLintUtils.RuleCreator(getDocsUrl)({ return new RegExp(testIdPattern.replace(FILENAME_PLACEHOLDER, fileName)); } + function isTestIdAttribute(name: string) { + if (typeof attr === 'string') { + return attr === name; + } else { + return attr.includes(name); + } + } + return { - [`JSXIdentifier[name=${attr}]`]: (node: TSESTree.JSXIdentifier) => { - if (!isJSXAttribute(node.parent) || !isLiteral(node.parent.value)) { + [`JSXIdentifier`]: (node: TSESTree.JSXIdentifier) => { + if ( + !isJSXAttribute(node.parent) || + !isLiteral(node.parent.value) || + !isTestIdAttribute(node.name) + ) { return; } @@ -85,7 +107,7 @@ export default ESLintUtils.RuleCreator(getDocsUrl)({ node, messageId: 'invalidTestId', data: { - attr, + attr: node.name, value, regex, }, diff --git a/tests/lib/rules/consistent-data-testid.test.ts b/tests/lib/rules/consistent-data-testid.test.ts index 4eb6a689..0e662969 100644 --- a/tests/lib/rules/consistent-data-testid.test.ts +++ b/tests/lib/rules/consistent-data-testid.test.ts @@ -136,6 +136,25 @@ ruleTester.run(RULE_NAME, rule, { code: ` import React from 'react'; + const TestComponent = props => { + return ( +
+ Hello +
+ ) + }; + `, + options: [ + { + testIdPattern: '^right(.*)$', + testIdAttribute: ['custom-attr', 'another-custom-attr'], + }, + ], + }, + { + code: ` + import React from 'react'; + const TestComponent = props => { return (
@@ -256,6 +275,44 @@ ruleTester.run(RULE_NAME, rule, { code: ` import React from 'react'; + const TestComponent = props => { + return ( +
+ Hello +
+ ) + }; + `, + options: [ + { + testIdPattern: '^right$', + testIdAttribute: ['custom-attr', 'another-custom-attr'], + }, + ], + filename: '/my/cool/__tests__/Parent/index.js', + errors: [ + { + messageId: 'invalidTestId', + data: { + attr: 'custom-attr', + value: 'wrong', + regex: '/^right$/', + }, + }, + { + messageId: 'invalidTestId', + data: { + attr: 'another-custom-attr', + value: 'wrong', + regex: '/^right$/', + }, + }, + ], + }, + { + code: ` + import React from 'react'; + const TestComponent = props => { return (