kopia lustrzana https://github.com/cloudflare/wildebeest
92 wiersze
3.5 KiB
TypeScript
92 wiersze
3.5 KiB
TypeScript
import { test, expect, Page, Request } from '@playwright/test'
|
|
import type { Account, MastodonStatus } from 'wildebeest/frontend/src/types'
|
|
|
|
test.describe('Infinite (statuses) scrolling', () => {
|
|
const tests = [
|
|
{
|
|
description: 'in explore page',
|
|
goToPageFn: async (page: Page) => await page.goto('http://127.0.0.1:8788/explore'),
|
|
fetchUrl: 'http://127.0.0.1:8788/api/v1/timelines/public?*',
|
|
},
|
|
{
|
|
description: 'in local page',
|
|
goToPageFn: async (page: Page) => await page.goto('http://127.0.0.1:8788/public/local'),
|
|
fetchUrl: 'http://127.0.0.1:8788/api/v1/timelines/public?*',
|
|
isRequestValid: (request: Request) => {
|
|
const searchParams = new URL(request.url()).searchParams
|
|
return searchParams.get('local') === 'true'
|
|
},
|
|
},
|
|
{
|
|
description: 'in federated page',
|
|
goToPageFn: async (page: Page) => await page.goto('http://127.0.0.1:8788/public'),
|
|
fetchUrl: 'http://127.0.0.1:8788/api/v1/timelines/public?*',
|
|
},
|
|
{
|
|
description: 'in account page',
|
|
goToPageFn: async (page: Page) => {
|
|
await page.goto('http://127.0.0.1:8788/explore')
|
|
await page.getByRole('article').getByRole('link').filter({ hasText: 'Raffa123$' }).first().click()
|
|
await expect(page.getByTestId('account-info').getByRole('img', { name: 'Header of Raffa123$' })).toBeVisible()
|
|
},
|
|
fetchUrl: 'http://127.0.0.1:8788/api/v1/accounts/Rafael/statuses?*',
|
|
},
|
|
]
|
|
|
|
tests.forEach(({ description, fetchUrl, goToPageFn, isRequestValid }) =>
|
|
test(description, async ({ page, browserName }) => {
|
|
test.skip(browserName !== 'chromium', 'Only chromium tests infinite scrolling well')
|
|
|
|
await goToPageFn(page)
|
|
await page.waitForLoadState('networkidle')
|
|
|
|
const generateFakeStatus = getMockStatusFn()
|
|
await page.route(fetchUrl, async (route, request) => {
|
|
let newStatuses: MastodonStatus[] = []
|
|
if (!isRequestValid || isRequestValid(request)) {
|
|
newStatuses = new Array(5).fill(null).map(generateFakeStatus)
|
|
}
|
|
await route.fulfill({ body: JSON.stringify(newStatuses) })
|
|
})
|
|
|
|
for (let i = 0; i < 3; i++) {
|
|
await page.keyboard.down('End')
|
|
for (let j = 0; j < 5; j++) {
|
|
const paddedJ = `${i * 5 + j}`.padStart(3, '0')
|
|
// check that the new toots have been loaded
|
|
await expect(page.locator('article').filter({ hasText: `Mock Fetched Status #${paddedJ}` })).toBeVisible()
|
|
}
|
|
const paddedExtra = `${i * 5 + 6}`.padStart(3, '0')
|
|
// check that a 6th toot hasn't been loaded (since the mock endpoint returns 5 toots)
|
|
await expect(
|
|
page.locator('article').filter({ hasText: `Mock Fetched Status #${paddedExtra}` })
|
|
).not.toBeVisible()
|
|
}
|
|
|
|
const numOfMockFetchedToots = await page.locator('article').filter({ hasText: `Mock Fetched Status` }).count()
|
|
// check that all 15 toots have been loaded
|
|
expect(numOfMockFetchedToots).toBe(15)
|
|
})
|
|
)
|
|
})
|
|
|
|
/**
|
|
* generates a function that creates mock statuses when called,
|
|
* it uses a closure to keep track of the number of generated
|
|
* statuses to that they are consistently enumerated
|
|
* ('Mock Fetched Status #000', 'Mock Fetched Status #001', ...)
|
|
*/
|
|
export function getMockStatusFn(): () => MastodonStatus {
|
|
let numOfGeneratedMockStatuses = 0
|
|
return () => {
|
|
const paddedNum = `${numOfGeneratedMockStatuses}`.padStart(3, '0')
|
|
const status = {
|
|
content: `Mock Fetched Status #${paddedNum}`,
|
|
account: { display_name: 'test', emojis: [] } as unknown as Account,
|
|
media_attachments: [],
|
|
} as unknown as MastodonStatus
|
|
numOfGeneratedMockStatuses++
|
|
return status
|
|
}
|
|
}
|