[Security Solution][Resolver] Graph Control Tests and Update Simulator Selectors#74680
Conversation
|
Pinging @elastic/endpoint-app-team (Feature:Resolver) |
|
Pinging @elastic/endpoint-data-visibility-team (Team:Endpoint Data Visibility) |
oatkiller
left a comment
There was a problem hiding this comment.
thanks for the PR. tests look good. put in a few suggestions
There was a problem hiding this comment.
| this.sideEffectSimulator.controls.time = new Date().getTime() + time; | |
| this.sideEffectSimulator.controls.time = time; |
new Date isn't needed here.
There was a problem hiding this comment.
| public readonly sideEffectSimulator: SideEffectSimulator; | |
| private readonly sideEffectSimulator: SideEffectSimulator; |
This could be private
There was a problem hiding this comment.
would you mind changing this data-test-subj to use the same format as the others?
There was a problem hiding this comment.
This test might not be needed. The existence of a wrapper element isn't important to the AC of any feature and its specific to the implementation details. Maybe check that the 4 buttons exist instead?
There was a problem hiding this comment.
Yea, I checked for the existence of all the functional buttons instead
There was a problem hiding this comment.
could you phrase the spec like:
describe('when the user clicks the south panning button', () => {
beforeEach(/* the click code does here*/)
it('should show the origin node lower on the screen', () => {
// the expect here
This way we can easily add more it blocks that have the same setup and we can easily tell which code sets up the condition vs which code asserts stuff
There was a problem hiding this comment.
Yea, this works really well. Thanks for the tip 👍
There was a problem hiding this comment.
.find will return react components as well as DOM nodes. In order to test the DOM only you need to use domNodes: https://github.com/elastic/kibana/blob/master/x-pack/plugins/security_solution/public/resolver/test_utilities/simulator/index.tsx#L246
Would you consider using that instead?
Also, these tests would be more resilient to change if you use .map. As it is, these pass because Resolver shows the controls immediately on the first render. If we (for example) made the controls show up after data had loaded then these tests would likely fail. They might even fail now if you make the mock data access layer resolve the API calls in the next event-loop cycle.
For that reason, would you consider using .map?
There was a problem hiding this comment.
Or consider resolveWrapper (uses map indirectly)
There was a problem hiding this comment.
Yea, I forgot about that concern when I wrote this tbh. Updated and refactored to use .map and domNodes. Thanks!
|
@elasticmachine merge upstream |
|
merge conflict between base and head |
621a823 to
cf33fd5
Compare
| }); | ||
|
|
||
| it('should show the origin node further left on the screen', async () => { | ||
| expect(originNode.getDOMNode()).toHaveStyle({ left: '796.93132px', top: '535.5792px' }); |
There was a problem hiding this comment.
I think this is fine to merge but long term I have some concerns:
This test relies on react to keep the same DOM node for the origin after the user clicks the pan element. If that component got a new DOM node for some reason then originNode would point to an old element that may not be in the DOM any more.
Also this relies on the react code to update the style of the element in the same event loop cycle when the user clicks the panning button.
I think we should use the pattern of calling expect on an async iterable. How about I make those changes after you merge?
There was a problem hiding this comment.
@michaelolo24 Here's a commit with my ideas: 3de7be9
There was a problem hiding this comment.
Thanks, cherry-picked it in and updated the selectors based on our zoom meeting
|
@elasticmachine merge upstream |
db589d3 to
e782753
Compare
|
@elasticmachine merge upstream |
…s before use. use yield-equal-to pattern in graph control tests. change graph control spec language
07a5ce1 to
505a348
Compare
| * @param entityID The entity ID of the proocess node to select in | ||
| * @param selector The selector for the child element of the process node | ||
| */ | ||
| public processNodeChildElements(entityID: string, selector: string): ReactWrapper { |
There was a problem hiding this comment.
@bkimmel, thoughts? I wanted to generalize your method a bit for any other buttons or things that might be added to the process node in the future
There was a problem hiding this comment.
❔ It looks good, generally. Two points:
- The parameter isn't really a
selector(it only feeds the data-test-subj attrib). So I'd say adjust the comment. - To make that even more clear, you could put a "ByDataTestSubj" at the end of the method name (but that's awful long)
There was a problem hiding this comment.
Yea, we can talk about these patterns later today as well. Gonna merge this for now
| await expect( | ||
| simulator.map(() => simulator.testSubject('resolver:node-list:node-link:title').length) | ||
| ).toYieldEqualTo(3); | ||
| await expect( |
There was a problem hiding this comment.
seems this is duplicated
There was a problem hiding this comment.
oh i see. the old version had an expect for 'text' and an expect for 'icons'
| await expect( | ||
| simulator.map(() => ({ | ||
| relatedEventButtons: simulator.processNodeRelatedEventButton(entityIDs.origin).length, | ||
| relatedEventButtons: simulator.processNodeChildElements( |
There was a problem hiding this comment.
Whats the purpose of the special treatment here?
There was a problem hiding this comment.
Same as below. Retain the original intention here. I could move all of the actual selector string into this test or maybe even export the processNodeElementSelector and build the string at this level. Alternatively, I could tie the actual selector with the associated entity-id (see below comment)
| beforeEach(async () => { | ||
| const button = await simulator.resolveWrapper(() => | ||
| simulator.processNodeRelatedEventButton(entityIDs.origin) | ||
| simulator.processNodeChildElements(entityIDs.origin, 'resolver:submenu:button') |
There was a problem hiding this comment.
why not just testSubject here? This couples the test to DOM structure. Is there a reason?
There was a problem hiding this comment.
I was just doing a one to one replacement that generalized this test a bit more. The only way to really not have this tied to the structure of the DOM would be to replace the resolver:submenu:button with a reference to the entity-id, maybe resolver:node-${entityID}:submenu:button. Is that what you're suggesting?
There was a problem hiding this comment.
Oh I see what you mean. I wasn't necessarily suggesting anything but here's my thoughts:
- The user doesn't care about the DOM structure and so if we don't rely on it our tests will be less brittle.
- It would be cool if we are only coupled to data-test attributes. That should make it simple to keep tests working. If we remove a wrapper div, I would hope that no tests break.
Maybe at our next office hours we can discuss those ideas more.
There was a problem hiding this comment.
I think there is some semantic weight to. e.g. the button being a child / ("owned by" in the case of semantics) of the process node. I say keep it as is.
There was a problem hiding this comment.
Or to put it another way: If the relationship between the node and the interactive element it's expected to contain changes in some way, I think it's good that a test picks that up.
💚 Build SucceededBuild metricsasync chunks size
History
To update your PR or re-run it, just comment with: |
|
|
||
| it('should show the origin node as larger on the screen', async () => { | ||
| await expect(originNodeStyle()).toYieldObjectEqualTo({ | ||
| width: '427.7538290724795px', |
There was a problem hiding this comment.
ℹ️ this comes from the yarn snapshot deal?
| className="north-button" | ||
| data-test-subj="north-button" | ||
| data-test-subj="resolver:graph-controls:north-button" | ||
| title="North" |
There was a problem hiding this comment.
🎗️ later to fix these to better things like "Pan the scene up" or something. North is not a good description for what this does.
There was a problem hiding this comment.
Yea, we can talk about this during office hours :)
…r Selectors (elastic#74680) Co-authored-by: oatkiller <robert.austin@elastic.co> # Conflicts: # x-pack/plugins/security_solution/public/resolver/view/clickthrough.test.tsx
* master: (23 commits) Adding API test for custom link transaction example (elastic#74238) [Uptime] Singular alert (elastic#74659) Revert "attempt excluding a codeowners directory" (elastic#75023) [Metrics UI] Remove TSVB dependency from Metrics Explorer APIs (elastic#74804) Remove degraded state from ES status service (elastic#75007) [Reporting/Functional] unskip pagination test (elastic#74973) [Resolver] Stale query string values are removed when resolver's component instance ID changes. (elastic#74979) Add public url to Workplace Search plugin (elastic#74991) [Reporting] Update more Server Types for TaskManager (elastic#74915) [I18n] verify select icu-message options are in english (elastic#74963) Make data.search.aggs available on the server. (elastic#74472) [Security Solution][Resolver] Graph Control Tests and Update Simulator Selectors (elastic#74680) attempt excluding a codeowners directory [ML] DF Analytics: allow failed job to be stopped by force via the UI (elastic#74710) Add kibana-core-ui-designers team (elastic#74970) [Metrics UI] Fix inventory footer misalignment (elastic#74707) Remove legacy optimizer (elastic#73154) Update design-specific GH code-owners (elastic#74877) skip test Reporting paginates content elastic#74922 [Metrics UI] Add Jest tests for alert previews (elastic#74890) ...
Summary
Adds tests for the graph panning and zoom controls
Checklist