towerops/e2e/tests/team.spec.ts
Graham McIntire d5b0f38ed6
feat: add remaining e2e tests and fix 'too many open files' error
- Added e2e tests for auth flows (registration, login, password reset, TOTP)
- Added e2e tests for onboarding and organization creation
- Added e2e tests for team collaboration (org switching, invitations)
- Added e2e tests for activity feed
- Added e2e tests for device graphs (sensors, time ranges, interfaces)
- Added e2e tests for MikroTik backup comparison
- Added e2e tests for sites map (geographic view)
- Added e2e tests for network trace tool

- Fixed 'too many open files' error by configuring Phoenix code reloader
  to ignore deps/, _build/, node_modules/, e2e/, and other non-source directories
- This prevents the file system watcher from monitoring unnecessary files
2026-03-06 17:08:27 -06:00

95 lines
3.1 KiB
TypeScript

import { test, expect } from '@playwright/test';
test.describe('Team Collaboration', () => {
test.describe('Organization Switching', () => {
test('can view organizations list', async ({ page }) => {
await page.goto('/orgs');
await expect(page).toHaveURL(/\/orgs/);
await expect(page.locator('body')).toBeVisible();
});
test('shows available organizations', async ({ page }) => {
await page.goto('/orgs');
// Look for organization cards or list items
const orgCard = page.locator('[data-org], [data-organization], .org-card').first();
const orgList = page.locator('a[href*="/dashboard"], button:has-text("Switch")').first();
const cardVisible = await orgCard.isVisible({ timeout: 2000 }).catch(() => false);
const listVisible = await orgList.isVisible({ timeout: 2000 }).catch(() => false);
if (cardVisible || listVisible) {
// At least one should be visible
expect(cardVisible || listVisible).toBe(true);
}
});
test('can switch organizations', async ({ page }) => {
await page.goto('/orgs');
// Look for switch/select button
const switchButton = page.locator('button:has-text("Switch"), a:has-text("Select")').first();
if (await switchButton.isVisible({ timeout: 2000 }).catch(() => false)) {
await switchButton.click();
await page.waitForTimeout(500);
}
});
});
test.describe('Team Members', () => {
test('can view team members in settings', async ({ page }) => {
await page.goto('/settings');
// Skip if redirected to sudo verification
if ((await page.url()).includes('sudo-verify')) {
return;
}
// Look for team members section
const membersSection = page.locator(
':has-text("Members"), :has-text("Team"), a[href*="members"]'
).first();
if (await membersSection.isVisible({ timeout: 2000 }).catch(() => false)) {
await expect(membersSection).toBeVisible();
}
});
test('shows invite button', async ({ page }) => {
await page.goto('/settings');
// Skip if redirected
if ((await page.url()).includes('sudo-verify')) {
return;
}
const inviteButton = page.locator(
'button:has-text("Invite"), a:has-text("Invite")'
).first();
if (await inviteButton.isVisible({ timeout: 2000 }).catch(() => false)) {
await expect(inviteButton).toBeVisible();
}
});
});
test.describe('Invitations', () => {
test('invitation page requires token', async ({ page }) => {
// Try to access without token (should handle gracefully)
await page.goto('/invitations/invalid-token-example');
await expect(page.locator('body')).toBeVisible();
// Should show some kind of message (error or invitation form)
const message = page.locator(
':has-text("invitation"), :has-text("expired"), :has-text("invalid")'
).first();
if (await message.isVisible({ timeout: 2000 }).catch(() => false)) {
await expect(message).toBeVisible();
}
});
});
});