mirror of
https://github.com/supabase/supabase.git
synced 2026-07-01 01:25:54 +08:00
* added tests for users and minor refactor * fix helpers * addressed PR feedback * remove before await * missed the await
254 lines
8.0 KiB
TypeScript
254 lines
8.0 KiB
TypeScript
import { expect } from '@playwright/test'
|
|
import path from 'path'
|
|
import { test } from '../utils/test.js'
|
|
import { waitForApiResponse } from '../utils/wait-for-response.js'
|
|
import {
|
|
createBucket,
|
|
createFolder,
|
|
deleteAllBuckets,
|
|
deleteBucket,
|
|
deleteItem,
|
|
downloadFile,
|
|
navigateToBucket,
|
|
renameItem,
|
|
uploadFile,
|
|
} from '../utils/storage-helpers.js'
|
|
import { dismissToastsIfAny } from '../utils/dismiss-toast.js'
|
|
|
|
const bucketNamePrefix = 'pw_bucket'
|
|
|
|
test.describe.serial('Storage', () => {
|
|
test.beforeEach(async ({ page, ref }) => {
|
|
await deleteAllBuckets(page, ref)
|
|
})
|
|
|
|
test('can navigate to storage page', async ({ page, ref }) => {
|
|
await expect(
|
|
page.getByRole('button', { name: 'New bucket' }),
|
|
'New bucket button should be visible'
|
|
).toBeVisible()
|
|
|
|
// Verify we're on the storage files page
|
|
await expect(page).toHaveURL(new RegExp(`/project/${ref}/storage/files`))
|
|
})
|
|
|
|
test('can create a private bucket', async ({ page, ref }) => {
|
|
const bucketName = `${bucketNamePrefix}_private`
|
|
|
|
await createBucket(page, ref, bucketName, false)
|
|
|
|
// Verify it's marked as private (no "Public" badge should be visible)
|
|
const bucketRow = page.getByRole('row').filter({ hasText: bucketName })
|
|
await expect(bucketRow, 'Bucket row should be visible').toBeVisible()
|
|
await expect(
|
|
bucketRow.getByText('Public'),
|
|
'Private bucket should not have Public badge'
|
|
).not.toBeVisible()
|
|
})
|
|
|
|
test('can create a public bucket', async ({ page, ref }) => {
|
|
const bucketName = `${bucketNamePrefix}_public`
|
|
|
|
await createBucket(page, ref, bucketName, true)
|
|
|
|
// Verify it's marked as public - wait for the badge to appear
|
|
const bucketRow = page.getByRole('row').filter({ hasText: bucketName })
|
|
await expect(bucketRow, 'Bucket row should be visible').toBeVisible()
|
|
|
|
// The Public badge should be visible within the bucket row
|
|
await expect(
|
|
bucketRow.getByText('Public', { exact: true }),
|
|
'Bucket should be marked as Public'
|
|
).toBeVisible()
|
|
})
|
|
|
|
test('can edit bucket settings', async ({ page, ref }) => {
|
|
const bucketName = `${bucketNamePrefix}_edit`
|
|
|
|
// Create a private bucket
|
|
await createBucket(page, ref, bucketName, false)
|
|
|
|
// Navigate to the bucket
|
|
await navigateToBucket(page, ref, bucketName)
|
|
|
|
// Open edit bucket dropdown
|
|
await page.getByRole('button', { name: 'Edit bucket' }).click()
|
|
await page.getByRole('menuitem', { name: 'Bucket settings' }).click()
|
|
|
|
// Toggle public setting
|
|
const publicToggle = page.getByRole('switch', { name: 'Public bucket' })
|
|
await expect(publicToggle, 'Public toggle should be visible').toBeVisible()
|
|
await publicToggle.click()
|
|
|
|
// Save changes
|
|
const apiPromise = waitForApiResponse(page, 'storage', ref, `buckets/${bucketName}`, {
|
|
method: 'PATCH',
|
|
})
|
|
await page.getByRole('button', { name: 'Save' }).click()
|
|
await apiPromise
|
|
|
|
// Verify the bucket is now public
|
|
await expect(
|
|
page.getByText('Public').first(),
|
|
'Bucket should now be marked as Public'
|
|
).toBeVisible()
|
|
})
|
|
|
|
test('can delete a bucket', async ({ page, ref }) => {
|
|
const bucketName = `${bucketNamePrefix}_delete`
|
|
|
|
// Create a bucket
|
|
await createBucket(page, ref, bucketName, false)
|
|
|
|
// Delete it
|
|
await deleteBucket(page, ref, bucketName)
|
|
|
|
// Verify it's gone
|
|
await expect(
|
|
page.getByRole('row').filter({ hasText: bucketName }),
|
|
'Bucket should not be visible after deletion'
|
|
).not.toBeVisible()
|
|
})
|
|
|
|
test('can search for buckets', async ({ page, ref }) => {
|
|
const bucketName1 = `${bucketNamePrefix}_search_1`
|
|
const bucketName2 = `${bucketNamePrefix}_search_2`
|
|
|
|
// Create two buckets
|
|
await createBucket(page, ref, bucketName1, false)
|
|
await dismissToastsIfAny(page)
|
|
await createBucket(page, ref, bucketName2, false)
|
|
|
|
// Search for first bucket
|
|
const searchInput = page.getByPlaceholder('Search for a bucket')
|
|
await searchInput.fill('search_1')
|
|
|
|
// Verify only first bucket is visible
|
|
await expect(
|
|
page.getByRole('row').filter({ hasText: bucketName1 }),
|
|
'First bucket should be visible in search results'
|
|
).toBeVisible()
|
|
await expect(
|
|
page.getByRole('row').filter({ hasText: bucketName2 }),
|
|
'Second bucket should not be visible in search results'
|
|
).not.toBeVisible()
|
|
|
|
// Clear search
|
|
await searchInput.clear()
|
|
|
|
// Verify both buckets are visible
|
|
await expect(
|
|
page.getByRole('row').filter({ hasText: bucketName1 }),
|
|
'First bucket should be visible after clearing search'
|
|
).toBeVisible()
|
|
await expect(
|
|
page.getByRole('row').filter({ hasText: bucketName2 }),
|
|
'Second bucket should be visible after clearing search'
|
|
).toBeVisible()
|
|
})
|
|
|
|
test('can upload a file', async ({ page, ref }) => {
|
|
const bucketName = `${bucketNamePrefix}_upload`
|
|
const fileName = 'test-file.txt'
|
|
|
|
// Create a bucket and navigate to it
|
|
await createBucket(page, ref, bucketName, false)
|
|
await navigateToBucket(page, ref, bucketName)
|
|
|
|
// Upload a file
|
|
const filePath = path.join(import.meta.dirname, 'files', fileName)
|
|
await uploadFile(page, filePath, fileName)
|
|
|
|
// Clean up
|
|
await deleteBucket(page, ref, bucketName)
|
|
})
|
|
|
|
test('can create a folder', async ({ page, ref }) => {
|
|
const bucketName = `${bucketNamePrefix}_folder`
|
|
const folderName = 'test_folder'
|
|
|
|
// Create a bucket and navigate to it
|
|
await createBucket(page, ref, bucketName, false)
|
|
await navigateToBucket(page, ref, bucketName)
|
|
|
|
// Create a folder
|
|
await createFolder(page, folderName)
|
|
})
|
|
|
|
test('can rename a file', async ({ page, ref }) => {
|
|
const bucketName = `${bucketNamePrefix}_rename_file`
|
|
const fileName = 'test-file.txt'
|
|
const newFileName = 'renamed-file.txt'
|
|
|
|
// Create a bucket, navigate to it, and upload a file
|
|
await createBucket(page, ref, bucketName, false)
|
|
await navigateToBucket(page, ref, bucketName)
|
|
|
|
const filePath = path.join(import.meta.dirname, 'files', fileName)
|
|
await uploadFile(page, filePath, fileName)
|
|
|
|
// Rename the file
|
|
await renameItem(page, fileName, newFileName)
|
|
|
|
// Clean up
|
|
await deleteBucket(page, ref, bucketName)
|
|
})
|
|
|
|
test('can rename a folder', async ({ page, ref }) => {
|
|
const bucketName = `${bucketNamePrefix}_rename_folder`
|
|
const folderName = 'old_folder'
|
|
const newFolderName = 'new_folder'
|
|
|
|
// Create a bucket, navigate to it, and create a folder
|
|
await createBucket(page, ref, bucketName, false)
|
|
await navigateToBucket(page, ref, bucketName)
|
|
await createFolder(page, folderName)
|
|
|
|
// Rename the folder
|
|
await renameItem(page, folderName, newFolderName)
|
|
})
|
|
|
|
test('can delete a file', async ({ page, ref }) => {
|
|
const bucketName = `${bucketNamePrefix}_delete_file`
|
|
const fileName = 'test-file.txt'
|
|
|
|
// Create a bucket, navigate to it, and upload a file
|
|
await createBucket(page, ref, bucketName, false)
|
|
await navigateToBucket(page, ref, bucketName)
|
|
|
|
const filePath = path.join(import.meta.dirname, 'files', fileName)
|
|
await uploadFile(page, filePath, fileName)
|
|
|
|
// Delete the file
|
|
await deleteItem(page, fileName)
|
|
})
|
|
|
|
test('can delete a folder', async ({ page, ref }) => {
|
|
const bucketName = `${bucketNamePrefix}_delete_folder`
|
|
const folderName = 'test_folder'
|
|
|
|
// Create a bucket, navigate to it, and create a folder
|
|
await createBucket(page, ref, bucketName, false)
|
|
await navigateToBucket(page, ref, bucketName)
|
|
await createFolder(page, folderName)
|
|
|
|
// Delete the folder
|
|
await deleteItem(page, folderName)
|
|
})
|
|
|
|
test('can download a file', async ({ page, ref }) => {
|
|
const bucketName = `${bucketNamePrefix}_download`
|
|
const fileName = 'test-file.txt'
|
|
|
|
// Create a bucket, navigate to it, and upload a file
|
|
await createBucket(page, ref, bucketName, false)
|
|
await navigateToBucket(page, ref, bucketName)
|
|
|
|
const filePath = path.join(import.meta.dirname, 'files', fileName)
|
|
await uploadFile(page, filePath, fileName)
|
|
|
|
// Download the file
|
|
await downloadFile(page, fileName)
|
|
})
|
|
})
|