feat: users row actions "Cancel invite" on Pending rows and "Renew invite" on Expired rows

This commit is contained in:
fsylvain committed 2026-09-30 02:48:49 +02:00
1 parent 1ece778caf
commit 142325730d
14 files changed
+1156 -35

No files matched your search

+61 -4
View File
@@ -634,6 +634,33 @@ async function openInviteModal(page: Page) {
await page.mouse.move(0, 0)
}
function rowActionButton(page: Page, email: string, name: string) {
return page
.locator('[data-testid="user-row"], [data-testid="user-card"]')
.filter({ hasText: email })
.getByRole('button', { name, exact: true })
}
async function openCancelInviteDialog(page: Page) {
await rowActionButton(page, 'sam.oliveira@renew.example', 'Cancel invite').click()
await page.getByRole('alertdialog').waitFor()
await page.mouse.move(0, 0)
}
async function confirmCancelInvite(page: Page) {
await openCancelInviteDialog(page)
await page
.getByRole('alertdialog')
.getByRole('button', { name: /^Cancel(ling…| invite)$/ })
.click()
await page.mouse.move(0, 0)
}
async function renewPaulHuberInvite(page: Page) {
await rowActionButton(page, 'p.huber@gmail.com', 'Renew invite').click()
await page.mouse.move(0, 0)
}
function inviteWith(email: string, response?: ApiMock) {
return async (page: Page) => {
await openInviteModal(page)
@@ -845,10 +872,40 @@ export const visualStates: Record<string, Record<string, VisualState>> = {
Default: {
path: '/users',
api: usersApi(),
exception: {
maxPercent: 10.5,
reason: 'Row actions (Cancel invite, Renew invite) drawn on the board are out of scope for this slice',
approvedBy: 'user',
},
'Cancel invite: confirm': {
path: '/users',
api: usersApi(),
steps: openCancelInviteDialog,
},
'Cancel invite: sending': {
path: '/users',
api: usersApi({ 'DELETE /v1/user/invite/2': { status: 204, hang: true } }),
steps: confirmCancelInvite,
},
'Cancel invite: failed': {
path: '/users',
api: usersApi({ 'DELETE /v1/user/invite/2': { status: 500 } }),
steps: async (page) => {
await confirmCancelInvite(page)
await page.getByText("Couldn't cancel the invite").waitFor()
await page.mouse.move(0, 0)
},
},
'Cancel invite: done': { path: '/users', skip: 'clock-sensitive' },
'Renew invite: sending': {
path: '/users',
api: usersApi({ 'POST /v1/user/invite/1/renew': { status: 200, hang: true } }),
steps: renewPaulHuberInvite,
},
'Renew invite: done': { path: '/users', skip: 'clock-sensitive' },
'Renew invite: failed': {
path: '/users',
api: usersApi({ 'POST /v1/user/invite/1/renew': { status: 500 } }),
steps: async (page) => {
await renewPaulHuberInvite(page)
await page.getByText("Couldn't renew the invite").waitFor()
await page.mouse.move(0, 0)
},
},
Loading: {