6
6
* Copyright Oxide Computer Company
7
7
*/
8
8
9
- import {
10
- clickRowAction ,
11
- expect ,
12
- expectRowVisible ,
13
- selectOption ,
14
- test ,
15
- type Locator ,
16
- } from './utils'
9
+ import { expect , test , type Locator , type Page } from '@playwright/test'
10
+
11
+ import { clickRowAction , expectRowVisible , selectOption } from './utils'
17
12
18
13
const defaultRules = [ 'allow-internal-inbound' , 'allow-ssh' , 'allow-icmp' ]
19
14
@@ -53,6 +48,7 @@ test('can create firewall rule', async ({ page }) => {
53
48
// add host filter instance "host-filter-instance"
54
49
await selectOption ( page , 'Host type' , 'Instance' )
55
50
await page . getByRole ( 'combobox' , { name : 'Instance name' } ) . fill ( 'host-filter-instance' )
51
+ await page . getByText ( 'host-filter-instance' ) . click ( )
56
52
await page . getByRole ( 'button' , { name : 'Add host filter' } ) . click ( )
57
53
58
54
// host is added to hosts table
@@ -167,11 +163,13 @@ test('firewall rule form targets table', async ({ page }) => {
167
163
// add targets with overlapping names and types to test delete
168
164
169
165
await targetVpcNameField . fill ( 'abc' )
166
+ await targetVpcNameField . press ( 'Enter' )
170
167
await addButton . click ( )
171
168
await expectRowVisible ( targets , { Type : 'vpc' , Value : 'abc' } )
172
169
173
170
// enter a VPC called 'mock-subnet', even if that doesn't make sense here, to test dropdown later
174
171
await targetVpcNameField . fill ( 'mock-subnet' )
172
+ await targetVpcNameField . press ( 'Enter' )
175
173
await addButton . click ( )
176
174
await expectRowVisible ( targets , { Type : 'vpc' , Value : 'mock-subnet' } )
177
175
@@ -188,6 +186,7 @@ test('firewall rule form targets table', async ({ page }) => {
188
186
// now add a subnet by entering text
189
187
await selectOption ( page , 'Target type' , 'VPC subnet' )
190
188
await subnetNameField . fill ( 'abc' )
189
+ await page . getByText ( 'abc' ) . first ( ) . click ( )
191
190
await addButton . click ( )
192
191
await expectRowVisible ( targets , { Type : 'subnet' , Value : 'abc' } )
193
192
@@ -221,6 +220,7 @@ test('firewall rule form target validation', async ({ page }) => {
221
220
// Enter invalid VPC name
222
221
const vpcNameField = page . getByRole ( 'combobox' , { name : 'VPC name' } ) . first ( )
223
222
await vpcNameField . fill ( 'ab-' )
223
+ await vpcNameField . press ( 'Enter' )
224
224
await addButton . click ( )
225
225
await expect ( nameError ) . toBeVisible ( )
226
226
@@ -246,6 +246,7 @@ test('firewall rule form target validation', async ({ page }) => {
246
246
await expect ( ipError ) . toBeHidden ( )
247
247
await expect ( nameError ) . toBeHidden ( )
248
248
await vpcNameField . fill ( 'abc' )
249
+ await page . getByText ( 'abc' ) . click ( )
249
250
await addButton . click ( )
250
251
await expectRowVisible ( targets , { Type : 'vpc' , Value : 'abc' } )
251
252
@@ -284,6 +285,7 @@ test('firewall rule form host validation', async ({ page }) => {
284
285
// Enter invalid VPC name
285
286
const vpcNameField = page . getByRole ( 'combobox' , { name : 'VPC name' } ) . nth ( 1 )
286
287
await vpcNameField . fill ( 'ab-' )
288
+ await vpcNameField . press ( 'Enter' )
287
289
await addButton . click ( )
288
290
await expect ( nameError ) . toBeVisible ( )
289
291
@@ -309,6 +311,7 @@ test('firewall rule form host validation', async ({ page }) => {
309
311
await expect ( ipError ) . toBeHidden ( )
310
312
await expect ( nameError ) . toBeHidden ( )
311
313
await vpcNameField . fill ( 'abc' )
314
+ await page . getByText ( 'abc' ) . click ( )
312
315
await addButton . click ( )
313
316
await expectRowVisible ( hosts , { Type : 'vpc' , Value : 'abc' } )
314
317
@@ -350,10 +353,12 @@ test('firewall rule form hosts table', async ({ page }) => {
350
353
// add hosts with overlapping names and types to test delete
351
354
352
355
await hostFiltersVpcNameField . fill ( 'abc' )
356
+ await hostFiltersVpcNameField . press ( 'Enter' )
353
357
await addButton . click ( )
354
358
await expectRowVisible ( hosts , { Type : 'vpc' , Value : 'abc' } )
355
359
356
360
await hostFiltersVpcNameField . fill ( 'def' )
361
+ await hostFiltersVpcNameField . press ( 'Enter' )
357
362
await addButton . click ( )
358
363
await expectRowVisible ( hosts , { Type : 'vpc' , Value : 'def' } )
359
364
@@ -364,6 +369,7 @@ test('firewall rule form hosts table', async ({ page }) => {
364
369
365
370
await selectOption ( page , 'Host type' , 'VPC subnet' )
366
371
await page . getByRole ( 'combobox' , { name : 'Subnet name' } ) . fill ( 'abc' )
372
+ await page . getByRole ( 'combobox' , { name : 'Subnet name' } ) . press ( 'Enter' )
367
373
await addButton . click ( )
368
374
await expectRowVisible ( hosts , { Type : 'subnet' , Value : 'abc' } )
369
375
@@ -427,6 +433,7 @@ test('can update firewall rule', async ({ page }) => {
427
433
// add host filter
428
434
await selectOption ( page , 'Host type' , 'VPC subnet' )
429
435
await page . getByRole ( 'combobox' , { name : 'Subnet name' } ) . fill ( 'edit-filter-subnet' )
436
+ await page . getByText ( 'edit-filter-subnet' ) . click ( )
430
437
await page . getByRole ( 'button' , { name : 'Add host filter' } ) . click ( )
431
438
432
439
// new host is added to hosts table
@@ -561,3 +568,49 @@ test('name conflict error on edit', async ({ page }) => {
561
568
await page . getByRole ( 'button' , { name : 'Update rule' } ) . click ( )
562
569
await expectRowVisible ( page . getByRole ( 'table' ) , { Name : 'allow-icmp2' , Priority : '37' } )
563
570
} )
571
+
572
+ async function expectOptions ( page : Page , options : string [ ] ) {
573
+ const selector = page . getByRole ( 'option' )
574
+ await expect ( selector ) . toHaveCount ( options . length )
575
+ for ( const option of options ) {
576
+ await expect ( page . getByRole ( 'option' , { name : option } ) ) . toBeVisible ( )
577
+ }
578
+ }
579
+
580
+ test ( 'arbitrary values combobox' , async ( { page } ) => {
581
+ await page . goto ( '/projects/mock-project/vpcs/mock-vpc/firewall-rules-new' )
582
+
583
+ // test for bug where we'd persist the d after add and only show 'Custom: d'
584
+ const vpcInput = page . getByRole ( 'combobox' , { name : 'VPC name' } ) . first ( )
585
+ await vpcInput . focus ( )
586
+ await expectOptions ( page , [ 'mock-vpc' ] )
587
+
588
+ await vpcInput . fill ( 'd' )
589
+ await expectOptions ( page , [ 'Custom: d' ] )
590
+
591
+ await vpcInput . blur ( )
592
+ page . getByRole ( 'button' , { name : 'Add target' } ) . click ( )
593
+ await expect ( vpcInput ) . toHaveValue ( '' )
594
+
595
+ await vpcInput . focus ( )
596
+ await expectOptions ( page , [ 'mock-vpc' ] ) // bug cause failure here
597
+
598
+ // test keeping query around on blur
599
+ await selectOption ( page , 'Target type' , 'Instance' )
600
+ const input = page . getByRole ( 'combobox' , { name : 'Instance name' } )
601
+
602
+ await input . focus ( )
603
+ await expectOptions ( page , [ 'db1' , 'you-fail' , 'not-there-yet' ] )
604
+
605
+ await input . fill ( 'd' )
606
+ await expectOptions ( page , [ 'db1' , 'Custom: d' ] )
607
+
608
+ await input . blur ( )
609
+ await expect ( page . getByRole ( 'option' ) ) . toBeHidden ( )
610
+
611
+ await expect ( input ) . toHaveValue ( 'd' )
612
+ await input . focus ( )
613
+
614
+ // same options show up after blur (there was a bug around this)
615
+ await expectOptions ( page , [ 'db1' , 'Custom: d' ] )
616
+ } )
0 commit comments