chore: editor test

This commit is contained in:
nathan
2025-09-23 21:35:45 +08:00
parent a0305677f3
commit 35b5d931fe
9 changed files with 390 additions and 11 deletions

View File

@@ -4,6 +4,7 @@ import {
AddPageSelectors,
DatabaseGridSelectors,
CheckboxSelectors,
byTestId,
waitForReactUpdate
} from '../../support/selectors';

View File

@@ -7,6 +7,7 @@ import {
PropertyMenuSelectors,
GridFieldSelectors,
FieldType,
byTestId,
waitForReactUpdate
} from '../../support/selectors';
@@ -55,7 +56,7 @@ describe('DateTime Column Type', () => {
// Verify cells exist
cy.log('[STEP 6] Verifying cells exist');
cy.get('[data-testid^="grid-cell-"]', { timeout: 10000 }).should('exist');
DatabaseGridSelectors.cells().should('exist');
// Add new column
cy.log('[STEP 7] Adding new column by clicking new property button');
@@ -68,7 +69,7 @@ describe('DateTime Column Type', () => {
cy.log('[STEP 8] Waiting for property menu to open');
cy.get('body').then($body => {
// Check if property type trigger exists
if ($body.find('[data-testid="property-type-trigger"]').length > 0) {
if ($body.find(byTestId('property-type-trigger')).length > 0) {
cy.log('[STEP 9] Property type trigger found, changing to DateTime');
PropertyMenuSelectors.propertyTypeTrigger().first().click({ force: true });
waitForReactUpdate(1000);
@@ -112,7 +113,7 @@ describe('DateTime Column Type', () => {
// Check if picker opens
cy.get('body').then($body => {
if ($body.find('[data-testid="datetime-picker-popover"]').length > 0) {
if ($body.find(byTestId('datetime-picker-popover')).length > 0) {
cy.log('[STEP 14] DateTime picker opened successfully');
// Enter a date

View File

@@ -6,7 +6,9 @@ import {
PropertyMenuSelectors,
GridFieldSelectors,
SingleSelectSelectors,
PageSelectors,
FieldType,
byTestId,
waitForReactUpdate
} from '../../support/selectors';
@@ -53,8 +55,8 @@ describe('Single Select Column Type', () => {
// Try to find either inline add button or new page button
cy.get('body').then($body => {
const inlineAddExists = $body.find('[data-testid="inline-add-page"]').length > 0;
const newPageExists = $body.find('[data-testid="new-page-button"]').length > 0;
const inlineAddExists = $body.find(byTestId('inline-add-page')).length > 0;
const newPageExists = $body.find(byTestId('new-page-button')).length > 0;
if (inlineAddExists) {
cy.log('[STEP 4.2] Using inline add button');
@@ -64,7 +66,7 @@ describe('Single Select Column Type', () => {
} else if (newPageExists) {
cy.log('[STEP 4.2] Using new page button instead');
return cy.wrap(null).then(() => {
cy.get('[data-testid="new-page-button"]').first().click({ force: true });
PageSelectors.newPageButton().first().click({ force: true });
});
} else {
// Wait a bit more and try inline add button
@@ -165,7 +167,7 @@ describe('Single Select Column Type', () => {
// Check if property menu is open and change to SingleSelect
cy.log('[STEP 7] Changing column type to SingleSelect');
cy.get('body').then($body => {
if ($body.find('[data-testid="property-type-trigger"]').length > 0) {
if ($body.find(byTestId('property-type-trigger')).length > 0) {
PropertyMenuSelectors.propertyTypeTrigger().first().click({ force: true });
waitForReactUpdate(1000);
PropertyMenuSelectors.propertyTypeOption(FieldType.SingleSelect).click({ force: true });
@@ -240,7 +242,7 @@ describe('Single Select Column Type', () => {
// Click edit property if available
cy.get('body').then($body => {
if ($body.find('[data-testid="grid-field-edit-property"]').length > 0) {
if ($body.find(byTestId('grid-field-edit-property')).length > 0) {
PropertyMenuSelectors.editPropertyMenuItem().click();
waitForReactUpdate(1000);
}
@@ -284,7 +286,7 @@ describe('Single Select Column Type', () => {
// Click edit property if available
cy.get('body').then($body => {
if ($body.find('[data-testid="grid-field-edit-property"]').length > 0) {
if ($body.find(byTestId('grid-field-edit-property')).length > 0) {
PropertyMenuSelectors.editPropertyMenuItem().click();
waitForReactUpdate(1000);
}
@@ -314,7 +316,7 @@ describe('Single Select Column Type', () => {
// Check if select menu appears
cy.get('body').then($body => {
if ($body.find('[data-testid="select-option-menu"]').length > 0) {
if ($body.find(byTestId('select-option-menu')).length > 0) {
cy.log('[STEP 18] Select option menu opened - options preserved!');
} else {
cy.log('[STEP 18] Select cells exist but menu behavior may differ');

View File

@@ -0,0 +1,110 @@
import { v4 as uuidv4 } from 'uuid';
import { AuthTestUtils } from '../../support/auth-utils';
import { waitForReactUpdate } from '../../support/selectors';
describe('Slash Menu - Text Formatting', () => {
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;
});
cy.viewport(1280, 720);
});
it('should show text formatting options in slash menu', () => {
const testEmail = generateRandomEmail();
cy.log(`[TEST START] Testing text formatting options - Test email: ${testEmail}`);
// Login
cy.visit('/login', { failOnStatusCode: false });
cy.wait(2000);
const authUtils = new AuthTestUtils();
authUtils.signInWithTestUrl(testEmail).then(() => {
cy.url({ timeout: 30000 }).should('include', '/app');
cy.wait(3000);
// Navigate to Getting started page
cy.contains('Getting started').click();
cy.wait(5000); // Give page time to fully load
// Focus on editor
cy.get('[data-slate-editor="true"]').should('exist').click();
waitForReactUpdate(1000);
// Type slash to open menu
cy.focused().type('/');
waitForReactUpdate(1000);
// Verify text formatting options are visible
cy.log('Verifying Text option');
cy.contains('Text').should('be.visible');
cy.log('Verifying Heading 1 option');
cy.contains('Heading 1').should('be.visible');
cy.log('Verifying Heading 2 option');
cy.contains('Heading 2').should('be.visible');
cy.log('Verifying Heading 3 option');
cy.contains('Heading 3').should('be.visible');
// Close menu
cy.get('body').type('{esc}');
waitForReactUpdate(500);
cy.log('Text formatting options verified successfully');
});
});
it('should allow selecting Heading 1 from slash menu', () => {
const testEmail = generateRandomEmail();
cy.log(`[TEST START] Testing Heading 1 selection - Test email: ${testEmail}`);
// Login
cy.visit('/login', { failOnStatusCode: false });
cy.wait(2000);
const authUtils = new AuthTestUtils();
authUtils.signInWithTestUrl(testEmail).then(() => {
cy.url({ timeout: 30000 }).should('include', '/app');
cy.wait(3000);
// Navigate to Getting started page
cy.contains('Getting started').click();
cy.wait(5000);
// Focus on editor and move to end
cy.get('[data-slate-editor="true"]').should('exist').click();
cy.focused().type('{end}');
cy.focused().type('{enter}{enter}'); // Add some space
waitForReactUpdate(1000);
// Type slash to open menu
cy.focused().type('/');
waitForReactUpdate(1000);
// Click Heading 1
cy.contains('Heading 1').should('be.visible').click();
waitForReactUpdate(1000);
// Type some text
cy.focused().type('Test Heading');
waitForReactUpdate(500);
// Verify the text was added
cy.get('[data-slate-editor="true"]').should('contain.text', 'Test Heading');
cy.log('Heading 1 added successfully');
});
});
});

View File

@@ -0,0 +1,105 @@
import { v4 as uuidv4 } from 'uuid';
import { AuthTestUtils } from '../../support/auth-utils';
import { waitForReactUpdate } from '../../support/selectors';
describe('Slash Menu - List Actions', () => {
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;
});
cy.viewport(1280, 720);
});
it('should show list options in slash menu', () => {
const testEmail = generateRandomEmail();
cy.log(`[TEST START] Testing list options - Test email: ${testEmail}`);
// Login
cy.visit('/login', { failOnStatusCode: false });
cy.wait(2000);
const authUtils = new AuthTestUtils();
authUtils.signInWithTestUrl(testEmail).then(() => {
cy.url({ timeout: 30000 }).should('include', '/app');
cy.wait(3000);
// Navigate to Getting started page
cy.contains('Getting started').click();
cy.wait(5000); // Give page time to fully load
// Focus on editor
cy.get('[data-slate-editor="true"]').should('exist').click();
waitForReactUpdate(1000);
// Type slash to open menu
cy.focused().type('/');
waitForReactUpdate(1000);
// Verify list options are visible
cy.log('Verifying Bulleted list option');
cy.contains('Bulleted list').should('be.visible');
cy.log('Verifying Numbered list option');
cy.contains('Numbered list').should('be.visible');
// Close menu
cy.get('body').type('{esc}');
waitForReactUpdate(500);
cy.log('List options verified successfully');
});
});
it('should allow selecting Bulleted list from slash menu', () => {
const testEmail = generateRandomEmail();
cy.log(`[TEST START] Testing Bulleted list selection - Test email: ${testEmail}`);
// Login
cy.visit('/login', { failOnStatusCode: false });
cy.wait(2000);
const authUtils = new AuthTestUtils();
authUtils.signInWithTestUrl(testEmail).then(() => {
cy.url({ timeout: 30000 }).should('include', '/app');
cy.wait(3000);
// Navigate to Getting started page
cy.contains('Getting started').click();
cy.wait(5000);
// Focus on editor and move to end
cy.get('[data-slate-editor="true"]').should('exist').click();
cy.focused().type('{end}');
cy.focused().type('{enter}{enter}'); // Add some space
waitForReactUpdate(1000);
// Type slash to open menu
cy.focused().type('/');
waitForReactUpdate(1000);
// Click Bulleted list
cy.contains('Bulleted list').should('be.visible').click();
waitForReactUpdate(1000);
// Type some text
cy.focused().type('Test bullet item');
waitForReactUpdate(500);
// Verify the text was added
cy.get('[data-slate-editor="true"]').should('contain.text', 'Test bullet item');
cy.log('Bulleted list added successfully');
});
});
});

View File

@@ -0,0 +1,97 @@
import { v4 as uuidv4 } from 'uuid';
import { AuthTestUtils } from '../../support/auth-utils';
import { waitForReactUpdate } from '../../support/selectors';
describe('Slash Menu - Media Actions', () => {
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;
});
cy.viewport(1280, 720);
});
it('should show media options in slash menu', () => {
const testEmail = generateRandomEmail();
cy.log(`[TEST START] Testing media options - Test email: ${testEmail}`);
// Login
cy.visit('/login', { failOnStatusCode: false });
cy.wait(2000);
const authUtils = new AuthTestUtils();
authUtils.signInWithTestUrl(testEmail).then(() => {
cy.url({ timeout: 30000 }).should('include', '/app');
cy.wait(3000);
// Navigate to Getting started page
cy.contains('Getting started').click();
cy.wait(5000); // Give page time to fully load
// Focus on editor
cy.get('[data-slate-editor="true"]').should('exist').click();
waitForReactUpdate(1000);
// Type slash to open menu
cy.focused().type('/');
waitForReactUpdate(1000);
// Verify media options are visible
cy.log('Verifying Image option');
cy.contains('Image').should('be.visible');
cy.log('Verifying Embed video option');
cy.contains('Embed video').should('be.visible');
// Close menu
cy.get('body').type('{esc}');
waitForReactUpdate(500);
cy.log('Media options verified successfully');
});
});
it('should allow selecting Image from slash menu', () => {
const testEmail = generateRandomEmail();
cy.log(`[TEST START] Testing Image selection - Test email: ${testEmail}`);
// Login
cy.visit('/login', { failOnStatusCode: false });
cy.wait(2000);
const authUtils = new AuthTestUtils();
authUtils.signInWithTestUrl(testEmail).then(() => {
cy.url({ timeout: 30000 }).should('include', '/app');
cy.wait(3000);
// Navigate to Getting started page
cy.contains('Getting started').click();
cy.wait(5000);
// Focus on editor and move to end
cy.get('[data-slate-editor="true"]').should('exist').click();
cy.focused().type('{end}');
cy.focused().type('{enter}{enter}'); // Add some space
waitForReactUpdate(1000);
// Type slash to open menu
cy.focused().type('/');
waitForReactUpdate(1000);
// Click Image
cy.contains('Image').should('be.visible').click();
waitForReactUpdate(1000);
cy.log('Image option clicked successfully');
});
});
});

View File

@@ -0,0 +1,62 @@
import { v4 as uuidv4 } from 'uuid';
import { AuthTestUtils } from '../../support/auth-utils';
import { PageSelectors, waitForReactUpdate } from '../../support/selectors';
describe('Editor Slash Menu', () => {
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;
});
cy.viewport(1280, 720);
});
it('should trigger slash menu when typing / and display menu options', () => {
const testEmail = generateRandomEmail();
cy.log(`[TEST START] Testing slash menu trigger - Test email: ${testEmail}`);
// Login
cy.visit('/login', { failOnStatusCode: false });
cy.wait(2000);
const authUtils = new AuthTestUtils();
authUtils.signInWithTestUrl(testEmail).then(() => {
cy.url({ timeout: 30000 }).should('include', '/app');
cy.wait(3000);
// Navigate to Getting started page
cy.contains('Getting started').click();
cy.wait(5000); // Give page time to fully load
// Focus on editor
cy.get('[data-slate-editor="true"]').should('exist').click();
waitForReactUpdate(1000);
// Type slash to open menu
cy.focused().type('/');
waitForReactUpdate(1000);
// Verify main menu items are visible
cy.contains('Ask AI Anything').should('be.visible');
cy.contains('Text').should('be.visible');
cy.contains('Heading 1').should('be.visible');
cy.contains('Image').should('be.visible');
cy.contains('Bulleted list').should('be.visible');
// Close menu
cy.get('body').type('{esc}');
waitForReactUpdate(500);
cy.log('Slash menu test completed successfully');
});
});
});

View File

@@ -6,7 +6,7 @@
/**
* Helper function to create a data-testid selector
*/
function byTestId(id: string): string {
export function byTestId(id: string): string {
return `[data-testid="${id}"]`;
}

View File

@@ -695,6 +695,7 @@ export function SlashPanel({
color={'inherit'}
startIcon={option.icon}
key={option.key}
data-testid={`slash-menu-${option.key}`}
data-option-key={option.key}
onClick={() => {
handleSelectOption(option.key);