Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 4 additions & 13 deletions cypress/e2e/account/avatar/avatar-test-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,30 +7,21 @@ import { AuthTestUtils } from '../../../support/auth-utils';
import { AvatarSelectors } from '../../../support/avatar-selectors';
import { dbUtils } from '../../../support/db-utils';
import { WorkspaceSelectors } from '../../../support/selectors';
import { TestConfig } from '../../../support/test-config';
import { setupCommonExceptionHandlers } from '../../../support/exception-handlers';

/**
* Shared utilities and setup for avatar tests
*/
export const avatarTestUtils = {
generateRandomEmail: () => `${uuidv4()}@appflowy.io`,
APPFLOWY_BASE_URL: Cypress.env('APPFLOWY_BASE_URL'),
APPFLOWY_BASE_URL: TestConfig.apiUrl,

/**
* Common beforeEach setup for avatar tests
*/
setupBeforeEach: () => {
// Suppress known transient errors
cy.on('uncaught:exception', (err) => {
if (
err.message.includes('Minified React error') ||
err.message.includes('View not found') ||
err.message.includes('No workspace or service found')
) {
return false;
}

return true;
});
setupCommonExceptionHandlers();
cy.viewport(1280, 720);
},

Expand Down
26 changes: 10 additions & 16 deletions cypress/e2e/account/update-user-profile.cy.ts
Original file line number Diff line number Diff line change
@@ -1,32 +1,26 @@
import { v4 as uuidv4 } from 'uuid';
import { AuthTestUtils } from '../../support/auth-utils';
import { TestConfig, logTestEnvironment } from '../../support/test-config';
import { setupCommonExceptionHandlers } from '../../support/exception-handlers';

describe('Update User Profile', () => {
const generateRandomEmail = () => `${uuidv4()}@appflowy.io`;

beforeEach(() => {
cy.on('uncaught:exception', (err) => {
if (err.message.includes('Minified React error') ||
err.message.includes('View not found') ||
err.message.includes('No workspace or service found')) {
return false;
}
return true;
});
before(() => {
logTestEnvironment();
});

beforeEach(() => {
setupCommonExceptionHandlers();
cy.viewport(1280, 720);
});

it('should update user profile settings through Account Settings', () => {
const testEmail = generateRandomEmail();
let testEmail: string;

// Login
cy.log('Step 1: Logging in to the application');
cy.visit('/login', { failOnStatusCode: false });
cy.wait(2000);

const authUtils = new AuthTestUtils();
authUtils.signInWithTestUrl(testEmail).then(() => {
cy.loginTestUser().then((email) => {
testEmail = email;
// Wait for app to load
cy.log('Step 2: Waiting for application to load');
cy.url({ timeout: 30000 }).should('include', '/app');
Expand Down
67 changes: 11 additions & 56 deletions cypress/e2e/app/sidebar-components.cy.ts
Original file line number Diff line number Diff line change
@@ -1,39 +1,18 @@
import { v4 as uuidv4 } from 'uuid';
import { AuthTestUtils } from '../../support/auth-utils';
import { PageSelectors, SidebarSelectors } from '../../support/selectors';
import { logTestEnvironment } from '../../support/test-config';
import { setupCommonExceptionHandlers } from '../../support/exception-handlers';

describe('Sidebar Components Resilience Tests', () => {
const generateRandomEmail = () => `${uuidv4()}@appflowy.io`;
let testEmail: string;
before(() => {
logTestEnvironment();
});

beforeEach(() => {
testEmail = generateRandomEmail();

// Handle uncaught exceptions that we expect during app initialization
cy.on('uncaught:exception', (err: Error) => {
// Ignore known non-critical errors
if (
err.message.includes('No workspace or service found') ||
err.message.includes('View not found') ||
err.message.includes('WebSocket') ||
err.message.includes('connection') ||
err.message.includes('Failed to load models') ||
err.message.includes('Minified React error') ||
err.message.includes('ResizeObserver loop') ||
err.message.includes('Non-Error promise rejection')
) {
return false;
}
return true;
});
setupCommonExceptionHandlers();
});

it('should load app without React error boundaries triggering for ShareWithMe and Favorite components', () => {
cy.visit('/login', { failOnStatusCode: false });
cy.wait(2000);

const authUtils = new AuthTestUtils();
authUtils.signInWithTestUrl(testEmail).then(() => {
cy.loginTestUser().then(() => {
cy.url().should('include', '/app');
cy.task('log', 'Signed in successfully');

Expand Down Expand Up @@ -78,13 +57,7 @@ describe('Sidebar Components Resilience Tests', () => {
});

it('should handle empty favorites gracefully', () => {
cy.visit('/login', { failOnStatusCode: false });
cy.wait(2000);

const authUtils = new AuthTestUtils();
authUtils.signInWithTestUrl(testEmail).then(() => {
cy.url().should('include', '/app');

cy.loginTestUser().then(() => {
// Wait for app to fully load
SidebarSelectors.pageHeader().should('be.visible', { timeout: 30000 });
PageSelectors.names().should('exist', { timeout: 30000 });
Expand All @@ -107,13 +80,7 @@ describe('Sidebar Components Resilience Tests', () => {
});

it('should handle ShareWithMe with no shared content gracefully', () => {
cy.visit('/login', { failOnStatusCode: false });
cy.wait(2000);

const authUtils = new AuthTestUtils();
authUtils.signInWithTestUrl(testEmail).then(() => {
cy.url().should('include', '/app');

cy.loginTestUser().then(() => {
// Wait for app to fully load
SidebarSelectors.pageHeader().should('be.visible', { timeout: 30000 });
PageSelectors.names().should('exist', { timeout: 30000 });
Expand All @@ -139,13 +106,7 @@ describe('Sidebar Components Resilience Tests', () => {
});

it('should handle invalid outline data gracefully', () => {
cy.visit('/login', { failOnStatusCode: false });
cy.wait(2000);

const authUtils = new AuthTestUtils();
authUtils.signInWithTestUrl(testEmail).then(() => {
cy.url().should('include', '/app');

cy.loginTestUser().then(() => {
// Wait for app to fully load
SidebarSelectors.pageHeader().should('be.visible', { timeout: 30000 });
PageSelectors.names().should('exist', { timeout: 30000 });
Expand Down Expand Up @@ -173,13 +134,7 @@ describe('Sidebar Components Resilience Tests', () => {
});

it('should handle favorites with invalid favorited_at dates gracefully', () => {
cy.visit('/login', { failOnStatusCode: false });
cy.wait(2000);

const authUtils = new AuthTestUtils();
authUtils.signInWithTestUrl(testEmail).then(() => {
cy.url().should('include', '/app');

cy.loginTestUser().then(() => {
// Wait for app to fully load
SidebarSelectors.pageHeader().should('be.visible', { timeout: 30000 });
PageSelectors.names().should('exist', { timeout: 30000 });
Expand Down
28 changes: 10 additions & 18 deletions cypress/e2e/auth/login-logout.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,22 +6,14 @@ import {
AuthSelectors,
waitForReactUpdate
} from '../../support/selectors';
import { TestConfig } from '../../support/test-config';
import { setupCommonExceptionHandlers } from '../../support/exception-handlers';

describe('Login and Logout Flow', () => {
const baseUrl = Cypress.config('baseUrl') || 'http://localhost:3000';
const gotrueUrl = Cypress.env('APPFLOWY_GOTRUE_BASE_URL') || 'http://localhost/gotrue';
const apiUrl = Cypress.env('APPFLOWY_BASE_URL') || 'http://localhost';
const { baseUrl, gotrueUrl, apiUrl } = TestConfig;

beforeEach(() => {
// Handle uncaught exceptions
cy.on('uncaught:exception', (err) => {
if (err.message.includes('Minified React error') ||
err.message.includes('View not found') ||
err.message.includes('No workspace or service found')) {
return false;
}
return true;
});
setupCommonExceptionHandlers();
cy.viewport(1280, 720);
});

Expand Down Expand Up @@ -54,8 +46,8 @@ describe('Login and Logout Flow', () => {

// Step 5: Verify workspace is loaded by checking dropdown trigger
cy.log('[STEP 5] Verifying workspace loaded');
WorkspaceSelectors.dropdownTrigger({ timeout: 15000 })
.should('be.visible');
WorkspaceSelectors.dropdownTrigger()
.should('be.visible', { timeout: 15000 });

// Step 6: Open workspace dropdown
cy.log('[STEP 6] Opening workspace dropdown');
Expand Down Expand Up @@ -124,8 +116,8 @@ describe('Login and Logout Flow', () => {

// Step 4: Verify user is logged in
cy.log('[STEP 4] Verifying user is logged in');
WorkspaceSelectors.dropdownTrigger({ timeout: 15000 })
.should('be.visible');
WorkspaceSelectors.dropdownTrigger()
.should('be.visible', { timeout: 15000 });

// Step 5: Open workspace dropdown
cy.log('[STEP 5] Opening workspace dropdown');
Expand Down Expand Up @@ -188,8 +180,8 @@ describe('Login and Logout Flow', () => {

// Step 4: Open workspace dropdown
cy.log('[STEP 4] Opening workspace dropdown');
WorkspaceSelectors.dropdownTrigger({ timeout: 15000 })
.should('be.visible');
WorkspaceSelectors.dropdownTrigger()
.should('be.visible', { timeout: 15000 });
TestTool.openWorkspaceDropdown();

// Verify dropdown is open
Expand Down
23 changes: 8 additions & 15 deletions cypress/e2e/auth/oauth-login.cy.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import { v4 as uuidv4 } from 'uuid';
import { TestConfig, logTestEnvironment } from '../../support/test-config';
import { setupCommonExceptionHandlers } from '../../support/exception-handlers';

/**
* OAuth Login Flow Tests
Expand All @@ -19,23 +21,14 @@ import { v4 as uuidv4 } from 'uuid';
* - Context initialization timing
*/
describe('OAuth Login Flow', () => {
const baseUrl = Cypress.config('baseUrl') || 'http://localhost:3000';
const gotrueUrl = Cypress.env('APPFLOWY_GOTRUE_BASE_URL') || 'http://localhost/gotrue';
const apiUrl = Cypress.env('APPFLOWY_BASE_URL') || 'http://localhost';
const { baseUrl, gotrueUrl, apiUrl } = TestConfig;

before(() => {
logTestEnvironment();
});

beforeEach(() => {
// Handle uncaught exceptions
cy.on('uncaught:exception', (err) => {
if (
err.message.includes('Minified React error') ||
err.message.includes('View not found') ||
err.message.includes('No workspace or service found') ||
err.message.includes('Cannot read properties of undefined')
) {
return false;
}
return true;
});
setupCommonExceptionHandlers();
cy.viewport(1280, 720);

// Clear localStorage before each test
Expand Down
13 changes: 8 additions & 5 deletions cypress/e2e/auth/otp-login.cy.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import { v4 as uuidv4 } from 'uuid';
import { TestConfig, logTestEnvironment } from '../../support/test-config';
import { setupCommonExceptionHandlers } from '../../support/exception-handlers';

/**
* OTP Login Flow Tests
Expand All @@ -20,13 +22,14 @@ import { v4 as uuidv4 } from 'uuid';
* - localStorage cleanup for new users
*/
describe('OTP Login Flow', () => {
const baseUrl = Cypress.config('baseUrl') || 'http://localhost:3000';
const gotrueUrl = Cypress.env('APPFLOWY_GOTRUE_BASE_URL') || 'http://localhost/gotrue';
const apiUrl = Cypress.env('APPFLOWY_BASE_URL') || 'http://localhost';
const { baseUrl, gotrueUrl, apiUrl } = TestConfig;

before(() => {
logTestEnvironment();
});

beforeEach(() => {
// Handle uncaught exceptions
cy.on('uncaught:exception', () => false);
setupCommonExceptionHandlers();
cy.viewport(1280, 720);
});

Expand Down
13 changes: 8 additions & 5 deletions cypress/e2e/auth/password-login.cy.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
import { v4 as uuidv4 } from 'uuid';
import { TestConfig, logTestEnvironment } from '../../support/test-config';
import { setupCommonExceptionHandlers } from '../../support/exception-handlers';

describe('Password Login Flow', () => {
const baseUrl = Cypress.config('baseUrl') || 'http://localhost:3000';
const gotrueUrl = Cypress.env('APPFLOWY_GOTRUE_BASE_URL') || 'http://localhost/gotrue';
const apiUrl = Cypress.env('APPFLOWY_BASE_URL') || 'http://localhost';
const { baseUrl, gotrueUrl, apiUrl } = TestConfig;

before(() => {
logTestEnvironment();
});

beforeEach(() => {
// Handle uncaught exceptions
cy.on('uncaught:exception', () => false);
setupCommonExceptionHandlers();
cy.viewport(1280, 720);
});

Expand Down
Loading
Loading