66 * Copyright Oxide Computer Company
77 */
88
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'
1712
1813const defaultRules = [ 'allow-internal-inbound' , 'allow-ssh' , 'allow-icmp' ]
1914
@@ -53,6 +48,7 @@ test('can create firewall rule', async ({ page }) => {
5348 // add host filter instance "host-filter-instance"
5449 await selectOption ( page , 'Host type' , 'Instance' )
5550 await page . getByRole ( 'combobox' , { name : 'Instance name' } ) . fill ( 'host-filter-instance' )
51+ await page . getByText ( 'host-filter-instance' ) . click ( )
5652 await page . getByRole ( 'button' , { name : 'Add host filter' } ) . click ( )
5753
5854 // host is added to hosts table
@@ -167,11 +163,13 @@ test('firewall rule form targets table', async ({ page }) => {
167163 // add targets with overlapping names and types to test delete
168164
169165 await targetVpcNameField . fill ( 'abc' )
166+ await targetVpcNameField . press ( 'Enter' )
170167 await addButton . click ( )
171168 await expectRowVisible ( targets , { Type : 'vpc' , Value : 'abc' } )
172169
173170 // enter a VPC called 'mock-subnet', even if that doesn't make sense here, to test dropdown later
174171 await targetVpcNameField . fill ( 'mock-subnet' )
172+ await targetVpcNameField . press ( 'Enter' )
175173 await addButton . click ( )
176174 await expectRowVisible ( targets , { Type : 'vpc' , Value : 'mock-subnet' } )
177175
@@ -188,6 +186,7 @@ test('firewall rule form targets table', async ({ page }) => {
188186 // now add a subnet by entering text
189187 await selectOption ( page , 'Target type' , 'VPC subnet' )
190188 await subnetNameField . fill ( 'abc' )
189+ await page . getByText ( 'abc' ) . first ( ) . click ( )
191190 await addButton . click ( )
192191 await expectRowVisible ( targets , { Type : 'subnet' , Value : 'abc' } )
193192
@@ -221,6 +220,7 @@ test('firewall rule form target validation', async ({ page }) => {
221220 // Enter invalid VPC name
222221 const vpcNameField = page . getByRole ( 'combobox' , { name : 'VPC name' } ) . first ( )
223222 await vpcNameField . fill ( 'ab-' )
223+ await vpcNameField . press ( 'Enter' )
224224 await addButton . click ( )
225225 await expect ( nameError ) . toBeVisible ( )
226226
@@ -246,6 +246,7 @@ test('firewall rule form target validation', async ({ page }) => {
246246 await expect ( ipError ) . toBeHidden ( )
247247 await expect ( nameError ) . toBeHidden ( )
248248 await vpcNameField . fill ( 'abc' )
249+ await page . getByText ( 'abc' ) . click ( )
249250 await addButton . click ( )
250251 await expectRowVisible ( targets , { Type : 'vpc' , Value : 'abc' } )
251252
@@ -284,6 +285,7 @@ test('firewall rule form host validation', async ({ page }) => {
284285 // Enter invalid VPC name
285286 const vpcNameField = page . getByRole ( 'combobox' , { name : 'VPC name' } ) . nth ( 1 )
286287 await vpcNameField . fill ( 'ab-' )
288+ await vpcNameField . press ( 'Enter' )
287289 await addButton . click ( )
288290 await expect ( nameError ) . toBeVisible ( )
289291
@@ -309,6 +311,7 @@ test('firewall rule form host validation', async ({ page }) => {
309311 await expect ( ipError ) . toBeHidden ( )
310312 await expect ( nameError ) . toBeHidden ( )
311313 await vpcNameField . fill ( 'abc' )
314+ await page . getByText ( 'abc' ) . click ( )
312315 await addButton . click ( )
313316 await expectRowVisible ( hosts , { Type : 'vpc' , Value : 'abc' } )
314317
@@ -350,10 +353,12 @@ test('firewall rule form hosts table', async ({ page }) => {
350353 // add hosts with overlapping names and types to test delete
351354
352355 await hostFiltersVpcNameField . fill ( 'abc' )
356+ await hostFiltersVpcNameField . press ( 'Enter' )
353357 await addButton . click ( )
354358 await expectRowVisible ( hosts , { Type : 'vpc' , Value : 'abc' } )
355359
356360 await hostFiltersVpcNameField . fill ( 'def' )
361+ await hostFiltersVpcNameField . press ( 'Enter' )
357362 await addButton . click ( )
358363 await expectRowVisible ( hosts , { Type : 'vpc' , Value : 'def' } )
359364
@@ -364,6 +369,7 @@ test('firewall rule form hosts table', async ({ page }) => {
364369
365370 await selectOption ( page , 'Host type' , 'VPC subnet' )
366371 await page . getByRole ( 'combobox' , { name : 'Subnet name' } ) . fill ( 'abc' )
372+ await page . getByRole ( 'combobox' , { name : 'Subnet name' } ) . press ( 'Enter' )
367373 await addButton . click ( )
368374 await expectRowVisible ( hosts , { Type : 'subnet' , Value : 'abc' } )
369375
@@ -427,6 +433,7 @@ test('can update firewall rule', async ({ page }) => {
427433 // add host filter
428434 await selectOption ( page , 'Host type' , 'VPC subnet' )
429435 await page . getByRole ( 'combobox' , { name : 'Subnet name' } ) . fill ( 'edit-filter-subnet' )
436+ await page . getByText ( 'edit-filter-subnet' ) . click ( )
430437 await page . getByRole ( 'button' , { name : 'Add host filter' } ) . click ( )
431438
432439 // new host is added to hosts table
@@ -561,3 +568,49 @@ test('name conflict error on edit', async ({ page }) => {
561568 await page . getByRole ( 'button' , { name : 'Update rule' } ) . click ( )
562569 await expectRowVisible ( page . getByRole ( 'table' ) , { Name : 'allow-icmp2' , Priority : '37' } )
563570} )
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