Files
AppFlowy-Web/cypress/e2e/database/row-insertion.cy.ts
2025-11-17 12:12:56 +08:00

237 lines
8.7 KiB
TypeScript

import {
AddPageSelectors,
DatabaseGridSelectors,
RowControlsSelectors,
waitForReactUpdate
} from '../../support/selectors';
import { AuthTestUtils } from '../../support/auth-utils';
import { generateRandomEmail } from '../../support/test-config';
describe('Database Row Insertion', () => {
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 insert rows above and below existing row', () => {
const testEmail = generateRandomEmail();
const originalContent = `Original Row ${Date.now()}`;
const aboveContent = `Above Row ${Date.now()}`;
const belowContent = `Below Row ${Date.now()}`;
cy.log(`[TEST START] Testing row insertion above and below - Test email: ${testEmail}`);
// Login
cy.log('[STEP 1] Visiting login page');
cy.visit('/login', { failOnStatusCode: false });
cy.wait(2000);
const authUtils = new AuthTestUtils();
cy.log('[STEP 2] Starting authentication');
authUtils.signInWithTestUrl(testEmail).then(() => {
cy.log('[STEP 3] Authentication successful');
cy.url({ timeout: 30000 }).should('include', '/app');
cy.wait(3000);
// Create a new grid
cy.log('[STEP 4] Creating new grid');
AddPageSelectors.inlineAddButton().first().should('be.visible').click();
waitForReactUpdate(1000);
AddPageSelectors.addGridButton().should('be.visible').click();
cy.wait(8000);
// Verify grid exists
cy.log('[STEP 5] Verifying grid exists');
DatabaseGridSelectors.grid().should('exist');
// Get cells and edit the first one
cy.log('[STEP 6] Getting cells and editing first cell');
DatabaseGridSelectors.cells().should('exist');
DatabaseGridSelectors.cells().then($cells => {
cy.log(`[STEP 7] Found ${$cells.length} cells`);
// Click first cell and type content
cy.wrap($cells.first()).click();
waitForReactUpdate(500);
cy.focused().type(originalContent);
cy.focused().type('{enter}');
waitForReactUpdate(1000);
// Verify data was entered
cy.log('[STEP 8] Verifying content was added');
cy.wrap($cells.first()).should('contain.text', originalContent);
});
// Get initial row count
cy.log('[STEP 9] Getting initial row count');
DatabaseGridSelectors.rows().then($rows => {
const initialRowCount = $rows.length;
cy.log(`[STEP 9.1] Initial row count: ${initialRowCount}`);
// Insert a row above
cy.log('[STEP 10] Inserting row above');
// Get the first row and hover over it
DatabaseGridSelectors.firstRow()
.parent()
.parent()
.trigger('mouseenter', { force: true })
.trigger('mouseover', { force: true });
cy.wait(1000);
// Click on the drag icon/row accessory button
cy.log('[STEP 11] Looking for and clicking row accessory button');
RowControlsSelectors.rowAccessoryButton().then($button => {
if ($button.length > 0) {
cy.log('[STEP 11.1] Found row accessory button with data-testid');
cy.wrap($button.first()).click({ force: true });
} else {
cy.log('[STEP 11.1] Looking for drag icon by class');
cy.get('div[class*="cursor-pointer"]').first().click({ force: true });
}
});
cy.wait(1000);
// Now the dropdown menu should be open
cy.log('[STEP 12] Looking for insert above option in dropdown menu');
// Wait for the dropdown menu to be visible
cy.get('[role="menu"], [data-slot="dropdown-menu-content"]').should('be.visible');
// Click on the insert above option - using data-testid first
RowControlsSelectors.rowMenuInsertAbove().then($insertAbove => {
if ($insertAbove.length > 0) {
cy.log('[STEP 12.1] Found insert above menu item by data-testid');
cy.wrap($insertAbove).click();
} else {
cy.log('[STEP 12.1] Looking for insert above by position');
// First menu item is typically insert above
cy.get('[role="menuitem"]').first().click();
}
});
cy.wait(2000);
// Verify a new row was added
cy.log('[STEP 13] Verifying row was inserted above');
DatabaseGridSelectors.rows().should('have.length', initialRowCount + 1);
// Add content to the newly inserted row (which should be the first row now)
cy.log('[STEP 14] Adding content to newly inserted row above');
DatabaseGridSelectors.cells().first().click();
waitForReactUpdate(500);
cy.focused().type(aboveContent);
cy.focused().type('{enter}');
waitForReactUpdate(1000);
// Now insert a row below the original row (which is now the second row)
cy.log('[STEP 15] Inserting row below original row');
// Get the second row and hover over it
DatabaseGridSelectors.rows().eq(1)
.parent()
.parent()
.trigger('mouseenter', { force: true })
.trigger('mouseover', { force: true });
cy.wait(1000);
// Click on the drag icon/row accessory button again
cy.log('[STEP 16] Looking for and clicking row accessory button for second row');
// The row controls should appear for the second row after hovering
RowControlsSelectors.rowAccessoryButton().then($buttons => {
if ($buttons.length > 0) {
cy.log('[STEP 16.1] Found row accessory button');
// Click the last visible button (should be for the hovered row)
cy.wrap($buttons.last()).click({ force: true });
} else {
cy.log('[STEP 16.1] Looking for drag icon by class');
cy.get('div[class*="cursor-pointer"]').last().click({ force: true });
}
});
cy.wait(1000);
// Now the dropdown menu should be open
cy.log('[STEP 17] Looking for insert below option in dropdown menu');
// Wait for the dropdown menu to be visible
cy.get('[role="menu"], [data-slot="dropdown-menu-content"]').should('be.visible');
// Click on the insert below option - using data-testid first
RowControlsSelectors.rowMenuInsertBelow().then($insertBelow => {
if ($insertBelow.length > 0) {
cy.log('[STEP 17.1] Found insert below menu item by data-testid');
cy.wrap($insertBelow).click();
} else {
cy.log('[STEP 17.1] Looking for insert below by position');
// Second menu item is typically insert below
cy.get('[role="menuitem"]').eq(1).click();
}
});
cy.wait(2000);
// Verify another new row was added
cy.log('[STEP 18] Verifying row was inserted below');
DatabaseGridSelectors.rows().should('have.length', initialRowCount + 2);
// Add content to the newly inserted row below (should be the third row)
cy.log('[STEP 19] Adding content to newly inserted row below');
DatabaseGridSelectors.rows().eq(2).within(() => {
DatabaseGridSelectors.cells().first().click();
});
waitForReactUpdate(500);
cy.focused().type(belowContent);
cy.focused().type('{enter}');
waitForReactUpdate(1000);
// Final verification - check all cells have the correct content
cy.log('[STEP 20] Final verification of content');
DatabaseGridSelectors.cells().then($allCells => {
// Find cells that contain our test content
let foundAbove = false;
let foundOriginal = false;
let foundBelow = false;
$allCells.each((index, cell) => {
const text = Cypress.$(cell).text();
if (text.includes(aboveContent)) {
foundAbove = true;
cy.log(`[STEP 20.1] Found above content at index ${index}`);
}
if (text.includes(originalContent)) {
foundOriginal = true;
cy.log(`[STEP 20.2] Found original content at index ${index}`);
}
if (text.includes(belowContent)) {
foundBelow = true;
cy.log(`[STEP 20.3] Found below content at index ${index}`);
}
});
// Verify all content was found
expect(foundAbove).to.be.true;
expect(foundOriginal).to.be.true;
expect(foundBelow).to.be.true;
});
cy.log('[STEP 21] Row insertion test completed successfully');
});
});
});
});