mirror of
https://github.com/AppFlowy-IO/AppFlowy-Web.git
synced 2026-03-13 10:00:26 +08:00
chore: editor test
This commit is contained in:
@@ -4,6 +4,7 @@ import {
|
||||
AddPageSelectors,
|
||||
DatabaseGridSelectors,
|
||||
CheckboxSelectors,
|
||||
byTestId,
|
||||
waitForReactUpdate
|
||||
} from '../../support/selectors';
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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');
|
||||
|
||||
110
cypress/e2e/editor/slash-menu-formatting.cy.ts
Normal file
110
cypress/e2e/editor/slash-menu-formatting.cy.ts
Normal 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');
|
||||
});
|
||||
});
|
||||
});
|
||||
105
cypress/e2e/editor/slash-menu-lists.cy.ts
Normal file
105
cypress/e2e/editor/slash-menu-lists.cy.ts
Normal 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');
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
97
cypress/e2e/editor/slash-menu-media.cy.ts
Normal file
97
cypress/e2e/editor/slash-menu-media.cy.ts
Normal 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');
|
||||
});
|
||||
});
|
||||
});
|
||||
62
cypress/e2e/editor/slash-menu.cy.ts
Normal file
62
cypress/e2e/editor/slash-menu.cy.ts
Normal 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');
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
@@ -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}"]`;
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user