343 lines
14 KiB
TypeScript
343 lines
14 KiB
TypeScript
import { test, expect } from './fixtures/auth';
|
||
import { TIMEOUTS, API_ENDPOINTS } from './utils/test-data';
|
||
import { TestHelpers } from './utils/test-helpers';
|
||
|
||
test.describe('WebDAV Workflow', () => {
|
||
let helpers: TestHelpers;
|
||
|
||
test.beforeEach(async ({ dynamicAdminPage }) => {
|
||
helpers = new TestHelpers(dynamicAdminPage);
|
||
await helpers.navigateToPage('/sources');
|
||
});
|
||
|
||
test.skip('should create and configure WebDAV source', async ({ dynamicAdminPage: page }) => {
|
||
// Increase timeout for this test as WebDAV operations can be slow
|
||
// This addresses the timeout issues with Material-UI Select components
|
||
test.setTimeout(60000);
|
||
// Navigate to sources page
|
||
await page.goto('/sources');
|
||
await helpers.waitForLoadingToComplete();
|
||
|
||
// Wait for loading to complete and sources to be displayed
|
||
// The Add Source button only appears after the loading state finishes
|
||
await page.waitForLoadState('networkidle');
|
||
|
||
// Wait for the loading spinner to disappear
|
||
const loadingSpinner = page.locator('[role="progressbar"], .MuiCircularProgress-root');
|
||
if (await loadingSpinner.isVisible({ timeout: 2000 })) {
|
||
await expect(loadingSpinner).not.toBeVisible({ timeout: TIMEOUTS.long });
|
||
}
|
||
|
||
// Wait extra time for WebKit to fully render the page
|
||
await page.waitForTimeout(5000);
|
||
|
||
// For WebKit, try to wait for specific page elements to be loaded
|
||
await page.waitForFunction(() => {
|
||
return document.querySelector('[data-testid="add-source"]') !== null ||
|
||
document.querySelector('button:has-text("Add Source")') !== null ||
|
||
document.body.textContent?.includes('Add Source');
|
||
}, { timeout: TIMEOUTS.long });
|
||
|
||
// Look for add source button (try multiple selectors in order of preference)
|
||
let addSourceButton = page.locator('[data-testid="add-source"]').first();
|
||
|
||
if (!(await addSourceButton.isVisible({ timeout: 5000 }))) {
|
||
addSourceButton = page.locator('button:has-text("Add Source")').first();
|
||
}
|
||
|
||
if (!(await addSourceButton.isVisible({ timeout: 5000 }))) {
|
||
addSourceButton = page.locator('button:has-text("Add")').first();
|
||
}
|
||
|
||
if (!(await addSourceButton.isVisible({ timeout: 5000 }))) {
|
||
addSourceButton = page.locator('button[aria-label*="add"], button[title*="add"]').first();
|
||
}
|
||
|
||
if (await addSourceButton.isVisible({ timeout: 5000 })) {
|
||
console.log('Found add source button, clicking...');
|
||
await addSourceButton.click();
|
||
} else {
|
||
// Enhanced debugging for WebKit
|
||
const pageContent = await page.textContent('body');
|
||
console.log('Page content (first 500 chars):', pageContent?.substring(0, 500));
|
||
console.log('Page URL:', page.url());
|
||
|
||
// Check if we're actually on the sources page
|
||
const pageTitle = await page.title();
|
||
console.log('Page title:', pageTitle);
|
||
|
||
// Try to find any buttons on the page
|
||
const allButtons = await page.locator('button').count();
|
||
console.log('Total buttons found:', allButtons);
|
||
|
||
throw new Error('Could not find add source button');
|
||
}
|
||
|
||
// Wait for source creation form/modal to appear
|
||
await page.waitForTimeout(1000);
|
||
|
||
// Debug: log what's currently visible
|
||
await page.waitForLoadState('networkidle');
|
||
console.log('Waiting for source creation form to load...');
|
||
|
||
// Select WebDAV source type if source type selection exists
|
||
try {
|
||
// First, look for any select/dropdown elements - focusing on Material-UI patterns
|
||
const selectTrigger = page.locator([
|
||
'[role="combobox"]',
|
||
'.MuiSelect-select:not([aria-hidden="true"])',
|
||
'div[aria-haspopup="listbox"]',
|
||
'.MuiOutlinedInput-input[role="combobox"]',
|
||
'select[name*="type"]',
|
||
'select[name*="source"]'
|
||
].join(', ')).first();
|
||
|
||
if (await selectTrigger.isVisible({ timeout: 5000 })) {
|
||
console.log('Found select trigger, attempting to click...');
|
||
|
||
try {
|
||
// Try normal click first
|
||
await selectTrigger.click({ timeout: 10000 });
|
||
} catch (clickError) {
|
||
console.log('Normal click failed, trying alternative methods:', clickError);
|
||
|
||
try {
|
||
// Try force click
|
||
await selectTrigger.click({ force: true, timeout: 5000 });
|
||
} catch (forceClickError) {
|
||
console.log('Force click also failed, trying keyboard navigation:', forceClickError);
|
||
// As last resort, try keyboard navigation
|
||
await selectTrigger.focus();
|
||
await page.keyboard.press('Enter');
|
||
}
|
||
}
|
||
|
||
// Wait for dropdown menu to appear
|
||
await page.waitForTimeout(1000);
|
||
|
||
// Look for WebDAV option in the dropdown
|
||
const webdavOption = page.locator([
|
||
'[role="option"]:has-text("webdav")',
|
||
'[role="option"]:has-text("WebDAV")',
|
||
'li:has-text("WebDAV")',
|
||
'li:has-text("webdav")',
|
||
'[data-value="webdav"]',
|
||
'option[value="webdav"]'
|
||
].join(', ')).first();
|
||
|
||
if (await webdavOption.isVisible({ timeout: 5000 })) {
|
||
console.log('Found WebDAV option, selecting it...');
|
||
await webdavOption.click();
|
||
} else {
|
||
console.log('WebDAV option not found in dropdown, checking if already selected');
|
||
// Sometimes the form might default to WebDAV or not need selection
|
||
}
|
||
} else {
|
||
console.log('No source type selector found, continuing with form...');
|
||
}
|
||
} catch (error) {
|
||
console.log('Error selecting WebDAV source type:', error);
|
||
// Continue with the test - the form might not have a source type selector
|
||
}
|
||
|
||
// Fill WebDAV configuration form
|
||
console.log('Filling WebDAV configuration form...');
|
||
|
||
// Wait for form to be ready
|
||
await page.waitForTimeout(1000);
|
||
|
||
const nameInput = page.locator('input[name="name"], input[placeholder*="name"], input[label*="Name"]').first();
|
||
if (await nameInput.isVisible({ timeout: 10000 })) {
|
||
await nameInput.fill('Test WebDAV Source');
|
||
console.log('Filled name input');
|
||
}
|
||
|
||
const urlInput = page.locator('input[name="url"], input[placeholder*="url"], input[type="url"]').first();
|
||
if (await urlInput.isVisible({ timeout: 5000 })) {
|
||
await urlInput.fill('https://demo.webdav.server/');
|
||
console.log('Filled URL input');
|
||
}
|
||
|
||
const usernameInput = page.locator('input[name="username"], input[placeholder*="username"]').first();
|
||
if (await usernameInput.isVisible({ timeout: 5000 })) {
|
||
await usernameInput.fill('webdav_user');
|
||
console.log('Filled username input');
|
||
}
|
||
|
||
const passwordInput = page.locator('input[name="password"], input[type="password"]').first();
|
||
if (await passwordInput.isVisible({ timeout: 5000 })) {
|
||
await passwordInput.fill('webdav_pass');
|
||
console.log('Filled password input');
|
||
}
|
||
|
||
// Save the source configuration
|
||
console.log('Looking for save button...');
|
||
const saveButton = page.locator('button:has-text("Save"), button:has-text("Create"), button[type="submit"]').first();
|
||
if (await saveButton.isVisible({ timeout: 10000 })) {
|
||
console.log('Found save button, clicking...');
|
||
|
||
// Wait for save API call
|
||
const savePromise = page.waitForResponse(response =>
|
||
response.url().includes('/sources') && (response.status() === 200 || response.status() === 201),
|
||
{ timeout: TIMEOUTS.medium }
|
||
);
|
||
|
||
await saveButton.click();
|
||
console.log('Clicked save button, waiting for response...');
|
||
|
||
try {
|
||
const response = await savePromise;
|
||
console.log('WebDAV source created successfully with status:', response.status());
|
||
} catch (error) {
|
||
console.log('Source creation may have failed or timed out:', error);
|
||
// Don't fail the test immediately - continue to check the results
|
||
}
|
||
} else {
|
||
console.log('Save button not found');
|
||
}
|
||
|
||
// Verify source appears in the list
|
||
await helpers.waitForLoadingToComplete();
|
||
|
||
// Wait for sources to load again after creation
|
||
await page.waitForLoadState('networkidle');
|
||
|
||
// Wait for loading spinner to disappear
|
||
const postCreateSpinner = page.locator('[role="progressbar"], .MuiCircularProgress-root');
|
||
if (await postCreateSpinner.isVisible({ timeout: 2000 })) {
|
||
await expect(postCreateSpinner).not.toBeVisible({ timeout: TIMEOUTS.long });
|
||
}
|
||
|
||
// Look for sources list or individual source items
|
||
const sourcesList = page.locator('[data-testid="sources-list"]');
|
||
const sourceItems = page.locator('[data-testid="source-item"]');
|
||
|
||
// Check if either the sources list container or source items are visible
|
||
const sourcesVisible = await sourcesList.isVisible({ timeout: TIMEOUTS.medium }).catch(() => false);
|
||
const itemsVisible = await sourceItems.first().isVisible({ timeout: TIMEOUTS.medium }).catch(() => false);
|
||
|
||
if (sourcesVisible || itemsVisible) {
|
||
console.log('✅ Sources list or source items are visible');
|
||
} else {
|
||
console.log('ℹ️ Sources list not immediately visible - source creation may be async');
|
||
}
|
||
});
|
||
|
||
test('should test WebDAV connection', async ({ dynamicAdminPage: page }) => {
|
||
// This test assumes a WebDAV source exists from the previous test or setup
|
||
await page.goto('/sources');
|
||
await helpers.waitForLoadingToComplete();
|
||
|
||
// Find WebDAV source and test connection
|
||
const testConnectionButton = page.locator('button:has-text("Test"), [data-testid="test-connection"]').first();
|
||
|
||
if (await testConnectionButton.isVisible()) {
|
||
// Wait for connection test API call
|
||
const testPromise = page.waitForResponse(response =>
|
||
response.url().includes('/test') || response.url().includes('/connection'),
|
||
{ timeout: TIMEOUTS.medium }
|
||
);
|
||
|
||
await testConnectionButton.click();
|
||
|
||
try {
|
||
const response = await testPromise;
|
||
console.log('Connection test completed with status:', response.status());
|
||
} catch (error) {
|
||
console.log('Connection test may have failed:', error);
|
||
}
|
||
}
|
||
|
||
// Look for connection status indicator
|
||
const statusIndicator = page.locator('.status, [data-testid="connection-status"], .connection-result');
|
||
if (await statusIndicator.isVisible()) {
|
||
const statusText = await statusIndicator.textContent();
|
||
console.log('Connection status:', statusText);
|
||
}
|
||
});
|
||
|
||
test('should initiate WebDAV sync', async ({ dynamicAdminPage: page }) => {
|
||
await page.goto('/sources');
|
||
await helpers.waitForLoadingToComplete();
|
||
|
||
// Find and click sync button
|
||
const syncButton = page.locator('button:has-text("Sync"), [data-testid="sync-source"]').first();
|
||
|
||
if (await syncButton.isVisible()) {
|
||
// Wait for sync API call
|
||
const syncPromise = page.waitForResponse(response =>
|
||
response.url().includes('/sync') && response.status() === 200,
|
||
{ timeout: TIMEOUTS.medium }
|
||
);
|
||
|
||
await syncButton.click();
|
||
|
||
try {
|
||
await syncPromise;
|
||
console.log('WebDAV sync initiated successfully');
|
||
|
||
// Look for sync progress indicators
|
||
const progressIndicator = page.locator('.progress, [data-testid="sync-progress"], .syncing');
|
||
if (await progressIndicator.isVisible({ timeout: 5000 })) {
|
||
console.log('Sync progress indicator visible');
|
||
}
|
||
} catch (error) {
|
||
console.log('Sync may have failed or timed out:', error);
|
||
}
|
||
}
|
||
});
|
||
|
||
test('should show WebDAV sync history', async ({ dynamicAdminPage: page }) => {
|
||
await page.goto('/sources');
|
||
await helpers.waitForLoadingToComplete();
|
||
|
||
// Look for sync history or logs
|
||
const historyButton = page.locator('button:has-text("History"), button:has-text("Logs"), [data-testid="sync-history"]').first();
|
||
|
||
if (await historyButton.isVisible()) {
|
||
await historyButton.click();
|
||
|
||
// Check if history modal or page opens
|
||
const historyContainer = page.locator('.history, [data-testid="sync-history"], .logs-container');
|
||
await expect(historyContainer.first()).toBeVisible({ timeout: TIMEOUTS.short });
|
||
|
||
// Check for history entries
|
||
const historyEntries = page.locator('.history-item, .log-entry, tr');
|
||
if (await historyEntries.first().isVisible({ timeout: 5000 })) {
|
||
const entryCount = await historyEntries.count();
|
||
console.log(`Found ${entryCount} sync history entries`);
|
||
}
|
||
}
|
||
});
|
||
|
||
test('should handle WebDAV source deletion', async ({ dynamicAdminPage: page }) => {
|
||
await page.goto('/sources');
|
||
await helpers.waitForLoadingToComplete();
|
||
|
||
// Find delete button for WebDAV source
|
||
const deleteButton = page.locator('button:has-text("Delete"), [data-testid="delete-source"], .delete-button').first();
|
||
|
||
if (await deleteButton.isVisible()) {
|
||
await deleteButton.click();
|
||
|
||
// Handle confirmation dialog if it appears
|
||
const confirmButton = page.locator('button:has-text("Confirm"), button:has-text("Delete"), button:has-text("Yes")').first();
|
||
if (await confirmButton.isVisible({ timeout: 3000 })) {
|
||
// Wait for delete API call
|
||
const deletePromise = page.waitForResponse(response =>
|
||
response.url().includes('/sources') && response.status() === 200,
|
||
{ timeout: TIMEOUTS.medium }
|
||
);
|
||
|
||
await confirmButton.click();
|
||
|
||
try {
|
||
await deletePromise;
|
||
console.log('WebDAV source deleted successfully');
|
||
} catch (error) {
|
||
console.log('Source deletion may have failed:', error);
|
||
}
|
||
}
|
||
}
|
||
});
|
||
}); |