Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

playwright: fix flaky contact method tests #3882

Merged
merged 5 commits into from
May 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 22 additions & 32 deletions test/integration/email-cm.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { dropdownSelect, pageAction, userSessionFile } from './lib'
import Chance from 'chance'
const c = new Chance()

test.describe.configure({ mode: 'serial' })
test.describe.configure({ mode: 'parallel' })
test.use({ storageState: userSessionFile })

// test create, edit, verify, and delete of an EMAIL contact method
Expand Down Expand Up @@ -62,73 +62,63 @@ test('EMAIL contact method', async ({ page, browser }) => {

await page.fill('input[name=code]', code)
await page.click('[role=dialog] button[type=submit]')
await page.locator('[role=dialog]').isHidden()
await expect(page.locator('[role=dialog]')).toBeHidden()

// edit name and enable status updates
const updatedName = 'updated name ' + c.name()
await page
.locator('.MuiCard-root', {
has: page.locator('div > div > h2', { hasText: 'Contact Methods' }),
})
.locator('li', { hasText: email })
.locator('[aria-label="Other Actions"]')
.click()
await page.click(`li:has-text("${email}") [aria-label="Other Actions"]`)
await page.getByRole('menuitem', { name: 'Edit' }).click()
await page.fill('input[name=name]', updatedName)
await page.click('input[name=enableStatusUpdates]')
await page.click('[role=dialog] button[type=submit]')
// We need to move the mouse, otherwise it will keep it's position over the submit button and activate the speed dial...
await page.mouse.move(0, 0)
await expect(page.locator('[role=dialog]')).toBeHidden()

// open edit dialog to verify name change and status updates are enabled
await page
.locator('.MuiCard-root', {
has: page.locator('div > div > h2', { hasText: 'Contact Methods' }),
})
.locator('li', { hasText: email })
.locator('[aria-label="Other Actions"]')
.click()
await page.click(`li:has-text("${email}") [aria-label="Other Actions"]`)
await page.getByRole('menuitem', { name: 'Edit' }).click()
await expect(page.locator('input[name=name]')).toHaveValue(updatedName)
await expect(page.locator('input[name=enableStatusUpdates]')).toBeChecked()
await page.click('[role=dialog] button[type=submit]')

await page.mouse.move(0, 0)
await expect(page.locator('[role=dialog]')).toBeHidden()

// verify deleting a notification rule (immediate by default)
await page
.locator('li', {
hasText: `Immediately notify me via Email at ${email}`,
})
.locator('button')
.click()
await page.click(
`li:has-text("Immediately notify me via Email at ${email}") button`,
)

// click confirm
await page.getByRole('button', { name: 'Confirm' }).click()
await expect(
page.locator('li', {
hasText: `Immediately notify me via Email at ${email}`,
}),
).not.toBeVisible()
).toBeHidden()

// verify adding a notification rule (delayed)
await pageAction(page, 'Add Notification Rule', 'Add Rule')
await dropdownSelect(page, 'Contact Method', updatedName)
await page.fill('input[name=delayMinutes]', '5')
await page.click('[role=dialog] button[type=submit]')

await page.mouse.move(0, 0)
await expect(page.locator('[role=dialog]')).toBeHidden()

await expect(
page.locator('li', {
hasText: `After 5 minutes notify me via Email at ${email}`,
}),
).not.toBeVisible()
).toBeVisible()

await page
.locator('.MuiCard-root', {
has: page.locator('div > div > h2', { hasText: 'Contact Methods' }),
})
.locator('li', { hasText: email })
.locator('[aria-label="Other Actions"]')
.click()
await page.click(`li:has-text("${email}") [aria-label="Other Actions"]`)
await page.getByRole('menuitem', { name: 'Delete' }).click()
await page.getByRole('button', { name: 'Confirm' }).click()

await expect(page.locator('[role=dialog]')).not.toBeVisible()
await page.mouse.move(0, 0)
await expect(page.locator('[role=dialog]')).toBeHidden()
await page
.locator('.MuiCard-root', {
has: page.locator('div > div > h2', { hasText: 'Contact Methods' }),
Expand Down
19 changes: 8 additions & 11 deletions test/integration/first-login.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { dropdownSelect, userSessionFile } from './lib'
import Chance from 'chance'
const c = new Chance()

test.describe.configure({ mode: 'serial' })
test.describe.configure({ mode: 'parallel' })
test.use({ storageState: userSessionFile })

// test create, edit, verify, and delete of an EMAIL contact method
Expand All @@ -28,19 +28,16 @@ test('first time setup', async ({ page }) => {
await page.locator('[role=dialog] button', { hasText: 'Cancel' }).click()

// ensure dialog is not shown
await expect(page.locator('[role=dialog]')).toHaveCount(0)
await expect(page.locator('[role=dialog]')).toBeHidden()

await page.goto('./profile')
await page
.locator('.MuiCard-root', {
has: page.locator('div > div > h2', { hasText: 'Contact Methods' }),
})
.locator('li', { hasText: email })
.locator('[aria-label="Other Actions"]')
.click()
await page.click(`li:has-text("${email}") [aria-label="Other Actions"]`)

await page.getByRole('menuitem', { name: 'Delete' }).click()
await page.getByRole('button', { name: 'Confirm' }).click()

await expect(page.locator('[role=dialog]')).not.toBeVisible()
await expect(page.locator('li', { hasText: email })).not.toBeVisible()
await expect(page.locator('[role=dialog]')).toBeHidden()
await expect(
page.locator(`li:has-text("${email}") [aria-label="Other Actions"]`),
).toBeHidden()
})
11 changes: 10 additions & 1 deletion test/integration/lib/select.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Page } from '@playwright/test'
import { Page, expect } from '@playwright/test'

export async function dropdownSelect(
page: Page,
Expand Down Expand Up @@ -26,9 +26,18 @@ export async function pageAction(
.getAttribute('aria-haspopup')
if (hasPopup) {
await page.hover('button[data-cy="page-fab"]')
await expect(
await page.locator('button[data-cy="page-fab"]'),
).toHaveAttribute('aria-expanded', 'true')
}

await page.getByLabel(mobileAction).locator('button').click()

if (hasPopup) {
await expect(
await page.locator('button[data-cy="page-fab"]'),
).toHaveAttribute('aria-expanded', 'false')
}
return
}

Expand Down
2 changes: 1 addition & 1 deletion web/src/app/lists/FlatList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -364,7 +364,7 @@ export default function FlatList({
)
}

return <FlatListItem key={`${idx}-${item.id}`} index={idx} item={item} />
return <FlatListItem key={item.id || idx} index={idx} item={item} />
})
}

Expand Down
1 change: 0 additions & 1 deletion web/src/app/lists/FlatListItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,6 @@ export default function FlatListItem(props: FlatListItemProps): JSX.Element {

return (
<MUIListItem
key={props.index}
{...linkProps}
{...onClickProps}
{...muiListItemProps}
Expand Down
2 changes: 1 addition & 1 deletion web/src/app/users/UserContactMethodDeleteDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ function UserContactMethodDeleteDialog(props: {
{
id: contactMethodID,
},
{ additionalTypenames: ['UserContactMethod'] },
{ additionalTypenames: ['UserContactMethod', 'User'] },
).then((res) => {
if (res.error) return

Expand Down
6 changes: 5 additions & 1 deletion web/src/app/users/UserNotificationRuleDeleteDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,11 @@ export default function UserNotificationRuleDeleteDialog(props: {
deleteNotification(
{ id: ruleID },
{
additionalTypenames: ['UserNotificationRule', 'UserContactMethod'],
additionalTypenames: [
'UserNotificationRule',
'UserContactMethod',
'User',
],
},
).then((result) => {
if (!result.error) props.onClose()
Expand Down
3 changes: 1 addition & 2 deletions web/src/app/util/OtherActionsDesktop.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ export default function OtherActionsMenuDesktop({

return (
<Menu
anchorEl={() => anchorEl}
anchorEl={anchorEl}
open={isOpen}
onClose={onClose}
PaperProps={{
Expand All @@ -40,7 +40,6 @@ export default function OtherActionsMenuDesktop({
<Tooltip key={idx} title={o.tooltip}>
<div>
<MenuItem
key={idx}
onClick={() => {
onClose()
o.onClick()
Expand Down
1 change: 1 addition & 0 deletions web/src/app/util/SpeedDial.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ export default function CustomSpeedDial(
return
}
action.onClick(e)
setOpen(false)
}}
/>
))}
Expand Down
Loading