Ensures the browser uses fresh data after seeding by refreshing the route and navigating when done.
161 lines
5.8 KiB
TypeScript
161 lines
5.8 KiB
TypeScript
import type { BrowserContext, Page } from '@playwright/test'
|
|
|
|
import { expect, test } from '@playwright/test'
|
|
import { RESTClient } from 'helpers/rest.js'
|
|
import path from 'path'
|
|
import { fileURLToPath } from 'url'
|
|
|
|
import type { PayloadTestSDK } from '../helpers/sdk/index.js'
|
|
import type { Config } from './payload-types.js'
|
|
|
|
import { ensureCompilationIsDone, initPageConsoleErrorCatch } from '../helpers.js'
|
|
import { AdminUrlUtil } from '../helpers/adminUrlUtil.js'
|
|
import { initPayloadE2ENoConfig } from '../helpers/initPayloadE2ENoConfig.js'
|
|
import { TEST_TIMEOUT_LONG } from '../playwright.config.js'
|
|
import { orderableSlug } from './collections/Orderable/index.js'
|
|
import { orderableJoinSlug } from './collections/OrderableJoin/index.js'
|
|
const filename = fileURLToPath(import.meta.url)
|
|
const dirname = path.dirname(filename)
|
|
|
|
const { beforeAll, describe } = test
|
|
let page: Page
|
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
let payload: PayloadTestSDK<Config>
|
|
let client: RESTClient
|
|
let serverURL: string
|
|
let context: BrowserContext
|
|
|
|
describe('Sort functionality', () => {
|
|
beforeAll(async ({ browser }, testInfo) => {
|
|
testInfo.setTimeout(TEST_TIMEOUT_LONG)
|
|
;({ payload, serverURL } = await initPayloadE2ENoConfig<Config>({ dirname }))
|
|
|
|
context = await browser.newContext()
|
|
page = await context.newPage()
|
|
|
|
initPageConsoleErrorCatch(page)
|
|
|
|
client = new RESTClient({ defaultSlug: 'users', serverURL })
|
|
await client.login()
|
|
|
|
await ensureCompilationIsDone({ page, serverURL })
|
|
})
|
|
|
|
// NOTES: It works for me in headed browser but not in headless, I don't know why.
|
|
// If you are debugging this test, remember to press the seed button before each attempt.
|
|
// assertRows contains expect
|
|
// eslint-disable-next-line playwright/expect-expect
|
|
test('Orderable collection', async () => {
|
|
const url = new AdminUrlUtil(serverURL, orderableSlug)
|
|
await page.goto(url.list)
|
|
|
|
const joinFieldResolvePromise = page.waitForResponse(
|
|
(response) => response.url().includes('/api/orderable-join') && response.status() === 200,
|
|
)
|
|
const seedResponsePromise = page.waitForResponse(
|
|
(response) => response.url().includes('/api/seed') && response.status() === 200,
|
|
)
|
|
await page.locator('.collection-list button', { hasText: 'Seed' }).click()
|
|
await seedResponsePromise
|
|
await joinFieldResolvePromise
|
|
await page.goto(`${url.list}?sort=-_order`)
|
|
|
|
// SORT BY ORDER ASCENDING
|
|
await page.locator('.sort-header button').nth(0).click()
|
|
await assertRows(0, 'A', 'B', 'C', 'D')
|
|
await moveRow(2, 3) // move to middle
|
|
await assertRows(0, 'A', 'C', 'B', 'D')
|
|
await moveRow(3, 1) // move to top
|
|
await assertRows(0, 'B', 'A', 'C', 'D')
|
|
await moveRow(1, 4) // move to bottom
|
|
await assertRows(0, 'A', 'C', 'D', 'B')
|
|
|
|
// SORT BY ORDER DESCENDING
|
|
await page.locator('.sort-header button').nth(0).click()
|
|
await page.waitForURL(/sort=-_order/, { timeout: 2000 })
|
|
await assertRows(0, 'B', 'D', 'C', 'A')
|
|
await moveRow(1, 3) // move to middle
|
|
await assertRows(0, 'D', 'C', 'B', 'A')
|
|
await moveRow(3, 1) // move to top
|
|
await assertRows(0, 'B', 'D', 'C', 'A')
|
|
await moveRow(1, 4) // move to bottom
|
|
await assertRows(0, 'D', 'C', 'A', 'B')
|
|
|
|
// SORT BY TITLE
|
|
await page.getByLabel('Sort by Title Ascending').click()
|
|
await page.waitForURL(/sort=title/, { timeout: 2000 })
|
|
await moveRow(1, 3, 'warning') // warning because not sorted by order first
|
|
})
|
|
|
|
test('Orderable join fields', async () => {
|
|
const url = new AdminUrlUtil(serverURL, orderableJoinSlug)
|
|
await page.goto(url.list)
|
|
|
|
await page.getByText('Join A').click()
|
|
await expect(page.locator('.sort-header button')).toHaveCount(3)
|
|
|
|
await assertRows(0, 'A', 'B', 'C', 'D')
|
|
await moveRow(2, 3, 'success', 0) // move to middle
|
|
await assertRows(0, 'A', 'C', 'B', 'D')
|
|
|
|
await assertRows(1, 'A', 'B', 'C', 'D')
|
|
await moveRow(1, 4, 'success', 1) // move to end
|
|
await assertRows(1, 'B', 'C', 'D', 'A')
|
|
|
|
await page.reload()
|
|
await assertRows(0, 'A', 'C', 'B', 'D')
|
|
await assertRows(1, 'B', 'C', 'D', 'A')
|
|
})
|
|
})
|
|
|
|
async function moveRow(
|
|
from: number,
|
|
to: number,
|
|
expected: 'success' | 'warning' = 'success',
|
|
nthTable = 0,
|
|
) {
|
|
// counting from 1, zero excluded
|
|
const table = page.locator(`tbody`).nth(nthTable)
|
|
const dragHandle = table.locator(`.sort-row`)
|
|
const source = dragHandle.nth(from - 1)
|
|
const target = dragHandle.nth(to - 1)
|
|
|
|
const sourceBox = await source.boundingBox()
|
|
const targetBox = await target.boundingBox()
|
|
if (!sourceBox || !targetBox) {
|
|
throw new Error(
|
|
`Could not find elements to DnD. Probably the dndkit animation is not finished. Try increasing the timeout`,
|
|
)
|
|
}
|
|
// steps is important: move slightly to trigger the drag sensor of DnD-kit
|
|
await page.mouse.move(sourceBox.x + sourceBox.width / 2, sourceBox.y + sourceBox.height / 2, {
|
|
steps: 10,
|
|
})
|
|
await page.mouse.down()
|
|
await page.mouse.move(targetBox.x + targetBox.width / 2, targetBox.y + targetBox.height / 2, {
|
|
steps: 10,
|
|
})
|
|
await page.mouse.up()
|
|
// eslint-disable-next-line playwright/no-wait-for-timeout
|
|
await page.waitForTimeout(400) // dndkit animation
|
|
|
|
if (expected === 'warning') {
|
|
const toast = page.locator('.payload-toast-item.toast-warning')
|
|
await expect(toast).toHaveText(
|
|
'To reorder the rows you must first sort them by the "Order" column',
|
|
)
|
|
}
|
|
}
|
|
|
|
async function assertRows(nthTable: number, ...expectedRows: Array<string>) {
|
|
const table = page.locator('tbody').nth(nthTable)
|
|
const cellTitle = table.locator('.cell-title > :first-child')
|
|
|
|
const rows = table.locator('.sort-row')
|
|
await expect.poll(() => rows.count()).toBe(expectedRows.length)
|
|
|
|
for (let i = 0; i < expectedRows.length; i++) {
|
|
await expect(cellTitle.nth(i)).toHaveText(expectedRows[i]!)
|
|
}
|
|
}
|