Этот коммит содержится в:
Mario Vitale
2023-03-27 16:28:42 +02:00
родитель da7a6825ce
Коммит ba6b97fb62
1142 изменённых файлов: 44 добавлений и 44 удалений

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

@@ -0,0 +1,94 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
// ***************************************************************
// - [#] indicates a test step (e.g. # Go to a page)
// - [*] indicates an assertion (e.g. * Check the title)
// - Use element ID when selecting an element. Create one if none.
// ***************************************************************
// Stage: @prod
// Group: @channels @integrations
import * as TIMEOUTS from '../../../../fixtures/timeouts';
describe('Integrations', () => {
let testTeam;
let testChannel;
let testUser;
let outgoingWebhook;
before(() => {
const callbackUrl = `${Cypress.env().webhookBaseUrl}/post_outgoing_webhook`;
cy.requireWebhookServer();
// # Create test team, channel, and webhook
cy.apiInitSetup().then(({team, channel, user}) => {
testTeam = team.name;
testChannel = channel.name;
testUser = user;
const newOutgoingHook = {
team_id: team.id,
display_name: 'New Outgoing Webhook',
trigger_words: ['testing'],
callback_urls: [callbackUrl],
};
cy.apiCreateWebhook(newOutgoingHook, false).then((hook) => {
outgoingWebhook = hook;
cy.apiGetOutgoingWebhook(outgoingWebhook.id).then(({webhook, status}) => {
expect(status).equal(200);
expect(webhook.id).equal(outgoingWebhook.id);
});
});
cy.apiLogin(user);
});
});
it('MM-T617 Delete outgoing webhook', () => {
// # Confirm outgoing webhook is working
cy.visit(`/${testTeam}/channels/${testChannel}`);
cy.postMessage('testing');
cy.uiWaitUntilMessagePostedIncludes('Outgoing Webhook Payload');
// # Login as sysadmin
cy.apiAdminLogin();
// * Assert from API that outgoing webhook is active
cy.apiGetOutgoingWebhook(outgoingWebhook.id).then(({status}) => {
expect(status).equal(200);
});
// # Delete outgoing webhook
cy.visit(`/${testTeam}/integrations/outgoing_webhooks`);
cy.findAllByText('Delete', {timeout: TIMEOUTS.ONE_MIN}).click();
cy.get('#confirmModalButton').click();
// * Assert the webhook has been deleted
cy.findByText('No outgoing webhooks found').should('exist');
cy.apiGetOutgoingWebhook(outgoingWebhook.id).then(({status}) => {
expect(status).equal(404);
});
// * Return to app and assert trigger word no longer works
cy.apiLogin(testUser);
cy.visit(`/${testTeam}/channels/${testChannel}`);
cy.postMessage('testing');
// * Assert bot message does not arrive
cy.wait(TIMEOUTS.TWO_SEC);
cy.getLastPostId().then((lastPostId) => {
cy.get(`#${lastPostId}_message`).should('not.contain', 'Outgoing Webhook Payload');
});
// * Verify from API that outgoing webhook has been deleted
cy.apiAdminLogin();
cy.apiGetOutgoingWebhook(outgoingWebhook.id).then(({status}) => {
expect(status).equal(404);
});
});
});

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

@@ -0,0 +1,109 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
// ***************************************************************
// - [#] indicates a test step (e.g. # Go to a page)
// - [*] indicates an assertion (e.g. * Check the title)
// - Use element ID when selecting an element. Create one if none.
// ***************************************************************
// Group: @channels @integrations
import * as TIMEOUTS from '../../../../fixtures/timeouts';
describe('Integrations', () => {
let testTeam;
let testChannel;
let testUser;
let outgoingWebhook;
before(() => {
const callbackUrl = `${Cypress.env().webhookBaseUrl}/post_outgoing_webhook`;
cy.requireWebhookServer();
// # Create test team, channel, and webhook
cy.apiInitSetup().then(({team, channel, user}) => {
testTeam = team.name;
testChannel = channel.name;
testUser = user;
const newOutgoingHook = {
team_id: team.id,
display_name: 'New Outgoing Webhook',
trigger_words: ['testing'],
callback_urls: [callbackUrl],
};
cy.apiCreateWebhook(newOutgoingHook, false).then((hook) => {
outgoingWebhook = hook;
cy.apiGetOutgoingWebhook(outgoingWebhook.id).then(({webhook, status}) => {
expect(status).equal(200);
expect(webhook.id).equal(outgoingWebhook.id);
});
});
cy.apiLogin(testUser);
});
});
it('MM-T613 Disable outgoing webhooks in System Console', () => {
// # Confirm outgoing webhook is working with trigger word
cy.visit(`/${testTeam}/channels/${testChannel}`);
cy.postMessage('testing');
cy.uiWaitUntilMessagePostedIncludes('Outgoing Webhook Payload');
// # Login as sysadmin
cy.apiAdminLogin();
// * Assert from API that outgoing webhook is active
cy.apiGetOutgoingWebhook(outgoingWebhook.id).then(({status}) => {
expect(status).equal(200);
});
// # Disable outgoing webhooks from console
cy.visit('/admin_console/integrations/integration_management');
cy.findByTestId('ServiceSettings.EnableOutgoingWebhooksfalse').click().should('be.checked');
cy.get('#saveSetting').click();
cy.get('#saveSetting').should('be.disabled');
// * Assert from API that outgoing webhook has been disabled
cy.apiAdminLogin();
cy.apiGetOutgoingWebhook(outgoingWebhook.id).then(({status}) => {
expect(status).equal(501);
});
// # Login as regular user
cy.apiLogin(testUser);
// * Assert that trigger word no longer triggers webhook
cy.visit(`/${testTeam}/channels/${testChannel}`);
cy.postMessage('testing');
cy.wait(TIMEOUTS.TWO_SEC);
cy.getLastPostId().then((lastPostId) => {
cy.get(`#${lastPostId}_message`).should('not.contain', 'Outgoing Webhook Payload');
});
// # Login as sysadmin
cy.apiAdminLogin();
// # Re-enable outgoing webhooks from console
cy.visit('/admin_console/integrations/integration_management');
cy.findByTestId('ServiceSettings.EnableOutgoingWebhookstrue').click().should('be.checked');
cy.get('#saveSetting').click();
// * Assert from API that outgoing webhook is active
cy.apiGetOutgoingWebhook(outgoingWebhook.id).then(({status}) => {
expect(status).equal(200);
});
// # Login as regular user
cy.apiLogin(testUser);
// * Assert outgoing webhook is working with trigger word
cy.visit(`/${testTeam}/channels/${testChannel}`);
cy.postMessage('testing');
cy.uiWaitUntilMessagePostedIncludes('Outgoing Webhook Payload');
});
});

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

@@ -0,0 +1,398 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
// ***************************************************************
// - [#] indicates a test step (e.g. # Go to a page)
// - [*] indicates an assertion (e.g. * Check the title)
// - Use element ID when selecting an element. Create one if none.
// ***************************************************************
// Group: @channels @outgoing_webhook
import * as TIMEOUTS from '../../../../fixtures/timeouts';
import {
enableUsernameAndIconOverrideInt,
enableUsernameAndIconOverride,
} from '../incoming_webhook/helpers';
describe('Outgoing webhook', () => {
const triggerWord = 'text';
const messageWithTriggerWord = 'text with some more text';
const callbackUrl = `${Cypress.env().webhookBaseUrl}/post_outgoing_webhook`;
const noChannelSelectionOption = '--- Select a channel ---';
const overrideIconUrl = 'http://via.placeholder.com/150/00F/888';
const defaultUsername = 'webhook';
const overriddenUsername = 'user-overridden';
const defaultIcon = 'webhook_icon.jpg';
const overriddenIcon = 'webhook_override_icon.png';
let sysadmin;
let testTeam;
let testChannel;
let testUser;
let otherUser;
let siteName;
let offTopicUrl;
let testChannelUrl;
before(() => {
cy.apiGetConfig().then(({config}) => {
siteName = config.TeamSettings.SiteName;
});
cy.apiGetMe().then(({user}) => {
sysadmin = user;
});
cy.requireWebhookServer();
});
beforeEach(() => {
cy.apiAdminLogin();
cy.apiUpdateConfig({
ServiceSettings: {
EnablePostUsernameOverride: false,
EnablePostIconOverride: false,
},
});
cy.apiInitSetup().then((out) => {
testTeam = out.team;
testChannel = out.channel;
testUser = out.user;
offTopicUrl = out.offTopicUrl;
testChannelUrl = out.channelUrl;
});
cy.apiCreateUser().then(({user: user1}) => {
otherUser = user1;
cy.apiAddUserToTeam(testTeam.id, otherUser.id);
});
});
it('MM-T584 default username and profile pic Trigger = posting anything in the specified channel', () => {
// # Enable user name and icon overrides
cy.apiAdminLogin();
enableUsernameAndIconOverride(true);
// # Visit test channel and post a message
cy.visit(testChannelUrl);
cy.postMessage('hello');
// # Set outgoing webhook
setOutgoingWebhook(testTeam.name, siteName, {callbackUrl, channelSelect: testChannel.display_name});
// * Verify it redirects to test channel
cy.url().should('include', testChannelUrl);
// # Post any message in a channel as testUser
postMessageInChannel(testUser, testChannelUrl, Date.now());
// * Verify default profile name and icon of posted webhook message
verifyProfileNameAndIcon({username: defaultUsername, userIcon: defaultIcon});
// # Post any message in a channel as otherUser
postMessageInChannel(testUser, testChannelUrl, Date.now());
// * Verify default profile name and icon of posted webhook message
verifyProfileNameAndIcon({username: defaultUsername, userIcon: defaultIcon});
});
it('MM-T2035 default username and overridden profile pic (using command) Trigger = posting a trigger word in any channel', () => {
// # Visit test channel and post a message
cy.visit(testChannelUrl);
cy.postMessage('hello');
// # Set outgoing webhook
setOutgoingWebhook(testTeam.name, siteName, {callbackUrl, triggerWord, channelSelect: testChannel.display_name});
// * Verify it redirects to test channel
cy.url().should('include', testChannelUrl);
// # Enable user icon override only
cy.apiAdminLogin();
enableUsernameAndIconOverrideInt(false, true);
// # Visit test channel
cy.visit(testChannelUrl);
// # Edit outgoing webhook
editOutgoingWebhook(testTeam.name, siteName, {iconUrl: overrideIconUrl, channelSelect: noChannelSelectionOption});
// * Verify it redirects to test channel
cy.url().should('include', testChannelUrl);
// # Post a message in test channel as testUser
postMessageInChannel(testUser, testChannelUrl, messageWithTriggerWord);
// * Verify default profile name and overridden icon of posted webhook message
verifyProfileNameAndIcon({username: sysadmin.username, userIcon: overriddenIcon});
// # Visit off-topic channel
cy.visit(offTopicUrl);
// # Post a message in off-topic channel as testUser
postMessageInChannel(testUser, offTopicUrl, messageWithTriggerWord);
// * Verify default profile name and overridden icon of posted webhook message
verifyProfileNameAndIcon({username: sysadmin.username, userIcon: overriddenIcon});
});
it('MM-T2036 overridden username and profile pic (using Mattermost UI)', () => {
// # Go to test channel and post a message
cy.visit(testChannelUrl);
cy.postMessage('hello');
// # Set outgoing webhook
setOutgoingWebhook(testTeam.name, siteName, {callbackUrl, triggerWord});
// * Verify it redirects to test channel
cy.url().should('include', testChannelUrl);
// # Enable user name and icon overrides
cy.apiAdminLogin();
enableUsernameAndIconOverride(true);
// # Visit test channel
cy.visit(testChannelUrl);
// # Edit outgoing webhook
editOutgoingWebhook(testTeam.name, siteName, {username: overriddenUsername, iconUrl: overrideIconUrl});
// * Verify it redirects to test channel
cy.url().should('include', testChannelUrl);
// # Post a message in off-topic channel as testUser
postMessageInChannel(testUser, offTopicUrl, messageWithTriggerWord);
// * Verify default profile name and overridden icon of posted webhook message
verifyProfileNameAndIcon({username: overriddenUsername, userIcon: overriddenIcon});
});
it('MM-T2037 Outgoing Webhooks - overridden username and profile pic from webhook', () => {
const usernameFromWebhook = 'user_from_webhook';
const newCallbackUrl = callbackUrl + '?override_username=' + usernameFromWebhook + '&override_icon_url=' + overrideIconUrl;
// # Visit test channel and post a message
cy.visit(testChannelUrl);
cy.postMessage('hello');
// # Set outgoing webhook
setOutgoingWebhook(testTeam.name, siteName, {callbackUrl: newCallbackUrl, triggerWord});
// * Verify it redirects to test channel
cy.url().should('include', testChannelUrl);
// # Enable user name and icon overrides
cy.apiAdminLogin();
enableUsernameAndIconOverride(true);
// # Visit test channel
cy.visit(testChannelUrl);
// # Edit outgoing webhook
editOutgoingWebhook(testTeam.name, siteName, {callbackUrl: newCallbackUrl, withConfirmation: true});
// * Verify it redirects to test channel
cy.url().should('include', testChannelUrl);
// # Post a message in off-topic as testUser
postMessageInChannel(testUser, offTopicUrl, messageWithTriggerWord);
// # Verify overridden profile name and icon from posted webhook message
verifyProfileNameAndIcon({username: usernameFromWebhook, userIcon: overriddenIcon});
// # Post a message in test channel as otherUser
postMessageInChannel(otherUser, testChannelUrl, messageWithTriggerWord);
// # Verify overridden profile name and icon from posted webhook message
verifyProfileNameAndIcon({username: usernameFromWebhook, userIcon: overriddenIcon});
});
it('MM-T2038 Bot posts as a comment/reply', () => {
const newCallbackUrl = callbackUrl + '?response_type=comment';
// # Visit test channel and post a message
cy.visit(testChannelUrl);
cy.postMessage('hello');
// # Set outgoing webhook
setOutgoingWebhook(testTeam.name, siteName, {callbackUrl: newCallbackUrl, triggerWord});
// * Verify it redirects to test channel
cy.url().should('include', testChannelUrl);
// # Edit outgoing webhook
editOutgoingWebhook(testTeam.name, siteName, {callbackUrl: newCallbackUrl, withConfirmation: true});
// * Verify it redirects to test channel
cy.url().should('include', testChannelUrl);
// # Post a message in off-topic as testUser
postMessageInChannel(testUser, offTopicUrl, messageWithTriggerWord);
cy.getLastPost().should('contain', 'comment');
});
it('MM-T2039 Outgoing Webhooks - Reply to bot post', () => {
const secondMessage = 'some text';
// # Visit test channel and post a message
cy.visit(testChannelUrl);
cy.postMessage('hello');
// # Set outgoing webhook
setOutgoingWebhook(testTeam.name, siteName, {callbackUrl, triggerWord});
// * Verify it redirects to test channel
cy.url().should('include', testChannelUrl);
// # Post a message in off-topic as testUser
postMessageInChannel(testUser, offTopicUrl, messageWithTriggerWord);
cy.postMessage(secondMessage);
// # Post a reply on RHS to the webhook post
cy.getNthPostId(-2).then((postId) => {
cy.clickPostCommentIcon(postId);
cy.uiGetRHS();
cy.postMessageReplyInRHS('A reply to the webhook post');
cy.wait(TIMEOUTS.HALF_SEC);
});
cy.uiGetPostHeader().contains('Commented on ' + sysadmin.username + '\'s message: #### Outgoing Webhook Payload');
});
it('MM-T2040 Disable overriding username and profile pic in System Console', () => {
// # Visit test channel and post a message
cy.visit(testChannelUrl);
cy.postMessage('hello');
// # Set outgoing webhook
setOutgoingWebhook(testTeam.name, siteName, {callbackUrl, triggerWord});
// * Verify it redirects to test channel
cy.url().should('include', testChannelUrl);
cy.apiAdminLogin();
// # Enable user name and icon overrides
enableUsernameAndIconOverride(true);
// # Disable user name and icon overrides
enableUsernameAndIconOverride(false);
// # Post a message in off-topic as testUser
postMessageInChannel(testUser, offTopicUrl, messageWithTriggerWord);
// # Verify creator's profile name and icon from posted webhook message
verifyProfileNameAndIcon({username: sysadmin.username, userId: sysadmin.id});
});
});
function postMessageInChannel(user, channelUrl, message) {
cy.apiLogin(user);
cy.visit(channelUrl);
cy.postMessage(message);
cy.uiWaitUntilMessagePostedIncludes('#### Outgoing Webhook Payload');
}
function setOutgoingWebhook(teamName, siteName, {callbackUrl, channelSelect, triggerWord}) {
cy.uiOpenProductMenu('Integrations');
// * Verify that it redirects to integrations URL. Then, click "Outgoing Webhooks"
cy.url().should('include', `${teamName}/integrations`);
cy.get('.backstage-sidebar').should('be.visible').findByText('Outgoing Webhooks').click();
// * Verify that it redirects to outgoing webhooks URL. Then, click "Add Outgoing Webhook"
cy.url().should('include', `${teamName}/integrations/outgoing_webhooks`);
cy.findByText('Add Outgoing Webhook').click();
// * Verify that it redirects to where it can add outgoing webhook
cy.url().should('include', `${teamName}/integrations/outgoing_webhooks/add`);
// # Enter webhook details such as title, description and channel, then save
cy.get('.backstage-form').should('be.visible').within(() => {
cy.get('#displayName').type('Webhook Title');
cy.get('#description').type('Webhook Description');
if (triggerWord) {
cy.get('#triggerWords').type(triggerWord);
}
if (channelSelect) {
cy.get('#channelSelect').select(channelSelect);
}
cy.get('#callbackUrls').type(callbackUrl);
cy.findByText('Save').scrollIntoView().should('be.visible').click();
});
// # Click "Done" and verify that it redirects to incoming webhooks URL
cy.findByText('Done').click();
cy.url().should('include', `${teamName}/integrations/outgoing_webhooks`);
// # Click back to site name and verify that it redirects to test team/channel
cy.findByText(`Back to ${siteName}`).click();
}
function editOutgoingWebhook(teamName, siteName, {username, iconUrl, callbackUrl, channelSelect, withConfirmation}) {
cy.uiOpenProductMenu('Integrations');
// * click "Outgoing Webhooks"
cy.get('.backstage-sidebar').should('be.visible').findByText('Outgoing Webhooks').click();
// * click "Edit"
cy.get('.item-actions > a > span').click();
// * Verify that it redirects to where it can add outgoing webhook
cy.url().should('include', `${teamName}/integrations/outgoing_webhooks/edit`);
// # Change the profile pic for the outgoing webhook
cy.get('.backstage-form').should('be.visible').within(() => {
if (username) {
cy.get('#username').type(username);
}
if (iconUrl) {
cy.get('#iconURL').scrollIntoView().type(iconUrl);
}
if (channelSelect) {
cy.get('#channelSelect').select(channelSelect);
}
if (callbackUrl) {
cy.get('#callbackUrls').type(callbackUrl);
}
cy.get('#saveWebhook').click().wait(TIMEOUTS.ONE_SEC);
});
if (withConfirmation) {
cy.get('#confirmModalButton').should('be.visible').click();
}
// # Click back to site name and verify that it redirects to test team/channel
cy.findByText(`Back to ${siteName}`).click();
}
function verifyProfileNameAndIcon({username, userIcon, userId}) {
// * Verify the username
cy.uiGetPostHeader().findByText(username);
// * Verify the overridden user profile icon
if (userIcon) {
cy.uiGetPostProfileImage().
find('img').
invoke('attr', 'src').
then((url) => cy.request({url, encoding: 'base64'})).
then(({status, body}) => {
cy.fixture(userIcon).then((imageData) => {
expect(status).to.equal(200);
expect(body).to.eq(imageData);
});
});
}
// * Verify the user profile icon
if (userId) {
cy.uiGetPostProfileImage().
find('img').
should('have.attr', 'src').
and('include', `/api/v4/users/${userId}/image?_=`);
}
}

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

@@ -0,0 +1,104 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
// ***************************************************************
// - [#] indicates a test step (e.g. # Go to a page)
// - [*] indicates an assertion (e.g. * Check the title)
// - Use element ID when selecting an element. Create one if none.
// ***************************************************************
// Stage: @prod
import * as TIMEOUTS from '../../../../fixtures/timeouts';
describe('Prompting set status', () => {
let user1;
let user2;
let testChannelUrl;
before(() => {
cy.apiInitSetup().then(({user, team}) => {
user1 = user;
testChannelUrl = `/${team.name}/channels/town-square`;
cy.apiCreateUser().then(({user: otherUser}) => {
user2 = otherUser;
cy.apiAddUserToTeam(team.id, user2.id);
});
cy.apiLogin(user1);
cy.visit(testChannelUrl);
});
});
it('MM-T673 Prompting to set status to online', () => {
// # Set user status to offline
cy.uiOpenUserMenu('Offline');
// * Your status stays offline in your view
cy.uiGetSetStatusButton().find('.icon-circle-outline');
// # Log out
cy.apiLogout();
cy.apiLogin(user2);
cy.visit(testChannelUrl);
openDM(user1.username);
// * Your status stays offline in other users' views.
cy.get('#channelHeaderInfo').within(() => {
cy.get('.offline--icon').should('be.visible');
cy.get('.online--icon').should('not.exist');
cy.findByText('Offline').should('be.visible');
});
cy.apiGetUserStatus(user1.id).then((result) => {
cy.wrap(result.status.status).should('be.equal', 'offline');
});
// # Log back in
cy.apiLogin(user1);
cy.visit(testChannelUrl);
// # On modal that asks if you want to be set Online, select No.
cy.get('.modal-content').within(() => {
cy.findByText('Your Status is Set to "Offline"').should('be.visible');
cy.get('#cancelModalButton').click();
});
// * Your status stays offline in your view
cy.uiGetSetStatusButton().find('.icon-circle-outline');
// * Your status stays offline in other user's view.
cy.apiLogin(user2);
cy.visit(testChannelUrl);
openDM(user1.username);
// * Your status stays offline in other user's view.
cy.get('#channelHeaderInfo').within(() => {
cy.get('.offline--icon').should('be.visible');
cy.get('.online--icon').should('not.exist');
cy.findByText('Offline').should('be.visible');
});
cy.apiGetUserStatus(user1.id).then((result) => {
cy.wrap(result.status.status).should('be.equal', 'offline');
});
});
});
const openDM = (username) => {
// # Click '+' to open DM and wait for some time to get the DM modal fully loaded
cy.uiAddDirectMessage().click().wait(TIMEOUTS.TWO_SEC);
// # Type username and wait for some time to load users list
cy.get('#selectItems input').typeWithForce(username).wait(TIMEOUTS.TWO_SEC);
// # Find the user in the list and click
cy.get('#multiSelectList').findByText(`@${username}`).click();
// * Verify that the user is selected
cy.get('#selectItems').findByText(username).should('be.visible');
// # Click go to open DM with the user
cy.findByText('Go').click();
};

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

@@ -0,0 +1,75 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
// ***************************************************************
// - [#] indicates a test step (e.g. # Go to a page)
// - [*] indicates an assertion (e.g. * Check the title)
// - Use element ID when selecting an element. Create one if none.
// ***************************************************************
// Stage: @prod
// Group: @channels @integrations
describe('Integrations', () => {
let testTeam;
let testChannel;
before(() => {
const callbackUrl = `${Cypress.env().webhookBaseUrl}/post_outgoing_webhook`;
cy.requireWebhookServer();
// # Create test team, channel, and webhook
cy.apiInitSetup().then(({team, channel}) => {
testTeam = team.name;
testChannel = channel.name;
const newOutgoingHook = {
team_id: team.id,
display_name: 'New Outgoing Webhook',
trigger_words: ['testing'],
callback_urls: [callbackUrl],
};
cy.apiCreateWebhook(newOutgoingHook, false);
cy.visit(`/${testTeam}/integrations/outgoing_webhooks`);
});
});
it('MM-T612 Regenerate token', () => {
// # Grab the generated token
let generatedToken;
cy.get('.item-details__token').then((number1) => {
generatedToken = number1.text().split(' ').pop();
cy.visit(`/${testTeam}/channels/${testChannel}`);
// * Post message and assert token is present in test message
cy.postMessage('testing');
cy.uiWaitUntilMessagePostedIncludes(generatedToken);
// # Regenerate the token
cy.visit(`/${testTeam}/integrations/outgoing_webhooks`);
cy.findAllByText('Regenerate Token').click();
// # Wait until the old token is replaced by a new one
cy.waitUntil(() => cy.get('.item-details__token').then((el) => {
return !el[0].innerText.includes(generatedToken);
}));
// # Grab the regenerated token
let regeneratedToken;
cy.get('.item-details__token').then((number2) => {
regeneratedToken = number2.text().split(' ').pop();
// * Post a message and confirm regenerated token appears only
cy.visit(`/${testTeam}/channels/${testChannel}`);
cy.postMessage('testing');
cy.uiWaitUntilMessagePostedIncludes(regeneratedToken).then(() => {
cy.getLastPostId().then((lastPostId) => {
cy.get(`#${lastPostId}_message`).should('not.contain', generatedToken);
});
});
});
});
});
});

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

@@ -0,0 +1,119 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
// ***************************************************************
// - [#] indicates a test step (e.g. # Go to a page)
// - [*] indicates an assertion (e.g. * Check the title)
// - Use element ID when selecting an element. Create one if none.
// ***************************************************************
// Stage: @prod
// Group: @channels @integrations
describe('Integrations', () => {
let testTeam;
let outgoingWebhook;
const missing = 'missing';
const Alpha = 'Alpha Common';
const Bravo = 'Bravo & $ @';
const Charlie = 'Charlie Common';
const triggerA = 'apple';
const triggerB = 'banana';
const triggerC = 'carrot';
before(() => {
const callbackUrl = `${Cypress.env().webhookBaseUrl}/post_outgoing_webhook`;
cy.requireWebhookServer();
// # Create test team and 3 outgoing web-hooks
cy.apiInitSetup().then(({team}) => {
testTeam = team.name;
const firstOutgoingHook = {
team_id: team.id,
display_name: Alpha,
trigger_words: [triggerA],
callback_urls: [callbackUrl],
};
const secondOutgoingHook = {
team_id: team.id,
display_name: Bravo,
trigger_words: [triggerB],
callback_urls: [callbackUrl],
};
const thirdOutgoingHook = {
team_id: team.id,
display_name: Charlie,
trigger_words: [triggerC],
callback_urls: [callbackUrl],
};
cy.apiCreateWebhook(firstOutgoingHook, false).then((hook) => {
outgoingWebhook = hook;
cy.apiGetOutgoingWebhook(outgoingWebhook.id).then(({webhook, status}) => {
expect(status).equal(200);
expect(webhook.id).equal(outgoingWebhook.id);
});
});
cy.apiCreateWebhook(secondOutgoingHook, false).then((hook) => {
outgoingWebhook = hook;
cy.apiGetOutgoingWebhook(outgoingWebhook.id).then(({webhook, status}) => {
expect(status).equal(200);
expect(webhook.id).equal(outgoingWebhook.id);
});
});
cy.apiCreateWebhook(thirdOutgoingHook, false).then((hook) => {
outgoingWebhook = hook;
cy.apiGetOutgoingWebhook(outgoingWebhook.id).then(({webhook, status}) => {
expect(status).equal(200);
expect(webhook.id).equal(outgoingWebhook.id);
});
});
});
});
it('MM-T614 Search on Outgoing Webhooks page', () => {
// * Assert that search for Alpha (lower-case) returns only Alpha webhook
cy.visit(`/${testTeam}/integrations/outgoing_webhooks`);
cy.get('#searchInput').type('alpha');
verifyWebhooksList([Alpha], [Bravo, Charlie]);
// * Assert that search for Bravo (upper-case) returns only Bravo webhook
cy.get('#searchInput').clear().type('BRAVO');
verifyWebhooksList([Bravo], [Alpha, Charlie]);
// * Assert that search for Charlie (mixed-case, partial) returns only Charlie webhook
cy.get('#searchInput').clear().type('cHaRl');
verifyWebhooksList([Charlie], [Alpha, Bravo]);
// * Assert that search for random text returns no results
cy.get('#searchInput').clear().type(missing);
cy.get('.backstage-list').contains(`No outgoing webhooks match ${missing}`);
// * Assert that search for special character text returns only Bravo webhook
cy.get('#searchInput').clear().type('$');
verifyWebhooksList([Bravo], [Alpha, Charlie]);
// * Assert that a common search term surfaces correct webhooks
cy.get('#searchInput').clear().type('common');
verifyWebhooksList([Alpha, Charlie], [Bravo]);
});
});
function verifyWebhooksList(contain = [], notContain = []) {
contain.forEach((name) => {
cy.get('.backstage-list').findByText(name).should('be.visible');
});
notContain.forEach((name) => {
cy.get('.backstage-list').findByText(name).should('not.exist');
});
}

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

@@ -0,0 +1,54 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
// ***************************************************************
// - [#] indicates a test step (e.g. # Go to a page)
// - [*] indicates an assertion (e.g. * Check the title)
// - Use element ID when selecting an element. Create one if none.
// ***************************************************************
// Stage: @prod
// Group: @channels @integrations
describe('Integrations', () => {
let testTeam;
let testChannel;
before(() => {
// # Create test team and channel
cy.apiInitSetup().then(({team, channel}) => {
testTeam = team.name;
testChannel = channel.display_name;
});
});
it('MM-T616 Copy icon for Outgoing Webhook token', () => {
// Visit the integrations > add page
cy.visit(`/${testTeam}/integrations/outgoing_webhooks/add`);
// * Assert that we are on the add page
cy.url().should('include', '/outgoing_webhooks/add');
// # Manually set up an outgoing web-hook
cy.get('#displayName').type('test');
cy.get('#channelSelect').select(testChannel);
cy.get('#triggerWords').type('trigger');
cy.get('#callbackUrls').type('https://mattermost.com');
cy.findByText('Save').click();
// Assert that webhook was set up
cy.findByText('Setup Successful').should('be.visible');
// * Assert that token copy icon is present
cy.findByTestId('copyText').should('be.visible');
// # Close the add outgoing webhooks page
cy.findByText('Done').click();
// * Assert that we are back on the integrations > outgoing webhooks page
cy.get('#addOutgoingWebhook').should('exist');
// * Assert that the copy icon is present
cy.findByTestId('copyText').should('be.visible');
});
});