diff --git a/lint/plugin.js b/lint/plugin.js index 4db8b45c1..5fbea44aa 100644 --- a/lint/plugin.js +++ b/lint/plugin.js @@ -203,6 +203,42 @@ const noVueStyleBlocks = { const TEST_ID_FORMAT = /^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$/ +const noRawTestIdStringProps = { + meta: { + docs: { + description: 'Disallow raw testId string props — use TestIdProps or RequiredTestIdProps' + } + }, + create(context) { + const file = normalizedFilename(context) + if (file.endsWith('/packages/vue/src/testing/test-id.ts')) return {} + + function isTestIdKey(key) { + return key?.type === 'Identifier' && key.name === 'testId' + } + + function isStringType(member) { + return member.typeAnnotation?.typeAnnotation?.type === 'TSStringKeyword' + } + + function report(node, optional) { + context.report({ + node, + message: optional + ? 'Use TestIdProps instead of declaring testId?: string directly.' + : 'Use RequiredTestIdProps or TestId instead of declaring testId: string directly.' + }) + } + + return { + TSPropertySignature(node) { + if (!isTestIdKey(node.key) || !isStringType(node)) return + report(node, !!node.optional) + } + } + } +} + const noInvalidTestIdAttributes = { meta: { docs: { @@ -1325,6 +1361,7 @@ const plugin = { 'no-inline-named-types': noInlineNamedTypes, 'no-structuredclone-scene-arrays': noStructuredCloneSceneArrays, 'no-vue-style-blocks': noVueStyleBlocks, + 'no-raw-test-id-string-props': noRawTestIdStringProps, 'no-invalid-test-id-attributes': noInvalidTestIdAttributes, 'no-document-query-selector-in-vue': noDocumentQuerySelectorInVue, 'no-direct-selection-tool-state-mutation': noDirectSelectionToolStateMutation, diff --git a/oxlint.json b/oxlint.json index ea5c29985..38220e499 100644 --- a/oxlint.json +++ b/oxlint.json @@ -112,6 +112,7 @@ ], "open-pencil/no-structuredclone-scene-arrays": "error", "open-pencil/no-vue-style-blocks": "error", + "open-pencil/no-raw-test-id-string-props": "error", "open-pencil/no-invalid-test-id-attributes": "error", "open-pencil/no-document-query-selector-in-vue": "error", "open-pencil/no-direct-selection-tool-state-mutation": "error",