diff --git a/ui-e2e-tests-utils/getMockStatusFn.ts b/ui-e2e-tests-utils/getMockStatusFn.ts deleted file mode 100644 index 698849e..0000000 --- a/ui-e2e-tests-utils/getMockStatusFn.ts +++ /dev/null @@ -1,67 +0,0 @@ -import type { MastodonStatus } from 'wildebeest/frontend/src/types' - -/** - * 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: MastodonStatus = { - id: `mock-fetch-status-${paddedNum}`, - created_at: new Date().toISOString(), - in_reply_to_id: null, - in_reply_to_account_id: null, - sensitive: false, - spoiler_text: '', - visibility: 'public', - language: 'en', - uri: '', - url: '', - replies_count: 0, - reblogs_count: 0, - favourites_count: 0, - edited_at: null, - content: `Mock Fetched Status #${paddedNum}`, - reblog: null, - account: { - id: '109355700962815786', - username: 'georgetakei', - acct: 'georgetakei@universeodon.com', - display_name: 'George Takei 🏳️‍🌈🖖🏽', - locked: false, - bot: false, - discoverable: true, - group: false, - created_at: '2022-11-15T00:00:00.000Z', - note: '\u003cp\u003eI boldly went to this new site. Follow for more recipes and tips.\u003c/p\u003e', - url: 'https://universeodon.com/@georgetakei', - avatar: - 'https://files.mastodon.social/cache/accounts/avatars/109/355/700/962/815/786/original/7d278db7224de27d.jpg', - avatar_static: - 'https://files.mastodon.social/cache/accounts/avatars/109/355/700/962/815/786/original/7d278db7224de27d.jpg', - header: - 'https://files.mastodon.social/cache/accounts/headers/109/355/700/962/815/786/original/01c05d0b46e15480.jpg', - header_static: - 'https://files.mastodon.social/cache/accounts/headers/109/355/700/962/815/786/original/01c05d0b46e15480.jpg', - followers_count: 331437, - following_count: 37, - statuses_count: 187, - last_status_at: '2023-01-04', - emojis: [], - fields: [], - }, - media_attachments: [], - mentions: [], - tags: [], - emojis: [], - card: null, - poll: null, - } - numOfGeneratedMockStatuses++ - return status - } -} diff --git a/ui-e2e-tests/account-page.spec.ts b/ui-e2e-tests/account-page.spec.ts index c7b3e91..77cd122 100644 --- a/ui-e2e-tests/account-page.spec.ts +++ b/ui-e2e-tests/account-page.spec.ts @@ -1,5 +1,4 @@ import { test, expect } from '@playwright/test' -import { getMockStatusFn } from 'wildebeest/ui-e2e-tests-utils/getMockStatusFn' test('Navigation to and view of an account (with 1 post)', async ({ page }) => { await page.goto('http://127.0.0.1:8788/explore') @@ -46,35 +45,3 @@ test('Navigation to and view of an account (with 2 posts)', async ({ page }) => await expect(post2Locator.getByRole('img', { name: 'Avatar of Raffa123$' })).toBeVisible() await expect(post2Locator).toContainText('Hi! My name is Rafael!') }) - -test('Fetching of new account toots on scroll (infinite scrolling)', async ({ page, browserName }) => { - test.skip(browserName !== 'chromium', 'Only chromium tests this well') - - const generateFakeStatus = getMockStatusFn() - await page.route('http://127.0.0.1:8788/api/v1/accounts/rafa/statuses?*', async (route) => { - const newStatuses = new Array(5).fill(null).map(generateFakeStatus) - await route.fulfill({ body: JSON.stringify(newStatuses) }) - }) - - await page.goto('http://127.0.0.1:8788/explore') - await page.locator('article').filter({ hasText: "I'm Rafa, a designer and app" }).locator('i.fa-globe + span').click() - await page.waitForLoadState('networkidle') - await page.getByRole('link', { name: 'Rafa', exact: true }).click() - await page.waitForLoadState('networkidle') - - 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) -}) diff --git a/ui-e2e-tests/explore-page.spec.ts b/ui-e2e-tests/explore-page.spec.ts index 544d486..704fc49 100644 --- a/ui-e2e-tests/explore-page.spec.ts +++ b/ui-e2e-tests/explore-page.spec.ts @@ -1,5 +1,4 @@ import { test, expect } from '@playwright/test' -import { getMockStatusFn } from 'wildebeest/ui-e2e-tests-utils/getMockStatusFn' test('Display the list of toots in the explore page', async ({ page }) => { await page.goto('http://127.0.0.1:8788/explore') @@ -15,32 +14,3 @@ test('Display the list of toots in the explore page', async ({ page }) => { await expect(page.locator('article').filter({ hasText: tootText })).toBeVisible() } }) - -test('Fetching of new toots on scroll (infinite scrolling)', async ({ page, browserName }) => { - test.skip(browserName !== 'chromium', 'Only chromium tests this well') - - const generateFakeStatus = getMockStatusFn() - await page.route('http://127.0.0.1:8788/api/v1/timelines/public?*', async (route) => { - const newStatuses = new Array(5).fill(null).map(generateFakeStatus) - await route.fulfill({ body: JSON.stringify(newStatuses) }) - }) - - await page.goto('http://127.0.0.1:8788/explore') - await page.waitForLoadState('networkidle') - - 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) -}) diff --git a/ui-e2e-tests/infinite-scrolling.spec.ts b/ui-e2e-tests/infinite-scrolling.spec.ts new file mode 100644 index 0000000..b146b6c --- /dev/null +++ b/ui-e2e-tests/infinite-scrolling.spec.ts @@ -0,0 +1,76 @@ +import { test, expect, Page } 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 account page', + goToPageFn: async (page: Page) => { + await page.goto('http://127.0.0.1:8788/explore') + await page.locator('article').filter({ hasText: "I'm Rafael" }).locator('i.fa-globe + span').click() + await page.waitForLoadState('networkidle') + await page.getByRole('link', { name: 'Raffa123$', exact: true }).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 }) => + 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) => { + const 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: {} as Account, + media_attachments: [], + } as unknown as MastodonStatus + numOfGeneratedMockStatuses++ + return status + } +}