-
Notifications
You must be signed in to change notification settings - Fork 8.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Security Solution] JSON diffs test coverage #176770
[Security Solution] JSON diffs test coverage #176770
Conversation
20a4463
to
0ae76c5
Compare
Pinging @elastic/security-detections-response (Team:Detections and Resp) |
Pinging @elastic/security-solution (Team: SecuritySolution) |
Pinging @elastic/security-detection-rule-management (Team:Detection Rule Management) |
...s/cypress/e2e/detection_response/rule_management/prebuilt_rules/prebuilt_rules_preview.cy.ts
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@nikitaindik thank you for covering JSON diffs component by test from the test plan 👍
I haven't found a Properties should be sorted alphabetically
scenario. Is it missed or it's a part of some other scenario?
My main concern is unit tests overcomplicated by matchInOrder
. If I'm not missing anything it should be possible to assert Diff
's component textContent
and avoid hardcoded colors in the test or even completely omit it.
...public/detection_engine/rule_management/components/rule_details/json_diff/json_diff.test.tsx
Outdated
Show resolved
Hide resolved
* otherwise `false`. | ||
* Utilizes Lodash's `escapeRegExp` to handle special characters in the `strings` array. | ||
*/ | ||
const matchInOrder = |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Have you considered using Diff
component's textContent
instead?
I'm afraid this helper will make the test logic harder but it still doesn't protect again sensitivity to changes. Looking at the Diff's textContent
below it's clear we should be able to implement many testing scenarios.
{{ "author": [ "author": [ "Alice", "Alice",- "Bob", "Charlie" "Charlie" ], ], "description": "some desc", "description": "some desc",Expand 15 unchanged lines ], ], "interval": "5m", "interval": "5m", "language": "kuery", "language": "kuery",+ "license": "GPLv3", "max_signals": 100, "max_signals": 100, "name": "Test rule", "name": "Test rule", "note": "", "note": "",Expand 19 unchanged lines ], ], "to": "now", "to": "now", "type": "query", "type": "query",- "version": 1+ "version": 2}}
For example normalizing it by removing extra spaces will make it simple to implement a test which verifies there is - "version": 1+ "version": 2
. Of course it can break as well
We also shouldn't retest react-diff-view
. It's enough to make sure the content is conceptually the same but how may components/tags and etc used isn't so important and will make the tests fragile.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Refactored this part in a follow-up commit
.should('not.exist'); | ||
}); | ||
|
||
it('Dynamic properties should not be included in preview', () => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This test only checks for execution_summary
. What about the other fields specified in the test plan like revision
and updated_at
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These are in the React Testing Library test called "Technical properties should not be included in preview". I separated "dynamic" from "technical" because I wanted to test the "dynamic" ones in a more realistic way with a Cypress E2E test.
}; | ||
|
||
render(<RuleDiffTab oldRule={oldRule} newRule={newRule} />); | ||
['revision', 'created_at', 'created_by', 'updated_at', 'updated_by'].forEach((property) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it.each()
is intended to pass different test data or params. It allows to display modify the test name to something like should not include "revision" in preview
to make it clear what fields are checked.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Addressed in a follow-up commit
...s/cypress/e2e/detection_response/rule_management/prebuilt_rules/prebuilt_rules_preview.cy.ts
Outdated
Show resolved
Hide resolved
cy.get('@currentRuleValue').then(($currentRuleValue) => { | ||
const currentRuleLeftOffset = $currentRuleValue.offset()?.left || 0; | ||
cy.get('@updateVersionValue').then(($updateVersionValue) => { | ||
const updateVersionLeftOffset = $updateVersionValue.offset()?.left || 0; | ||
expect(currentRuleLeftOffset).to.be.lessThan(updateVersionLeftOffset); | ||
}); | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same here, but for the Diff
library. I think this is a level of detail greater than we should have for e2e tests as smoke tests.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed. Removed.
const removedBackgroundColor = 'rgb(255, 235, 233)'; | ||
const removedAccentColor = 'rgba(255, 129, 130, 0.4)'; | ||
const addedBackgroundColor = 'rgb(230, 255, 236)'; | ||
const addedAccentColor = 'rgb(171, 242, 188)'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it possible to make these importable from their implementation file? Do these constants already exist?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Addressed in a follow-up commit
...public/detection_engine/rule_management/components/rule_details/json_diff/json_diff.test.tsx
Outdated
Show resolved
Hide resolved
* | ||
* The Matcher function itself has the following signature: | ||
* @param {string} content - The content string to be checked. Not directly used in the current implementation | ||
* but is required for the matcher's signature. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If I understand correctly, content
needs to be passed here cause we need to return a function that is passed either to getByText
and queryAllByText
, and both those function require that signature.
Took me a bit to understand, maybe add this additional detail in this comment?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're right, it's too complicated. So I refactored a bit and removed this helper altogether.
...public/detection_engine/rule_management/components/rule_details/json_diff/json_diff.test.tsx
Show resolved
Hide resolved
...public/detection_engine/rule_management/components/rule_details/json_diff/json_diff.test.tsx
Outdated
Show resolved
Hide resolved
...public/detection_engine/rule_management/components/rule_details/json_diff/json_diff.test.tsx
Outdated
Show resolved
Hide resolved
0ae76c5
to
2f54479
Compare
/* | ||
Helper function to find an element with a particular text content. | ||
React Testing Library's doesn't provide an easy way to search by text if text is split into multiple DOM elements. | ||
*/ | ||
const getChildByTextContent = (parent: Element, textContent: string): HTMLElement => { | ||
return Array.from(parent.querySelectorAll('*')).find( | ||
(childElement) => childElement.textContent === textContent | ||
) as HTMLElement; | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Any reason this function and findDiffLineContaining
cannot be extracted out to the top as helper functions, outside of the tests? This one is redefined on each it
clause.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I thought it would be a bit easier to read if these functions are local to where they are used. But I understand that it's a matter of preference and the benefit is small, so I have no trouble moving these to the top level.
|
||
const removedLineAfter = getChildByTextContent(removedLine, ''); | ||
expect( | ||
removedLineAfter ? window.getComputedStyle(removedLineAfter).backgroundColor : null |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure I understand why these ternary operators are needed here. How can null
ever be ''
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch! Looks like I forgot to change this line after refactoring.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Approving in general, left a couple questions and nits.
Thanks for covering this feature with tests 👍 ✅
2f54479
to
a37e992
Compare
…upgrade" with an RTL test
…ed" with an RTL test
…as modified" with an RTL test
a37e992
to
3f6bac9
Compare
💛 Build succeeded, but was flaky
Failed CI StepsTest Failures
Metrics [docs]Async chunks
History
To update your PR or re-run it, just comment with: cc @nikitaindik |
**Resolves: elastic#166163 Flaky test runner runs: [1](https://buildkite.com/elastic/kibana-flaky-test-suite-runner/builds/5189), [2](https://buildkite.com/elastic/kibana-flaky-test-suite-runner/builds/5190), [3](https://buildkite.com/elastic/kibana-flaky-test-suite-runner/builds/5191), [4](https://buildkite.com/elastic/kibana-flaky-test-suite-runner/builds/5192) ## Summary This PR adds tests in accordance with the [test plan](elastic#175958) that was merged earlier. (cherry picked from commit cd374d2)
💚 All backports created successfully
Note: Successful backport PRs will be merged automatically after passing CI. Questions ?Please refer to the Backport tool documentation |
# Backport This will backport the following commits from `main` to `8.13`: - [[Security Solution] JSON diffs test coverage (#176770)](#176770) <!--- Backport version: 9.4.3 --> ### Questions ? Please refer to the [Backport tool documentation](https://github.com/sqren/backport) <!--BACKPORT [{"author":{"name":"Nikita Indik","email":"[email protected]"},"sourceCommit":{"committedDate":"2024-02-19T15:12:51Z","message":"[Security Solution] JSON diffs test coverage (#176770)\n\n**Resolves: https://github.com/elastic/kibana/issues/166163**\r\n\r\nFlaky test runner runs:\r\n[1](https://buildkite.com/elastic/kibana-flaky-test-suite-runner/builds/5189),\r\n[2](https://buildkite.com/elastic/kibana-flaky-test-suite-runner/builds/5190),\r\n[3](https://buildkite.com/elastic/kibana-flaky-test-suite-runner/builds/5191),\r\n[4](https://buildkite.com/elastic/kibana-flaky-test-suite-runner/builds/5192)\r\n\r\n## Summary\r\nThis PR adds tests in accordance with the [test\r\nplan](#175958) that was merged\r\nearlier.","sha":"cd374d23368de182a96df0948192a9bca7bdc4aa","branchLabelMapping":{"^v8.14.0$":"main","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["release_note:skip","test-coverage","Team:Detections and Resp","Team: SecuritySolution","Team:Detection Rule Management","Feature:Prebuilt Detection Rules","v8.13.0","v8.14.0"],"title":"[Security Solution] JSON diffs test coverage","number":176770,"url":"https://github.com/elastic/kibana/pull/176770","mergeCommit":{"message":"[Security Solution] JSON diffs test coverage (#176770)\n\n**Resolves: https://github.com/elastic/kibana/issues/166163**\r\n\r\nFlaky test runner runs:\r\n[1](https://buildkite.com/elastic/kibana-flaky-test-suite-runner/builds/5189),\r\n[2](https://buildkite.com/elastic/kibana-flaky-test-suite-runner/builds/5190),\r\n[3](https://buildkite.com/elastic/kibana-flaky-test-suite-runner/builds/5191),\r\n[4](https://buildkite.com/elastic/kibana-flaky-test-suite-runner/builds/5192)\r\n\r\n## Summary\r\nThis PR adds tests in accordance with the [test\r\nplan](#175958) that was merged\r\nearlier.","sha":"cd374d23368de182a96df0948192a9bca7bdc4aa"}},"sourceBranch":"main","suggestedTargetBranches":["8.13"],"targetPullRequestStates":[{"branch":"8.13","label":"v8.13.0","branchLabelMappingKey":"^v(\\d+).(\\d+).\\d+$","isSourceBranch":false,"state":"NOT_CREATED"},{"branch":"main","label":"v8.14.0","branchLabelMappingKey":"^v8.14.0$","isSourceBranch":true,"state":"MERGED","url":"https://github.com/elastic/kibana/pull/176770","number":176770,"mergeCommit":{"message":"[Security Solution] JSON diffs test coverage (#176770)\n\n**Resolves: https://github.com/elastic/kibana/issues/166163**\r\n\r\nFlaky test runner runs:\r\n[1](https://buildkite.com/elastic/kibana-flaky-test-suite-runner/builds/5189),\r\n[2](https://buildkite.com/elastic/kibana-flaky-test-suite-runner/builds/5190),\r\n[3](https://buildkite.com/elastic/kibana-flaky-test-suite-runner/builds/5191),\r\n[4](https://buildkite.com/elastic/kibana-flaky-test-suite-runner/builds/5192)\r\n\r\n## Summary\r\nThis PR adds tests in accordance with the [test\r\nplan](#175958) that was merged\r\nearlier.","sha":"cd374d23368de182a96df0948192a9bca7bdc4aa"}}]}] BACKPORT--> Co-authored-by: Nikita Indik <[email protected]>
**Resolves: elastic#166163 Flaky test runner runs: [1](https://buildkite.com/elastic/kibana-flaky-test-suite-runner/builds/5189), [2](https://buildkite.com/elastic/kibana-flaky-test-suite-runner/builds/5190), [3](https://buildkite.com/elastic/kibana-flaky-test-suite-runner/builds/5191), [4](https://buildkite.com/elastic/kibana-flaky-test-suite-runner/builds/5192) ## Summary This PR adds tests in accordance with the [test plan](elastic#175958) that was merged earlier.
Resolves: #166163
Flaky test runner runs: 1, 2, 3, 4
Summary
This PR adds tests in accordance with the test plan that was merged earlier.