diff --git a/app/pages/ProjectsPage.tsx b/app/pages/ProjectsPage.tsx
index ca99041c53..ed86d90ed4 100644
--- a/app/pages/ProjectsPage.tsx
+++ b/app/pages/ProjectsPage.tsx
@@ -89,6 +89,7 @@ export default function ProjectsPage() {
onActivate: confirmDelete({
doDelete: () => deleteProject({ path: { project: project.name } }),
label: project.name,
+ resourceKind: 'project',
}),
},
],
diff --git a/app/pages/SiloAccessPage.tsx b/app/pages/SiloAccessPage.tsx
index c1531bf1fc..66a7f3aabc 100644
--- a/app/pages/SiloAccessPage.tsx
+++ b/app/pages/SiloAccessPage.tsx
@@ -149,6 +149,7 @@ export default function SiloAccessPage() {
the {row.siloRole} role for {row.name}
),
+ resourceKind: 'role assignment',
extraContent:
row.id === me.id ? 'This will remove your own silo access.' : undefined,
}),
diff --git a/app/pages/SiloImagesPage.tsx b/app/pages/SiloImagesPage.tsx
index 16ddd126d8..6a830e3771 100644
--- a/app/pages/SiloImagesPage.tsx
+++ b/app/pages/SiloImagesPage.tsx
@@ -87,6 +87,7 @@ export default function SiloImagesPage() {
onActivate: confirmDelete({
doDelete: () => deleteImage({ path: { image: image.name } }),
label: image.name,
+ resourceKind: 'image',
}),
},
],
diff --git a/app/pages/project/access/ProjectAccessPage.tsx b/app/pages/project/access/ProjectAccessPage.tsx
index 07ee850d57..bcf10c78bc 100644
--- a/app/pages/project/access/ProjectAccessPage.tsx
+++ b/app/pages/project/access/ProjectAccessPage.tsx
@@ -192,6 +192,7 @@ export default function ProjectAccessPage() {
the {row.projectRole} role for {row.name}
),
+ resourceKind: 'role assignment',
}),
disabled: !row.projectRole && "You don't have permission to delete this user",
},
diff --git a/app/pages/project/disks/DisksPage.tsx b/app/pages/project/disks/DisksPage.tsx
index 7f6a37ae3f..469c4c8e95 100644
--- a/app/pages/project/disks/DisksPage.tsx
+++ b/app/pages/project/disks/DisksPage.tsx
@@ -133,6 +133,7 @@ export default function DisksPage() {
onActivate: confirmDelete({
doDelete: () => deleteDisk({ path: { disk: disk.name }, query: { project } }),
label: disk.name,
+ resourceKind: 'disk',
}),
disabled:
!diskCan.delete(disk) &&
diff --git a/app/pages/project/external-subnets/ExternalSubnetsPage.tsx b/app/pages/project/external-subnets/ExternalSubnetsPage.tsx
index 4d0aa1ec42..8c3bec28fd 100644
--- a/app/pages/project/external-subnets/ExternalSubnetsPage.tsx
+++ b/app/pages/project/external-subnets/ExternalSubnetsPage.tsx
@@ -139,7 +139,7 @@ export default function ExternalSubnetsPage() {
path: { externalSubnet: subnet.name },
query: { project },
}),
- modalTitle: 'Detach External Subnet',
+ modalTitle: 'Detach external subnet',
modalContent: (
@@ -196,6 +196,7 @@ export default function FloatingIpsPage() {
query: { project },
}),
label: floatingIp.name,
+ resourceKind: 'floating IP',
}),
},
]
diff --git a/app/pages/project/images/ImagesPage.tsx b/app/pages/project/images/ImagesPage.tsx
index 047287a3d7..f3e7880072 100644
--- a/app/pages/project/images/ImagesPage.tsx
+++ b/app/pages/project/images/ImagesPage.tsx
@@ -85,6 +85,7 @@ export default function ImagesPage() {
query: { project },
}),
label: image.name,
+ resourceKind: 'image',
}),
},
],
diff --git a/app/pages/project/instances/NetworkingTab.tsx b/app/pages/project/instances/NetworkingTab.tsx
index 249952d2e8..10817eac6e 100644
--- a/app/pages/project/instances/NetworkingTab.tsx
+++ b/app/pages/project/instances/NetworkingTab.tsx
@@ -445,6 +445,7 @@ export default function NetworkingTab() {
query: instanceSelector,
}),
label: nic.name,
+ resourceKind: 'network interface',
}),
disabled: deleteDisabledReason(),
},
@@ -511,7 +512,7 @@ export default function NetworkingTab() {
path: { externalSubnet: subnet.name },
query: { project },
}),
- modalTitle: 'Detach External Subnet',
+ modalTitle: 'Detach external subnet',
modalContent: (
@@ -254,7 +255,7 @@ export default function StorageTab() {
},
}),
errorTitle: `Could not ${verb} boot disk`,
- modalTitle: `Confirm ${verb} boot disk`,
+ modalTitle: `${capitalize(verb)} boot disk`,
modalContent: bootDiskName ? (
Are you sure you want to change the boot disk to {disk.name}?
@@ -286,7 +287,7 @@ export default function StorageTab() {
doAction: () =>
detachDisk({ body: { disk: disk.name }, path: { instance: instance.id } }),
errorTitle: 'Could not detach disk',
- modalTitle: 'Confirm detach disk',
+ modalTitle: 'Detach disk',
// prettier-ignore
modalContent:
Are you sure you want to detach {disk.name}?
,
actionType: 'danger',
diff --git a/app/pages/project/instances/actions.tsx b/app/pages/project/instances/actions.tsx
index f939c858b8..62e9ccb4ed 100644
--- a/app/pages/project/instances/actions.tsx
+++ b/app/pages/project/instances/actions.tsx
@@ -64,7 +64,7 @@ export const useMakeInstanceActions = (
// prettier-ignore
onSuccess: () => addToast(<>Starting instance
{instance.name}>),
}),
- modalTitle: 'Confirm start instance',
+ modalTitle: 'Start instance',
modalContent: (
Are you sure you want to start {instance.name}?
@@ -88,7 +88,7 @@ export const useMakeInstanceActions = (
// prettier-ignore
addToast(<>Stopping instance {instance.name}>),
}),
- modalTitle: 'Confirm stop instance',
+ modalTitle: 'Stop instance',
modalContent: (
@@ -128,7 +128,7 @@ export const useMakeInstanceActions = (
// prettier-ignore
addToast(<>Rebooting instance {instance.name}>),
}),
- modalTitle: 'Confirm reboot instance',
+ modalTitle: 'Reboot instance',
modalContent: (
Are you sure you want to reboot {instance.name}?
diff --git a/app/pages/project/snapshots/SnapshotsPage.tsx b/app/pages/project/snapshots/SnapshotsPage.tsx
index 16831b0485..3e2f29ce46 100644
--- a/app/pages/project/snapshots/SnapshotsPage.tsx
+++ b/app/pages/project/snapshots/SnapshotsPage.tsx
@@ -154,6 +154,7 @@ export default function SnapshotsPage() {
query: { project },
}),
label: snapshot.name,
+ resourceKind: 'snapshot',
}),
},
],
diff --git a/app/pages/project/vpcs/RouterPage.tsx b/app/pages/project/vpcs/RouterPage.tsx
index 70b01936f7..52428ae69b 100644
--- a/app/pages/project/vpcs/RouterPage.tsx
+++ b/app/pages/project/vpcs/RouterPage.tsx
@@ -151,8 +151,8 @@ export default function RouterPage() {
onActivate: () =>
confirmAction({
doAction: () => deleteRouterRoute({ path: { route: routerRoute.id } }),
- errorTitle: 'Could not remove route',
- modalTitle: 'Confirm remove route',
+ errorTitle: 'Could not delete route',
+ modalTitle: 'Delete route',
modalContent: (
Are you sure you want to delete route {routerRoute.name}?
diff --git a/app/pages/project/vpcs/VpcFirewallRulesTab.tsx b/app/pages/project/vpcs/VpcFirewallRulesTab.tsx
index 471aed5b96..96f75640fb 100644
--- a/app/pages/project/vpcs/VpcFirewallRulesTab.tsx
+++ b/app/pages/project/vpcs/VpcFirewallRulesTab.tsx
@@ -161,6 +161,7 @@ export default function VpcFirewallRulesTab() {
},
}),
label: rule.name,
+ resourceKind: 'firewall rule',
}),
},
]),
diff --git a/app/pages/project/vpcs/VpcPage.tsx b/app/pages/project/vpcs/VpcPage.tsx
index 100984ac63..6209e5495c 100644
--- a/app/pages/project/vpcs/VpcPage.tsx
+++ b/app/pages/project/vpcs/VpcPage.tsx
@@ -60,6 +60,7 @@ export default function VpcPage() {
onSelect={confirmDelete({
doDelete: () => deleteVpc({ path: { vpc: vpcName }, query: { project } }),
label: vpcName,
+ resourceKind: 'VPC',
})}
className="destructive"
/>
diff --git a/app/pages/project/vpcs/VpcRoutersTab.tsx b/app/pages/project/vpcs/VpcRoutersTab.tsx
index 7b8fc5790d..5e32ad2eb6 100644
--- a/app/pages/project/vpcs/VpcRoutersTab.tsx
+++ b/app/pages/project/vpcs/VpcRoutersTab.tsx
@@ -95,6 +95,7 @@ export default function VpcRoutersTab() {
}),
extraContent: 'This will also delete any routes belonging to this router.',
label: router.name,
+ resourceKind: 'VPC router',
}),
disabled: router.kind === 'system' && routeFormMessage.noDeletingSystemRouters,
},
diff --git a/app/pages/project/vpcs/VpcSubnetsTab.tsx b/app/pages/project/vpcs/VpcSubnetsTab.tsx
index 198a722ca6..cd1dca8223 100644
--- a/app/pages/project/vpcs/VpcSubnetsTab.tsx
+++ b/app/pages/project/vpcs/VpcSubnetsTab.tsx
@@ -60,6 +60,7 @@ export default function VpcSubnetsTab() {
onActivate: confirmDelete({
doDelete: () => deleteSubnet({ path: { subnet: subnet.id } }),
label: subnet.name,
+ resourceKind: 'VPC subnet',
}),
},
],
diff --git a/app/pages/project/vpcs/VpcsPage.tsx b/app/pages/project/vpcs/VpcsPage.tsx
index 3091816ac2..b7b0aaac74 100644
--- a/app/pages/project/vpcs/VpcsPage.tsx
+++ b/app/pages/project/vpcs/VpcsPage.tsx
@@ -104,6 +104,7 @@ export default function VpcsPage() {
onActivate: confirmDelete({
doDelete: () => deleteVpc({ path: { vpc: vpc.name }, query: { project } }),
label: vpc.name,
+ resourceKind: 'VPC',
}),
},
],
diff --git a/app/pages/settings/AccessTokensPage.tsx b/app/pages/settings/AccessTokensPage.tsx
index cf70bf405d..0ff8a4edb3 100644
--- a/app/pages/settings/AccessTokensPage.tsx
+++ b/app/pages/settings/AccessTokensPage.tsx
@@ -58,6 +58,7 @@ export default function AccessTokensPage() {
onActivate: confirmDelete({
doDelete: () => deleteToken({ path: { tokenId: token.id } }),
label: token.id,
+ resourceKind: 'access token',
extraContent:
'This cannot be undone. Any application or instance of the Oxide CLI that depends on this token will need a new one.',
}),
diff --git a/app/pages/settings/SSHKeysPage.tsx b/app/pages/settings/SSHKeysPage.tsx
index 92013e9664..2d4cc9f251 100644
--- a/app/pages/settings/SSHKeysPage.tsx
+++ b/app/pages/settings/SSHKeysPage.tsx
@@ -63,6 +63,7 @@ export default function SSHKeysPage() {
onActivate: confirmDelete({
doDelete: () => deleteSshKey({ path: { sshKey: sshKey.name } }),
label: sshKey.name,
+ resourceKind: 'SSH key',
}),
},
],
diff --git a/app/pages/system/FleetAccessPage.tsx b/app/pages/system/FleetAccessPage.tsx
index ec48e5063b..3410208497 100644
--- a/app/pages/system/FleetAccessPage.tsx
+++ b/app/pages/system/FleetAccessPage.tsx
@@ -227,6 +227,7 @@ export default function FleetAccessPage() {
the {row.fleetRole} role for {row.name}
),
+ resourceKind: 'role assignment',
extraContent:
row.id === me.id ? 'This will remove your own fleet access.' : undefined,
}),
diff --git a/app/pages/system/UpdatePage.tsx b/app/pages/system/UpdatePage.tsx
index e9f3de05d5..4fd9ca5241 100644
--- a/app/pages/system/UpdatePage.tsx
+++ b/app/pages/system/UpdatePage.tsx
@@ -245,7 +245,7 @@ export default function UpdatePage() {
setTargetRelease({
body: { systemVersion: repo.systemVersion },
}),
- modalTitle: 'Confirm set target release',
+ modalTitle: 'Set target release',
modalContent: (
Are you sure you want to set {repo.systemVersion}{' '}
diff --git a/app/pages/system/networking/IpPoolPage.tsx b/app/pages/system/networking/IpPoolPage.tsx
index 4177afbac4..6634122a14 100644
--- a/app/pages/system/networking/IpPoolPage.tsx
+++ b/app/pages/system/networking/IpPoolPage.tsx
@@ -57,6 +57,7 @@ import { ALL_ISH } from '~/util/consts'
import { docLinks } from '~/util/links'
import { pb } from '~/util/path-builder'
import type * as PP from '~/util/path-params'
+import { capitalize } from '~/util/str'
const ipPoolView = ({ pool }: PP.IpPool) => q(api.systemIpPoolView, { path: { pool } })
const ipPoolUtilizationView = ({ pool }: PP.IpPool) =>
@@ -164,6 +165,7 @@ export default function IpPoolpage() {
onSelect={confirmDelete({
doDelete: () => deletePool({ path: { pool: pool.name } }),
label: pool.name,
+ resourceKind: 'IP pool',
})}
disabled={
!!ranges.items.length &&
@@ -256,7 +258,7 @@ function IpRangesTable() {
body: range,
}),
errorTitle: 'Could not remove range',
- modalTitle: 'Confirm remove range',
+ modalTitle: 'Remove range',
modalContent: (
Are you sure you want to remove range{' '}
@@ -326,7 +328,7 @@ function LinkedSilosTable() {
path: { silo: link.siloId, pool: link.ipPoolId },
body: { isDefault: false },
}),
- modalTitle: 'Confirm clear default',
+ modalTitle: 'Clear default',
modalContent: (
Are you sure you want {pool.name} to stop being the default{' '}
@@ -376,7 +378,7 @@ function LinkedSilosTable() {
path: { silo: link.siloId, pool: link.ipPoolId },
body: { isDefault: true },
}),
- modalTitle: `Confirm ${verb} default`,
+ modalTitle: `${capitalize(verb)} default`,
modalContent,
errorTitle: `Could not ${verb} default`,
actionType: 'primary',
@@ -395,7 +397,7 @@ function LinkedSilosTable() {
confirmAction({
doAction: () =>
unlinkSilo({ path: { silo: link.siloId, pool: link.ipPoolId } }),
- modalTitle: 'Confirm unlink silo',
+ modalTitle: 'Unlink silo',
modalContent: (
Are you sure you want to unlink {siloLabel} from {pool.name}? Users
diff --git a/app/pages/system/networking/IpPoolsPage.tsx b/app/pages/system/networking/IpPoolsPage.tsx
index 914a841ca5..64e14c3d46 100644
--- a/app/pages/system/networking/IpPoolsPage.tsx
+++ b/app/pages/system/networking/IpPoolsPage.tsx
@@ -113,6 +113,7 @@ export default function IpPoolsPage() {
onActivate: confirmDelete({
doDelete: () => deletePool({ path: { pool: pool.name } }),
label: pool.name,
+ resourceKind: 'IP pool',
}),
},
],
diff --git a/app/pages/system/networking/SubnetPoolPage.tsx b/app/pages/system/networking/SubnetPoolPage.tsx
index 3403b133ed..524e951d97 100644
--- a/app/pages/system/networking/SubnetPoolPage.tsx
+++ b/app/pages/system/networking/SubnetPoolPage.tsx
@@ -57,6 +57,7 @@ import { ALL_ISH } from '~/util/consts'
import { docLinks } from '~/util/links'
import { pb } from '~/util/path-builder'
import type * as PP from '~/util/path-params'
+import { capitalize } from '~/util/str'
const subnetPoolView = ({ subnetPool }: PP.SubnetPool) =>
q(api.systemSubnetPoolView, { path: { pool: subnetPool } })
@@ -127,6 +128,7 @@ export default function SubnetPoolPage() {
onSelect={confirmDelete({
doDelete: () => deletePool({ path: { pool: pool.name } }),
label: pool.name,
+ resourceKind: 'subnet pool',
})}
disabled={
!!members.items.length &&
@@ -218,7 +220,7 @@ function MembersTable() {
body: { subnet: member.subnet },
}),
errorTitle: 'Could not remove member',
- modalTitle: 'Confirm remove member',
+ modalTitle: 'Remove member',
modalContent: (
Are you sure you want to remove subnet {member.subnet} from the
@@ -318,7 +320,7 @@ function LinkedSilosTable() {
path: { silo: link.siloId, pool: link.subnetPoolId },
body: { isDefault: false },
}),
- modalTitle: 'Confirm clear default',
+ modalTitle: 'Clear default',
modalContent: (
Are you sure you want {pool.name} to stop being the default{' '}
@@ -358,7 +360,7 @@ function LinkedSilosTable() {
path: { silo: link.siloId, pool: link.subnetPoolId },
body: { isDefault: true },
}),
- modalTitle: `Confirm ${verb} default`,
+ modalTitle: `${capitalize(verb)} default`,
modalContent,
errorTitle: `Could not ${verb} default`,
actionType: 'primary',
@@ -376,7 +378,7 @@ function LinkedSilosTable() {
confirmAction({
doAction: () =>
unlinkSilo({ path: { silo: link.siloId, pool: link.subnetPoolId } }),
- modalTitle: 'Confirm unlink silo',
+ modalTitle: 'Unlink silo',
modalContent: (
Are you sure you want to unlink {siloLabel} from {pool.name}? Users
diff --git a/app/pages/system/networking/SubnetPoolsPage.tsx b/app/pages/system/networking/SubnetPoolsPage.tsx
index 20cb35a816..aa45a0c8e4 100644
--- a/app/pages/system/networking/SubnetPoolsPage.tsx
+++ b/app/pages/system/networking/SubnetPoolsPage.tsx
@@ -116,6 +116,7 @@ export default function SubnetPoolsPage() {
onActivate: confirmDelete({
doDelete: () => deletePool({ path: { pool: pool.name } }),
label: pool.name,
+ resourceKind: 'subnet pool',
}),
},
],
diff --git a/app/pages/system/silos/SiloIpPoolsTab.tsx b/app/pages/system/silos/SiloIpPoolsTab.tsx
index 5303ca6d39..7750d816cb 100644
--- a/app/pages/system/silos/SiloIpPoolsTab.tsx
+++ b/app/pages/system/silos/SiloIpPoolsTab.tsx
@@ -43,6 +43,7 @@ import { Modal } from '~/ui/lib/Modal'
import { Tooltip } from '~/ui/lib/Tooltip'
import { ALL_ISH } from '~/util/consts'
import { pb } from '~/util/path-builder'
+import { capitalize } from '~/util/str'
function toIpPoolComboboxItem(p: IpPool): ComboboxItem {
return {
@@ -177,7 +178,7 @@ export default function SiloIpPoolsTab() {
path: { silo, pool: pool.id },
body: { isDefault: false },
}),
- modalTitle: 'Confirm clear default',
+ modalTitle: 'Clear default',
modalContent: (
Are you sure you want {pool.name} to stop being the default{' '}
@@ -209,7 +210,7 @@ export default function SiloIpPoolsTab() {
path: { silo, pool: pool.id },
body: { isDefault: true },
}),
- modalTitle: `Confirm ${verb} default`,
+ modalTitle: `${capitalize(verb)} default`,
modalContent,
errorTitle: `Could not ${verb} default`,
actionType: 'primary',
@@ -223,7 +224,7 @@ export default function SiloIpPoolsTab() {
onActivate() {
confirmAction({
doAction: () => unlinkPool({ path: { silo, pool: pool.id } }),
- modalTitle: `Confirm unlink pool`,
+ modalTitle: 'Unlink pool',
modalContent: (
Are you sure you want to unlink {pool.name}? Users in this silo
diff --git a/app/pages/system/silos/SiloSubnetPoolsTab.tsx b/app/pages/system/silos/SiloSubnetPoolsTab.tsx
index da4826e14d..349d42fb47 100644
--- a/app/pages/system/silos/SiloSubnetPoolsTab.tsx
+++ b/app/pages/system/silos/SiloSubnetPoolsTab.tsx
@@ -43,6 +43,7 @@ import { Modal } from '~/ui/lib/Modal'
import { Tooltip } from '~/ui/lib/Tooltip'
import { ALL_ISH } from '~/util/consts'
import { pb } from '~/util/path-builder'
+import { capitalize } from '~/util/str'
function toSubnetPoolComboboxItem(p: SubnetPool): ComboboxItem {
return {
@@ -165,7 +166,7 @@ export default function SiloSubnetPoolsTab() {
path: { silo, pool: pool.id },
body: { isDefault: false },
}),
- modalTitle: 'Confirm clear default',
+ modalTitle: 'Clear default',
modalContent: (
Are you sure you want {pool.name} to stop being the default{' '}
@@ -197,7 +198,7 @@ export default function SiloSubnetPoolsTab() {
path: { silo, pool: pool.id },
body: { isDefault: true },
}),
- modalTitle: `Confirm ${verb} default`,
+ modalTitle: `${capitalize(verb)} default`,
modalContent,
errorTitle: `Could not ${verb} default`,
actionType: 'primary',
@@ -211,7 +212,7 @@ export default function SiloSubnetPoolsTab() {
onActivate() {
confirmAction({
doAction: () => unlinkPool({ path: { silo, pool: pool.id } }),
- modalTitle: 'Confirm unlink pool',
+ modalTitle: 'Unlink pool',
modalContent: (
Are you sure you want to unlink {pool.name}? Users in this silo
diff --git a/app/pages/system/silos/SilosPage.tsx b/app/pages/system/silos/SilosPage.tsx
index baed459dab..e4546d51a0 100644
--- a/app/pages/system/silos/SilosPage.tsx
+++ b/app/pages/system/silos/SilosPage.tsx
@@ -84,6 +84,7 @@ export default function SilosPage() {
onActivate: confirmDelete({
doDelete: () => deleteSilo({ path: { silo: silo.name } }),
label: silo.name,
+ resourceKind: 'silo',
}),
},
],
diff --git a/app/stores/confirm-action.ts b/app/stores/confirm-action.ts
index 7b315bc7d3..a8d2f0d90f 100644
--- a/app/stores/confirm-action.ts
+++ b/app/stores/confirm-action.ts
@@ -11,7 +11,7 @@ import { create } from 'zustand'
type ActionConfig = {
/** Must be `mutateAsync`, otherwise we can't catch the error generically */
doAction: () => Promise
- /** e.g., Confirm delete, Confirm unlink */
+ /** e.g., Delete project, Unlink pool */
modalTitle: string
modalContent: ReactNode
/** Title of error toast */
diff --git a/app/stores/confirm-delete.tsx b/app/stores/confirm-delete.tsx
index 2486257358..420ffbd4e3 100644
--- a/app/stores/confirm-delete.tsx
+++ b/app/stores/confirm-delete.tsx
@@ -23,7 +23,9 @@ type DeleteConfig = {
* directly.
*/
label: React.ReactNode
- resourceKind?: string
+ /** Lowercase resource type, used in the modal title ("Delete X") and
+ * the error toast title ("Could not delete X"). */
+ resourceKind: string
extraContent?: React.ReactNode
}
@@ -31,7 +33,6 @@ export const confirmDelete =
({ doDelete, label, resourceKind, extraContent }: DeleteConfig) =>
() => {
const displayLabel = typeof label === 'string' ? {label} : label
- const modalTitle = resourceKind ? `Confirm delete ${resourceKind}` : 'Confirm delete'
useConfirmAction.setState({
actionConfig: {
doAction: doDelete,
@@ -41,8 +42,8 @@ export const confirmDelete =
{extraContent ? {extraContent}
: null}
),
- errorTitle: 'Could not delete resource',
- modalTitle,
+ errorTitle: `Could not delete ${resourceKind}`,
+ modalTitle: `Delete ${resourceKind}`,
actionType: 'danger',
},
})
diff --git a/test/e2e/anti-affinity.e2e.ts b/test/e2e/anti-affinity.e2e.ts
index 466b623174..09250980fb 100644
--- a/test/e2e/anti-affinity.e2e.ts
+++ b/test/e2e/anti-affinity.e2e.ts
@@ -170,7 +170,7 @@ test('can delete an anti-affinity group', async ({ page }) => {
test('can delete anti-affinity group from detail page', async ({ page }) => {
await page.goto('/projects/mock-project/affinity/romulus-remus')
- const modal = page.getByRole('dialog', { name: 'Confirm delete' })
+ const modal = page.getByRole('dialog', { name: 'Delete anti-affinity group' })
await expect(modal).toBeHidden()
await page.getByLabel('Anti-affinity group actions').click()
@@ -207,7 +207,7 @@ test('add and remove instance from group on instance settings', async ({ page })
// Stop the instance
await page.getByRole('button', { name: 'Stop' }).click()
- const confirmStopModal = page.getByRole('dialog', { name: 'Confirm stop' })
+ const confirmStopModal = page.getByRole('dialog', { name: 'Stop instance' })
await expect(confirmStopModal).toBeVisible()
await confirmStopModal.getByRole('button', { name: 'Confirm' }).click()
await expect(confirmStopModal).toBeHidden()
diff --git a/test/e2e/images.e2e.ts b/test/e2e/images.e2e.ts
index a966acdd23..1c3ef736c6 100644
--- a/test/e2e/images.e2e.ts
+++ b/test/e2e/images.e2e.ts
@@ -175,7 +175,7 @@ test("Silo viewer can't delete silo image", async ({ browser }) => {
await expect(spinner).toBeVisible()
// Check deletion was successful
- await expect(page.getByText('Could not delete resource', { exact: true })).toBeVisible()
+ await expect(page.getByText('Could not delete image', { exact: true })).toBeVisible()
await expect(cell).toBeVisible()
await expect(spinner).toBeHidden()
})
diff --git a/test/e2e/instance-networking.e2e.ts b/test/e2e/instance-networking.e2e.ts
index 112a4cb03d..e3c3d06a88 100644
--- a/test/e2e/instance-networking.e2e.ts
+++ b/test/e2e/instance-networking.e2e.ts
@@ -154,7 +154,7 @@ test('Instance networking tab — Detach / Attach Ephemeral IPs', async ({ page
// an explicit ipVersion selector), then reattach it.
await clickRowAction(page, 'fd00::1', 'Detach')
const confirmDetachDialog = page.getByRole('dialog', {
- name: 'Confirm detach ephemeral IP',
+ name: 'Detach ephemeral IP',
})
await expect(confirmDetachDialog).toBeVisible()
await confirmDetachDialog.getByRole('button', { name: 'Confirm' }).click()
diff --git a/test/e2e/ip-pools.e2e.ts b/test/e2e/ip-pools.e2e.ts
index 3df0e782e5..ba4427ac0c 100644
--- a/test/e2e/ip-pools.e2e.ts
+++ b/test/e2e/ip-pools.e2e.ts
@@ -87,7 +87,7 @@ test('IP pool silo list', async ({ page }) => {
// unlink silo and the row is gone
await clickRowAction(page, 'maze-war', 'Unlink')
- await expect(page.getByRole('dialog', { name: 'Confirm unlink' })).toBeVisible()
+ await expect(page.getByRole('dialog', { name: 'Unlink silo' })).toBeVisible()
await page.getByRole('button', { name: 'Confirm' }).click()
await expect(siloLink).toBeHidden()
})
@@ -133,7 +133,7 @@ test('IP pool silo make default (no existing default)', async ({ page }) => {
await clickRowAction(page, 'pelerines', 'Make default')
- const dialog = page.getByRole('dialog', { name: 'Confirm make default' })
+ const dialog = page.getByRole('dialog', { name: 'Make default' })
await expect(
dialog.getByText(
'Are you sure you want to make ip-pool-1 the default IPv4 unicast pool for silo pelerines?'
@@ -153,7 +153,7 @@ test('IP pool silo make default (with existing default)', async ({ page }) => {
await clickRowAction(page, 'myriad', 'Make default')
- const dialog = page.getByRole('dialog', { name: 'Confirm change default' })
+ const dialog = page.getByRole('dialog', { name: 'Change default' })
await expect(
dialog.getByText(
'Are you sure you want to change the default IPv4 unicast pool for silo myriad from ip-pool-1 to ip-pool-3?'
@@ -172,7 +172,7 @@ test('IP pool silo clear default', async ({ page }) => {
await clickRowAction(page, 'maze-war', 'Clear default')
- const dialog = page.getByRole('dialog', { name: 'Confirm clear default' })
+ const dialog = page.getByRole('dialog', { name: 'Clear default' })
await expect(
dialog.getByText(
'Are you sure you want ip-pool-1 to stop being the default IPv4 unicast pool for silo maze-war?'
@@ -188,19 +188,19 @@ test('IP pool delete from IP Pools list page', async ({ page }) => {
// can't delete a pool containing ranges
await clickRowAction(page, 'ip-pool-1', 'Delete')
- await expect(page.getByRole('dialog', { name: 'Confirm delete' })).toBeVisible()
+ await expect(page.getByRole('dialog', { name: 'Delete IP pool' })).toBeVisible()
await page.getByRole('button', { name: 'Confirm' }).click()
await expectToast(
page,
- 'Could not delete resourceIP pool cannot be deleted while it contains IP ranges'
+ 'Could not delete IP poolIP pool cannot be deleted while it contains IP ranges'
)
await expect(page.getByRole('cell', { name: 'ip-pool-3' })).toBeVisible()
// can delete a pool with no ranges
await clickRowAction(page, 'ip-pool-3', 'Delete')
- await expect(page.getByRole('dialog', { name: 'Confirm delete' })).toBeVisible()
+ await expect(page.getByRole('dialog', { name: 'Delete IP pool' })).toBeVisible()
await page.getByRole('button', { name: 'Confirm' }).click()
await expect(page.getByRole('cell', { name: 'ip-pool-3' })).toBeHidden()
@@ -216,7 +216,7 @@ test('IP pool delete from IP Pool view page', async ({ page }) => {
await page.goto('/system/networking/ip-pools/ip-pool-3')
await page.getByRole('button', { name: 'IP pool actions' }).click()
await page.getByRole('menuitem', { name: 'Delete' }).click()
- await expect(page.getByRole('dialog', { name: 'Confirm delete' })).toBeVisible()
+ await expect(page.getByRole('dialog', { name: 'Delete IP pool' })).toBeVisible()
await page.getByRole('button', { name: 'Confirm' }).click()
// get redirected back to the list after successful delete
@@ -375,7 +375,7 @@ test('remove range', async ({ page }) => {
await clickRowAction(page, '10.0.0.20', 'Remove')
- const confirmModal = page.getByRole('dialog', { name: 'Confirm remove range' })
+ const confirmModal = page.getByRole('dialog', { name: 'Remove range' })
await expect(confirmModal.getByText('range 10.0.0.20–10.0.0.22')).toBeVisible()
await page.getByRole('button', { name: 'Cancel' }).click()
diff --git a/test/e2e/scim-tokens.e2e.ts b/test/e2e/scim-tokens.e2e.ts
index 96a57d8b63..9948ab3351 100644
--- a/test/e2e/scim-tokens.e2e.ts
+++ b/test/e2e/scim-tokens.e2e.ts
@@ -91,7 +91,7 @@ test('Delete SCIM token', async ({ page }) => {
await clickRowAction(page, 'a1b2c3d4', 'Delete')
// Confirm deletion modal should appear
- const confirmModal = page.getByRole('dialog', { name: 'Confirm delete' })
+ const confirmModal = page.getByRole('dialog', { name: 'Delete SCIM token' })
await expect(confirmModal).toBeVisible()
await expect(confirmModal.getByText('Are you sure you want to delete')).toBeVisible()
diff --git a/test/e2e/silos.e2e.ts b/test/e2e/silos.e2e.ts
index 410df41c65..9a96d16d6c 100644
--- a/test/e2e/silos.e2e.ts
+++ b/test/e2e/silos.e2e.ts
@@ -287,7 +287,7 @@ test('Silo IP pools', async ({ page }) => {
await clickRowAction(page, 'ip-pool-1', 'Unlink')
await expect(
page
- .getByRole('dialog', { name: 'Confirm unlink pool' })
+ .getByRole('dialog', { name: 'Unlink pool' })
.getByText('Are you sure you want to unlink ip-pool-1?')
).toBeVisible()
await page.getByRole('button', { name: 'Confirm' }).click()
@@ -299,7 +299,7 @@ test('Silo IP pools', async ({ page }) => {
await clickRowAction(page, 'ip-pool-2', 'Clear default')
await expect(
page
- .getByRole('dialog', { name: 'Confirm clear default' })
+ .getByRole('dialog', { name: 'Clear default' })
.getByText('Are you sure you want ip-pool-2 to stop being the default')
).toBeVisible()
await page.getByRole('button', { name: 'Confirm' }).click()
diff --git a/test/e2e/snapshots.e2e.ts b/test/e2e/snapshots.e2e.ts
index c6ddc8183d..9338a3648a 100644
--- a/test/e2e/snapshots.e2e.ts
+++ b/test/e2e/snapshots.e2e.ts
@@ -53,7 +53,7 @@ test('Confirm delete snapshot', async ({ page }) => {
await clickDelete()
- const modal = page.getByRole('dialog', { name: 'Confirm delete' })
+ const modal = page.getByRole('dialog', { name: 'Delete snapshot' })
await expect(modal).toBeVisible()
// cancel works
@@ -77,7 +77,7 @@ test('Error on delete snapshot', async ({ page }) => {
await row.getByRole('button', { name: 'Row actions' }).click()
await page.getByRole('menuitem', { name: 'Delete' }).click()
- const modal = page.getByRole('dialog', { name: 'Confirm delete' })
+ const modal = page.getByRole('dialog', { name: 'Delete snapshot' })
await expect(modal).toBeVisible()
const spinner = page.getByRole('dialog').getByLabel('Spinner')
@@ -90,7 +90,7 @@ test('Error on delete snapshot', async ({ page }) => {
await expect(modal).toBeHidden()
await expectVisible(page, [
row,
- page.getByText('Could not delete resource', { exact: true }),
+ page.getByText('Could not delete snapshot', { exact: true }),
])
})
@@ -99,7 +99,8 @@ test('Create image from snapshot', async ({ page }) => {
await clickRowAction(page, 'disk-1-snapshot-8', 'Create image')
- await expectVisible(page, ['role=dialog[name="Create image from snapshot"]'])
+ const modal = page.getByRole('dialog', { name: 'Create image from snapshot' })
+ await expect(modal).toBeVisible()
await page.fill('role=textbox[name="Name"]', 'image-from-snapshot-8')
await page.fill('role=textbox[name="Description"]', 'image description')
@@ -109,8 +110,10 @@ test('Create image from snapshot', async ({ page }) => {
await page.click('role=button[name="Create image"]')
await expect(page).toHaveURL('/projects/mock-project/snapshots')
+ await expect(modal).toBeHidden()
- await page.click('role=link[name*="Images"]')
+ await page.getByRole('link', { name: 'Images', exact: true }).click()
+ await expect(page).toHaveURL('/projects/mock-project/images')
await expectRowVisible(page.getByRole('table'), {
name: 'image-from-snapshot-8',
description: 'image description',
diff --git a/test/e2e/subnet-pools.e2e.ts b/test/e2e/subnet-pools.e2e.ts
index 71d6e69528..92493314bc 100644
--- a/test/e2e/subnet-pools.e2e.ts
+++ b/test/e2e/subnet-pools.e2e.ts
@@ -144,7 +144,7 @@ test('Subnet pool remove member', async ({ page }) => {
await page.goto('/system/networking/subnet-pools/secondary-v4-subnet-pool')
await clickRowAction(page, '172.20.0.0/16', 'Remove')
- await expect(page.getByRole('dialog', { name: 'Confirm remove' })).toBeVisible()
+ await expect(page.getByRole('dialog', { name: 'Remove member' })).toBeVisible()
await page.getByRole('button', { name: 'Confirm' }).click()
// The row should be gone
@@ -168,7 +168,7 @@ test('Subnet pool linked silos', async ({ page }) => {
// Unlink fails when silo still has external subnets allocated from the pool
await clickRowAction(page, 'maze-war', 'Unlink')
- await expect(page.getByRole('dialog', { name: 'Confirm unlink' })).toBeVisible()
+ await expect(page.getByRole('dialog', { name: 'Unlink silo' })).toBeVisible()
await page.getByRole('button', { name: 'Confirm' }).click()
await expectToast(page, 'Could not unlink silo')
// Row should still be there
@@ -183,7 +183,7 @@ test('Subnet pool unlink silo succeeds when no subnets allocated', async ({ page
await expectRowVisible(table, { Silo: 'maze-war' })
await clickRowAction(page, 'maze-war', 'Unlink')
- await expect(page.getByRole('dialog', { name: 'Confirm unlink' })).toBeVisible()
+ await expect(page.getByRole('dialog', { name: 'Unlink silo' })).toBeVisible()
await page.getByRole('button', { name: 'Confirm' }).click()
await expect(page.getByRole('link', { name: 'maze-war' })).toBeHidden()
})
@@ -212,7 +212,7 @@ test('Subnet pool silo make default (no existing default)', async ({ page }) =>
await clickRowAction(page, 'maze-war', 'Make default')
- const dialog = page.getByRole('dialog', { name: 'Confirm make default' })
+ const dialog = page.getByRole('dialog', { name: 'Make default' })
await expect(
dialog.getByText(
'Are you sure you want to make ipv6-subnet-pool the default IPv6 subnet pool for silo maze-war?'
@@ -233,7 +233,7 @@ test('Subnet pool silo make default (with existing default)', async ({ page }) =
await clickRowAction(page, 'maze-war', 'Make default')
- const dialog = page.getByRole('dialog', { name: 'Confirm change default' })
+ const dialog = page.getByRole('dialog', { name: 'Change default' })
await expect(
dialog.getByText(
'Are you sure you want to change the default IPv4 subnet pool for silo maze-war from default-v4-subnet-pool to secondary-v4-subnet-pool?'
@@ -252,7 +252,7 @@ test('Subnet pool silo clear default', async ({ page }) => {
await clickRowAction(page, 'maze-war', 'Clear default')
- const dialog = page.getByRole('dialog', { name: 'Confirm clear default' })
+ const dialog = page.getByRole('dialog', { name: 'Clear default' })
await expect(
dialog.getByText(
'Are you sure you want default-v4-subnet-pool to stop being the default IPv4 subnet pool for silo maze-war?'
@@ -281,7 +281,7 @@ test('Subnet pool delete', async ({ page }) => {
// First remove the member so the pool can be deleted
await page.goto('/system/networking/subnet-pools/secondary-v4-subnet-pool')
await clickRowAction(page, '172.20.0.0/16', 'Remove')
- const removeDialog = page.getByRole('dialog', { name: 'Confirm remove' })
+ const removeDialog = page.getByRole('dialog', { name: 'Remove member' })
await expect(removeDialog).toBeVisible()
await removeDialog.getByRole('button', { name: 'Confirm' }).click()
await expect(page.getByRole('cell', { name: '172.20.0.0/16' })).toBeHidden()
@@ -289,7 +289,7 @@ test('Subnet pool delete', async ({ page }) => {
// Use client-side navigation to preserve MSW db state
await page.getByLabel('Breadcrumbs').getByRole('link', { name: 'Subnet Pools' }).click()
await clickRowAction(page, 'secondary-v4-subnet-pool', 'Delete')
- const deleteDialog = page.getByRole('dialog', { name: 'Confirm delete' })
+ const deleteDialog = page.getByRole('dialog', { name: 'Delete subnet pool' })
await expect(deleteDialog).toBeVisible()
await deleteDialog.getByRole('button', { name: 'Confirm' }).click()
await expect(page.getByRole('cell', { name: 'secondary-v4-subnet-pool' })).toBeHidden()
diff --git a/test/e2e/system-update.e2e.ts b/test/e2e/system-update.e2e.ts
index b3daf6f447..b68f1ddd0d 100644
--- a/test/e2e/system-update.e2e.ts
+++ b/test/e2e/system-update.e2e.ts
@@ -61,7 +61,7 @@ test('Set target release', async ({ page }) => {
await page.getByRole('button', { name: '18.0.0 actions' }).click()
await page.getByRole('menuitem', { name: 'Set as target release' }).click()
- const modal = page.getByRole('dialog', { name: 'Confirm set target release' })
+ const modal = page.getByRole('dialog', { name: 'Set target release' })
await expect(modal).toBeVisible()
await expect(
modal.getByText('Are you sure you want to set 18.0.0 as the target release?')