chore: unflake access-control, fix incorrect poll & toPass timeouts

This commit is contained in:
Alessio Gravili
2024-03-22 16:42:41 -04:00
parent 4c109a467f
commit 2c68f8fba1
5 changed files with 21 additions and 21 deletions

View File

@@ -1,9 +1,8 @@
import type { Page } from '@playwright/test'
import type { Payload } from 'payload/types'
import type { Payload, TypeWithID } from 'payload/types'
import { expect, test } from '@playwright/test'
import path from 'path'
import { wait } from 'payload/utilities'
import { fileURLToPath } from 'url'
import type { ReadOnlyCollection, RestrictedVersion } from './payload-types.js'
@@ -134,7 +133,6 @@ describe('access control', () => {
describe('restricted fields', () => {
test('should not show field without permission', async () => {
await page.goto(url.account)
await wait(500)
await expect(page.locator('#field-roles')).toBeHidden()
})
})
@@ -163,7 +161,7 @@ describe('access control', () => {
test('should have collection url', async () => {
await page.goto(readOnlyUrl.list)
await expect(page).toHaveURL(readOnlyUrl.list) // no redirect
await expect(page).toHaveURL(new RegExp(`${readOnlyUrl.list}.*`)) // will redirect to ?limit=10 at the end, so we have to use a wildcard at the end
})
test('should not have "Create New" button', async () => {
@@ -188,7 +186,6 @@ describe('access control', () => {
test('should not render dot menu popup when `create` and `delete` access control is set to false', async () => {
await page.goto(readOnlyUrl.edit(existingDoc.id))
await wait(1000)
await expect(page.locator('.collection-edit .doc-controls .doc-controls__popup')).toBeHidden()
})
})
@@ -213,7 +210,7 @@ describe('access control', () => {
describe('doc level access', () => {
let existingDoc: ReadOnlyCollection
let docLevelAccessURL
let docLevelAccessURL: AdminUrlUtil
beforeAll(async () => {
docLevelAccessURL = new AdminUrlUtil(serverURL, docLevelAccessSlug)
@@ -265,28 +262,26 @@ describe('access control', () => {
const unrestrictedURL = new AdminUrlUtil(serverURL, unrestrictedSlug)
await page.goto(unrestrictedURL.edit(unrestrictedDoc.id))
const button = page.locator(
const addDocButton = page.locator(
'#userRestrictedDocs-add-new button.relationship-add-new__add-button.doc-drawer__toggler',
)
await button.click()
await addDocButton.click()
const documentDrawer = page.locator('[id^=doc-drawer_user-restricted_1_]')
await expect(documentDrawer).toBeVisible()
await documentDrawer.locator('#field-name').fill('anonymous@email.com')
await documentDrawer.locator('#action-save').click()
await wait(200)
await expect(page.locator('.Toastify')).toContainText('successfully')
// ensure user is not allowed to edit this document
await expect(documentDrawer.locator('#field-name')).toBeDisabled()
await documentDrawer.locator('button.doc-drawer__header-close').click()
await wait(200)
await expect(documentDrawer).toBeHidden()
await button.click()
await addDocButton.click()
const documentDrawer2 = page.locator('[id^=doc-drawer_user-restricted_1_]')
await expect(documentDrawer2).toBeVisible()
await documentDrawer2.locator('#field-name').fill('dev@payloadcms.com')
await documentDrawer2.locator('#action-save').click()
await wait(200)
await expect(page.locator('.Toastify')).toContainText('successfully')
// ensure user is allowed to edit this document
@@ -294,7 +289,7 @@ describe('access control', () => {
})
})
async function createDoc(data: any): Promise<{ id: string }> {
async function createDoc(data: any): Promise<TypeWithID & Record<string, unknown>> {
return payload.create({
collection: slug,
data,

View File

@@ -8,6 +8,7 @@ import { fileURLToPath } from 'url'
import { delayNetwork, initPageConsoleErrorCatch, login, saveDocAndAssert } from '../helpers.js'
import { AdminUrlUtil } from '../helpers/adminUrlUtil.js'
import { initPayloadE2E } from '../helpers/initPayloadE2E.js'
import { POLL_TOPASS_TIMEOUT } from '../playwright.config.js'
import config from './config.js'
import { apiKeysSlug, slug } from './shared.js'
const filename = fileURLToPath(import.meta.url)
@@ -105,7 +106,7 @@ describe('auth', () => {
// assert that the value is set
const apiKeyLocator = page.locator('#apiKey')
await expect
.poll(async () => await apiKeyLocator.inputValue(), { timeout: 45000 })
.poll(async () => await apiKeyLocator.inputValue(), { timeout: POLL_TOPASS_TIMEOUT })
.toBeDefined()
await saveDocAndAssert(page)
@@ -114,7 +115,7 @@ describe('auth', () => {
const apiKey = await apiKeyLocator.inputValue()
expect(await page.locator('#apiKey').inputValue()).toStrictEqual(apiKey)
}).toPass({
timeout: 45000,
timeout: POLL_TOPASS_TIMEOUT,
})
})
@@ -140,7 +141,7 @@ describe('auth', () => {
expect(response.user).toBeNull()
}).toPass({
timeout: 45000,
timeout: POLL_TOPASS_TIMEOUT,
})
})
})

View File

@@ -5,6 +5,7 @@ import { wait } from 'payload/utilities'
import shelljs from 'shelljs'
import { devUser } from './credentials.js'
import { POLL_TOPASS_TIMEOUT } from './playwright.config.js'
type FirstRegisterArgs = {
page: Page
@@ -91,7 +92,7 @@ export async function saveDocHotkeyAndAssert(page: Page): Promise<void> {
export async function saveDocAndAssert(page: Page, selector = '#action-save'): Promise<void> {
await page.click(selector, { delay: 100 })
await expect(page.locator('.Toastify')).toContainText('successfully')
await expect.poll(() => page.url(), { timeout: 45000 }).not.toContain('create')
await expect.poll(() => page.url(), { timeout: POLL_TOPASS_TIMEOUT }).not.toContain('create')
}
export async function openNav(page: Page): Promise<void> {
@@ -137,7 +138,7 @@ export function exactText(text: string) {
export const checkPageTitle = async (page: Page, title: string) => {
await expect
.poll(async () => await page.locator('.doc-header__title.render-title')?.first()?.innerText(), {
timeout: 45000,
timeout: POLL_TOPASS_TIMEOUT,
})
.toBe(title)
}
@@ -147,7 +148,7 @@ export const checkBreadcrumb = async (page: Page, text: string) => {
.poll(
async () => await page.locator('.step-nav.app-header__step-nav .step-nav__last')?.innerText(),
{
timeout: 45000,
timeout: POLL_TOPASS_TIMEOUT,
},
)
.toBe(text)

View File

@@ -10,7 +10,7 @@ export class AdminUrlUtil {
constructor(serverURL: string, slug: string) {
this.account = `${serverURL}/admin/account`
this.admin = `${serverURL}/admin`
this.list = `${this.admin}/collections/${slug}?limit=10`
this.list = `${this.admin}/collections/${slug}`
this.create = `${this.list}/create`
}

View File

@@ -1,5 +1,8 @@
import { defineConfig } from '@playwright/test'
export const EXPECT_TIMEOUT = 45000
export const POLL_TOPASS_TIMEOUT = EXPECT_TIMEOUT * 4 // That way expect.poll() or expect().toPass can retry 4 times
export default defineConfig({
// Look for test files in the "test" directory, relative to this configuration file
testDir: '',
@@ -11,7 +14,7 @@ export default defineConfig({
video: 'retain-on-failure',
},
expect: {
timeout: 60000,
timeout: EXPECT_TIMEOUT,
},
workers: 16,
})