feat: add user data export, account deletion, cookie consent, footer, and admin e2e tests

This commit is contained in:
2025-11-13 10:47:50 +00:00
parent bff5742ced
commit df964a7fb1
11 changed files with 1386 additions and 7 deletions
+181
View File
@@ -0,0 +1,181 @@
import pytest
import asyncio
from playwright.async_api import expect
@pytest.mark.asyncio
class TestAdmin:
async def test_01_admin_login(self, page, base_url):
await page.goto(f"{base_url}/")
await page.wait_for_load_state("networkidle")
await page.fill('#login-form input[name="username"]', 'adminuser')
await page.fill('#login-form input[name="password"]', 'adminpassword123')
await page.click('#login-form button[type="submit"]')
await page.wait_for_timeout(2000)
# Admin should see admin nav links
await expect(page.locator('a.nav-link[data-view="admin"]')).to_be_visible()
await expect(page.locator('a.nav-link[data-view="admin-billing"]')).to_be_visible()
async def test_02_navigate_to_admin_dashboard(self, page, base_url):
await page.goto(f"{base_url}/")
await page.wait_for_load_state("networkidle")
await page.fill('#login-form input[name="username"]', 'adminuser')
await page.fill('#login-form input[name="password"]', 'adminpassword123')
await page.click('#login-form button[type="submit"]')
await page.wait_for_timeout(2000)
await page.click('a.nav-link[data-view="admin"]')
await page.wait_for_timeout(1000)
await expect(page.locator('admin-dashboard')).to_be_visible()
async def test_03_view_user_management(self, page, base_url):
await page.goto(f"{base_url}/")
await page.wait_for_load_state("networkidle")
await page.fill('#login-form input[name="username"]', 'adminuser')
await page.fill('#login-form input[name="password"]', 'adminpassword123')
await page.click('#login-form button[type="submit"]')
await page.wait_for_timeout(2000)
await page.click('a.nav-link[data-view="admin"]')
await page.wait_for_timeout(1000)
# Should show user list
await expect(page.locator('.user-list')).to_be_visible()
await expect(page.locator('text=e2etestuser')).to_be_visible()
async def test_04_view_system_statistics(self, page, base_url):
await page.goto(f"{base_url}/")
await page.wait_for_load_state("networkidle")
await page.fill('#login-form input[name="username"]', 'adminuser')
await page.fill('#login-form input[name="password"]', 'adminpassword123')
await page.click('#login-form button[type="submit"]')
await page.wait_for_timeout(2000)
await page.click('a.nav-link[data-view="admin"]')
await page.wait_for_timeout(1000)
# Should show system stats
await expect(page.locator('.system-stats')).to_be_visible()
await expect(page.locator('.stat-item')).to_be_visible()
async def test_05_manage_user_permissions(self, page, base_url):
await page.goto(f"{base_url}/")
await page.wait_for_load_state("networkidle")
await page.fill('#login-form input[name="username"]', 'adminuser')
await page.fill('#login-form input[name="password"]', 'adminpassword123')
await page.click('#login-form button[type="submit"]')
await page.wait_for_timeout(2000)
await page.click('a.nav-link[data-view="admin"]')
await page.wait_for_timeout(1000)
# Click on user to manage
await page.click('.user-item:has-text("e2etestuser")')
await page.wait_for_timeout(500)
# Should show user details modal
await expect(page.locator('.user-details-modal')).to_be_visible()
# Change permissions
await page.select_option('select[name="role"]', 'moderator')
await page.click('button:has-text("Save")')
await page.wait_for_timeout(1000)
async def test_06_view_storage_usage(self, page, base_url):
await page.goto(f"{base_url}/")
await page.wait_for_load_state("networkidle")
await page.fill('#login-form input[name="username"]', 'adminuser')
await page.fill('#login-form input[name="password"]', 'adminpassword123')
await page.click('#login-form button[type="submit"]')
await page.wait_for_timeout(2000)
await page.click('a.nav-link[data-view="admin"]')
await page.wait_for_timeout(1000)
# Should show storage usage
await expect(page.locator('.storage-usage')).to_be_visible()
async def test_07_navigate_to_admin_billing(self, page, base_url):
await page.goto(f"{base_url}/")
await page.wait_for_load_state("networkidle")
await page.fill('#login-form input[name="username"]', 'adminuser')
await page.fill('#login-form input[name="password"]', 'adminpassword123')
await page.click('#login-form button[type="submit"]')
await page.wait_for_timeout(2000)
await page.click('a.nav-link[data-view="admin-billing"]')
await page.wait_for_timeout(1000)
await expect(page.locator('admin-billing')).to_be_visible()
async def test_08_view_billing_statistics(self, page, base_url):
await page.goto(f"{base_url}/")
await page.wait_for_load_state("networkidle")
await page.fill('#login-form input[name="username"]', 'adminuser')
await page.fill('#login-form input[name="password"]', 'adminpassword123')
await page.click('#login-form button[type="submit"]')
await page.wait_for_timeout(2000)
await page.click('a.nav-link[data-view="admin-billing"]')
await page.wait_for_timeout(1000)
# Should show billing stats
await expect(page.locator('.billing-stats')).to_be_visible()
async def test_09_manage_pricing(self, page, base_url):
await page.goto(f"{base_url}/")
await page.wait_for_load_state("networkidle")
await page.fill('#login-form input[name="username"]', 'adminuser')
await page.fill('#login-form input[name="password"]', 'adminpassword123')
await page.click('#login-form button[type="submit"]')
await page.wait_for_timeout(2000)
await page.click('a.nav-link[data-view="admin-billing"]')
await page.wait_for_timeout(1000)
# Click pricing management
await page.click('button:has-text("Manage Pricing")')
await page.wait_for_timeout(500)
# Should show pricing form
await expect(page.locator('.pricing-form')).to_be_visible()
# Update a price
await page.fill('input[name="storage_per_gb_month"]', '0.005')
await page.click('button:has-text("Update")')
await page.wait_for_timeout(1000)
async def test_10_generate_invoice(self, page, base_url):
await page.goto(f"{base_url}/")
await page.wait_for_load_state("networkidle")
await page.fill('#login-form input[name="username"]', 'adminuser')
await page.fill('#login-form input[name="password"]', 'adminpassword123')
await page.click('#login-form button[type="submit"]')
await page.wait_for_timeout(2000)
await page.click('a.nav-link[data-view="admin-billing"]')
await page.wait_for_timeout(1000)
# Click generate invoice
await page.click('button:has-text("Generate Invoice")')
await page.wait_for_timeout(500)
# Select user
await page.select_option('select[name="user"]', 'e2etestuser')
await page.click('button:has-text("Generate")')
await page.wait_for_timeout(1000)
# Should show success message
await expect(page.locator('text=Invoice generated')).to_be_visible()
+170
View File
@@ -0,0 +1,170 @@
import pytest
import asyncio
from playwright.async_api import expect
@pytest.mark.asyncio
class TestAuthFlow:
async def test_01_user_registration(self, page, base_url):
await page.goto(f"{base_url}/")
await page.wait_for_load_state("networkidle")
# Click Sign Up
await page.click('text=Sign Up')
await page.wait_for_timeout(500)
# Fill registration form
await page.fill('#register-form input[name="username"]', 'e2etestuser')
await page.fill('#register-form input[name="email"]', 'e2etestuser@example.com')
await page.fill('#register-form input[name="password"]', 'testpassword123')
# Submit registration
await page.click('#register-form button[type="submit"]')
await page.wait_for_timeout(2000)
await expect(page.locator('text=My Files')).to_be_visible()
async def test_02_user_login(self, page, base_url):
await page.goto(f"{base_url}/")
await page.wait_for_load_state("networkidle")
# Unregister service worker to avoid interference
await page.evaluate("""
navigator.serviceWorker.getRegistrations().then(function(registrations) {
for(let registration of registrations) {
registration.unregister();
}
});
""")
await page.reload()
await page.wait_for_load_state("networkidle")
# Fill login form
await page.fill('#login-form input[name="username"]', 'e2etestuser')
await page.fill('#login-form input[name="password"]', 'testpassword123')
# Submit login
await page.click('#login-form button[type="submit"]')
await page.wait_for_timeout(2000)
await expect(page.locator('text=My Files')).to_be_visible()
async def test_03_navigate_to_files_view(self, page, base_url):
await page.goto(f"{base_url}/")
await page.wait_for_load_state("networkidle")
await page.fill('#login-form input[name="username"]', 'e2etestuser')
await page.fill('#login-form input[name="password"]', 'testpassword123')
await page.click('#login-form button[type="submit"]')
await page.wait_for_timeout(2000)
# Files view should be active by default
await expect(page.locator('a.nav-link.active[data-view="files"]')).to_be_visible()
await expect(page.locator('file-list')).to_be_visible()
async def test_04_navigate_to_photos_view(self, page, base_url):
await page.goto(f"{base_url}/")
await page.wait_for_load_state("networkidle")
await page.fill('#login-form input[name="username"]', 'e2etestuser')
await page.fill('#login-form input[name="password"]', 'testpassword123')
await page.click('#login-form button[type="submit"]')
await page.wait_for_timeout(2000)
await page.click('a.nav-link[data-view="photos"]')
await page.wait_for_timeout(1000)
await expect(page.locator('a.nav-link.active[data-view="photos"]')).to_be_visible()
await expect(page.locator('photo-gallery')).to_be_visible()
async def test_05_navigate_to_shared_view(self, page, base_url):
await page.goto(f"{base_url}/")
await page.wait_for_load_state("networkidle")
await page.fill('#login-form input[name="username"]', 'e2etestuser')
await page.fill('#login-form input[name="password"]', 'testpassword123')
await page.click('#login-form button[type="submit"]')
await page.wait_for_timeout(2000)
await page.click('a.nav-link[data-view="shared"]')
await page.wait_for_timeout(1000)
await expect(page.locator('a.nav-link.active[data-view="shared"]')).to_be_visible()
await expect(page.locator('shared-items')).to_be_visible()
async def test_06_navigate_to_starred_view(self, page, base_url):
await page.goto(f"{base_url}/")
await page.wait_for_load_state("networkidle")
await page.fill('#login-form input[name="username"]', 'e2etestuser')
await page.fill('#login-form input[name="password"]', 'testpassword123')
await page.click('#login-form button[type="submit"]')
await page.wait_for_timeout(2000)
await page.click('a.nav-link[data-view="starred"]')
await page.wait_for_timeout(1000)
await expect(page.locator('a.nav-link.active[data-view="starred"]')).to_be_visible()
await expect(page.locator('starred-items')).to_be_visible()
async def test_07_navigate_to_recent_view(self, page, base_url):
await page.goto(f"{base_url}/")
await page.wait_for_load_state("networkidle")
await page.fill('#login-form input[name="username"]', 'e2etestuser')
await page.fill('#login-form input[name="password"]', 'testpassword123')
await page.click('#login-form button[type="submit"]')
await page.wait_for_timeout(2000)
await page.click('a.nav-link[data-view="recent"]')
await page.wait_for_timeout(1000)
await expect(page.locator('a.nav-link.active[data-view="recent"]')).to_be_visible()
await expect(page.locator('recent-files')).to_be_visible()
async def test_08_navigate_to_deleted_view(self, page, base_url):
await page.goto(f"{base_url}/")
await page.wait_for_load_state("networkidle")
await page.fill('#login-form input[name="username"]', 'e2etestuser')
await page.fill('#login-form input[name="password"]', 'testpassword123')
await page.click('#login-form button[type="submit"]')
await page.wait_for_timeout(2000)
await page.click('a.nav-link[data-view="deleted"]')
await page.wait_for_timeout(1000)
await expect(page.locator('a.nav-link.active[data-view="deleted"]')).to_be_visible()
await expect(page.locator('deleted-files')).to_be_visible()
async def test_09_navigate_to_billing_view(self, page, base_url):
await page.goto(f"{base_url}/")
await page.wait_for_load_state("networkidle")
await page.fill('#login-form input[name="username"]', 'e2etestuser')
await page.fill('#login-form input[name="password"]', 'testpassword123')
await page.click('#login-form button[type="submit"]')
await page.wait_for_timeout(2000)
await page.click('a.nav-link[data-view="billing"]')
await page.wait_for_timeout(1000)
await expect(page.locator('a.nav-link.active[data-view="billing"]')).to_be_visible()
await expect(page.locator('billing-dashboard')).to_be_visible()
async def test_10_user_logout(self, page, base_url):
await page.goto(f"{base_url}/")
await page.wait_for_load_state("networkidle")
await page.fill('#login-form input[name="username"]', 'e2etestuser')
await page.fill('#login-form input[name="password"]', 'testpassword123')
await page.click('#login-form button[type="submit"]')
await page.wait_for_timeout(2000)
# Click logout
await page.click('#logout-btn')
await page.wait_for_timeout(1000)
# Should be back to login
await expect(page.locator('#login-form')).to_be_visible()
+222
View File
@@ -0,0 +1,222 @@
import pytest
import asyncio
from playwright.async_api import expect
@pytest.mark.asyncio
class TestFileManagement:
async def test_01_upload_file(self, page, base_url):
await page.goto(f"{base_url}/")
await page.wait_for_load_state("networkidle")
await page.fill('#login-form input[name="username"]', 'e2etestuser')
await page.fill('#login-form input[name="password"]', 'testpassword123')
await page.click('#login-form button[type="submit"]')
await page.wait_for_timeout(2000)
# Upload a file
await page.set_input_files('input[type="file"]', {
'name': 'test-file.txt',
'mimeType': 'text/plain',
'buffer': b'This is a test file for e2e testing.'
})
await page.click('button:has-text("Upload")')
await page.wait_for_timeout(2000)
await expect(page.locator('text=test-file.txt')).to_be_visible()
async def test_02_create_folder(self, page, base_url):
await page.goto(f"{base_url}/")
await page.wait_for_load_state("networkidle")
await page.fill('#login-form input[name="username"]', 'e2etestuser')
await page.fill('#login-form input[name="password"]', 'testpassword123')
await page.click('#login-form button[type="submit"]')
await page.wait_for_timeout(2000)
# Click create folder button
await page.click('button:has-text("New Folder")')
await page.wait_for_timeout(500)
# Fill folder name
await page.fill('input[placeholder="Folder name"]', 'Test Folder')
await page.click('button:has-text("Create")')
await page.wait_for_timeout(1000)
await expect(page.locator('text=Test Folder')).to_be_visible()
async def test_03_navigate_into_folder(self, page, base_url):
await page.goto(f"{base_url}/")
await page.wait_for_load_state("networkidle")
await page.fill('#login-form input[name="username"]', 'e2etestuser')
await page.fill('#login-form input[name="password"]', 'testpassword123')
await page.click('#login-form button[type="submit"]')
await page.wait_for_timeout(2000)
# Click on the folder
await page.click('text=Test Folder')
await page.wait_for_timeout(1000)
# Should be in the folder, breadcrumb should show it
await expect(page.locator('.breadcrumb')).to_contain_text('Test Folder')
async def test_04_upload_file_in_folder(self, page, base_url):
await page.goto(f"{base_url}/")
await page.wait_for_load_state("networkidle")
await page.fill('#login-form input[name="username"]', 'e2etestuser')
await page.fill('#login-form input[name="password"]', 'testpassword123')
await page.click('#login-form button[type="submit"]')
await page.wait_for_timeout(2000)
# Navigate to folder
await page.click('text=Test Folder')
await page.wait_for_timeout(1000)
# Upload file in folder
await page.set_input_files('input[type="file"]', {
'name': 'folder-file.txt',
'mimeType': 'text/plain',
'buffer': b'This file is in a folder.'
})
await page.click('button:has-text("Upload")')
await page.wait_for_timeout(2000)
await expect(page.locator('text=folder-file.txt')).to_be_visible()
async def test_05_navigate_back_from_folder(self, page, base_url):
await page.goto(f"{base_url}/")
await page.wait_for_load_state("networkidle")
await page.fill('#login-form input[name="username"]', 'e2etestuser')
await page.fill('#login-form input[name="password"]', 'testpassword123')
await page.click('#login-form button[type="submit"]')
await page.wait_for_timeout(2000)
# Navigate to folder
await page.click('text=Test Folder')
await page.wait_for_timeout(1000)
# Click breadcrumb to go back
await page.click('.breadcrumb a:first-child')
await page.wait_for_timeout(1000)
# Should be back in root
await expect(page.locator('text=Test Folder')).to_be_visible()
await expect(page.locator('text=test-file.txt')).to_be_visible()
async def test_06_select_and_delete_file(self, page, base_url):
await page.goto(f"{base_url}/")
await page.wait_for_load_state("networkidle")
await page.fill('#login-form input[name="username"]', 'e2etestuser')
await page.fill('#login-form input[name="password"]', 'testpassword123')
await page.click('#login-form button[type="submit"]')
await page.wait_for_timeout(2000)
# Select file
await page.click('.file-item:has-text("test-file.txt") .file-checkbox')
await page.wait_for_timeout(500)
# Click delete
await page.click('button:has-text("Delete")')
await page.wait_for_timeout(500)
# Confirm delete
await page.click('button:has-text("Confirm")')
await page.wait_for_timeout(1000)
# File should be gone
await expect(page.locator('text=test-file.txt')).not_to_be_visible()
async def test_07_restore_deleted_file(self, page, base_url):
await page.goto(f"{base_url}/")
await page.wait_for_load_state("networkidle")
await page.fill('#login-form input[name="username"]', 'e2etestuser')
await page.fill('#login-form input[name="password"]', 'testpassword123')
await page.click('#login-form button[type="submit"]')
await page.wait_for_timeout(2000)
# Go to deleted files
await page.click('a.nav-link[data-view="deleted"]')
await page.wait_for_timeout(1000)
# Select deleted file
await page.click('.file-item:has-text("test-file.txt") .file-checkbox')
await page.wait_for_timeout(500)
# Click restore
await page.click('button:has-text("Restore")')
await page.wait_for_timeout(1000)
# Go back to files
await page.click('a.nav-link[data-view="files"]')
await page.wait_for_timeout(1000)
# File should be back
await expect(page.locator('text=test-file.txt')).to_be_visible()
async def test_08_rename_folder(self, page, base_url):
await page.goto(f"{base_url}/")
await page.wait_for_load_state("networkidle")
await page.fill('#login-form input[name="username"]', 'e2etestuser')
await page.fill('#login-form input[name="password"]', 'testpassword123')
await page.click('#login-form button[type="submit"]')
await page.wait_for_timeout(2000)
# Right-click on folder or use context menu
await page.click('.folder-item:has-text("Test Folder")', button='right')
await page.wait_for_timeout(500)
# Click rename
await page.click('text=Rename')
await page.wait_for_timeout(500)
# Fill new name
await page.fill('input[placeholder="New name"]', 'Renamed Folder')
await page.click('button:has-text("Rename")')
await page.wait_for_timeout(1000)
await expect(page.locator('text=Renamed Folder')).to_be_visible()
await expect(page.locator('text=Test Folder')).not_to_be_visible()
async def test_09_star_file(self, page, base_url):
await page.goto(f"{base_url}/")
await page.wait_for_load_state("networkidle")
await page.fill('#login-form input[name="username"]', 'e2etestuser')
await page.fill('#login-form input[name="password"]', 'testpassword123')
await page.click('#login-form button[type="submit"]')
await page.wait_for_timeout(2000)
# Click star on file
await page.click('.file-item:has-text("test-file.txt") .star-btn')
await page.wait_for_timeout(1000)
# Go to starred
await page.click('a.nav-link[data-view="starred"]')
await page.wait_for_timeout(1000)
await expect(page.locator('text=test-file.txt')).to_be_visible()
async def test_10_search_files(self, page, base_url):
await page.goto(f"{base_url}/")
await page.wait_for_load_state("networkidle")
await page.fill('#login-form input[name="username"]', 'e2etestuser')
await page.fill('#login-form input[name="password"]', 'testpassword123')
await page.click('#login-form button[type="submit"]')
await page.wait_for_timeout(2000)
# Type in search
await page.fill('#search-input', 'test-file')
await page.wait_for_timeout(1000)
# Should show search results
await expect(page.locator('.search-results')).to_be_visible()
await expect(page.locator('text=test-file.txt')).to_be_visible()
+227
View File
@@ -0,0 +1,227 @@
import pytest
import asyncio
from playwright.async_api import expect
@pytest.mark.asyncio
class TestPhotoGallery:
async def test_01_upload_image_file(self, page, base_url):
await page.goto(f"{base_url}/")
await page.wait_for_load_state("networkidle")
await page.fill('#login-form input[name="username"]', 'e2etestuser')
await page.fill('#login-form input[name="password"]', 'testpassword123')
await page.click('#login-form button[type="submit"]')
await page.wait_for_timeout(2000)
# Upload an image file
await page.set_input_files('input[type="file"]', {
'name': 'test-image.jpg',
'mimeType': 'image/jpeg',
'buffer': b'fake image data' # In real test, use actual image bytes
})
await page.click('button:has-text("Upload")')
await page.wait_for_timeout(2000)
await expect(page.locator('text=test-image.jpg')).to_be_visible()
async def test_02_navigate_to_photo_gallery(self, page, base_url):
await page.goto(f"{base_url}/")
await page.wait_for_load_state("networkidle")
await page.fill('#login-form input[name="username"]', 'e2etestuser')
await page.fill('#login-form input[name="password"]', 'testpassword123')
await page.click('#login-form button[type="submit"]')
await page.wait_for_timeout(2000)
await page.click('a.nav-link[data-view="photos"]')
await page.wait_for_timeout(1000)
await expect(page.locator('photo-gallery')).to_be_visible()
async def test_03_view_image_in_gallery(self, page, base_url):
await page.goto(f"{base_url}/")
await page.wait_for_load_state("networkidle")
await page.fill('#login-form input[name="username"]', 'e2etestuser')
await page.fill('#login-form input[name="password"]', 'testpassword123')
await page.click('#login-form button[type="submit"]')
await page.wait_for_timeout(2000)
await page.click('a.nav-link[data-view="photos"]')
await page.wait_for_timeout(1000)
# Should show uploaded image
await expect(page.locator('.photo-item')).to_be_visible()
async def test_04_click_on_photo_to_preview(self, page, base_url):
await page.goto(f"{base_url}/")
await page.wait_for_load_state("networkidle")
await page.fill('#login-form input[name="username"]', 'e2etestuser')
await page.fill('#login-form input[name="password"]', 'testpassword123')
await page.click('#login-form button[type="submit"]')
await page.wait_for_timeout(2000)
await page.click('a.nav-link[data-view="photos"]')
await page.wait_for_timeout(1000)
# Click on photo
await page.click('.photo-item img')
await page.wait_for_timeout(1000)
# Should open preview
await expect(page.locator('file-preview')).to_be_visible()
async def test_05_close_photo_preview(self, page, base_url):
await page.goto(f"{base_url}/")
await page.wait_for_load_state("networkidle")
await page.fill('#login-form input[name="username"]', 'e2etestuser')
await page.fill('#login-form input[name="password"]', 'testpassword123')
await page.click('#login-form button[type="submit"]')
await page.wait_for_timeout(2000)
await page.click('a.nav-link[data-view="photos"]')
await page.wait_for_timeout(1000)
# Click on photo
await page.click('.photo-item img')
await page.wait_for_timeout(1000)
# Close preview
await page.click('.preview-close-btn')
await page.wait_for_timeout(500)
# Preview should be closed
await expect(page.locator('file-preview')).not_to_be_visible()
async def test_06_upload_multiple_images(self, page, base_url):
await page.goto(f"{base_url}/")
await page.wait_for_load_state("networkidle")
await page.fill('#login-form input[name="username"]', 'e2etestuser')
await page.fill('#login-form input[name="password"]', 'testpassword123')
await page.click('#login-form button[type="submit"]')
await page.wait_for_timeout(2000)
# Upload multiple images
await page.set_input_files('input[type="file"]', [
{
'name': 'image1.jpg',
'mimeType': 'image/jpeg',
'buffer': b'fake image 1'
},
{
'name': 'image2.png',
'mimeType': 'image/png',
'buffer': b'fake image 2'
}
])
await page.click('button:has-text("Upload")')
await page.wait_for_timeout(2000)
# Go to gallery
await page.click('a.nav-link[data-view="photos"]')
await page.wait_for_timeout(1000)
# Should show multiple photos
photo_count = await page.locator('.photo-item').count()
assert photo_count >= 2
async def test_07_filter_photos_by_date(self, page, base_url):
await page.goto(f"{base_url}/")
await page.wait_for_load_state("networkidle")
await page.fill('#login-form input[name="username"]', 'e2etestuser')
await page.fill('#login-form input[name="password"]', 'testpassword123')
await page.click('#login-form button[type="submit"]')
await page.wait_for_timeout(2000)
await page.click('a.nav-link[data-view="photos"]')
await page.wait_for_timeout(1000)
# Click date filter
await page.click('.date-filter-btn')
await page.wait_for_timeout(500)
# Select today
await page.click('text=Today')
await page.wait_for_timeout(1000)
# Should filter photos
await expect(page.locator('.photo-item')).to_be_visible()
async def test_08_search_photos(self, page, base_url):
await page.goto(f"{base_url}/")
await page.wait_for_load_state("networkidle")
await page.fill('#login-form input[name="username"]', 'e2etestuser')
await page.fill('#login-form input[name="password"]', 'testpassword123')
await page.click('#login-form button[type="submit"]')
await page.wait_for_timeout(2000)
await page.click('a.nav-link[data-view="photos"]')
await page.wait_for_timeout(1000)
# Type in gallery search
await page.fill('.gallery-search-input', 'image1')
await page.wait_for_timeout(1000)
# Should show filtered results
await expect(page.locator('text=image1.jpg')).to_be_visible()
await expect(page.locator('text=image2.png')).not_to_be_visible()
async def test_09_create_album(self, page, base_url):
await page.goto(f"{base_url}/")
await page.wait_for_load_state("networkidle")
await page.fill('#login-form input[name="username"]', 'e2etestuser')
await page.fill('#login-form input[name="password"]', 'testpassword123')
await page.click('#login-form button[type="submit"]')
await page.wait_for_timeout(2000)
await page.click('a.nav-link[data-view="photos"]')
await page.wait_for_timeout(1000)
# Click create album
await page.click('button:has-text("Create Album")')
await page.wait_for_timeout(500)
# Fill album name
await page.fill('input[name="album-name"]', 'Test Album')
await page.click('button:has-text("Create")')
await page.wait_for_timeout(1000)
# Should show album
await expect(page.locator('text=Test Album')).to_be_visible()
async def test_10_add_photos_to_album(self, page, base_url):
await page.goto(f"{base_url}/")
await page.wait_for_load_state("networkidle")
await page.fill('#login-form input[name="username"]', 'e2etestuser')
await page.fill('#login-form input[name="password"]', 'testpassword123')
await page.click('#login-form button[type="submit"]')
await page.wait_for_timeout(2000)
await page.click('a.nav-link[data-view="photos"]')
await page.wait_for_timeout(1000)
# Select photos
await page.click('.photo-item .photo-checkbox', { force: True })
await page.wait_for_timeout(500)
# Click add to album
await page.click('button:has-text("Add to Album")')
await page.wait_for_timeout(500)
# Select album
await page.click('text=Test Album')
await page.click('button:has-text("Add")')
await page.wait_for_timeout(1000)
# Should show success
await expect(page.locator('text=Photos added to album')).to_be_visible()
+207
View File
@@ -0,0 +1,207 @@
import pytest
import asyncio
from playwright.async_api import expect
@pytest.mark.asyncio
class TestSharing:
async def test_01_share_file_with_user(self, page, base_url):
await page.goto(f"{base_url}/")
await page.wait_for_load_state("networkidle")
await page.fill('#login-form input[name="username"]', 'e2etestuser')
await page.fill('#login-form input[name="password"]', 'testpassword123')
await page.click('#login-form button[type="submit"]')
await page.wait_for_timeout(2000)
# Select file
await page.click('.file-item:has-text("test-file.txt") .file-checkbox')
await page.wait_for_timeout(500)
# Click share
await page.click('button:has-text("Share")')
await page.wait_for_timeout(500)
# Share modal should appear
await expect(page.locator('share-modal')).to_be_visible()
# Fill share form
await page.fill('input[placeholder="Username to share with"]', 'billingtest')
await page.select_option('select[name="permission"]', 'read')
await page.click('button:has-text("Share")')
await page.wait_for_timeout(1000)
# Modal should close
await expect(page.locator('share-modal')).not_to_be_visible()
async def test_02_view_shared_items_as_recipient(self, page, base_url):
await page.goto(f"{base_url}/")
await page.wait_for_load_state("networkidle")
await page.fill('#login-form input[name="username"]', 'billingtest')
await page.fill('#login-form input[name="password"]', 'password123')
await page.click('#login-form button[type="submit"]')
await page.wait_for_timeout(2000)
# Go to shared items
await page.click('a.nav-link[data-view="shared"]')
await page.wait_for_timeout(1000)
await expect(page.locator('text=test-file.txt')).to_be_visible()
async def test_03_download_shared_file(self, page, base_url):
await page.goto(f"{base_url}/")
await page.wait_for_load_state("networkidle")
await page.fill('#login-form input[name="username"]', 'billingtest')
await page.fill('#login-form input[name="password"]', 'password123')
await page.click('#login-form button[type="submit"]')
await page.wait_for_timeout(2000)
# Go to shared items
await page.click('a.nav-link[data-view="shared"]')
await page.wait_for_timeout(1000)
# Click download on shared file
await page.click('.file-item:has-text("test-file.txt") .download-btn')
await page.wait_for_timeout(1000)
# Should trigger download (can't easily test actual download in e2e)
async def test_04_create_public_link(self, page, base_url):
await page.goto(f"{base_url}/")
await page.wait_for_load_state("networkidle")
await page.fill('#login-form input[name="username"]', 'e2etestuser')
await page.fill('#login-form input[name="password"]', 'testpassword123')
await page.click('#login-form button[type="submit"]')
await page.wait_for_timeout(2000)
# Select file
await page.click('.file-item:has-text("test-file.txt") .file-checkbox')
await page.wait_for_timeout(500)
# Click share
await page.click('button:has-text("Share")')
await page.wait_for_timeout(500)
# Click create public link
await page.click('button:has-text("Create Public Link")')
await page.wait_for_timeout(1000)
# Should show link
await expect(page.locator('.public-link')).to_be_visible()
async def test_05_access_public_link(self, page, base_url):
# First get the public link from previous test
await page.goto(f"{base_url}/")
await page.wait_for_load_state("networkidle")
await page.fill('#login-form input[name="username"]', 'e2etestuser')
await page.fill('#login-form input[name="password"]', 'testpassword123')
await page.click('#login-form button[type="submit"]')
await page.wait_for_timeout(2000)
# Get the public link
await page.click('.file-item:has-text("test-file.txt") .file-checkbox')
await page.click('button:has-text("Share")')
await page.wait_for_timeout(500)
link_element = page.locator('.public-link input')
public_url = await link_element.get_attribute('value')
# Logout
await page.click('#logout-btn')
await page.wait_for_timeout(1000)
# Access public link
await page.goto(public_url)
await page.wait_for_load_state("networkidle")
# Should be able to view/download the file
await expect(page.locator('text=test-file.txt')).to_be_visible()
async def test_06_revoke_share(self, page, base_url):
await page.goto(f"{base_url}/")
await page.wait_for_load_state("networkidle")
await page.fill('#login-form input[name="username"]', 'e2etestuser')
await page.fill('#login-form input[name="password"]', 'testpassword123')
await page.click('#login-form button[type="submit"]')
await page.wait_for_timeout(2000)
# Go to shared items view (as owner)
await page.click('a.nav-link[data-view="shared"]')
await page.wait_for_timeout(1000)
# Find the share and revoke
await page.click('.share-item .revoke-btn')
await page.wait_for_timeout(500)
# Confirm revoke
await page.click('button:has-text("Confirm")')
await page.wait_for_timeout(1000)
# Share should be gone
await expect(page.locator('.share-item')).not_to_be_visible()
async def test_07_share_folder(self, page, base_url):
await page.goto(f"{base_url}/")
await page.wait_for_load_state("networkidle")
await page.fill('#login-form input[name="username"]', 'e2etestuser')
await page.fill('#login-form input[name="password"]', 'testpassword123')
await page.click('#login-form button[type="submit"]')
await page.wait_for_timeout(2000)
# Select folder
await page.click('.folder-item:has-text("Renamed Folder") .folder-checkbox')
await page.wait_for_timeout(500)
# Click share
await page.click('button:has-text("Share")')
await page.wait_for_timeout(500)
# Share modal should appear
await expect(page.locator('share-modal')).to_be_visible()
# Fill share form
await page.fill('input[placeholder="Username to share with"]', 'billingtest')
await page.select_option('select[name="permission"]', 'read')
await page.click('button:has-text("Share")')
await page.wait_for_timeout(1000)
async def test_08_view_shared_folder_as_recipient(self, page, base_url):
await page.goto(f"{base_url}/")
await page.wait_for_load_state("networkidle")
await page.fill('#login-form input[name="username"]', 'billingtest')
await page.fill('#login-form input[name="password"]', 'password123')
await page.click('#login-form button[type="submit"]')
await page.wait_for_timeout(2000)
# Go to shared items
await page.click('a.nav-link[data-view="shared"]')
await page.wait_for_timeout(1000)
await expect(page.locator('text=Renamed Folder')).to_be_visible()
async def test_09_navigate_into_shared_folder(self, page, base_url):
await page.goto(f"{base_url}/")
await page.wait_for_load_state("networkidle")
await page.fill('#login-form input[name="username"]', 'billingtest')
await page.fill('#login-form input[name="password"]', 'password123')
await page.click('#login-form button[type="submit"]')
await page.wait_for_timeout(2000)
# Go to shared items
await page.click('a.nav-link[data-view="shared"]')
await page.wait_for_timeout(1000)
# Click on shared folder
await page.click('text=Renamed Folder')
await page.wait_for_timeout(1000)
# Should see the file inside
await expect(page.locator('text=folder-file.txt')).to_be_visible()