Skip to content

Commit

Permalink
test(renterd): files and uploads pagination
Browse files Browse the repository at this point in the history
  • Loading branch information
alexfreska committed Dec 20, 2024
1 parent 5a8824d commit 853b556
Show file tree
Hide file tree
Showing 11 changed files with 424 additions and 54 deletions.
83 changes: 83 additions & 0 deletions apps/hostd-e2e/src/specs/pagination.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
import { test, expect, Page } from '@playwright/test'
import { navigateToContracts } from '../fixtures/navigate'
import { afterTest, beforeTest } from '../fixtures/beforeTest'
import { getContractRowByIndex, getContractRows } from '../fixtures/contracts'
import { ContractsResponse, contractsRoute } from '@siafoundation/hostd-types'

test.beforeEach(async ({ page }) => {
await beforeTest(page, {
renterdCount: 3,
})
})

test.afterEach(async () => {
await afterTest()
})

test('viewing a page with no data shows the correct empty state', async ({
page,
}) => {
await page.goto('/contracts?offset=100')
// Check that the empty state is correct.
await expect(
page.getByText('No data on this page, reset pagination to continue.')
).toBeVisible()
await expect(page.getByText('Back to first page')).toBeVisible()
await page.getByText('Back to first page').click()
// Ensure we are now seeing rows of data.
await getContractRowByIndex(page, 0, true)
})

test('paginating contracts with known total and client side pagination', async ({
page,
}) => {
await interceptApiContactsAndEnsure3Results(page)
await navigateToContracts(page)
const url = page.url()
await page.goto(url + '?limit=1')

const first = page.getByRole('button', { name: 'go to first page' })
const previous = page.getByRole('button', { name: 'go to previous page' })
const next = page.getByRole('button', { name: 'go to next page' })
const last = page.getByRole('button', { name: 'go to last page' })
const rows = getContractRows(page)
await expect(rows).toHaveCount(1)
await expect(first).toBeDisabled()
await expect(previous).toBeDisabled()
await expect(next).toBeEnabled()
await expect(last).toBeEnabled()
await next.click()
await expect(rows).toHaveCount(1)
await expect(first).toBeEnabled()
await expect(previous).toBeEnabled()
await expect(next).toBeEnabled()
await expect(last).toBeEnabled()
await next.click()
await expect(rows).toHaveCount(1)
await expect(first).toBeEnabled()
await expect(previous).toBeEnabled()
await expect(next).toBeDisabled()
await expect(last).toBeDisabled()
})

async function interceptApiContactsAndEnsure3Results(page: Page) {
await page.route(`**/api${contractsRoute}*`, async (route) => {
console.log('Intercepted contracts API request')
// Fetch the original response.
const response = await route.fetch()

// Parse the response body as JSON.
const originalData: ContractsResponse = await response.json()

// Slice the contracts down to exactly 3 items.
const modifiedData: ContractsResponse = {
contracts: originalData.contracts.slice(0, 3),
count: Math.min(3, originalData.count),
}

// Fulfill the route with the modified response.
await route.fulfill({
json: modifiedData,
})
})
}
71 changes: 56 additions & 15 deletions apps/renterd-e2e/src/fixtures/files.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
import { Page, expect } from '@playwright/test'
import { readFileSync } from 'fs'
import {
fillTextInputByName,
maybeExpectAndReturn,
step,
} from '@siafoundation/e2e'
import { navigateToBuckets } from './navigate'
import { openBucket } from './buckets'
import { join } from 'path'

export const deleteFile = step(
'delete file',
Expand Down Expand Up @@ -185,14 +183,56 @@ export const getFileRowById = step(
}
)

export const expectFileRowById = step(
'expect file row by ID',
async (page: Page, id: string) => {
return expect(page.getByTestId('filesTable').getByTestId(id)).toBeVisible()
}
)

export const changeExplorerMode = step(
'change explorer mode',
async (page: Page, mode: 'directory' | 'all files' | 'uploads') => {
const changeMode = page.getByRole('button', {
name: 'change explorer mode',
})
const modeButton = page
.getByRole('menu')
.getByRole('menuitem', { name: mode })
await expect(changeMode).toBeVisible()
await changeMode.click()
await expect(modeButton).toBeVisible()
await modeButton.click()

if (mode === 'uploads') {
await expect(page.getByTestId('uploadsTable')).toBeVisible()
}
if (mode === 'all files') {
await expect(page.getByTestId('filesTable')).toBeVisible()
await expect(
page.getByTestId('navbar').getByText('All files')
).toBeVisible()
}
if (mode === 'directory') {
await expect(page.getByTestId('filesTable')).toBeVisible()
await expect(
page.getByTestId('navbar').getByText('All files')
).toBeHidden()
}
}
)

function generateDummyFile(sizeInBytes: number): Buffer {
return Buffer.alloc(sizeInBytes, 'a')
}

async function simulateDragAndDropFile(
page: Page,
selector: string,
filePath: string,
fileName: string,
fileType = ''
sizeInBytes: number
) {
const buffer = readFileSync(filePath).toString('base64')
const buffer = generateDummyFile(sizeInBytes).toString('base64')

const dataTransfer = await page.evaluateHandle(
async ({ bufferData, localFileName, localFileType }) => {
Expand All @@ -209,7 +249,7 @@ async function simulateDragAndDropFile(
{
bufferData: `data:application/octet-stream;base64,${buffer}`,
localFileName: fileName,
localFileType: fileType,
localFileType: '',
}
)

Expand All @@ -218,18 +258,18 @@ async function simulateDragAndDropFile(

export const dragAndDropFileFromSystem = step(
'drag and drop file from system',
async (page: Page, localFilePath: string, systemFile?: string) => {
async (page: Page, localFilePath: string, sizeInBytes = 10) => {
await simulateDragAndDropFile(
page,
`[data-testid=filesDropzone]`,
join(__dirname, 'sample-files', systemFile || 'sample.txt'),
'/' + localFilePath
'/' + localFilePath,
sizeInBytes
)
}
)

export interface FileMap {
[key: string]: string | FileMap
export type FileMap = {
[key: string]: number | FileMap
}

// Iterate through the file map and create files/directories.
Expand All @@ -246,7 +286,8 @@ export const createFilesMap = step(
await fileInList(page, path + '/')
await create(map[name] as FileMap, stack.concat(name))
} else {
await dragAndDropFileFromSystem(page, name)
const size = (map[name] as number) || 10
await dragAndDropFileFromSystem(page, name, size)
await fileInList(page, path)
}
}
Expand All @@ -257,15 +298,15 @@ export const createFilesMap = step(
}
)

interface FileExpectMap {
type FileExpectMap = {
[key: string]: 'visible' | 'hidden' | FileExpectMap
}

// Check each file and directory in the map exists.
export const expectFilesMap = step(
'expect files map',
async (page: Page, bucketName: string, map: FileExpectMap) => {
const check = async (map: FileMap, stack: string[]) => {
const check = async (map: FileExpectMap, stack: string[]) => {
for (const name in map) {
await openDirectoryFromAnywhere(page, stack.join('/'))
const currentDirPath = stack.join('/')
Expand All @@ -279,7 +320,7 @@ export const expectFilesMap = step(
}
} else {
await fileInList(page, path + '/')
await check(map[name] as FileMap, stack.concat(name))
await check(map[name], stack.concat(name))
}
}
}
Expand Down
37 changes: 37 additions & 0 deletions apps/renterd-e2e/src/fixtures/uploads.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { Page, expect } from '@playwright/test'
import { maybeExpectAndReturn, step } from '@siafoundation/e2e'

export const uploadInList = step(
'expect upload in list',
async (page: Page, id: string, timeout?: number) => {
await expect(page.getByTestId('uploadsTable').getByTestId(id)).toBeVisible({
timeout,
})
}
)

export const uploadNotInList = step(
'expect upload not in list',
async (page: Page, id: string) => {
await expect(page.getByTestId('uploadsTable').getByTestId(id)).toBeHidden()
}
)

export const getUploadRowById = step(
'get upload row by ID',
async (page: Page, id: string, shouldExpect?: boolean) => {
return maybeExpectAndReturn(
page.getByTestId('uploadsTable').getByTestId(id),
shouldExpect
)
}
)

export const expectUploadRowById = step(
'expect upload row by ID',
async (page: Page, id: string) => {
return expect(
page.getByTestId('uploadsTable').getByTestId(id)
).toBeVisible()
}
)
30 changes: 15 additions & 15 deletions apps/renterd-e2e/src/specs/files.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -251,13 +251,13 @@ test('bulk delete across nested directories', async ({ page }) => {
await createBucket(page, bucketName)
await createFilesMap(page, bucketName, {
dir1: {
'file1.txt': null,
'file2.txt': null,
'file1.txt': 10,
'file2.txt': 10,
},
dir2: {
'file3.txt': null,
'file4.txt': null,
'file5.txt': null,
'file3.txt': 10,
'file4.txt': 10,
'file5.txt': 10,
},
})
await navigateToBuckets({ page })
Expand Down Expand Up @@ -296,13 +296,13 @@ test('bulk delete using the all files explorer mode', async ({ page }) => {
await createBucket(page, bucketName)
await createFilesMap(page, bucketName, {
dir1: {
'file1.txt': null,
'file2.txt': null,
'file1.txt': 10,
'file2.txt': 10,
},
dir2: {
'file3.txt': null,
'file4.txt': null,
'file5.txt': null,
'file3.txt': 10,
'file4.txt': 10,
'file5.txt': 10,
},
})
await navigateToBuckets({ page })
Expand Down Expand Up @@ -346,11 +346,11 @@ test('bulk selecting the entire page ignores the .. parent directory nav row', a
await navigateToBuckets({ page })
await createBucket(page, bucketName)
await createFilesMap(page, bucketName, {
'file1.txt': null,
'file2.txt': null,
'file3.txt': null,
'file4.txt': null,
'file5.txt': null,
'file1.txt': 10,
'file2.txt': 10,
'file3.txt': 10,
'file4.txt': 10,
'file5.txt': 10,
})
await navigateToBuckets({ page })
await openBucket(page, bucketName)
Expand Down
36 changes: 18 additions & 18 deletions apps/renterd-e2e/src/specs/filesMove.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,16 +28,16 @@ test('move two files by selecting and dragging from one directory out to another
await navigateToBuckets({ page })
await createBucket(page, bucketName)
await createFilesMap(page, bucketName, {
'file1.txt': null,
'file1.txt': 10,
dir1: {
'file2.txt': null,
'file2.txt': 10,
},
dir2: {
'file3.txt': null,
'file4.txt': null,
'file3.txt': 10,
'file4.txt': 10,
dir3: {
'file5.txt': null,
'file6.txt': null,
'file5.txt': 10,
'file6.txt': 10,
},
},
})
Expand Down Expand Up @@ -88,15 +88,15 @@ test('move a file via drag and drop while leaving a separate set of selected fil
await navigateToBuckets({ page })
await createBucket(page, bucketName)
await createFilesMap(page, bucketName, {
'file0.txt': null,
'file1.txt': null,
'file0.txt': 10,
'file1.txt': 10,
dir1: {
'file2.txt': null,
'file2.txt': 10,
},
dir2: {
'file3.txt': null,
'file4.txt': null,
'file5.txt': null,
'file3.txt': 10,
'file4.txt': 10,
'file5.txt': 10,
},
})
await navigateToBuckets({ page })
Expand Down Expand Up @@ -143,16 +143,16 @@ test('move files by selecting and using the docked menu bulk action', async ({
await navigateToBuckets({ page })
await createBucket(page, bucketName)
await createFilesMap(page, bucketName, {
'file1.txt': null,
'file1.txt': 10,
dir1: {
'file2.txt': null,
'file2.txt': 10,
},
dir2: {
'file3.txt': null,
'file4.txt': null,
'file3.txt': 10,
'file4.txt': 10,
dir3: {
'file5.txt': null,
'file6.txt': null,
'file5.txt': 10,
'file6.txt': 10,
},
},
})
Expand Down
Loading

0 comments on commit 853b556

Please sign in to comment.