@@ -10,15 +10,16 @@ import { METRICS } from '../support/constants';
10
10
const indexName = 'sample_index' ;
11
11
12
12
/**
13
- Helper function to clean up the environment:
14
- - Deletes the test index.
15
- - Disables the top queries features.
13
+ Helper function to clean up the environment:
14
+ - Deletes the test index.
15
+ - Disables the top queries features.
16
16
*/
17
17
const clearAll = ( ) => {
18
18
cy . deleteIndexByName ( indexName ) ;
19
19
cy . disableTopQueries ( METRICS . LATENCY ) ;
20
20
cy . disableTopQueries ( METRICS . CPU ) ;
21
21
cy . disableTopQueries ( METRICS . MEMORY ) ;
22
+ cy . disableGrouping ( ) ;
22
23
} ;
23
24
24
25
describe ( 'Query Insights Dashboard' , ( ) => {
@@ -81,22 +82,6 @@ describe('Query Insights Dashboard', () => {
81
82
} ) ;
82
83
} ) ;
83
84
84
- /**
85
- * Validate pagination works as expected
86
- */
87
- it ( 'should paginate the query table' , ( ) => {
88
- for ( let i = 0 ; i < 20 ; i ++ ) {
89
- cy . searchOnIndex ( indexName ) ;
90
- }
91
- // waiting for the query insights queue to drain
92
- cy . wait ( 10000 ) ;
93
- cy . reload ( ) ;
94
- cy . get ( '.euiPagination' ) . should ( 'be.visible' ) ;
95
- cy . get ( '.euiPagination__item' ) . contains ( '2' ) . click ( ) ;
96
- // Verify rows on the second page
97
- cy . get ( '.euiTableRow' ) . should ( 'have.length.greaterThan' , 0 ) ;
98
- } ) ;
99
-
100
85
it ( 'should switch between tabs' , ( ) => {
101
86
// Click Configuration tab
102
87
cy . getElementByText ( '.euiTab' , 'Configuration' ) . click ( { force : true } ) ;
@@ -119,16 +104,151 @@ describe('Query Insights Dashboard', () => {
119
104
cy . get ( '.euiFieldSearch' ) . type ( 'random_string' ) ;
120
105
cy . get ( '.euiTableRow' ) . should ( 'have.length.greaterThan' , 0 ) ;
121
106
cy . get ( '.euiFieldSearch' ) . clear ( ) ;
122
- cy . get ( '.euiTableRow' ) . should ( 'have.length.greaterThan' , 0 ) ; // Validate reset
107
+ cy . get ( '.euiTableRow' ) . should ( 'have.length.greaterThan' , 0 ) ;
123
108
} ) ;
124
109
125
110
it ( 'should display a message when no top queries are found' , ( ) => {
126
- clearAll ( ) ; // disable top n queries
127
- // waiting for the query insights queue to drain
111
+ clearAll ( ) ;
128
112
cy . wait ( 10000 ) ;
129
113
cy . reload ( ) ;
130
114
cy . contains ( 'No items found' ) ;
131
115
} ) ;
132
116
117
+ it ( 'should paginate the query table' , ( ) => {
118
+ for ( let i = 0 ; i < 20 ; i ++ ) {
119
+ cy . searchOnIndex ( indexName ) ;
120
+ }
121
+ cy . wait ( 10000 ) ;
122
+ cy . reload ( ) ;
123
+ cy . get ( '.euiPagination' ) . should ( 'be.visible' ) ;
124
+ cy . get ( '.euiPagination__item' ) . contains ( '2' ) . click ( ) ;
125
+ // Verify rows on the second page
126
+ cy . get ( '.euiTableRow' ) . should ( 'have.length.greaterThan' , 0 ) ;
127
+ } ) ;
133
128
after ( ( ) => clearAll ( ) ) ;
134
129
} ) ;
130
+
131
+ describe ( 'Query Insights Dashboard - Dynamic Columns with Stubbed Top Queries' , ( ) => {
132
+ beforeEach ( ( ) => {
133
+ cy . fixture ( 'stub_top_queries.json' ) . then ( ( stubResponse ) => {
134
+ cy . intercept ( 'GET' , '**/api/top_queries/*' , {
135
+ statusCode : 200 ,
136
+ body : stubResponse ,
137
+ } ) . as ( 'getTopQueries' ) ;
138
+ } ) ;
139
+
140
+ cy . navigateToOverview ( ) ;
141
+ cy . wait ( 1000 ) ;
142
+ cy . wait ( '@getTopQueries' ) ;
143
+ } ) ;
144
+
145
+ const testMetricSorting = ( columnLabel , columnIndex ) => {
146
+ cy . get ( '.euiTableHeaderCell' ) . contains ( columnLabel ) . click ( ) ;
147
+ cy . wait ( 1000 ) ;
148
+
149
+ cy . get ( '.euiTableRow' ) . then ( ( $rows ) => {
150
+ const values = [ ...$rows ] . map ( ( $row ) => {
151
+ const rawText = Cypress . $ ( $row ) . find ( 'td' ) . eq ( columnIndex ) . text ( ) . trim ( ) ;
152
+ return parseFloat ( rawText . replace ( / [ ^ \d . ] / g, '' ) ) ; // remove 'ms'/'B'
153
+ } ) ;
154
+ const sortedAsc = [ ...values ] . sort ( ( a , b ) => a - b ) ;
155
+ expect ( values ) . to . deep . equal ( sortedAsc ) ;
156
+ } ) ;
157
+
158
+ cy . get ( '.euiTableHeaderCell' ) . contains ( columnLabel ) . click ( ) ;
159
+ cy . wait ( 1000 ) ;
160
+
161
+ cy . get ( '.euiTableRow' ) . then ( ( $rows ) => {
162
+ const values = [ ...$rows ] . map ( ( $row ) => {
163
+ const rawText = Cypress . $ ( $row ) . find ( 'td' ) . eq ( columnIndex ) . text ( ) . trim ( ) ;
164
+ return parseFloat ( rawText . replace ( / [ ^ \d . ] / g, '' ) ) ;
165
+ } ) ;
166
+ const sortedDesc = [ ...values ] . sort ( ( a , b ) => b - a ) ;
167
+ expect ( values ) . to . deep . equal ( sortedDesc ) ;
168
+ } ) ;
169
+ } ;
170
+
171
+ it ( 'should render only individual query-related headers when NONE filter is applied' , ( ) => {
172
+ cy . wait ( 1000 ) ;
173
+ cy . get ( '.euiFilterButton' ) . contains ( 'Type' ) . click ( ) ;
174
+ cy . get ( '.euiFilterSelectItem' ) . contains ( 'query' ) . click ( ) ;
175
+ cy . wait ( 1000 ) ;
176
+
177
+ const expectedHeaders = [
178
+ 'Id' ,
179
+ 'Type' ,
180
+ 'Timestamp' ,
181
+ 'Latency' ,
182
+ 'CPU Time' ,
183
+ 'Memory Usage' ,
184
+ 'Indices' ,
185
+ 'Search Type' ,
186
+ 'Coordinator Node ID' ,
187
+ 'Total Shards' ,
188
+ ] ;
189
+
190
+ cy . get ( '.euiTableHeaderCell' ) . should ( 'have.length' , expectedHeaders . length ) ;
191
+
192
+ cy . get ( '.euiTableHeaderCell' ) . should ( ( $headers ) => {
193
+ const actualHeaders = $headers . map ( ( index , el ) => Cypress . $ ( el ) . text ( ) . trim ( ) ) . get ( ) ;
194
+ expect ( actualHeaders ) . to . deep . equal ( expectedHeaders ) ;
195
+ } ) ;
196
+ testMetricSorting ( 'Timestamp' , 2 ) ;
197
+ testMetricSorting ( 'Latency' , 3 ) ;
198
+ testMetricSorting ( 'CPU Time' , 4 ) ;
199
+ testMetricSorting ( 'Memory Usage' , 5 ) ;
200
+ } ) ;
201
+
202
+ it ( 'should render only group-related headers in the correct order when SIMILARITY filter is applied' , ( ) => {
203
+ cy . get ( '.euiFilterButton' ) . contains ( 'Type' ) . click ( ) ;
204
+ cy . get ( '.euiFilterSelectItem' ) . contains ( 'group' ) . click ( ) ;
205
+ cy . wait ( 1000 ) ;
206
+
207
+ const expectedHeaders = [
208
+ 'Id' ,
209
+ 'Type' ,
210
+ 'Query Count' ,
211
+ 'Average Latency' ,
212
+ 'Average CPU Time' ,
213
+ 'Average Memory Usage' ,
214
+ ] ;
215
+
216
+ cy . get ( '.euiTableHeaderCell' ) . should ( ( $headers ) => {
217
+ const actualHeaders = $headers . map ( ( index , el ) => Cypress . $ ( el ) . text ( ) . trim ( ) ) . get ( ) ;
218
+ expect ( actualHeaders ) . to . deep . equal ( expectedHeaders ) ;
219
+ } ) ;
220
+ testMetricSorting ( 'Query Count' , 2 ) ;
221
+ testMetricSorting ( 'Average Latency' , 3 ) ;
222
+ testMetricSorting ( 'Average CPU Time' , 4 ) ;
223
+ testMetricSorting ( 'Average Memory Usage' , 5 ) ;
224
+ } ) ;
225
+ it ( 'should display both query and group data with proper headers when both are selected' , ( ) => {
226
+ cy . get ( '.euiFilterButton' ) . contains ( 'Type' ) . click ( ) ;
227
+ cy . get ( '.euiFilterSelectItem' ) . contains ( 'query' ) . click ( ) ;
228
+ cy . get ( '.euiFilterSelectItem' ) . contains ( 'group' ) . click ( ) ;
229
+ cy . wait ( 1000 ) ;
230
+
231
+ const expectedGroupHeaders = [
232
+ 'Id' ,
233
+ 'Type' ,
234
+ 'Query Count' ,
235
+ 'Timestamp' ,
236
+ 'Avg Latency / Latency' ,
237
+ 'Avg CPU Time / CPU Time' ,
238
+ 'Avg Memory Usage / Memory Usage' ,
239
+ 'Indices' ,
240
+ 'Search Type' ,
241
+ 'Coordinator Node ID' ,
242
+ 'Total Shards' ,
243
+ ] ;
244
+ cy . get ( '.euiTableHeaderCell' ) . should ( ( $headers ) => {
245
+ const actualHeaders = $headers . map ( ( index , el ) => Cypress . $ ( el ) . text ( ) . trim ( ) ) . get ( ) ;
246
+ expect ( actualHeaders ) . to . deep . equal ( expectedGroupHeaders ) ;
247
+ } ) ;
248
+ testMetricSorting ( 'Query Count' , 2 ) ;
249
+ testMetricSorting ( 'Timestamp' , 3 ) ;
250
+ testMetricSorting ( 'Avg Latency / Latency' , 4 ) ;
251
+ testMetricSorting ( 'Avg CPU Time / CPU Time' , 5 ) ;
252
+ testMetricSorting ( 'Avg Memory Usage / Memory Usage' , 6 ) ;
253
+ } ) ;
254
+ } ) ;
0 commit comments