diff --git a/package.json b/package.json index ee788acb..fbc97ba9 100644 --- a/package.json +++ b/package.json @@ -48,7 +48,7 @@ "eslint-remote-tester": "eslint-remote-tester --config eslint-remote-tester.config.ts", "semantic-release": "semantic-release", "test": "vitest run", - "test:ci": "vitest run --coverage", + "test:ci": "vitest run --coverage --maxWorkers=2", "test:ui": "vitest --ui", "test:watch": "vitest", "type-check": "tsc --noEmit" diff --git a/src/rules/no-test-id-queries.ts b/src/rules/no-test-id-queries.ts index 88f79e84..556eebc1 100644 --- a/src/rules/no-test-id-queries.ts +++ b/src/rules/no-test-id-queries.ts @@ -7,7 +7,12 @@ const RULE_NAME = 'no-test-id-queries'; export type MessageIds = 'noTestIdQueries'; type Options = []; -const QUERIES_REGEX = `/^(${ALL_QUERIES_VARIANTS.join('|')})TestId$/`; +const QUERY_VARIANTS = [ + ...ALL_QUERIES_VARIANTS, + ...ALL_QUERIES_VARIANTS.map((query) => `${query}Shadow` as const), +]; + +const QUERIES_REGEX = `/^(${QUERY_VARIANTS.join('|')})TestId$/`; export default createTestingLibraryRule({ name: RULE_NAME, diff --git a/src/utils/index.ts b/src/utils/index.ts index 065a15b9..53966db7 100644 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -28,6 +28,7 @@ const LIBRARY_MODULES = [ '@testing-library/vue', '@testing-library/svelte', '@marko/testing-library', + 'shadow-dom-testing-library', ] as const; const USER_EVENT_MODULE = '@testing-library/user-event'; @@ -59,6 +60,15 @@ const ALL_QUERIES_METHODS = [ 'ByDisplayValue', 'ByRole', 'ByTestId', + // queries coming from 'shadow-dom-testing-library' + 'ByShadowLabelText', + 'ByShadowPlaceholderText', + 'ByShadowText', + 'ByShadowAltText', + 'ByShadowTitle', + 'ByShadowDisplayValue', + 'ByShadowRole', + 'ByShadowTestId', ] as const; const SYNC_QUERIES_COMBINATIONS = combineQueries( @@ -157,27 +167,27 @@ const PRESENCE_MATCHERS = [ const ABSENCE_MATCHERS = ['toBeNull', 'toBeFalsy'] as const; export { - combineQueries, - getDocsUrl, - SYNC_QUERIES_VARIANTS, - ASYNC_QUERIES_VARIANTS, - ALL_QUERIES_VARIANTS, + ABSENCE_MATCHERS, + ALL_QUERIES_COMBINATIONS, ALL_QUERIES_METHODS, - SYNC_QUERIES_COMBINATIONS, + ALL_QUERIES_VARIANTS, + ALL_RETURNING_NODES, ASYNC_QUERIES_COMBINATIONS, - ALL_QUERIES_COMBINATIONS, + ASYNC_QUERIES_VARIANTS, ASYNC_UTILS, + combineQueries, DEBUG_UTILS, + EVENT_HANDLER_METHODS, EVENTS_SIMULATORS, - TESTING_FRAMEWORK_SETUP_HOOKS, + getDocsUrl, LIBRARY_MODULES, - PROPERTIES_RETURNING_NODES, METHODS_RETURNING_NODES, - ALL_RETURNING_NODES, + OLD_LIBRARY_MODULES, PRESENCE_MATCHERS, - ABSENCE_MATCHERS, - EVENT_HANDLER_METHODS, + PROPERTIES_RETURNING_NODES, + SYNC_QUERIES_COMBINATIONS, + SYNC_QUERIES_VARIANTS, + TESTING_FRAMEWORK_SETUP_HOOKS, USER_EVENT_METHODS, USER_EVENT_MODULE, - OLD_LIBRARY_MODULES, }; diff --git a/tests/rules/await-async-queries.test.ts b/tests/rules/await-async-queries.test.ts index 932a5ac2..1485c058 100644 --- a/tests/rules/await-async-queries.test.ts +++ b/tests/rules/await-async-queries.test.ts @@ -25,6 +25,7 @@ const SUPPORTED_TESTING_FRAMEWORKS = [ '@testing-library/react', '@testing-library/vue', '@marko/testing-library', + 'shadow-dom-testing-library', ]; interface TestCode { @@ -121,6 +122,11 @@ ruleTester.run(rule.name, rule, { testingFramework: '@marko/testing-library', }), + // async shadow-dom-testing-library screen queries declaration are valid + ...createTestCase((query) => `await screen.${query}('foo')`, { + testingFramework: 'shadow-dom-testing-library', + }), + // async queries not called are valid ...createTestCase((query) => `expect(screen.${query}).toBeDefined()`, { isAsync: false, diff --git a/tests/rules/await-async-utils.test.ts b/tests/rules/await-async-utils.test.ts index 2713e99f..d1633c9c 100644 --- a/tests/rules/await-async-utils.test.ts +++ b/tests/rules/await-async-utils.test.ts @@ -19,6 +19,7 @@ const SUPPORTED_TESTING_FRAMEWORKS = [ '@testing-library/react', '@testing-library/vue', '@marko/testing-library', + // 'shadow-dom-testing-library', does not export waitFor and waitForElementToBeRemoved utils, so not relevant to this rule ]; ruleTester.run(rule.name, rule, { diff --git a/tests/rules/no-container.test.ts b/tests/rules/no-container.test.ts index e4fcec8b..4b6db2d4 100644 --- a/tests/rules/no-container.test.ts +++ b/tests/rules/no-container.test.ts @@ -8,6 +8,7 @@ const SUPPORTED_TESTING_FRAMEWORKS = [ '@testing-library/react', '@testing-library/vue', '@marko/testing-library', + 'shadow-dom-testing-library', ]; ruleTester.run(rule.name, rule, { diff --git a/tests/rules/no-debugging-utils.test.ts b/tests/rules/no-debugging-utils.test.ts index db025f82..067ae14a 100644 --- a/tests/rules/no-debugging-utils.test.ts +++ b/tests/rules/no-debugging-utils.test.ts @@ -8,6 +8,7 @@ const SUPPORTED_TESTING_FRAMEWORKS = [ '@testing-library/react', '@testing-library/vue', '@marko/testing-library', + 'shadow-dom-testing-library', ]; ruleTester.run(rule.name, rule, { diff --git a/tests/rules/no-node-access.test.ts b/tests/rules/no-node-access.test.ts index 2c82251e..fb332957 100644 --- a/tests/rules/no-node-access.test.ts +++ b/tests/rules/no-node-access.test.ts @@ -18,6 +18,7 @@ const SUPPORTED_TESTING_FRAMEWORKS = [ '@testing-library/react', '@testing-library/vue', '@marko/testing-library', + 'shadow-dom-testing-library', ]; ruleTester.run(rule.name, rule, { diff --git a/tests/rules/no-render-in-lifecycle.test.ts b/tests/rules/no-render-in-lifecycle.test.ts index f47dc771..f8bee1ef 100644 --- a/tests/rules/no-render-in-lifecycle.test.ts +++ b/tests/rules/no-render-in-lifecycle.test.ts @@ -9,6 +9,7 @@ const SUPPORTED_TESTING_FRAMEWORKS = [ '@testing-library/react', '@testing-library/vue', '@marko/testing-library', + 'shadow-dom-testing-library', ]; ruleTester.run(rule.name, rule, { diff --git a/tests/rules/no-test-id-queries.test.ts b/tests/rules/no-test-id-queries.test.ts index 5dddc56a..1aa0debd 100644 --- a/tests/rules/no-test-id-queries.test.ts +++ b/tests/rules/no-test-id-queries.test.ts @@ -9,6 +9,7 @@ const SUPPORTED_TESTING_FRAMEWORKS = [ '@testing-library/react', '@testing-library/vue', '@marko/testing-library', + 'shadow-dom-testing-library', ]; const QUERIES = [ @@ -20,6 +21,47 @@ const QUERIES = [ 'findAllByTestId', ]; +const createInvalidTestCase = (framework: string, query: string) => { + return [ + { + code: ` + import { render } from '${framework}'; + + test('test', async () => { + const { ${query} } = render(); + + expect(${query}('my-test-id')).toBeInTheDocument(); + }); + `, + errors: [ + { + messageId: 'noTestIdQueries', + line: 7, + column: 14, + }, + ], + }, + { + code: ` + import { render, screen } from '${framework}'; + + test('test', async () => { + render(); + + expect(screen.${query}('my-test-id')).toBeInTheDocument(); + }); + `, + errors: [ + { + messageId: 'noTestIdQueries', + line: 7, + column: 14, + }, + ], + }, + ] as const; +}; + ruleTester.run(rule.name, rule, { valid: [ ` @@ -43,44 +85,20 @@ ruleTester.run(rule.name, rule, { `, ], - invalid: SUPPORTED_TESTING_FRAMEWORKS.flatMap((framework) => - QUERIES.flatMap((query) => [ - { - code: ` - import { render } from '${framework}'; - - test('test', async () => { - const { ${query} } = render(); - - expect(${query}('my-test-id')).toBeInTheDocument(); - }); - `, - errors: [ - { - messageId: 'noTestIdQueries', - line: 7, - column: 14, - }, - ], - }, - { - code: ` - import { render, screen } from '${framework}'; - - test('test', async () => { - render(); - - expect(screen.${query}('my-test-id')).toBeInTheDocument(); - }); - `, - errors: [ - { - messageId: 'noTestIdQueries', - line: 7, - column: 14, - }, - ], - }, - ]) - ), + invalid: [ + ...SUPPORTED_TESTING_FRAMEWORKS.flatMap((framework) => + QUERIES.flatMap((query) => createInvalidTestCase(framework, query)) + ), + // special cases for shadow-dom-testing-library + ...[ + 'getByShadowTestId', + 'queryByShadowTestId', + 'getAllByShadowTestId', + 'queryAllByShadowTestId', + 'findByShadowTestId', + 'findAllByShadowTestId', + ].flatMap((query) => + createInvalidTestCase('shadow-dom-testing-library', query) + ), + ], }); diff --git a/tests/rules/prefer-find-by.test.ts b/tests/rules/prefer-find-by.test.ts index e1b2b8d2..288eef80 100644 --- a/tests/rules/prefer-find-by.test.ts +++ b/tests/rules/prefer-find-by.test.ts @@ -19,6 +19,10 @@ const SUPPORTED_TESTING_FRAMEWORKS = [ '@testing-library/react', '@testing-library/vue', '@marko/testing-library', + // list of supported frameworks, but not tested + // this test suite has too much test cases already, + // so we are skipping some of them to avoid making it even bigger + // 'shadow-dom-testing-library' ]; function buildFindByMethod(queryMethod: string) { diff --git a/tests/rules/prefer-query-by-disappearance.test.ts b/tests/rules/prefer-query-by-disappearance.test.ts index 4700299f..59a71abd 100644 --- a/tests/rules/prefer-query-by-disappearance.test.ts +++ b/tests/rules/prefer-query-by-disappearance.test.ts @@ -9,6 +9,7 @@ const SUPPORTED_TESTING_FRAMEWORKS = [ '@testing-library/react', '@testing-library/vue', '@marko/testing-library', + 'shadow-dom-testing-library', ]; ruleTester.run(rule.name, rule, { diff --git a/tests/rules/prefer-screen-queries.test.ts b/tests/rules/prefer-screen-queries.test.ts index 6d60153d..84396a9c 100644 --- a/tests/rules/prefer-screen-queries.test.ts +++ b/tests/rules/prefer-screen-queries.test.ts @@ -14,6 +14,7 @@ const SUPPORTED_TESTING_FRAMEWORKS = [ '@testing-library/react', '@testing-library/vue', '@marko/testing-library', + 'shadow-dom-testing-library', ]; const CUSTOM_QUERY_COMBINATIONS = combineQueries(ALL_QUERIES_VARIANTS, [ diff --git a/tests/utils/is-testing-library-module.test.ts b/tests/utils/is-testing-library-module.test.ts index 84edc728..7b2fe8d7 100644 --- a/tests/utils/is-testing-library-module.test.ts +++ b/tests/utils/is-testing-library-module.test.ts @@ -1,4 +1,4 @@ -import { it, expect, describe } from 'vitest'; +import { describe, expect, it } from 'vitest'; import { isCustomTestingLibraryModule, @@ -20,6 +20,7 @@ const LIBRARY_MODULES = [ '@testing-library/vue', '@testing-library/svelte', '@marko/testing-library', + 'shadow-dom-testing-library', ] as const; const USER_EVENT_MODULE = '@testing-library/user-event';