mirror of
https://github.com/mattermost/mattermost.git
synced 2026-09-21 14:20:41 +08:00
fix(cypress): demo plugin (#36056)
This commit is contained in:
@@ -17,10 +17,18 @@ describe('Link tooltips', () => {
|
||||
cy.shouldNotRunOnCloudEdition();
|
||||
cy.shouldHavePluginUploadEnabled();
|
||||
|
||||
// # Set plugin settings
|
||||
// # Set plugin settings, including demo plugin defaults so that
|
||||
// OnConfigurationChange can create the demo user with a valid email
|
||||
const newSettings = {
|
||||
PluginSettings: {
|
||||
Enable: true,
|
||||
Plugins: {
|
||||
[demoPlugin.id]: {
|
||||
channelname: 'demo_plugin',
|
||||
username: 'demo_plugin',
|
||||
lastname: 'Plugin User',
|
||||
},
|
||||
},
|
||||
},
|
||||
ServiceSettings: {
|
||||
EnableGifPicker: true,
|
||||
@@ -47,7 +55,7 @@ describe('Link tooltips', () => {
|
||||
cy.uiWaitUntilMessagePostedIncludes(url);
|
||||
|
||||
// # Hover over the plugin link
|
||||
cy.findByText(url).should('exist').focus();
|
||||
cy.getLastPost().findByText(url).should('exist').focus();
|
||||
|
||||
// * Check tooltip has appeared
|
||||
cy.findByText('This is a custom tooltip from the Demo Plugin').should('be.visible');
|
||||
|
||||
@@ -56,14 +56,15 @@ Cypress.Commands.add('apiUploadPlugin', (filename) => {
|
||||
|
||||
Cypress.Commands.add('apiUploadAndEnablePlugin', ({filename, url, id, version}) => {
|
||||
return cy.apiGetPluginStatus(id, version).then((data) => {
|
||||
// # If already active, then only return the data
|
||||
if (data.isActive) {
|
||||
// # Only short-circuit when version is specified, so we know the exact
|
||||
// installed version matches the desired artifact. Without a version,
|
||||
// any installed version would match and we'd silently skip the install.
|
||||
if (version && data.isActive) {
|
||||
cy.log(`${id}: Plugin is active.`);
|
||||
return cy.wrap(data);
|
||||
}
|
||||
|
||||
// # If already installed, then only enable the plugin
|
||||
if (data.isInstalled) {
|
||||
if (version && data.isInstalled) {
|
||||
cy.log(`${id}: Plugin is inactive. Only going to enable.`);
|
||||
return cy.apiEnablePluginById(id).then(() => {
|
||||
cy.wait(TIMEOUTS.ONE_SEC);
|
||||
@@ -71,23 +72,39 @@ Cypress.Commands.add('apiUploadAndEnablePlugin', ({filename, url, id, version})
|
||||
});
|
||||
}
|
||||
|
||||
// # Remove any old version of the plugin before installing the new one
|
||||
const removeOldVersion = () => {
|
||||
return cy.apiGetPluginStatus(id).then((anyVersionData) => {
|
||||
if (anyVersionData.isInstalled || anyVersionData.isActive) {
|
||||
cy.log(`${id}: Removing old version before installing new one.`);
|
||||
return cy.apiRemovePluginById(id);
|
||||
}
|
||||
|
||||
return cy.wrap(null);
|
||||
});
|
||||
};
|
||||
|
||||
if (url) {
|
||||
// # Upload plugin by URL then enable
|
||||
cy.log(`${id}: Plugin is to be uploaded via URL and then enable.`);
|
||||
return cy.apiInstallPluginFromUrl(url).then(() => {
|
||||
cy.wait(TIMEOUTS.FIVE_SEC);
|
||||
return cy.apiEnablePluginById(id).then(() => {
|
||||
cy.wait(TIMEOUTS.ONE_SEC);
|
||||
return cy.wrap({isInstalled: true, isActive: true});
|
||||
return removeOldVersion().then(() => {
|
||||
return cy.apiInstallPluginFromUrl(url).then(() => {
|
||||
cy.wait(TIMEOUTS.FIVE_SEC);
|
||||
return cy.apiEnablePluginById(id).then(() => {
|
||||
cy.wait(TIMEOUTS.ONE_SEC);
|
||||
return cy.wrap({isInstalled: true, isActive: true});
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// # Upload plugin by file then enable
|
||||
cy.log(`${id}: Plugin is to be uploaded by filename and then enable.`);
|
||||
return cy.apiUploadPlugin(filename).then(() => {
|
||||
return cy.apiEnablePluginById(id).then(() => {
|
||||
return cy.wrap({isInstalled: true, isActive: true});
|
||||
return removeOldVersion().then(() => {
|
||||
return cy.apiUploadPlugin(filename).then(() => {
|
||||
return cy.apiEnablePluginById(id).then(() => {
|
||||
return cy.wrap({isInstalled: true, isActive: true});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -23,9 +23,9 @@ export const agendaPlugin = {
|
||||
|
||||
export const demoPlugin = {
|
||||
id: 'com.mattermost.demo-plugin',
|
||||
version: '0.10.0',
|
||||
url: 'https://github.com/mattermost/mattermost-plugin-demo/releases/download/v0.10.0/com.mattermost.demo-plugin-0.10.0.tar.gz',
|
||||
filename: 'com.mattermost.demo-plugin-0.10.0.tar.gz',
|
||||
version: '0.11.0',
|
||||
url: 'https://github.com/mattermost/mattermost-plugin-demo/releases/download/v0.11.0/mattermost-plugin-demo-v0.11.0.tar.gz',
|
||||
filename: 'mattermost-plugin-demo-v0.11.0.tar.gz',
|
||||
};
|
||||
|
||||
export const demoPluginOld = {
|
||||
|
||||
@@ -7,7 +7,7 @@ import {expect} from '@mattermost/playwright-lib';
|
||||
|
||||
const DEMO_PLUGIN_ID = 'com.mattermost.demo-plugin';
|
||||
const DEMO_PLUGIN_URL =
|
||||
'https://github.com/mattermost/mattermost-plugin-demo/releases/download/v0.11.0/mattermost-plugin-demo-v0.11.0-linux-amd64.tar.gz';
|
||||
'https://github.com/mattermost/mattermost-plugin-demo/releases/download/v0.11.0/mattermost-plugin-demo-v0.11.0.tar.gz';
|
||||
|
||||
export async function setupDemoPlugin(
|
||||
adminClient: Client4,
|
||||
|
||||
@@ -33,7 +33,7 @@ test('should install and enable demo plugin from URL', async ({pw}) => {
|
||||
// Install and enable
|
||||
await pw.installAndEnablePlugin(
|
||||
adminClient,
|
||||
'https://github.com/mattermost/mattermost-plugin-demo/releases/download/v0.11.0/com.mattermost.demo-plugin-0.11.0.tar.gz',
|
||||
'https://github.com/mattermost/mattermost-plugin-demo/releases/download/v0.11.0/mattermost-plugin-demo-v0.11.0.tar.gz',
|
||||
'com.mattermost.demo-plugin',
|
||||
);
|
||||
|
||||
|
||||
@@ -94,6 +94,37 @@ describe('PluginLinkTooltip', () => {
|
||||
expect(screen.getByTestId('textarea')).toHaveFocus();
|
||||
});
|
||||
|
||||
test('should not block interaction with elements outside the tooltip', async () => {
|
||||
renderWithContext(
|
||||
<>
|
||||
<textarea
|
||||
data-testid='textarea'
|
||||
defaultValue='some text'
|
||||
/>
|
||||
<PluginLinkTooltip
|
||||
nodeAttributes={{
|
||||
href: 'https://example.com/tooltip',
|
||||
}}
|
||||
>
|
||||
{'This is a link'}
|
||||
</PluginLinkTooltip>
|
||||
<div id={RootHtmlPortalId}/>
|
||||
</>,
|
||||
baseState,
|
||||
);
|
||||
|
||||
// # Hover over the link to show the tooltip
|
||||
await userEvent.hover(screen.getByText('This is a link'));
|
||||
await waitFor(() => {
|
||||
expect(screen.queryByText('This is a link tooltip')).toBeVisible();
|
||||
});
|
||||
|
||||
// * Verify the overlay has pointer-events: none so it doesn't block clicks
|
||||
const overlay = document.querySelector('.plugin-link-tooltip-floating-overlay') as HTMLElement;
|
||||
expect(overlay).toBeInTheDocument();
|
||||
expect(overlay.style.pointerEvents || getComputedStyle(overlay).pointerEvents).toBe('none');
|
||||
});
|
||||
|
||||
test('should not take focus when hovered without a tooltip', async () => {
|
||||
renderWithContext(
|
||||
<>
|
||||
|
||||
@@ -2,6 +2,11 @@
|
||||
|
||||
.plugin-link-tooltip-floating-overlay {
|
||||
z-index: variables.$z-index-popover;
|
||||
pointer-events: none;
|
||||
|
||||
> * {
|
||||
pointer-events: auto;
|
||||
}
|
||||
}
|
||||
|
||||
// This is as per UX guidelines what the container of the
|
||||
|
||||
@@ -5,7 +5,21 @@ import {TestHelper} from 'utils/test_helper';
|
||||
|
||||
import type {GlobalState} from 'types/store';
|
||||
|
||||
import {makeGetMentionKeysForPost} from './index';
|
||||
import {hasPluginTooltips, makeGetMentionKeysForPost} from './index';
|
||||
|
||||
describe('hasPluginTooltips', () => {
|
||||
it('should be false when LinkTooltip is an empty array', () => {
|
||||
expect(hasPluginTooltips([])).toBe(false);
|
||||
});
|
||||
|
||||
it('should be false when LinkTooltip is undefined', () => {
|
||||
expect(hasPluginTooltips(undefined)).toBe(false);
|
||||
});
|
||||
|
||||
it('should be true when LinkTooltip has registered components', () => {
|
||||
expect(hasPluginTooltips([{id: 'test', pluginId: 'com.example', component: () => null}])).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('makeGetMentionKeysForPost', () => {
|
||||
const channel = TestHelper.getChannelMock({});
|
||||
|
||||
@@ -56,6 +56,10 @@ export function makeGetMentionKeysForPost(): (
|
||||
);
|
||||
}
|
||||
|
||||
export function hasPluginTooltips(linkTooltip?: unknown[]): boolean {
|
||||
return Boolean(linkTooltip?.length);
|
||||
}
|
||||
|
||||
function makeMapStateToProps() {
|
||||
const getMentionKeysForPost = makeGetMentionKeysForPost();
|
||||
|
||||
@@ -73,7 +77,7 @@ function makeMapStateToProps() {
|
||||
channel,
|
||||
currentTeam,
|
||||
pluginHooks: state.plugins.components.MessageWillFormat,
|
||||
hasPluginTooltips: Boolean(state.plugins.components.LinkTooltip),
|
||||
hasPluginTooltips: hasPluginTooltips(state.plugins.components.LinkTooltip),
|
||||
isUserCanManageMembers: channel && canManageMembers(state, channel),
|
||||
mentionKeys: getMentionKeysForPost(state, ownProps.post, channel),
|
||||
highlightKeys: getHighlightWithoutNotificationKeys(state),
|
||||
|
||||
Reference in New Issue
Block a user