@@ -117,7 +117,127 @@ test.describe('Search', { tag: '@search' }, () => {
117
117
} ) ;
118
118
} ) ;
119
119
120
- //TODO: Add query test using sql
120
+ test ( 'should support multiline SQL WHERE clauses' , async ( { page } ) => {
121
+ const searchForm = page . locator ( '[data-testid="search-form"]' ) ;
122
+ const sqlToggle = searchForm . locator ( 'text=SQL' ) . first ( ) ;
123
+ const whereContainer = searchForm . locator ( 'div:has(p.mantine-Text-root:has-text("WHERE"))' ) ;
124
+ const whereLabel = whereContainer . locator ( 'p.mantine-Text-root:has-text("WHERE")' ) ;
125
+ const whereEditor = whereContainer . locator ( '.cm-editor' ) ;
126
+ const searchResults = page . locator ( '[data-testid="search-results-table"]' ) ;
127
+
128
+ await test . step ( 'Switch to SQL mode' , async ( ) => {
129
+ await sqlToggle . click ( ) ;
130
+ await expect ( whereLabel ) . toBeVisible ( ) ;
131
+ } ) ;
132
+
133
+ await test . step ( 'Test multiline input with Shift+Enter' , async ( ) => {
134
+ await whereEditor . click ( ) ;
135
+
136
+ await whereEditor . type ( 'timestamp >= now() - interval 1 hour' ) ;
137
+ await page . keyboard . press ( 'Shift+Enter' ) ;
138
+ await whereEditor . type ( 'AND level = "error"' ) ;
139
+ await page . keyboard . press ( 'Shift+Enter' ) ;
140
+ await whereEditor . type ( 'AND service_name = "api"' ) ;
141
+
142
+ const editorContent = await whereEditor . textContent ( ) ;
143
+ expect ( editorContent ) . toContain ( 'timestamp >= now() - interval 1 hour' ) ;
144
+ expect ( editorContent ) . toContain ( 'AND level = "error"' ) ;
145
+ expect ( editorContent ) . toContain ( 'AND service_name = "api"' ) ;
146
+ } ) ;
147
+
148
+ await test . step ( 'Test editor height expansion' , async ( ) => {
149
+ const initialBox = await whereEditor . boundingBox ( ) ;
150
+ const initialHeight = initialBox ?. height || 0 ;
151
+
152
+ await whereEditor . press ( 'Shift+Enter' ) ;
153
+ await whereEditor . type ( 'AND response_time > 1000' ) ;
154
+ await whereEditor . press ( 'Shift+Enter' ) ;
155
+ await whereEditor . type ( 'AND user_id IS NOT NULL' ) ;
156
+
157
+ const expandedBox = await whereEditor . boundingBox ( ) ;
158
+ const expandedHeight = expandedBox ?. height || 0 ;
159
+ expect ( expandedHeight ) . toBeGreaterThan ( initialHeight ) ;
160
+ } ) ;
161
+
162
+ await test . step ( 'Test max height with scroll overflow' , async ( ) => {
163
+ for ( let i = 0 ; i < 10 ; i ++ ) {
164
+ await whereEditor . press ( 'Shift+Enter' ) ;
165
+ await whereEditor . type ( `AND field_${ i } = "value_${ i } "` ) ;
166
+ }
167
+
168
+ const editorBox = await whereEditor . boundingBox ( ) ;
169
+ const maxHeight = 150 ;
170
+ expect ( editorBox ?. height ) . toBeLessThanOrEqual ( maxHeight + 10 ) ;
171
+
172
+ const scroller = whereEditor . locator ( '.cm-scroller' ) ;
173
+ await expect ( scroller ) . toHaveCSS ( 'overflow-y' , 'auto' ) ;
174
+ } ) ;
175
+
176
+ await test . step ( 'Test Enter submits query' , async ( ) => {
177
+ await whereEditor . click ( ) ;
178
+
179
+ await page . keyboard . press ( 'Control+a' ) ;
180
+ await whereEditor . type ( 'level = "info"' ) ;
181
+
182
+ await page . keyboard . press ( 'Enter' ) ;
183
+
184
+ await page . waitForTimeout ( 1000 ) ;
185
+ await expect ( searchResults ) . toBeVisible ( { timeout : 5000 } ) ;
186
+ } ) ;
187
+ } ) ;
188
+
189
+ test ( 'should support multiline Lucene search input' , async ( { page } ) => {
190
+ const searchForm = page . locator ( '[data-testid="search-form"]' ) ;
191
+ const luceneToggle = searchForm . locator ( 'text=Lucene' ) . first ( ) ;
192
+ const searchInput = page . locator ( '[data-testid="search-input"]' ) ;
193
+ const searchResults = page . locator ( '[data-testid="search-results-table"]' ) ;
194
+
195
+ await test . step ( 'Ensure Lucene mode is active' , async ( ) => {
196
+ await luceneToggle . click ( ) ;
197
+ await expect ( searchInput ) . toBeVisible ( ) ;
198
+ } ) ;
199
+
200
+ await test . step ( 'Test multiline input with auto-expansion' , async ( ) => {
201
+ await searchInput . click ( ) ;
202
+
203
+ await searchInput . type ( 'level:error' ) ;
204
+ await page . keyboard . press ( 'Shift+Enter' ) ;
205
+ await searchInput . type ( 'service_name:api' ) ;
206
+ await page . keyboard . press ( 'Shift+Enter' ) ;
207
+ await searchInput . type ( 'timestamp:[now-1h TO now]' ) ;
208
+
209
+ const inputValue = await searchInput . inputValue ( ) ;
210
+ expect ( inputValue ) . toContain ( 'level:error' ) ;
211
+ expect ( inputValue ) . toContain ( 'service_name:api' ) ;
212
+ expect ( inputValue ) . toContain ( 'timestamp:[now-1h TO now]' ) ;
213
+ } ) ;
214
+
215
+ await test . step ( 'Test textarea auto-expansion' , async ( ) => {
216
+ const initialBox = await searchInput . boundingBox ( ) ;
217
+ const initialHeight = initialBox ?. height || 0 ;
218
+
219
+ await page . keyboard . press ( 'Shift+Enter' ) ;
220
+ await searchInput . type ( 'response_time:>1000' ) ;
221
+ await page . keyboard . press ( 'Shift+Enter' ) ;
222
+ await searchInput . type ( 'user_id:*' ) ;
223
+
224
+ const expandedBox = await searchInput . boundingBox ( ) ;
225
+ const expandedHeight = expandedBox ?. height || 0 ;
226
+ expect ( expandedHeight ) . toBeGreaterThan ( initialHeight ) ;
227
+ } ) ;
228
+
229
+ await test . step ( 'Test Enter submits search' , async ( ) => {
230
+ await searchInput . click ( ) ;
231
+
232
+ await page . keyboard . press ( 'Control+a' ) ;
233
+ await searchInput . type ( 'level:info' ) ;
234
+
235
+ await page . keyboard . press ( 'Enter' ) ;
236
+
237
+ await page . waitForTimeout ( 1000 ) ;
238
+ await expect ( searchResults ) . toBeVisible ( { timeout : 5000 } ) ;
239
+ } ) ;
240
+ } ) ;
121
241
122
242
test ( 'Comprehensive Search Workflow - Search, View Results, Navigate Side Panel' , async ( {
123
243
page,
0 commit comments