mirror of
https://github.com/AppFlowy-IO/AppFlowy-Web.git
synced 2025-12-01 20:08:10 +08:00
chore: fix scroll to top when insert database at the bottom
This commit is contained in:
129
cypress/e2e/embeded/database/database-bottom-scroll-simple.cy.ts
Normal file
129
cypress/e2e/embeded/database/database-bottom-scroll-simple.cy.ts
Normal file
@@ -0,0 +1,129 @@
|
||||
import { AuthTestUtils } from '../../../support/auth-utils';
|
||||
import { getSlashMenuItemName } from '../../../support/i18n-constants';
|
||||
import {
|
||||
EditorSelectors,
|
||||
SlashCommandSelectors,
|
||||
waitForReactUpdate
|
||||
} from '../../../support/selectors';
|
||||
import { generateRandomEmail } from '../../../support/test-config';
|
||||
|
||||
describe('Embedded Database - Bottom Scroll Preservation (Simplified)', () => {
|
||||
|
||||
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') ||
|
||||
err.message.includes('Cannot resolve a DOM point from Slate point') ||
|
||||
err.message.includes('No range and node found')) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
|
||||
cy.viewport(1280, 720);
|
||||
});
|
||||
|
||||
it('should preserve scroll position when creating grid at bottom', () => {
|
||||
const testEmail = generateRandomEmail();
|
||||
|
||||
cy.task('log', `[TEST] Email: ${testEmail}`);
|
||||
|
||||
// Login
|
||||
const authUtils = new AuthTestUtils();
|
||||
|
||||
// Use cy.session for authentication like the working tests
|
||||
cy.session(testEmail, () => {
|
||||
authUtils.signInWithTestUrl(testEmail);
|
||||
}, {
|
||||
validate: () => {
|
||||
cy.window().then((win) => {
|
||||
const token = win.localStorage.getItem('af_auth_token');
|
||||
expect(token).to.be.ok;
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// Visit app and open Getting Started document (like working tests)
|
||||
cy.visit('/app');
|
||||
cy.url({ timeout: 30000 }).should('include', '/app');
|
||||
cy.contains('Getting started', { timeout: 10000 }).should('be.visible').click();
|
||||
cy.wait(2000);
|
||||
|
||||
// Clear existing content and add 30 lines
|
||||
EditorSelectors.firstEditor().click({ force: true });
|
||||
cy.focused().type('{selectall}{backspace}');
|
||||
waitForReactUpdate(500);
|
||||
|
||||
let content = '';
|
||||
for (let i = 1; i <= 30; i++) {
|
||||
content += `Line ${i} content{enter}`;
|
||||
}
|
||||
cy.focused().type(content, { delay: 1 });
|
||||
waitForReactUpdate(2000);
|
||||
|
||||
// Scroll to bottom
|
||||
cy.get('.appflowy-scroll-container').first().then($container => {
|
||||
const scrollHeight = $container[0].scrollHeight;
|
||||
const clientHeight = $container[0].clientHeight;
|
||||
const targetScroll = scrollHeight - clientHeight;
|
||||
|
||||
// Scroll to bottom using DOM
|
||||
$container[0].scrollTop = targetScroll;
|
||||
cy.task('log', `[SCROLL] Scrolled to: ${targetScroll}`);
|
||||
});
|
||||
|
||||
cy.wait(1000); // Give more time for any scroll settling
|
||||
|
||||
// Record scroll position and store it globally so code can access it
|
||||
let scrollBefore = 0;
|
||||
cy.get('.appflowy-scroll-container').first().then($container => {
|
||||
scrollBefore = $container[0].scrollTop;
|
||||
cy.task('log', `[SCROLL] Immediately before typing "/": ${scrollBefore}`);
|
||||
|
||||
// Store in window so our code can access it
|
||||
cy.window().then((win) => {
|
||||
win.__CYPRESS_EXPECTED_SCROLL__ = scrollBefore;
|
||||
});
|
||||
});
|
||||
|
||||
// Create database at bottom (cursor already at end from previous typing, just type "/")
|
||||
// Don't click - clicking might cause scroll. Use cy.focused() since cursor is already there.
|
||||
cy.focused().type('/', { delay: 0 });
|
||||
waitForReactUpdate(500);
|
||||
|
||||
SlashCommandSelectors.slashPanel().should('be.visible').within(() => {
|
||||
SlashCommandSelectors.slashMenuItem(getSlashMenuItemName('grid')).first().click();
|
||||
});
|
||||
|
||||
waitForReactUpdate(2000);
|
||||
|
||||
// Check modal opened
|
||||
cy.get('[role="dialog"]', { timeout: 10000 }).should('be.visible');
|
||||
|
||||
// CRITICAL: Verify scroll position is preserved (didn't jump to top)
|
||||
cy.get('.appflowy-scroll-container').first().then($container => {
|
||||
const scrollAfter = $container[0].scrollTop;
|
||||
const scrollDelta = Math.abs(scrollAfter - scrollBefore);
|
||||
|
||||
cy.task('log', `[SCROLL] After grid creation: ${scrollAfter}`);
|
||||
cy.task('log', `[SCROLL] Scroll delta: ${scrollBefore} -> ${scrollAfter} (changed by ${scrollAfter - scrollBefore})`);
|
||||
|
||||
// Verify scroll didn't jump to top (the bug we're testing for)
|
||||
if (scrollAfter < 200) {
|
||||
cy.task('log', `[FAIL] Document scrolled to top (${scrollAfter})! This is the bug we are testing for.`);
|
||||
}
|
||||
|
||||
// Should NOT scroll to top (scrollAfter should be > 200)
|
||||
expect(scrollAfter).to.be.greaterThan(200,
|
||||
`Document should not scroll to top when creating database at bottom. Before: ${scrollBefore}, After: ${scrollAfter}`);
|
||||
|
||||
// Verify scroll stayed close to original position (within 100px tolerance)
|
||||
// This ensures we not only avoided scrolling to top, but preserved the actual position
|
||||
expect(scrollDelta).to.be.lessThan(100,
|
||||
`Scroll position should be preserved within 100px. Before: ${scrollBefore}, After: ${scrollAfter}, Delta: ${scrollDelta}`);
|
||||
|
||||
cy.task('log', `[SUCCESS] Scroll preserved! Before: ${scrollBefore}, After: ${scrollAfter}, Delta: ${scrollDelta}px`);
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user