From 4b078578d5d6b68db77de69b9384c986c7664766 Mon Sep 17 00:00:00 2001 From: Charlie Park Date: Thu, 5 Sep 2024 16:23:57 -0700 Subject: [PATCH 01/11] Move VPC edit form to view page --- app/forms/vpc-edit.tsx | 22 +++++----- app/pages/project/vpcs/VpcPage/VpcPage.tsx | 47 +++++++++++++++++++--- app/pages/project/vpcs/VpcsPage.tsx | 4 +- app/routes.tsx | 12 +++--- test/e2e/vpcs.e2e.ts | 29 +++++++++++++ 5 files changed, 93 insertions(+), 21 deletions(-) diff --git a/app/forms/vpc-edit.tsx b/app/forms/vpc-edit.tsx index b50a73ab40..cee9a721b7 100644 --- a/app/forms/vpc-edit.tsx +++ b/app/forms/vpc-edit.tsx @@ -37,18 +37,22 @@ export function EditVpcSideModalForm() { query: { project }, }) - const onDismiss = () => navigate(pb.vpcs({ project })) + const onDismiss = () => navigate(pb.vpc({ project, vpc: vpcName })) const editVpc = useApiMutation('vpcUpdate', { - onSuccess(vpc) { + onSuccess(updatedVpc) { + navigate(pb.vpc({ project, vpc: updatedVpc.name })) queryClient.invalidateQueries('vpcList') - queryClient.setQueryData( - 'vpcView', - { path: { vpc: vpc.name }, query: { project } }, - vpc - ) - addToast({ content: 'Your VPC has been created' }) - onDismiss() + + // Only invalidate if we're staying on the same page. If the name + // _has_ changed, invalidating ipPoolView causes an error page to flash + // while the loader for the target page is running because the current + // page's pool gets cleared out while we're still on the page. If we're + // navigating to a different page, its query will fetch anew regardless. + if (vpc.name === updatedVpc.name) { + queryClient.invalidateQueries('vpcView') + } + addToast({ content: 'Your VPC has been updated' }) }, }) diff --git a/app/pages/project/vpcs/VpcPage/VpcPage.tsx b/app/pages/project/vpcs/VpcPage/VpcPage.tsx index b1bf4073e5..0cc924c0ee 100644 --- a/app/pages/project/vpcs/VpcPage/VpcPage.tsx +++ b/app/pages/project/vpcs/VpcPage/VpcPage.tsx @@ -5,13 +5,17 @@ * * Copyright Oxide Computer Company */ -import type { LoaderFunctionArgs } from 'react-router-dom' +import { useMemo } from 'react' +import { useNavigate, type LoaderFunctionArgs } from 'react-router-dom' -import { apiQueryClient, usePrefetchedApiQuery } from '@oxide/api' +import { apiQueryClient, useApiMutation, usePrefetchedApiQuery } from '@oxide/api' import { Networking24Icon } from '@oxide/design-system/icons/react' +import { MoreActionsMenu } from '~/components/MoreActionsMenu' import { RouteTabs, Tab } from '~/components/RouteTabs' import { getVpcSelector, useVpcSelector } from '~/hooks' +import { confirmDelete } from '~/stores/confirm-delete' +import { addToast } from '~/stores/toast' import { DescriptionCell } from '~/table/cells/DescriptionCell' import { DateTime } from '~/ui/lib/DateTime' import { PageHeader, PageTitle } from '~/ui/lib/PageHeader' @@ -27,17 +31,50 @@ VpcPage.loader = async ({ params }: LoaderFunctionArgs) => { } export function VpcPage() { + const navigate = useNavigate() const vpcSelector = useVpcSelector() + const { project, vpc: vpcName } = vpcSelector const { data: vpc } = usePrefetchedApiQuery('vpcView', { - path: { vpc: vpcSelector.vpc }, - query: { project: vpcSelector.project }, + path: { vpc: vpcName }, + query: { project }, }) + const { mutateAsync: deleteVpc } = useApiMutation('vpcDelete', { + onSuccess() { + navigate(pb.vpcs({ project })) + apiQueryClient.invalidateQueries('vpcList') + addToast({ content: 'VPC deleted' }) + }, + }) + + const actions = useMemo( + () => [ + { + label: 'Edit', + onActivate() { + navigate(pb.vpcEdit(vpcSelector)) + }, + }, + { + label: 'Delete', + onActivate: confirmDelete({ + doDelete: () => deleteVpc({ path: { vpc: vpc.name }, query: { project } }), + label: vpc.name, + }), + className: 'destructive', + }, + ], + [deleteVpc, navigate, vpcSelector, project, vpc.name] + ) + return ( <> }>{vpc.name} - +
+ + +
diff --git a/app/pages/project/vpcs/VpcsPage.tsx b/app/pages/project/vpcs/VpcsPage.tsx index 87f01df470..8b4d8a931b 100644 --- a/app/pages/project/vpcs/VpcsPage.tsx +++ b/app/pages/project/vpcs/VpcsPage.tsx @@ -22,6 +22,7 @@ import { Networking16Icon, Networking24Icon } from '@oxide/design-system/icons/r import { DocsPopover } from '~/components/DocsPopover' import { getProjectSelector, useProjectSelector, useQuickActions } from '~/hooks' import { confirmDelete } from '~/stores/confirm-delete' +import { addToast } from '~/stores/toast' import { SkeletonCell } from '~/table/cells/EmptyCell' import { LinkCell, makeLinkCell } from '~/table/cells/LinkCell' import { getActionsCol, type MenuAction } from '~/table/columns/action-col' @@ -83,6 +84,7 @@ export function VpcsPage() { const deleteVpc = useApiMutation('vpcDelete', { onSuccess() { queryClient.invalidateQueries('vpcList') + addToast({ content: 'VPC deleted' }) }, }) @@ -147,7 +149,7 @@ export function VpcsPage() { }>VPCs - + New Vpc } /> diff --git a/app/routes.tsx b/app/routes.tsx index f6f21f3856..609a39f96c 100644 --- a/app/routes.tsx +++ b/app/routes.tsx @@ -348,12 +348,6 @@ export const routes = createRoutesFromElements( element={} handle={{ crumb: 'New VPC' }} /> - } - loader={EditVpcSideModalForm.loader} - handle={{ crumb: 'Edit VPC' }} - /> @@ -365,6 +359,12 @@ export const routes = createRoutesFromElements( loader={VpcFirewallRulesTab.loader} /> } loader={VpcFirewallRulesTab.loader}> + } + loader={EditVpcSideModalForm.loader} + handle={{ crumb: 'Edit VPC' }} + /> { await expect(page.getByRole('cell', { name: 'allow-icmp' })).toBeVisible() }) +test('can edit VPC', async ({ page }) => { + // update the VPC name, starting from the VPCs list page + await page.goto('/projects/mock-project/vpcs') + await expectRowVisible(page.getByRole('table'), { name: 'mock-vpc' }) + await clickRowAction(page, 'mock-vpc', 'Edit') + await expect(page).toHaveURL('/projects/mock-project/vpcs/mock-vpc/edit') + await page.getByRole('textbox', { name: 'Name' }).first().fill('mock-vpc-2') + await page.getByRole('button', { name: 'Update VPC' }).click() + await expect(page).toHaveURL('/projects/mock-project/vpcs/mock-vpc-2/firewall-rules') + await expect(page.getByRole('heading', { name: 'mock-vpc-2' })).toBeVisible() + + // now update the VPC description, starting from the VPC view page + await page.getByRole('button', { name: 'VPC actions' }).click() + await page.getByRole('menuitem', { name: 'Edit' }).click() + await expect(page).toHaveURL('/projects/mock-project/vpcs/mock-vpc-2/edit') + await page.getByRole('textbox', { name: 'Description' }).fill('updated description') + await page.getByRole('button', { name: 'Update VPC' }).click() + await expect(page).toHaveURL('/projects/mock-project/vpcs/mock-vpc-2/firewall-rules') + + // go to the VPCs list page and verify the name and description change + await page.getByRole('link', { name: 'VPCs' }).click() + await expect(page.getByRole('table').locator('tbody >> tr')).toHaveCount(1) + await expectRowVisible(page.getByRole('table'), { + name: 'mock-vpc-2', + 'DNS name': 'mock-vpc', + description: 'updated description', + }) +}) + test('can create and delete subnet', async ({ page }) => { await page.goto('/projects/mock-project/vpcs/mock-vpc') await page.getByRole('tab', { name: 'Subnets' }).click() From 4052aee12aeab0d2d233cd76c4f1ebcb67a3e3c3 Mon Sep 17 00:00:00 2001 From: Charlie Park Date: Fri, 6 Sep 2024 20:24:21 -0700 Subject: [PATCH 02/11] better invalidation --- app/forms/ip-pool-edit.tsx | 9 --------- app/pages/project/vpcs/VpcPage/VpcPage.tsx | 10 ++++++++-- 2 files changed, 8 insertions(+), 11 deletions(-) diff --git a/app/forms/ip-pool-edit.tsx b/app/forms/ip-pool-edit.tsx index b794327469..615eae9810 100644 --- a/app/forms/ip-pool-edit.tsx +++ b/app/forms/ip-pool-edit.tsx @@ -41,15 +41,6 @@ export function EditIpPoolSideModalForm() { queryClient.invalidateQueries('ipPoolList') navigate(pb.ipPool({ pool: updatedPool.name })) addToast({ content: 'Your IP pool has been updated' }) - - // Only invalidate if we're staying on the same page. If the name - // _has_ changed, invalidating ipPoolView causes an error page to flash - // while the loader for the target page is running because the current - // page's pool gets cleared out while we're still on the page. If we're - // navigating to a different page, its query will fetch anew regardless. - if (pool.name === updatedPool.name) { - queryClient.invalidateQueries('ipPoolView') - } }, }) diff --git a/app/pages/project/vpcs/VpcPage/VpcPage.tsx b/app/pages/project/vpcs/VpcPage/VpcPage.tsx index 0cc924c0ee..78f8415802 100644 --- a/app/pages/project/vpcs/VpcPage/VpcPage.tsx +++ b/app/pages/project/vpcs/VpcPage/VpcPage.tsx @@ -8,7 +8,12 @@ import { useMemo } from 'react' import { useNavigate, type LoaderFunctionArgs } from 'react-router-dom' -import { apiQueryClient, useApiMutation, usePrefetchedApiQuery } from '@oxide/api' +import { + apiQueryClient, + useApiMutation, + useApiQueryClient, + usePrefetchedApiQuery, +} from '@oxide/api' import { Networking24Icon } from '@oxide/design-system/icons/react' import { MoreActionsMenu } from '~/components/MoreActionsMenu' @@ -31,6 +36,7 @@ VpcPage.loader = async ({ params }: LoaderFunctionArgs) => { } export function VpcPage() { + const queryClient = useApiQueryClient() const navigate = useNavigate() const vpcSelector = useVpcSelector() const { project, vpc: vpcName } = vpcSelector @@ -41,8 +47,8 @@ export function VpcPage() { const { mutateAsync: deleteVpc } = useApiMutation('vpcDelete', { onSuccess() { + queryClient.invalidateQueries('vpcList') navigate(pb.vpcs({ project })) - apiQueryClient.invalidateQueries('vpcList') addToast({ content: 'VPC deleted' }) }, }) From 5b47b36130f6a718c3bbe6058964f047cbf65b4a Mon Sep 17 00:00:00 2001 From: Charlie Park Date: Fri, 6 Sep 2024 20:29:43 -0700 Subject: [PATCH 03/11] remove probably unnecessary code --- app/forms/vpc-edit.tsx | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/app/forms/vpc-edit.tsx b/app/forms/vpc-edit.tsx index cee9a721b7..009cdbd266 100644 --- a/app/forms/vpc-edit.tsx +++ b/app/forms/vpc-edit.tsx @@ -41,17 +41,8 @@ export function EditVpcSideModalForm() { const editVpc = useApiMutation('vpcUpdate', { onSuccess(updatedVpc) { - navigate(pb.vpc({ project, vpc: updatedVpc.name })) queryClient.invalidateQueries('vpcList') - - // Only invalidate if we're staying on the same page. If the name - // _has_ changed, invalidating ipPoolView causes an error page to flash - // while the loader for the target page is running because the current - // page's pool gets cleared out while we're still on the page. If we're - // navigating to a different page, its query will fetch anew regardless. - if (vpc.name === updatedVpc.name) { - queryClient.invalidateQueries('vpcView') - } + navigate(pb.vpc({ project, vpc: updatedVpc.name })) addToast({ content: 'Your VPC has been updated' }) }, }) From 61e9299aaae42df43cb694a8929e78e78b49b63b Mon Sep 17 00:00:00 2001 From: Charlie Park Date: Mon, 9 Sep 2024 16:59:59 -0700 Subject: [PATCH 04/11] refactor some of the code; will probably split this out --- app/pages/project/vpcs/VpcPage/VpcPage.tsx | 33 ++++++++++------------ 1 file changed, 15 insertions(+), 18 deletions(-) diff --git a/app/pages/project/vpcs/VpcPage/VpcPage.tsx b/app/pages/project/vpcs/VpcPage/VpcPage.tsx index 78f8415802..2b864b8e7f 100644 --- a/app/pages/project/vpcs/VpcPage/VpcPage.tsx +++ b/app/pages/project/vpcs/VpcPage/VpcPage.tsx @@ -38,12 +38,8 @@ VpcPage.loader = async ({ params }: LoaderFunctionArgs) => { export function VpcPage() { const queryClient = useApiQueryClient() const navigate = useNavigate() - const vpcSelector = useVpcSelector() - const { project, vpc: vpcName } = vpcSelector - const { data: vpc } = usePrefetchedApiQuery('vpcView', { - path: { vpc: vpcName }, - query: { project }, - }) + const { project, vpc } = useVpcSelector() + const { data } = usePrefetchedApiQuery('vpcView', { path: { vpc }, query: { project } }) const { mutateAsync: deleteVpc } = useApiMutation('vpcDelete', { onSuccess() { @@ -58,25 +54,26 @@ export function VpcPage() { { label: 'Edit', onActivate() { - navigate(pb.vpcEdit(vpcSelector)) + navigate(pb.vpcEdit({ project, vpc })) }, }, { label: 'Delete', onActivate: confirmDelete({ - doDelete: () => deleteVpc({ path: { vpc: vpc.name }, query: { project } }), - label: vpc.name, + doDelete: () => deleteVpc({ path: { vpc }, query: { project } }), + label: vpc, }), className: 'destructive', }, ], - [deleteVpc, navigate, vpcSelector, project, vpc.name] + [deleteVpc, navigate, project, vpc] ) + const { name, description, dnsName, timeCreated, timeModified } = data return ( <> - }>{vpc.name} + }>{name}
@@ -85,24 +82,24 @@ export function VpcPage() { - + - {vpc.dnsName} + {dnsName} - + - + - Firewall Rules - Subnets - Routers + Firewall Rules + Subnets + Routers ) From 7d5cd6249e5032f75af88285699a4743cff44f33 Mon Sep 17 00:00:00 2001 From: Charlie Park Date: Tue, 10 Sep 2024 10:32:54 -0700 Subject: [PATCH 05/11] Add query invalidation --- app/forms/vpc-edit.tsx | 9 +++++++++ app/pages/project/vpcs/VpcPage/VpcPage.tsx | 2 +- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/app/forms/vpc-edit.tsx b/app/forms/vpc-edit.tsx index 009cdbd266..ca6be08f67 100644 --- a/app/forms/vpc-edit.tsx +++ b/app/forms/vpc-edit.tsx @@ -44,6 +44,15 @@ export function EditVpcSideModalForm() { queryClient.invalidateQueries('vpcList') navigate(pb.vpc({ project, vpc: updatedVpc.name })) addToast({ content: 'Your VPC has been updated' }) + + // Only invalidate if we're staying on the same page. If the name + // _has_ changed, invalidating vpcView causes an error page to flash + // while the loader for the target page is running because the current + // page's vpc gets cleared out while we're still on the page. If we're + // navigating to a different page, its query will fetch anew regardless. + if (vpc.name === updatedVpc.name) { + queryClient.invalidateQueries('vpcView') + } }, }) diff --git a/app/pages/project/vpcs/VpcPage/VpcPage.tsx b/app/pages/project/vpcs/VpcPage/VpcPage.tsx index 2b864b8e7f..5416b02813 100644 --- a/app/pages/project/vpcs/VpcPage/VpcPage.tsx +++ b/app/pages/project/vpcs/VpcPage/VpcPage.tsx @@ -45,7 +45,7 @@ export function VpcPage() { onSuccess() { queryClient.invalidateQueries('vpcList') navigate(pb.vpcs({ project })) - addToast({ content: 'VPC deleted' }) + addToast({ content: 'Your VPC has been deleted' }) }, }) From 206f62dc2bc2355754809d79275159bc4e08d988 Mon Sep 17 00:00:00 2001 From: Charlie Park Date: Tue, 10 Sep 2024 10:57:28 -0700 Subject: [PATCH 06/11] no need for extra const --- app/forms/vpc-edit.tsx | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/app/forms/vpc-edit.tsx b/app/forms/vpc-edit.tsx index ca6be08f67..ef3aff22fe 100644 --- a/app/forms/vpc-edit.tsx +++ b/app/forms/vpc-edit.tsx @@ -37,8 +37,6 @@ export function EditVpcSideModalForm() { query: { project }, }) - const onDismiss = () => navigate(pb.vpc({ project, vpc: vpcName })) - const editVpc = useApiMutation('vpcUpdate', { onSuccess(updatedVpc) { queryClient.invalidateQueries('vpcList') @@ -63,7 +61,7 @@ export function EditVpcSideModalForm() { form={form} formType="edit" resourceName="VPC" - onDismiss={onDismiss} + onDismiss={() => navigate(pb.vpc({ project, vpc: vpcName }))} onSubmit={({ name, description, dnsName }) => { editVpc.mutate({ path: { vpc: vpcName }, From 80478423d6a63ded6d20e40365e8a881300afdfb Mon Sep 17 00:00:00 2001 From: Charlie Park Date: Tue, 10 Sep 2024 11:22:45 -0700 Subject: [PATCH 07/11] const name adjustments --- app/forms/vpc-edit.tsx | 2 +- app/pages/project/vpcs/VpcPage/VpcPage.tsx | 33 ++++++++++++---------- 2 files changed, 19 insertions(+), 16 deletions(-) diff --git a/app/forms/vpc-edit.tsx b/app/forms/vpc-edit.tsx index ef3aff22fe..8d8ec43edb 100644 --- a/app/forms/vpc-edit.tsx +++ b/app/forms/vpc-edit.tsx @@ -46,7 +46,7 @@ export function EditVpcSideModalForm() { // Only invalidate if we're staying on the same page. If the name // _has_ changed, invalidating vpcView causes an error page to flash // while the loader for the target page is running because the current - // page's vpc gets cleared out while we're still on the page. If we're + // page's VPC gets cleared out while we're still on the page. If we're // navigating to a different page, its query will fetch anew regardless. if (vpc.name === updatedVpc.name) { queryClient.invalidateQueries('vpcView') diff --git a/app/pages/project/vpcs/VpcPage/VpcPage.tsx b/app/pages/project/vpcs/VpcPage/VpcPage.tsx index 5416b02813..48dffb222c 100644 --- a/app/pages/project/vpcs/VpcPage/VpcPage.tsx +++ b/app/pages/project/vpcs/VpcPage/VpcPage.tsx @@ -38,8 +38,12 @@ VpcPage.loader = async ({ params }: LoaderFunctionArgs) => { export function VpcPage() { const queryClient = useApiQueryClient() const navigate = useNavigate() - const { project, vpc } = useVpcSelector() - const { data } = usePrefetchedApiQuery('vpcView', { path: { vpc }, query: { project } }) + const vpcSelector = useVpcSelector() + const { project, vpc: vpcName } = vpcSelector + const { data: vpc } = usePrefetchedApiQuery('vpcView', { + path: { vpc: vpcName }, + query: { project }, + }) const { mutateAsync: deleteVpc } = useApiMutation('vpcDelete', { onSuccess() { @@ -54,26 +58,25 @@ export function VpcPage() { { label: 'Edit', onActivate() { - navigate(pb.vpcEdit({ project, vpc })) + navigate(pb.vpcEdit(vpcSelector)) }, }, { label: 'Delete', onActivate: confirmDelete({ - doDelete: () => deleteVpc({ path: { vpc }, query: { project } }), - label: vpc, + doDelete: () => deleteVpc({ path: { vpc: vpcName }, query: { project } }), + label: vpcName, }), className: 'destructive', }, ], - [deleteVpc, navigate, project, vpc] + [deleteVpc, navigate, project, vpcName, vpcSelector] ) - const { name, description, dnsName, timeCreated, timeModified } = data return ( <> - }>{name} + }>{vpc.name}
@@ -82,24 +85,24 @@ export function VpcPage() { - + - {dnsName} + {vpc.dnsName} - + - + - Firewall Rules - Subnets - Routers + Firewall Rules + Subnets + Routers ) From a34876b3399136d10fa21541575eb8caf7fe5ec8 Mon Sep 17 00:00:00 2001 From: Charlie Park Date: Tue, 10 Sep 2024 11:49:56 -0700 Subject: [PATCH 08/11] Update useForm import to match main --- app/forms/vpc-edit.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/forms/vpc-edit.tsx b/app/forms/vpc-edit.tsx index 8d8ec43edb..7e5881ff0f 100644 --- a/app/forms/vpc-edit.tsx +++ b/app/forms/vpc-edit.tsx @@ -5,6 +5,7 @@ * * Copyright Oxide Computer Company */ +import { useForm } from 'react-hook-form' import { useNavigate, type LoaderFunctionArgs } from 'react-router-dom' import { @@ -17,7 +18,7 @@ import { import { DescriptionField } from '~/components/form/fields/DescriptionField' import { NameField } from '~/components/form/fields/NameField' import { SideModalForm } from '~/components/form/SideModalForm' -import { getVpcSelector, useForm, useVpcSelector } from '~/hooks' +import { getVpcSelector, useVpcSelector } from '~/hooks' import { addToast } from '~/stores/toast' import { pb } from '~/util/path-builder' From 88b5f29fc1047810b416867f61ab5b4f816b19be Mon Sep 17 00:00:00 2001 From: Charlie Park Date: Tue, 10 Sep 2024 11:57:45 -0700 Subject: [PATCH 09/11] One more update to match changes to main --- app/forms/vpc-edit.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/forms/vpc-edit.tsx b/app/forms/vpc-edit.tsx index 7e5881ff0f..9a6380f5fa 100644 --- a/app/forms/vpc-edit.tsx +++ b/app/forms/vpc-edit.tsx @@ -18,7 +18,7 @@ import { import { DescriptionField } from '~/components/form/fields/DescriptionField' import { NameField } from '~/components/form/fields/NameField' import { SideModalForm } from '~/components/form/SideModalForm' -import { getVpcSelector, useVpcSelector } from '~/hooks' +import { getVpcSelector, useVpcSelector } from '~/hooks/use-params' import { addToast } from '~/stores/toast' import { pb } from '~/util/path-builder' From 116512c194f181c2af0600b0a4fcafbeef4e5241 Mon Sep 17 00:00:00 2001 From: Charlie Park Date: Tue, 10 Sep 2024 12:50:44 -0700 Subject: [PATCH 10/11] add test --- app/forms/vpc-edit.tsx | 2 +- test/e2e/vpcs.e2e.ts | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/app/forms/vpc-edit.tsx b/app/forms/vpc-edit.tsx index 7e5881ff0f..9a6380f5fa 100644 --- a/app/forms/vpc-edit.tsx +++ b/app/forms/vpc-edit.tsx @@ -18,7 +18,7 @@ import { import { DescriptionField } from '~/components/form/fields/DescriptionField' import { NameField } from '~/components/form/fields/NameField' import { SideModalForm } from '~/components/form/SideModalForm' -import { getVpcSelector, useVpcSelector } from '~/hooks' +import { getVpcSelector, useVpcSelector } from '~/hooks/use-params' import { addToast } from '~/stores/toast' import { pb } from '~/util/path-builder' diff --git a/test/e2e/vpcs.e2e.ts b/test/e2e/vpcs.e2e.ts index ed55cb0346..e819789f41 100644 --- a/test/e2e/vpcs.e2e.ts +++ b/test/e2e/vpcs.e2e.ts @@ -59,6 +59,7 @@ test('can edit VPC', async ({ page }) => { await page.getByRole('textbox', { name: 'Description' }).fill('updated description') await page.getByRole('button', { name: 'Update VPC' }).click() await expect(page).toHaveURL('/projects/mock-project/vpcs/mock-vpc-2/firewall-rules') + await expect(page.getByText('descriptionupdated')).toBeVisible() // go to the VPCs list page and verify the name and description change await page.getByRole('link', { name: 'VPCs' }).click() From 8d667efa8d002bb4689694f87a34409bff495703 Mon Sep 17 00:00:00 2001 From: Charlie Park Date: Tue, 10 Sep 2024 12:51:43 -0700 Subject: [PATCH 11/11] oops; wanted more precise assertion here --- test/e2e/vpcs.e2e.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/e2e/vpcs.e2e.ts b/test/e2e/vpcs.e2e.ts index e819789f41..d356ecbc32 100644 --- a/test/e2e/vpcs.e2e.ts +++ b/test/e2e/vpcs.e2e.ts @@ -59,7 +59,7 @@ test('can edit VPC', async ({ page }) => { await page.getByRole('textbox', { name: 'Description' }).fill('updated description') await page.getByRole('button', { name: 'Update VPC' }).click() await expect(page).toHaveURL('/projects/mock-project/vpcs/mock-vpc-2/firewall-rules') - await expect(page.getByText('descriptionupdated')).toBeVisible() + await expect(page.getByText('descriptionupdated description')).toBeVisible() // go to the VPCs list page and verify the name and description change await page.getByRole('link', { name: 'VPCs' }).click()