Skip to content

Commit 9df4dba

Browse files
dmlemeshkokibanamachinedelanni
authored
Update deprecated scout tags + ESLint rule (elastic#258203)
## Summary This PR updates Scout tags from deprecated ones to the new ones and add ESLint rule to prevent old tags used again (probably only temporarily needed). **Wrong tagging caused tests not to run on Kibana CI** Some `kbn-streamlang-tests` were skipped because they became out-dated while not run on CI elastic#258476 --------- Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com> Co-authored-by: Alex Szabo <alex.szabo@elastic.co>
1 parent 150e289 commit 9df4dba

53 files changed

Lines changed: 3290 additions & 2553 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.eslintrc.js

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2758,12 +2758,13 @@ module.exports = {
27582758
},
27592759
// Custom rules for scout tests
27602760
{
2761-
// Platform & Solutions
2761+
// Platform & Solutions (plugins and packages, excluding Scout framework's own tests)
27622762
files: [
2763-
'src/platform/plugins/**/test/{scout,scout_*}/**/*.ts',
2764-
'x-pack/platform/**/plugins/**/test/{scout,scout_*}/**/*.ts',
2765-
'x-pack/solutions/**/plugins/**/test/{scout,scout_*}/**/*.ts',
2763+
'src/platform/{packages,plugins}/**/test/{scout,scout_*}/**/*.ts',
2764+
'x-pack/platform/{packages,plugins}/**/test/{scout,scout_*}/**/*.ts',
2765+
'x-pack/solutions/**/{packages,plugins}/**/test/{scout,scout_*}/**/*.ts',
27662766
],
2767+
excludedFiles: ['src/platform/packages/shared/kbn-scout/test/**'],
27672768
rules: {
27682769
'@kbn/eslint/scout_no_describe_configure': 'error',
27692770
'@kbn/eslint/scout_max_one_describe': 'error',
@@ -2772,6 +2773,7 @@ module.exports = {
27722773
'@kbn/eslint/scout_no_es_archiver_in_parallel_tests': 'error',
27732774
'@kbn/eslint/scout_no_cross_boundary_imports': 'error',
27742775
'@kbn/eslint/scout_expect_import': 'error',
2776+
'@kbn/eslint/scout_no_deprecated_tags': 'error',
27752777
'@kbn/eslint/scout_no_locators': ['error', { restricted: ['globalLoadingIndicator'] }],
27762778
'@kbn/eslint/require_include_in_check_a11y': 'warn',
27772779
},

packages/kbn-eslint-plugin-eslint/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ module.exports = {
3030
scout_require_global_setup_hook_in_parallel_tests: require('./rules/scout_require_global_setup_hook_in_parallel_tests'),
3131
scout_no_es_archiver_in_parallel_tests: require('./rules/scout_no_es_archiver_in_parallel_tests'),
3232
scout_expect_import: require('./rules/scout_expect_import'),
33+
scout_no_deprecated_tags: require('./rules/scout_no_deprecated_tags'),
3334
scout_no_cross_boundary_imports: require('./rules/scout_no_cross_boundary_imports'),
3435
scout_no_locators: require('./rules/scout_no_locators'),
3536
require_kbn_fs: require('./rules/require_kbn_fs'),
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
/*
2+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3+
* or more contributor license agreements. Licensed under the "Elastic License
4+
* 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side
5+
* Public License v 1"; you may not use this file except in compliance with, at
6+
* your election, the "Elastic License 2.0", the "GNU Affero General Public
7+
* License v3.0 only", or the "Server Side Public License, v 1".
8+
*/
9+
10+
/** @typedef {import("eslint").Rule.RuleModule} Rule */
11+
/** @typedef {import("@typescript-eslint/typescript-estree").TSESTree.CallExpression} CallExpression */
12+
13+
const DEPRECATED_TAGS = ['@ess', '@svlOblt', '@svlSecurity', '@svlSearch'];
14+
15+
const ERROR_MSG =
16+
'Use the `tags` helper from @kbn/scout (e.g. `tags.stateful.classic`, `tags.serverless.observability.complete`) instead of deprecated string tags like `@ess` or `@svlOblt`.';
17+
18+
/**
19+
* Checks if a node represents a method describe() call (e.g., test.describe, apiTest.describe)
20+
* @param {CallExpression} node
21+
* @returns {boolean}
22+
*/
23+
const isDescribeCall = (node) => {
24+
return (
25+
node.callee.type === 'MemberExpression' &&
26+
node.callee.property.type === 'Identifier' &&
27+
node.callee.property.name === 'describe'
28+
);
29+
};
30+
31+
/**
32+
* Extracts string literals from an AST node (handles array elements and spread).
33+
* @param {import('@typescript-eslint/typescript-estree').TSESTree.Node} node
34+
* @returns {string[]}
35+
*/
36+
const getStringLiteralsFromNode = (node) => {
37+
if (!node) return [];
38+
39+
if (node.type === 'ArrayExpression') {
40+
return node.elements.flatMap((el) => getStringLiteralsFromNode(el));
41+
}
42+
43+
if (node.type === 'Literal' && typeof node.value === 'string') {
44+
return [node.value];
45+
}
46+
47+
return [];
48+
};
49+
50+
/** @type {Rule} */
51+
module.exports = {
52+
meta: {
53+
type: 'problem',
54+
docs: {
55+
description:
56+
'Disallow deprecated Scout test tags (@ess, @svlOblt, @svlSecurity, @svlSearch). Use the `tags` helper from @kbn/scout instead.',
57+
category: 'Best Practices',
58+
},
59+
fixable: null,
60+
schema: [],
61+
messages: {
62+
deprecatedTag: ERROR_MSG,
63+
},
64+
},
65+
66+
create(context) {
67+
return {
68+
CallExpression(node) {
69+
if (!isDescribeCall(node) || node.arguments.length < 2) {
70+
return;
71+
}
72+
73+
const optionsArg = node.arguments[1];
74+
if (optionsArg.type !== 'ObjectExpression') {
75+
return;
76+
}
77+
78+
const tagProperty = optionsArg.properties.find(
79+
(prop) =>
80+
prop.type === 'Property' && prop.key.type === 'Identifier' && prop.key.name === 'tag'
81+
);
82+
83+
if (!tagProperty || tagProperty.type !== 'Property') {
84+
return;
85+
}
86+
87+
const tagValue = tagProperty.value;
88+
const stringLiterals = getStringLiteralsFromNode(tagValue);
89+
90+
for (const literal of stringLiterals) {
91+
if (DEPRECATED_TAGS.includes(literal)) {
92+
context.report({
93+
node: tagProperty,
94+
messageId: 'deprecatedTag',
95+
});
96+
return;
97+
}
98+
}
99+
},
100+
};
101+
},
102+
};
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
/*
2+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3+
* or more contributor license agreements. Licensed under the "Elastic License
4+
* 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side
5+
* Public License v 1"; you may not use this file except in compliance with, at
6+
* your election, the "Elastic License 2.0", the "GNU Affero General Public
7+
* License v3.0 only", or the "Server Side Public License, v 1".
8+
*/
9+
10+
const { RuleTester } = require('eslint');
11+
const rule = require('./scout_no_deprecated_tags');
12+
const dedent = require('dedent');
13+
14+
const ruleTester = new RuleTester({
15+
parser: require.resolve('@typescript-eslint/parser'),
16+
parserOptions: {
17+
sourceType: 'module',
18+
ecmaVersion: 2018,
19+
ecmaFeatures: {
20+
jsx: true,
21+
},
22+
},
23+
});
24+
25+
ruleTester.run('@kbn/eslint/scout_no_deprecated_tags', rule, {
26+
valid: [
27+
{
28+
code: dedent`
29+
test.describe('my test suite', () => {
30+
test('should work', () => {
31+
expect(true).toBe(true);
32+
});
33+
});
34+
`,
35+
},
36+
{
37+
code: dedent`
38+
import { tags } from '@kbn/scout';
39+
test.describe('my test suite', { tag: [...tags.stateful.classic, ...tags.serverless.observability.complete] }, () => {
40+
test('should work', () => {
41+
expect(true).toBe(true);
42+
});
43+
});
44+
`,
45+
},
46+
{
47+
code: dedent`
48+
import { tags } from '@kbn/scout-oblt';
49+
apiTest.describe('API test', { tag: [...tags.stateful.classic] }, () => {
50+
apiTest('should work', () => {});
51+
});
52+
`,
53+
},
54+
{
55+
code: dedent`
56+
spaceTest.describe('space test', { tag: tags.stateful.classic }, () => {
57+
spaceTest('should work', () => {});
58+
});
59+
`,
60+
},
61+
{
62+
code: dedent`
63+
test.describe('my test suite', { tag: ['@perf'] }, () => {
64+
test('should work', () => {});
65+
});
66+
`,
67+
},
68+
],
69+
70+
invalid: [
71+
{
72+
code: dedent`
73+
test.describe('my test suite', { tag: ['@ess'] }, () => {
74+
test('should work', () => {});
75+
});
76+
`,
77+
errors: [{ messageId: 'deprecatedTag' }],
78+
},
79+
{
80+
code: dedent`
81+
test.describe('my test suite', { tag: ['@ess', '@svlOblt'] }, () => {
82+
test('should work', () => {});
83+
});
84+
`,
85+
errors: [{ messageId: 'deprecatedTag' }],
86+
},
87+
{
88+
code: dedent`
89+
apiTest.describe('API test', { tag: ['@svlSecurity', '@svlSearch'] }, () => {
90+
apiTest('should work', () => {});
91+
});
92+
`,
93+
errors: [{ messageId: 'deprecatedTag' }],
94+
},
95+
{
96+
code: dedent`
97+
spaceTest.describe('space test', { tag: ['@ess', '@svlOblt', '@svlSecurity'] }, () => {
98+
spaceTest('should work', () => {});
99+
});
100+
`,
101+
errors: [{ messageId: 'deprecatedTag' }],
102+
},
103+
],
104+
});

packages/kbn-eslint-plugin-eslint/rules/scout_test_file_naming.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ module.exports = {
150150
// File is in /test/scout but not in the correct subdirectory structure
151151
// Only report if it looks like a test file (has test/spec in name or is .ts)
152152
const basename = path.basename(filename, '.ts');
153-
if (basename.includes('test') || basename.includes('spec') || hasSpecExtension(filename)) {
153+
if (basename.includes('spec') || hasSpecExtension(filename)) {
154154
return {
155155
Program(node) {
156156
context.report({

packages/kbn-eslint-plugin-eslint/rules/scout_test_file_naming.test.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,12 @@ ruleTester.run('@kbn/eslint/scout_test_file_naming', rule, {
7474
code: '',
7575
filename: 'x-pack/solutions/observability/plugins/my_plugin/test/scout/common/constants.ts',
7676
},
77+
// Valid: Scout fixture file with 'test' in the name (not a test file)
78+
{
79+
code: '',
80+
filename:
81+
'x-pack/platform/packages/shared/kbn-streamlang-tests/test/scout/api/fixtures/test_bed_fixture.ts',
82+
},
7783
// Valid: Scout config file
7884
{
7985
code: '',

0 commit comments

Comments
 (0)