@@ -1191,6 +1191,62 @@ test('network interface options disabled when no VPCs exist', async ({ page }) =
11911191 await expect ( noneRadio ) . toBeChecked ( )
11921192} )
11931193
1194+ // The default_* attachment types resolve a VPC named 'default', so they 404 if
1195+ // that VPC has been deleted. other-project has a VPC, just not one named
1196+ // 'default', so only custom interfaces work there.
1197+ test ( 'custom network interface works without a default VPC' , async ( { page } ) => {
1198+ await page . goto ( '/projects/other-project/instances-new' )
1199+ const instanceName = 'custom-nic-without-default-vpc'
1200+
1201+ const defaultRadio = page . getByRole ( 'radio' , { name : 'Default' , exact : true } )
1202+ const customRadio = page . getByRole ( 'radio' , { name : 'Custom' , exact : true } )
1203+ const noneRadio = page . getByRole ( 'radio' , { name : 'None' , exact : true } )
1204+
1205+ // default is out, but the project has a VPC, so custom interfaces still work
1206+ await expect ( defaultRadio ) . toBeDisabled ( )
1207+ await expect ( defaultRadio ) . not . toBeChecked ( )
1208+ await expect ( customRadio ) . toBeEnabled ( )
1209+
1210+ const defaultRow = defaultRadio . locator ( '..' ) . locator ( '..' ) . locator ( '..' )
1211+ const defaultTip = defaultRow . getByRole ( 'button' , { name : 'Tip' } )
1212+ const tooltip = page . getByRole ( 'tooltip' )
1213+
1214+ await defaultTip . hover ( )
1215+ await expect ( tooltip ) . toHaveText ( 'Default networking requires a VPC named default' )
1216+
1217+ await page . mouse . move ( 0 , 0 )
1218+ await expect ( tooltip ) . toBeHidden ( )
1219+ await defaultTip . focus ( )
1220+ await expect ( tooltip ) . toHaveText ( 'Default networking requires a VPC named default' )
1221+
1222+ await expect ( noneRadio ) . toBeEnabled ( )
1223+ await expect ( noneRadio ) . toBeChecked ( )
1224+
1225+ await page . getByRole ( 'textbox' , { name : 'Name' , exact : true } ) . fill ( instanceName )
1226+ await selectASiloImage ( page , 'ubuntu-22-04' )
1227+
1228+ await customRadio . click ( )
1229+ await page . getByRole ( 'button' , { name : 'Add network interface' } ) . click ( )
1230+
1231+ const modal = page . getByRole ( 'dialog' , { name : 'Add network interface' } )
1232+ await modal . getByRole ( 'textbox' , { name : 'Name' } ) . fill ( 'custom-primary' )
1233+ await expect ( modal . getByLabel ( 'VPC' , { exact : true } ) ) . toContainText ( 'mock-vpc-2' )
1234+ await modal . getByRole ( 'button' , { name : 'VPC subnet' } ) . click ( )
1235+ await page . getByRole ( 'option' , { name : 'other-subnet' , exact : true } ) . click ( )
1236+ await modal . getByRole ( 'button' , { name : 'Add network interface' } ) . click ( )
1237+
1238+ await page . getByRole ( 'button' , { name : 'Create instance' } ) . click ( )
1239+ await closeToast ( page )
1240+ await expect ( page ) . toHaveURL ( `/projects/other-project/instances/${ instanceName } /storage` )
1241+
1242+ await page . getByRole ( 'tab' , { name : 'Networking' } ) . click ( )
1243+ await expectRowVisible ( page . getByRole ( 'table' , { name : 'Network interfaces' } ) , {
1244+ name : 'custom-primaryprimary' ,
1245+ vpc : 'mock-vpc-2' ,
1246+ subnet : 'other-subnet' ,
1247+ } )
1248+ } )
1249+
11941250test ( 'floating IPs are filtered by NIC IP version' , async ( { page } ) => {
11951251 await page . goto ( '/projects/mock-project/instances-new' )
11961252
0 commit comments