Update E2E tests and simplify performance tests
CI Pipeline / e2e (chromium) (pull_request) Successful in 6m13s
CI Pipeline / e2e (firefox) (pull_request) Successful in 7m3s
CI Pipeline / e2e (webkit) (pull_request) Successful in 5m52s
CI Pipeline / visual-regression (pull_request) Successful in 7m48s
CI Pipeline / performance (pull_request) Successful in 7m59s
CI Pipeline / lint (pull_request) Successful in 6m16s
CI Pipeline / build (pull_request) Successful in 5m30s
CI Pipeline / test (pull_request) Successful in 6m26s

This commit is contained in:
adilallo
2026-01-28 18:22:59 -07:00
parent 9cb89162ab
commit a30bf6be4c
124 changed files with 452 additions and 4190 deletions
+19 -538
View File
@@ -6,14 +6,16 @@ test.describe("Edge Cases and Error Scenarios", () => {
});
test("handles slow network conditions", async ({ page }) => {
// Simulate slow network
// Page is already loaded from beforeEach
// Simulate slow network for any subsequent requests
await page.route("**/*", (route) => {
// Add 2 second delay to all requests
setTimeout(() => route.continue(), 2000);
});
// Reload page with slow network
await page.reload();
// Navigate to a new page to test slow network conditions
// Use a fresh navigation instead of reload to avoid Web Inspector issues
await page.goto("/", { waitUntil: "domcontentloaded", timeout: 10000 });
// Page should still load eventually
await expect(page.locator("text=Collaborate")).toBeVisible({
@@ -22,213 +24,23 @@ test.describe("Edge Cases and Error Scenarios", () => {
});
test("handles offline mode gracefully", async ({ page }) => {
// Note: page.setOffline() is not available in current Playwright version
// This test would require network interception to simulate offline mode
// For now, we'll test that the page loads and functions normally
// Page is already loaded from beforeEach, so we can test offline behavior
// without reloading (which is blocked by Web Inspector in local environments)
// Page should function normally
await expect(page.locator("text=Collaborate")).toBeVisible();
const learnButtons = page.locator(
'button:has-text("Learn how CommunityRule works")',
);
const buttonCount = await learnButtons.count();
let visibleButton = null;
for (let i = 0; i < buttonCount; i++) {
const button = learnButtons.nth(i);
if (await button.isVisible()) {
visibleButton = button;
break;
}
}
if (!visibleButton) {
throw new Error(
'No visible "Learn how CommunityRule works" button found',
);
}
await visibleButton.click();
});
test("handles rapid user interactions", async ({ page }) => {
// Rapidly click visible buttons
const buttons = page.locator("button");
const buttonCount = await buttons.count();
let clickedCount = 0;
for (let i = 0; i < buttonCount && clickedCount < 3; i++) {
const button = buttons.nth(i);
if (await button.isVisible()) {
await button.click();
await page.waitForTimeout(100); // Very short delay
clickedCount++;
}
}
// Page should remain stable
await expect(page.locator("text=Collaborate")).toBeVisible();
});
test("handles rapid scrolling", async ({ page }) => {
// Rapid scroll to bottom
await page.evaluate(() => {
for (let i = 0; i < 10; i++) {
window.scrollTo(0, document.body.scrollHeight * (i / 10));
}
// Simulate offline mode by blocking all network requests
await page.route("**/*", (route) => {
route.abort();
});
// Should end up at bottom - use a more specific selector
await expect(page.locator("footer").first()).toBeVisible();
});
// Verify page content is still visible (cached content should remain)
// This tests that the page doesn't crash when network requests fail
const body = page.locator("body");
await expect(body).toBeVisible();
test("handles viewport size changes", async ({ page }) => {
// Rapidly change viewport sizes
const viewports = [
{ width: 375, height: 667 },
{ width: 768, height: 1024 },
{ width: 1440, height: 900 },
{ width: 1920, height: 1080 },
];
for (const viewport of viewports) {
await page.setViewportSize(viewport);
await page.waitForTimeout(500);
// Content should remain visible
await expect(page.locator("text=Collaborate")).toBeVisible();
}
});
test("handles browser back/forward navigation", async ({ page }) => {
// Navigate to a section
const learnButtons = page.locator(
'button:has-text("Learn how CommunityRule works")',
);
const buttonCount = await learnButtons.count();
let visibleButton = null;
for (let i = 0; i < buttonCount; i++) {
const button = learnButtons.nth(i);
if (await button.isVisible()) {
visibleButton = button;
break;
}
}
if (!visibleButton) {
throw new Error(
'No visible "Learn how CommunityRule works" button found',
);
}
await visibleButton.click();
// Since the button click doesn't navigate to a new page,
// we'll test that the page handles back/forward gracefully
await page.goBack();
await page.goForward();
// Should still have content
await expect(page.locator("body")).toBeVisible();
});
test("handles page refresh during interactions", async ({ page }) => {
// Start an interaction
const learnButtons = page.locator(
'button:has-text("Learn how CommunityRule works")',
);
const buttonCount = await learnButtons.count();
let visibleButton = null;
for (let i = 0; i < buttonCount; i++) {
const button = learnButtons.nth(i);
if (await button.isVisible()) {
visibleButton = button;
break;
}
}
if (!visibleButton) {
throw new Error(
'No visible "Learn how CommunityRule works" button found',
);
}
await visibleButton.click();
// Refresh page during interaction
await page.reload();
// Should reload successfully
// Verify key content is still accessible
await expect(page.locator("text=Collaborate")).toBeVisible();
});
test("handles multiple browser tabs", async ({ page, context }) => {
// Open multiple tabs
const page1 = await context.newPage();
const page2 = await context.newPage();
// Navigate all tabs to homepage
await page1.goto("/");
await page2.goto("/");
// Interact with each tab - find the first visible button
const learnButtons = page.locator(
'button:has-text("Learn how CommunityRule works")',
);
const buttonCount = await learnButtons.count();
let visibleButton = null;
for (let i = 0; i < buttonCount; i++) {
const button = learnButtons.nth(i);
if (await button.isVisible()) {
visibleButton = button;
break;
}
}
if (!visibleButton) {
throw new Error(
'No visible "Learn how CommunityRule works" button found',
);
}
await visibleButton.click();
await page1.locator("text=Consensus clusters").click();
// Find the first visible "Ask an organizer" link (it's an <a> tag, not a button)
const askLinks = page2.locator('a:has-text("Ask an organizer")');
const askLinkCount = await askLinks.count();
let visibleAskLink = null;
for (let i = 0; i < askLinkCount; i++) {
const link = askLinks.nth(i);
if (await link.isVisible()) {
visibleAskLink = link;
break;
}
}
if (!visibleAskLink) {
throw new Error('No visible "Ask an organizer" link found');
}
await visibleAskLink.click();
// All tabs should work independently
await expect(
page.locator('h2:has-text("How CommunityRule works")'),
).toBeVisible();
await expect(page1.locator("text=Consensus clusters")).toBeVisible();
await expect(page2.locator("text=Still have questions?")).toBeVisible();
// Close extra tabs
await page1.close();
await page2.close();
});
test("handles JavaScript errors gracefully", async ({ page }) => {
// Inject a JavaScript error
await page.evaluate(() => {
@@ -248,6 +60,7 @@ test.describe("Edge Cases and Error Scenarios", () => {
// Page should continue to function
await expect(page.locator("text=Collaborate")).toBeVisible();
const learnButtons = page.locator(
'button:has-text("Learn how CommunityRule works")',
);
@@ -277,345 +90,13 @@ test.describe("Edge Cases and Error Scenarios", () => {
route.abort();
});
// Reload page
await page.reload();
// Navigate to a new page to test missing images
// Use a fresh navigation instead of reload to avoid Web Inspector issues
await page.goto("/", { waitUntil: "domcontentloaded" });
// Page should still function without images
await expect(page.locator("text=Collaborate")).toBeVisible();
const learnButtons = page.locator(
'button:has-text("Learn how CommunityRule works")',
);
const buttonCount = await learnButtons.count();
let visibleButton = null;
for (let i = 0; i < buttonCount; i++) {
const button = learnButtons.nth(i);
if (await button.isVisible()) {
visibleButton = button;
break;
}
}
if (!visibleButton) {
throw new Error(
'No visible "Learn how CommunityRule works" button found',
);
}
await visibleButton.click();
});
test("handles CSS loading failures", async ({ page }) => {
// Block CSS requests
await page.route("**/*.css", (route) => {
route.abort();
});
// Reload page
await page.reload();
// Page should still function without styles
await expect(page.locator("text=Collaborate")).toBeVisible();
const learnButtons = page.locator(
'button:has-text("Learn how CommunityRule works")',
);
const buttonCount = await learnButtons.count();
let visibleButton = null;
for (let i = 0; i < buttonCount; i++) {
const button = learnButtons.nth(i);
if (await button.isVisible()) {
visibleButton = button;
break;
}
}
if (!visibleButton) {
throw new Error(
'No visible "Learn how CommunityRule works" button found',
);
}
await visibleButton.click();
});
test("handles font loading failures", async ({ page }) => {
// Block font requests
await page.route("**/*.{woff,woff2,ttf,otf}", (route) => {
route.abort();
});
// Reload page
await page.reload();
// Page should still function with fallback fonts
await expect(page.locator("text=Collaborate")).toBeVisible();
const learnButtons = page.locator(
'button:has-text("Learn how CommunityRule works")',
);
const buttonCount = await learnButtons.count();
let visibleButton = null;
for (let i = 0; i < buttonCount; i++) {
const button = learnButtons.nth(i);
if (await button.isVisible()) {
visibleButton = button;
break;
}
}
if (!visibleButton) {
throw new Error(
'No visible "Learn how CommunityRule works" button found',
);
}
await visibleButton.click();
});
test("handles memory pressure", async ({ page }) => {
// Simulate memory pressure by creating many elements
await page.evaluate(() => {
// Create temporary elements to simulate memory usage
for (let i = 0; i < 1000; i++) {
const div = document.createElement("div");
div.textContent = `Test element ${i}`;
document.body.appendChild(div);
}
// Clean up
setTimeout(() => {
const testElements = document.querySelectorAll(
'div[textContent*="Test element"]',
);
testElements.forEach((el) => el.remove());
}, 100);
});
// Page should remain functional
await expect(page.locator("text=Collaborate")).toBeVisible();
const learnButtons = page.locator(
'button:has-text("Learn how CommunityRule works")',
);
const buttonCount = await learnButtons.count();
let visibleButton = null;
for (let i = 0; i < buttonCount; i++) {
const button = learnButtons.nth(i);
if (await button.isVisible()) {
visibleButton = button;
break;
}
}
if (!visibleButton) {
throw new Error(
'No visible "Learn how CommunityRule works" button found',
);
}
await visibleButton.click();
});
test("handles long content gracefully", async ({ page }) => {
// Add a lot of content to test scrolling performance
await page.evaluate(() => {
const container = document.createElement("div");
container.style.height = "10000px";
container.style.background = "linear-gradient(red, blue)";
document.body.appendChild(container);
});
// Scroll through the content
await page.evaluate(() => window.scrollTo(0, document.body.scrollHeight));
// Should handle long content without issues
await expect(page.locator("text=Collaborate")).toBeVisible();
});
test("handles focus management", async ({ page }) => {
// Test focus trapping and management
await page.keyboard.press("Tab");
await expect(page.locator(":focus")).toBeVisible();
// Navigate through focusable elements
for (let i = 0; i < 10; i++) {
await page.keyboard.press("Tab");
await expect(page.locator(":focus")).toBeVisible();
}
// Test Shift+Tab for reverse navigation
for (let i = 0; i < 5; i++) {
await page.keyboard.press("Shift+Tab");
await expect(page.locator(":focus")).toBeVisible();
}
});
test("handles keyboard shortcuts", async ({ page }) => {
// Test common keyboard shortcuts
await page.keyboard.press("Home");
await page.keyboard.press("End");
await page.keyboard.press("PageUp");
await page.keyboard.press("PageDown");
// Page should handle shortcuts gracefully
await expect(page.locator("text=Collaborate")).toBeVisible();
});
test("handles copy/paste operations", async ({ page }) => {
// Test text selection and copy
await page.locator("text=Collaborate").selectText();
await page.keyboard.press("Control+c");
// Test paste (should work in input fields if any)
const inputs = page.locator("input, textarea");
if ((await inputs.count()) > 0) {
await inputs.first().click();
await page.keyboard.press("Control+v");
}
});
test("handles right-click context menu", async ({ page }) => {
// Test right-click on various elements
await page.locator("text=Collaborate").click({ button: "right" });
// Find visible button for right-click
const learnButtons = page.locator(
'button:has-text("Learn how CommunityRule works")',
);
const buttonCount = await learnButtons.count();
let visibleButton = null;
for (let i = 0; i < buttonCount; i++) {
const button = learnButtons.nth(i);
if (await button.isVisible()) {
visibleButton = button;
break;
}
}
if (visibleButton) {
await visibleButton.click({ button: "right" });
}
// Try to right-click on a visible image if it exists
const images = page.locator("img");
const imageCount = await images.count();
let visibleImage = null;
for (let i = 0; i < imageCount; i++) {
const image = images.nth(i);
if (await image.isVisible()) {
visibleImage = image;
break;
}
}
if (visibleImage) {
await visibleImage.click({ button: "right" });
}
// Should handle right-clicks gracefully
await expect(page.locator("text=Collaborate")).toBeVisible();
});
test("handles drag and drop operations", async ({ page }) => {
// Test drag and drop (if applicable)
const draggableElements = page.locator('[draggable="true"]');
const dropZones = page.locator('[data-testid*="drop"], [class*="drop"]');
if (
(await draggableElements.count()) > 0 &&
(await dropZones.count()) > 0
) {
await draggableElements.first().dragTo(dropZones.first());
}
// Page should handle drag operations gracefully
await expect(page.locator("text=Collaborate")).toBeVisible();
});
test("handles print functionality", async ({ page }) => {
// Test print functionality
await page.evaluate(() => {
// Mock print function
window.print = () => {};
});
// Trigger print
await page.keyboard.press("Control+p");
// Should handle print gracefully
await expect(page.locator("text=Collaborate")).toBeVisible();
});
test("handles browser zoom", async ({ page }) => {
// Test different zoom levels
await page.evaluate(() => {
document.body.style.zoom = "0.5";
});
await expect(page.locator("text=Collaborate")).toBeVisible();
await page.evaluate(() => {
document.body.style.zoom = "2.0";
});
await expect(page.locator("text=Collaborate")).toBeVisible();
// Reset zoom
await page.evaluate(() => {
document.body.style.zoom = "1.0";
});
});
test("handles high contrast mode", async ({ page }) => {
// Simulate high contrast mode
await page.evaluate(() => {
document.body.style.filter = "contrast(200%)";
});
// Content should remain readable
await expect(page.locator("text=Collaborate")).toBeVisible();
const learnButtons = page.locator(
'button:has-text("Learn how CommunityRule works")',
);
const buttonCount = await learnButtons.count();
let visibleButton = null;
for (let i = 0; i < buttonCount; i++) {
const button = learnButtons.nth(i);
if (await button.isVisible()) {
visibleButton = button;
break;
}
}
if (!visibleButton) {
throw new Error(
'No visible "Learn how CommunityRule works" button found',
);
}
await visibleButton.click();
// Reset contrast
await page.evaluate(() => {
document.body.style.filter = "none";
});
});
test("handles reduced motion preferences", async ({ page }) => {
// Simulate reduced motion preference
await page.evaluate(() => {
document.documentElement.style.setProperty(
"--prefers-reduced-motion",
"reduce",
);
});
// Page should respect reduced motion
await expect(page.locator("text=Collaborate")).toBeVisible();
const learnButtons = page.locator(
'button:has-text("Learn how CommunityRule works")',
);