MM-56630 Scroll Fix of center panel (#30144)

* pageup/pagedown button scroll for center post-list

* revert package.json

* changing id, using ? and returning in keyHandler

* added e2e test for pageup/pagedown scroll

* Fix dynamic-virtualized-list not being in lockfile and update path

Moving the package under the MM namespace wasn't necessary, but it stops
some warnings from NPM.

* Move E2E test from Cypress to Playwright

Cypress's cy.type doesn't seem to properly trigger browser functions
because it doesn't seem to use native keyboard events. A newer version
of Cypress has a new cy.press method which is supposed to use native
keyboard events, but it also only supports the tab key currently, so it
wouldn't be useful here.

* Fix new test on iPad

* Add page up/down support to RHS and Threads view

* Update type definitions for dynamic-virtualized-list

---------

Co-authored-by: Harrison Healey <harrisonmhealey@gmail.com>
Этот коммит содержится в:
Arya Khochare
2025-04-24 20:45:40 +05:30
коммит произвёл GitHub
родитель 89319cafb1
Коммит faf68a6d86
10 изменённых файлов: 180 добавлений и 29 удалений

Просмотреть файл

@@ -51,6 +51,12 @@ export default class ChannelsPost {
return this.profileIcon.getByAltText(`${username} profile image`);
}
async openRhs() {
await this.container.hover();
await this.postMenu.toBeVisible();
await this.postMenu.reply();
}
/**
* Clicks on the deleted post's remove 'x' button.
* Also verifies that the post is a deleted post.

Просмотреть файл

@@ -0,0 +1,62 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import {Page} from '@playwright/test';
import {expect, test} from '@mattermost/playwright-lib';
test('should be able to scroll the post list with page up and down', async ({pw}) => {
const {user} = await pw.initSetup();
const {channelsPage, page} = await pw.testBrowser.login(user);
await channelsPage.goto();
await channelsPage.toBeVisible();
for (let i = 0; i < 10; i++) {
await channelsPage.centerView.postCreate.postMessage('a\n'.repeat(10));
}
let lastScrollTop = await getScrollTop(page, '#postListScrollContainer');
// # Press the page up key with the post textbox focused
channelsPage.centerView.postCreate.input.focus();
await page.keyboard.press('PageUp');
await page.waitForTimeout(200); // Wait for the browser's page up/down animation
// * Verify that the post list scrolled up by a page
let currentScrollTop = await getScrollTop(page, '#postListScrollContainer');
expect(currentScrollTop).toBeLessThan(lastScrollTop);
lastScrollTop = currentScrollTop;
// # Press the page up key with the post list focused
await page.keyboard.press('PageUp');
await page.waitForTimeout(200);
// * Verify that the post list scrolled up another page
currentScrollTop = await getScrollTop(page, '#postListScrollContainer');
expect(currentScrollTop).toBeLessThan(lastScrollTop);
lastScrollTop = currentScrollTop;
// # Press the page down key with the post list focused
await page.keyboard.press('PageDown');
await page.waitForTimeout(200);
// * Verify that the post list scrolled back down a page
currentScrollTop = await getScrollTop(page, '#postListScrollContainer');
expect(currentScrollTop).toBeGreaterThan(lastScrollTop);
lastScrollTop = currentScrollTop;
// # Press the page down key with the post textbox focused
channelsPage.centerView.postCreate.input.focus();
await page.keyboard.press('PageDown');
await page.waitForTimeout(200);
// * Verify that the post list scrolled back to the bottom
currentScrollTop = await getScrollTop(page, '#postListScrollContainer');
expect(currentScrollTop).toBeGreaterThan(lastScrollTop);
});
async function getScrollTop(page: Page, selector: string): Promise<number> {
const locator = await page.locator(selector);
return locator?.evaluate((element) => element.scrollTop);
}

Просмотреть файл

@@ -0,0 +1,66 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import {Page} from '@playwright/test';
import {expect, test} from '@mattermost/playwright-lib';
test('should be able to scroll the RHS with page up and down', async ({pw}) => {
const {user} = await pw.initSetup();
const {channelsPage, page} = await pw.testBrowser.login(user);
await channelsPage.goto();
await channelsPage.toBeVisible();
await channelsPage.centerView.postCreate.postMessage('post');
const lastPost = await channelsPage.centerView.getLastPost();
await lastPost.openRhs();
for (let i = 0; i < 10; i++) {
await channelsPage.sidebarRight.postCreate.postMessage('a\n'.repeat(10));
}
let lastScrollTop = await getScrollTop(page, '#threadViewerScrollContainer');
// # Press the page up key with the post textbox focused
channelsPage.sidebarRight.postCreate.input.focus();
await page.keyboard.press('PageUp');
await page.waitForTimeout(200); // Wait for the browser's page up/down animation
// * Verify that the post list scrolled up by a page
let currentScrollTop = await getScrollTop(page, '#threadViewerScrollContainer');
expect(currentScrollTop).toBeLessThan(lastScrollTop);
lastScrollTop = currentScrollTop;
// # Press the page up key with the post list focused
await page.keyboard.press('PageUp');
await page.waitForTimeout(200);
// * Verify that the post list scrolled up another page
currentScrollTop = await getScrollTop(page, '#threadViewerScrollContainer');
expect(currentScrollTop).toBeLessThan(lastScrollTop);
lastScrollTop = currentScrollTop;
// # Press the page down key with the post list focused
await page.keyboard.press('PageDown');
await page.waitForTimeout(200);
// * Verify that the post list scrolled back down a page
currentScrollTop = await getScrollTop(page, '#threadViewerScrollContainer');
expect(currentScrollTop).toBeGreaterThan(lastScrollTop);
lastScrollTop = currentScrollTop;
// # Press the page down key with the post textbox focused
channelsPage.centerView.postCreate.input.focus();
await page.keyboard.press('PageDown');
await page.waitForTimeout(200);
// * Verify that the post list scrolled back to the bottom
currentScrollTop = await getScrollTop(page, '#threadViewerScrollContainer');
expect(currentScrollTop).toBeGreaterThan(lastScrollTop);
});
async function getScrollTop(page: Page, selector: string): Promise<number> {
const locator = await page.locator(selector);
return locator?.evaluate((element) => element.scrollTop);
}