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

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

@@ -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
// Group: @channels @interactive_dialog
/**
* Note: This test requires webhook server running. Initiate `npm run start:webhook` to start.
*/
const webhookUtils = require('../../../../utils/webhook_utils');
let createdCommand;
let simpleDialog;
describe('Interactive Dialog', () => {
before(() => {
// # Ensure that teammate name display setting is set to default 'username'
cy.apiSaveTeammateNameDisplayPreference('username');
cy.requireWebhookServer();
// # Create new team and create command on it
cy.apiCreateTeam('test-team', 'Test Team').then(({team}) => {
cy.visit(`/${team.name}`);
const webhookBaseUrl = Cypress.env().webhookBaseUrl;
const command = {
auto_complete: false,
description: 'Test for boolean dialog',
display_name: 'Simple Dialog with boolean element',
icon_url: '',
method: 'P',
team_id: team.id,
trigger: 'boolean_dialog',
url: `${webhookBaseUrl}/boolean_dialog_request`,
username: '',
};
cy.apiCreateCommand(command).then(({data}) => {
createdCommand = data;
simpleDialog = webhookUtils.getBooleanDialog(createdCommand.id, webhookBaseUrl);
});
});
});
it('MM-T2502 - Boolean element check', () => {
// # Post a slash command
cy.postMessage(`/${createdCommand.trigger} `);
// * Verify that the interactive dialog modal open up
cy.get('#interactiveDialogModal').should('be.visible').within(() => {
// * Verify that the header of modal contains icon URL, title and close button
cy.get('.modal-header').should('be.visible').within(($elForm) => {
cy.get('#interactiveDialogIconUrl').should('be.visible').and('have.attr', 'src', simpleDialog.dialog.icon_url);
cy.get('#interactiveDialogModalLabel').should('be.visible').and('have.text', simpleDialog.dialog.title);
cy.wrap($elForm).find('button.close').should('be.visible').and('contain', '×').and('contain', 'Close');
});
// * Verify that the body contains the boolean element
cy.get('.modal-body').should('be.visible').children().should('have.length', 1).each(($elForm, index) => {
const element = simpleDialog.dialog.elements[index];
cy.wrap($elForm).find('label.control-label').scrollIntoView().should('be.visible').and('have.text', `${element.display_name} ${element.optional ? '(optional)' : '*'}`);
expect(element.name).to.equal('boolean_input');
cy.wrap($elForm).find('.checkbox').should('be.visible').within(() => {
cy.get('#boolean_input').
should('be.visible').
and('be.checked');
cy.get('span').should('have.text', element.placeholder);
});
if (element.help_text) {
cy.wrap($elForm).find('.help-text').should('be.visible').and('have.text', element.help_text);
}
});
// * Verify that the footer contains cancel and submit buttons
cy.get('.modal-footer').should('be.visible').within(($elForm) => {
cy.wrap($elForm).find('#interactiveDialogCancel').should('be.visible').and('have.text', 'Cancel');
cy.wrap($elForm).find('#interactiveDialogSubmit').should('be.visible').and('have.text', simpleDialog.dialog.submit_label);
});
closeInteractiveDialog();
});
});
});
function closeInteractiveDialog() {
cy.get('.modal-header').should('be.visible').within(($elForm) => {
cy.wrap($elForm).find('button.close').should('be.visible').click();
});
cy.get('#interactiveDialogModal').should('not.exist');
}

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

@@ -0,0 +1,261 @@
// 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 @interactive_dialog @plugin
// If the contents of the interactive dialog from the demo plugin change, please update the demoPluginDialogElements object.
import {demoPlugin} from '../../../utils/plugins';
describe('Interactive Dialogs', () => {
let testTeam;
let testChannel;
// # The format of the elements in the interactive dialog from the demo plugin:
const demoPluginDialogElements = [
{
display_name: 'Display Name',
name: 'realname',
type: 'text',
default: 'default text',
placeholder: 'placeholder',
help_text: 'This a regular input in an interactive dialog triggered by a test integration.',
}, {
display_name: 'Email',
name: 'someemail',
type: 'text',
subtype: 'email',
placeholder: 'placeholder@bladekick.com',
help_text: 'This a regular email input in an interactive dialog triggered by a test integration.',
}, {
display_name: 'Password',
name: 'somepassword',
type: 'text',
subtype: 'password',
placeholder: 'Password',
help_text: 'This a password input in an interactive dialog triggered by a test integration.',
}, {
display_name: 'Number',
name: 'somenumber',
type: 'text',
subtype: 'number',
}, {
display_name: 'Display Name Long Text Area',
name: 'realnametextarea',
type: 'textarea',
placeholder: 'placeholder',
optional: true,
min_length: 5,
max_length: 100,
}, {
display_name: 'User Selector',
name: 'someuserselector',
type: 'select',
placeholder: 'Select a user...',
help_text: 'Choose a user from the list.',
optional: true,
min_length: 5,
max_length: 100,
data_source: 'users',
}, {
display_name: 'Channel Selector',
name: 'somechannelselector',
type: 'select',
placeholder: 'Select a channel...',
help_text: 'Choose a channel from the list.',
optional: true,
min_length: 5,
max_length: 100,
data_source: 'channels',
}, {
display_name: 'Option Selector',
name: 'someoptionselector',
type: 'select',
placeholder: 'Select an option...',
help_text: 'Choose an option from the list.',
options: [{
text: 'Option1',
value: 'opt1',
}, {
text: 'Option2',
value: 'opt2',
}, {
text: 'Option3',
value: 'opt3',
}],
}, {
display_name: 'Option Selector with default',
name: 'someoptionselector2',
type: 'select',
default: 'opt2',
placeholder: 'Select an option...',
help_text: 'Choose an option from the list.',
options: [{
text: 'Option1',
value: 'opt1',
}, {
text: 'Option2',
value: 'opt2',
}, {
text: 'Option3',
value: 'opt3',
}],
}, {
display_name: 'Boolean Selector',
name: 'someboolean',
type: 'bool',
placeholder: 'Agree to the terms of service',
help_text: 'You must agree to the terms of service to proceed.',
}, {
display_name: 'Boolean Selector',
name: 'someboolean_optional',
type: 'bool',
placeholder: 'Sign up for monthly emails?',
help_text: "It's up to you if you want to get monthly emails.",
optional: true,
}, {
display_name: 'Boolean Selector (default true)',
name: 'someboolean_default_true',
type: 'bool',
placeholder: 'Enable secure login',
help_text: 'You must enable secure login to proceed.',
default: 'true',
}, {
display_name: 'Boolean Selector (default true)',
name: 'someboolean_default_true_optional',
type: 'bool',
placeholder: 'Enable painfully secure login',
help_text: 'You may optionally enable painfully secure login.',
default: 'true',
optional: true,
}, {
display_name: 'Boolean Selector (default false)',
name: 'someboolean_default_false',
type: 'bool',
placeholder: 'Agree to the annoying terms of service',
help_text: 'You must also agree to the annoying terms of service to proceed.',
default: 'false',
}, {
display_name: 'Boolean Selector (default false)',
name: 'someboolean_default_false_optional',
type: 'bool',
placeholder: 'Throw-away account',
help_text: 'A throw-away account will be deleted after 24 hours.',
default: 'false',
optional: true,
}, {
display_name: 'Radio Option Selector',
name: 'someradiooptionselector',
type: 'radio',
help_text: 'Choose an option from the list.',
options: [{
text: 'Option1',
value: 'opt1',
}, {
text: 'Option2',
value: 'opt2',
}, {
text: 'Option3',
value: 'opt3',
}],
},
];
before(() => {
cy.shouldNotRunOnCloudEdition();
cy.shouldHavePluginUploadEnabled();
// # Set plugin settings
const newSettings = {
PluginSettings: {
Enable: true,
},
};
cy.apiUpdateConfig(newSettings);
cy.apiInitSetup().then(({team, channel}) => {
testTeam = team;
testChannel = channel;
// # Install demo plugin by file
cy.apiUploadAndEnablePlugin(demoPlugin);
// # Visit the test channel
cy.visit(`/${testTeam.name}/channels/${testChannel.name}`);
});
});
it('MM-T2503 Boolean value check', () => {
// # Post the /dialog slash command message
cy.uiGetPostTextBox().type('/dialog {enter}');
// * Check that the interactive dialog modal from the plugin opens up
cy.get('#interactiveDialogModal').should('be.visible').within(() => {
// * Verify that the body is visible
cy.get('.modal-body').should('be.visible').children().each(($elForm, index) => {
const element = demoPluginDialogElements[index];
// * Verify that when the element comes into view the proper display name is showing
cy.wrap($elForm).find('label.control-label').scrollIntoView().should('be.visible').and('have.text', `${element.display_name} ${element.optional ? '(optional)' : '*'}`);
if (element.name.includes('someboolean')) {
// * Verify that the checkbox for a boolean element is visible
cy.wrap($elForm).find('.checkbox').should('be.visible').within(() => {
// * Verify that if the element default is true, it should be checked, and vice versa.
let checked = true;
if (element.default === 'true') {
cy.get(`#${element.name}`).
should('be.visible').
and('be.checked');
} else {
cy.get(`#${element.name}`).
should('be.visible').
not('be.checked');
checked = false;
}
// * Verify that the checkbox has the proper text.
cy.get('span').should('have.text', element.placeholder);
// # Click on the checkbox.
if (checked === false) {
cy.get(`#${element.name}`).check();
}
});
} else if (element.name === 'someemail') {
cy.get(`#${element.name}`).scrollIntoView().clear().type('test@test.com');
} else if (element.name === 'somepassword') {
cy.get(`#${element.name}`).scrollIntoView().clear().type('test');
} else if (element.name === 'somenumber') {
cy.get(`#${element.name}`).scrollIntoView().clear().type('42');
} else if (element.name === 'someoptionselector') {
cy.wrap($elForm).find('input').click();
cy.wrap($elForm).find('#suggestionList').scrollIntoView().should('be.visible').click();
} else if (element.name === 'someradiooptionselector') {
cy.wrap($elForm).find('input').first().click();
}
});
// # Submit the form of the interactive dialog.
cy.intercept('/api/v4/actions/dialogs/submit').as('submitAction');
cy.get('#interactiveDialogSubmit').click();
});
// * The interactive dialog should not be visible anymore.
cy.get('#interactiveDialogModal').not('be.visible');
// * Verify that submitted values are boolean and not strings.
cy.wait('@submitAction').should('include.all.keys', ['request', 'response']).then((result) => {
const boolQuestions = Object.entries(result.request.body.submission).filter((element) => element[0].includes('someboolean'));
for (let i = 0; i < boolQuestions.length; i++) {
assert.isBoolean(boolQuestions[i][1]);
}
});
});
});

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

@@ -0,0 +1,303 @@
// 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 @interactive_dialog
/**
* Note: This test requires webhook server running. Initiate `npm run start:webhook` to start.
*/
const webhookUtils = require('../../../../utils/webhook_utils');
describe('Interactive Dialog', () => {
const inputTypes = {
realname: 'input',
someemail: 'email',
somenumber: 'number',
somepassword: 'password',
};
const optionsLength = {
someuserselector: 25, // default number of users in autocomplete
somechannelselector: 2, // town-square and off-topic for new team
someoptionselector: 3, // number of defined basic options
someradiooptions: 2, // number of defined basic options
};
let createdCommand;
let fullDialog;
before(() => {
cy.requireWebhookServer();
// # Ensure that teammate name display setting is set to default 'username'
cy.apiSaveTeammateNameDisplayPreference('username');
// # Create new team and create command on it
cy.apiCreateTeam('test-team', 'Test Team').then(({team}) => {
cy.visit(`/${team.name}`);
const webhookBaseUrl = Cypress.env().webhookBaseUrl;
const command = {
auto_complete: false,
description: 'Test for dialog',
display_name: 'Dialog',
icon_url: '',
method: 'P',
team_id: team.id,
trigger: 'dialog',
url: `${webhookBaseUrl}/dialog_request`,
username: '',
};
cy.apiCreateCommand(command).then(({data}) => {
createdCommand = data;
fullDialog = webhookUtils.getFullDialog(createdCommand.id, webhookBaseUrl);
});
});
});
afterEach(() => {
// # Reload current page after each test to close any dialogs left open
cy.reload();
});
it('MM-T2491 - UI check', () => {
// # Post a slash command
cy.get('#postListContent').should('be.visible');
cy.postMessage(`/${createdCommand.trigger} `);
// * Verify that the interactive dialog modal open up
cy.get('#interactiveDialogModal').should('be.visible').within(() => {
// * Verify that the header of modal contains icon URL, title and close button
cy.get('.modal-header').should('be.visible').within(($elForm) => {
cy.get('#interactiveDialogIconUrl').should('be.visible').and('have.attr', 'src', fullDialog.dialog.icon_url);
cy.get('#interactiveDialogModalLabel').should('be.visible').and('have.text', fullDialog.dialog.title);
cy.wrap($elForm).find('button.close').should('be.visible').and('contain', '×').and('contain', 'Close');
cy.get('#interactiveDialogModalLabel').should('be.visible').and('have.text', fullDialog.dialog.title);
});
// * Verify that the body contains all the elements
cy.get('.modal-body').should('be.visible').children().each(($elForm, index) => {
const element = fullDialog.dialog.elements[index];
cy.wrap($elForm).find('label.control-label').scrollIntoView().should('exist').and('have.text', `${element.display_name} ${element.optional ? '(optional)' : '*'}`);
if (['someuserselector', 'somechannelselector', 'someoptionselector'].includes(element.name)) {
cy.wrap($elForm).find('input').should('be.visible').and('have.attr', 'autocomplete', 'off').and('have.attr', 'placeholder', element.placeholder);
// * Verify that the suggestion list or autocomplete open up on click of input element
cy.wrap($elForm).find('#suggestionList').should('not.exist');
cy.wrap($elForm).find('input').click();
cy.wrap($elForm).find('#suggestionList').scrollIntoView().should('be.visible');
// # Click field label to close any opened drop-downs
cy.wrap($elForm).find('label.control-label').scrollIntoView().click();
} else if (element.name === 'someradiooptions') {
cy.wrap($elForm).find('input').should('be.visible').and('have.length', optionsLength[element.name]);
// * Verify that no option is selected by default
cy.wrap($elForm).find('input').each(($elInput) => {
cy.wrap($elInput).should('not.be.checked');
});
} else if (element.name === 'boolean_input') {
cy.wrap($elForm).find('.checkbox').should('be.visible').within(() => {
cy.get('#boolean_input').
should('be.visible').
and('be.checked');
cy.get('span').should('have.text', element.placeholder);
});
} else {
cy.wrap($elForm).find(`#${element.name}`).should('be.visible').and('have.value', element.default).and('have.attr', 'placeholder', element.placeholder);
}
// * Verify that input element are given with the correct type of "input", "email", "number" and "password".
// * To take advantage of supported built-in validation.
if (inputTypes[element.name]) {
cy.wrap($elForm).find(`#${element.name}`).should('have.attr', 'type', inputTypes[element.name]);
}
if (element.help_text) {
cy.wrap($elForm).find('.help-text').should('exist').and('have.text', element.help_text);
}
});
// * Verify that the footer contains cancel and submit buttons
cy.get('.modal-footer').should('be.visible').within(($elForm) => {
cy.wrap($elForm).find('#interactiveDialogCancel').should('be.visible').and('have.text', 'Cancel');
cy.wrap($elForm).find('#interactiveDialogSubmit').should('be.visible').and('have.text', fullDialog.dialog.submit_label);
});
closeInteractiveDialog();
});
});
it('MM-T2492 - Cancel button works', () => {
// # Post a slash command
cy.postMessage(`/${createdCommand.trigger} `);
// * Verify that the interactive dialog modal open up
cy.get('#interactiveDialogModal').should('be.visible');
// # Click cancel from the modal
cy.get('#interactiveDialogCancel').click();
// * Verify that the interactive dialog modal is closed
cy.get('#interactiveDialogModal').should('not.exist');
});
it('MM-T2493 - "X" closes the dialog', () => {
// # Post a slash command
cy.postMessage(`/${createdCommand.trigger} `);
// * Verify that the interactive dialog modal open up
cy.get('#interactiveDialogModal').should('be.visible');
// # Click "X" button from the modal
cy.get('.modal-header').should('be.visible').within(($elForm) => {
cy.wrap($elForm).find('button.close').should('be.visible').click();
});
// * Verify that the interactive dialog modal is closed
cy.get('#interactiveDialogModal').should('not.exist');
});
it('MM-T2494 - Correct error messages displayed if empty form is submitted', () => {
// # Post a slash command
cy.postMessage(`/${createdCommand.trigger} `);
// * Verify that the interactive dialog modal open up
cy.get('#interactiveDialogModal').should('be.visible');
// # Click submit button from the modal
cy.get('#interactiveDialogSubmit').click();
// * Verify that the interactive dialog modal is still open
cy.get('#interactiveDialogModal').should('be.visible');
// * Verify that not optional element without text value shows an error and vice versa
cy.get('.modal-body').should('be.visible').children().each(($elForm, index) => {
const element = fullDialog.dialog.elements[index];
if (!element.optional && !element.default) {
cy.wrap($elForm).find('div.error-text').scrollIntoView().should('be.visible').and('have.text', 'This field is required.').and('have.css', 'color', 'rgb(210, 75, 78)');
} else {
cy.wrap($elForm).find('div.error-text').should('not.exist');
}
});
closeInteractiveDialog();
});
it('MM-T2495_1 - Email validation for invalid input', () => {
// # Post a slash command
cy.postMessage(`/${createdCommand.trigger} `);
// * Verify that the interactive dialog modal open up
cy.get('#interactiveDialogModal').should('be.visible');
// # Enter invalid and valid email
// * Verify that error is: shown for invalid email and not shown for valid email.
const invalidEmail = 'invalid-email';
cy.get('#someemail').scrollIntoView().clear().type(invalidEmail);
cy.get('#interactiveDialogSubmit').click();
cy.get('input:invalid').should('have.length', 1);
cy.get('#someemail').then(($input) => {
expect($input[0].validationMessage).to.eq(`Please include an '@' in the email address. '${invalidEmail}' is missing an '@'.`);
});
closeInteractiveDialog();
});
it('MM-T2495_2 - Email validation for valid input', () => {
// # Post a slash command
cy.postMessage(`/${createdCommand.trigger} `);
// * Verify that the interactive dialog modal open up
cy.get('#interactiveDialogModal').should('be.visible');
// # Enter valid email
// * Verify that error is not shown for valid email.
const validEmail = 'test@mattermost.com';
cy.get('#someemail').scrollIntoView().clear().type(validEmail);
cy.get('#interactiveDialogSubmit').click();
cy.get('input:invalid').should('have.length', 0);
closeInteractiveDialog();
});
it('MM-T2496_1 - Number validation for invalid input', () => {
cy.postMessage(`/${createdCommand.trigger} `);
cy.get('#interactiveDialogModal').should('be.visible');
// # Enter invalid number
// * Verify that error is shown for invalid number.
const invalidNumber = 'invalid-number';
cy.get('#somenumber').scrollIntoView().clear().type(invalidNumber);
cy.get('#interactiveDialogSubmit').click();
cy.get('.modal-body').should('be.visible').children().eq(2).within(($elForm) => {
cy.wrap($elForm).find('div.error-text').should('be.visible').and('have.text', 'This field is required.').and('have.css', 'color', 'rgb(210, 75, 78)');
});
closeInteractiveDialog();
});
it('MM-T2496_2 - Number validation for valid input', () => {
cy.postMessage(`/${createdCommand.trigger} `);
cy.get('#interactiveDialogModal').should('be.visible');
// # Enter a valid number
// * Verify that error is not shown for valid number.
const validNumber = 12;
cy.get('#somenumber').scrollIntoView().clear().type(validNumber);
cy.get('#interactiveDialogSubmit').click();
cy.get('.modal-body').should('be.visible').children().eq(2).within(($elForm) => {
cy.wrap($elForm).find('div.error-text').should('not.exist');
});
closeInteractiveDialog();
});
it('MM-T2501 - Password element check', () => {
// # Post a slash command
cy.postMessage(`/${createdCommand.trigger} `);
// * Verify that the interactive dialog modal open up
cy.get('#interactiveDialogModal').should('be.visible');
// * Verify that the password text area is visible
cy.get('#somepassword').should('be.visible');
// * Verify that the password is masked on enter of text
cy.get('#somepassword').should('have.attr', 'type', 'password');
closeInteractiveDialog();
});
});
function closeInteractiveDialog() {
cy.get('.modal-header').should('be.visible').within(($elForm) => {
cy.wrap($elForm).find('button.close').should('be.visible').click();
});
cy.get('#interactiveDialogModal').should('not.exist');
}

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

@@ -0,0 +1,121 @@
// 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 @interactive_dialog
/**
* Note: This test requires webhook server running. Initiate `npm run start:webhook` to start.
*/
const webhookUtils = require('../../../../utils/webhook_utils');
let createdCommand;
let userAndChannelDialog;
describe('Interactive Dialog', () => {
before(() => {
cy.requireWebhookServer();
// # Ensure that teammate name display setting is set to default 'username'
cy.apiSaveTeammateNameDisplayPreference('username');
// # Create new team and create command on it
cy.apiCreateTeam('test-team', 'Test Team').then(({team}) => {
for (let i = 0; i < 20; i++) {
cy.apiCreateChannel(team.id, `channel-${i}`, `Channel ${i}`);
}
cy.visit(`/${team.name}`);
const webhookBaseUrl = Cypress.env().webhookBaseUrl;
const command = {
auto_complete: false,
description: 'Test for user and channel dialog',
display_name: 'Dialog with user and channel',
icon_url: '',
method: 'P',
team_id: team.id,
trigger: 'user_and_channel_dialog',
url: `${webhookBaseUrl}/user_and_channel_dialog_request`,
username: '',
};
cy.apiCreateCommand(command).then(({data}) => {
createdCommand = data;
userAndChannelDialog = webhookUtils.getUserAndChannelDialog(createdCommand.id, webhookBaseUrl);
});
});
});
it('MM-T2498 - Individual "User" and "Channel" screens are scrollable', () => {
// # Post a slash command
cy.postMessage(`/${createdCommand.trigger} `);
// * Verify that the interactive dialog modal open up
cy.get('#interactiveDialogModal').should('be.visible').within(() => {
// * Verify that the header of modal contains icon URL, title and close button
cy.get('.modal-header').should('be.visible').within(($elForm) => {
cy.get('#interactiveDialogIconUrl').should('be.visible').and('have.attr', 'src', userAndChannelDialog.dialog.icon_url);
cy.get('#interactiveDialogModalLabel').should('be.visible').and('have.text', userAndChannelDialog.dialog.title);
cy.wrap($elForm).find('button.close').should('be.visible').and('contain', '×').and('contain', 'Close');
});
// * Verify that the body contains the both elements
cy.get('.modal-body').should('be.visible').children().should('have.length', 2).each(($elForm, index) => {
const element = userAndChannelDialog.dialog.elements[index];
cy.wrap($elForm).find('label.control-label').scrollIntoView().should('be.visible').and('have.text', `${element.display_name} ${element.optional ? '(optional)' : '*'}`);
cy.wrap($elForm).find('input').should('be.visible').and('have.attr', 'autocomplete', 'off').and('have.attr', 'placeholder', element.placeholder);
// * Verify that the suggestion list or autocomplete open up on click of input element
cy.wrap($elForm).find('#suggestionList').should('not.exist');
cy.wrap($elForm).find('input').click();
cy.wrap($elForm).find('#suggestionList').scrollIntoView().should('be.visible').children();
if (index === 0) {
expect(element.name).to.equal('someuserselector');
cy.wrap($elForm).find('.suggestion-list__item').first().should('be.visible');
cy.wrap($elForm).find('.form-control').type('{downarrow}'.repeat(10));
cy.wrap($elForm).find('.suggestion-list__item').first().should('not.be.visible');
cy.wrap($elForm).find('.form-control').type('{uparrow}'.repeat(10));
cy.wrap($elForm).find('.suggestion-list__item').first().should('be.visible');
} else if (index === 1) {
expect(element.name).to.equal('somechannelselector');
cy.wrap($elForm).find('.suggestion-list__item').first().should('be.visible');
cy.wrap($elForm).find('.form-control').type('{downarrow}'.repeat(10));
cy.wrap($elForm).find('.suggestion-list__item').first().should('not.be.visible');
cy.wrap($elForm).find('.form-control').type('{uparrow}'.repeat(10));
cy.wrap($elForm).find('.suggestion-list__item').first().should('be.visible');
}
// # Select one element to close the dropdown
cy.wrap($elForm).find('.suggestion-list__item').first().click();
if (element.help_text) {
cy.wrap($elForm).find('.help-text').should('be.visible').and('have.text', element.help_text);
}
});
// * Verify that the footer contains cancel and submit buttons
cy.get('.modal-footer').should('be.visible').within(($elForm) => {
cy.wrap($elForm).find('#interactiveDialogCancel').should('be.visible').and('have.text', 'Cancel');
cy.wrap($elForm).find('#interactiveDialogSubmit').should('be.visible').and('have.text', userAndChannelDialog.dialog.submit_label);
});
// # Close interactive dialog
cy.get('.modal-header').should('be.visible').within(($elForm) => {
cy.wrap($elForm).find('button.close').should('be.visible').click();
});
cy.get('#interactiveDialogModal').should('not.exist');
});
});
});

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

@@ -0,0 +1,142 @@
// 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 @not_cloud @interactive_dialog
/**
* Note: This test requires webhook server running. Initiate `npm run start:webhook` to start.
*/
import * as TIMEOUTS from '../../../fixtures/timeouts';
const webhookUtils = require('../../../../utils/webhook_utils');
let createdCommand;
let simpleDialog;
describe('Interactive Dialog without element', () => {
before(() => {
cy.shouldNotRunOnCloudEdition();
cy.requireWebhookServer();
// # Ensure that teammate name display setting is set to default 'username'
cy.apiSaveTeammateNameDisplayPreference('username');
// # Create new team and create command on it
cy.apiCreateTeam('test-team', 'Test Team').then(({team}) => {
cy.visit(`/${team.name}`);
const webhookBaseUrl = Cypress.env().webhookBaseUrl;
const command = {
auto_complete: false,
description: 'Test for simple dialog - no element',
display_name: 'Simple Dialog without element',
icon_url: '',
method: 'P',
team_id: team.id,
trigger: 'simple_dialog',
url: `${webhookBaseUrl}/simple_dialog_request`,
username: '',
};
cy.apiCreateCommand(command).then(({data}) => {
createdCommand = data;
simpleDialog = webhookUtils.getSimpleDialog(createdCommand.id, webhookBaseUrl);
});
});
});
it('MM-T2500_1 UI check', () => {
// # Post a slash command
cy.postMessage(`/${createdCommand.trigger} `);
// * Verify that the interactive dialog modal open up
cy.get('#interactiveDialogModal').should('be.visible').within(() => {
// * Verify that the header of modal contains icon URL, title and close button
cy.get('.modal-header').should('be.visible').within(($elForm) => {
cy.get('#interactiveDialogIconUrl').should('be.visible').and('have.attr', 'src', simpleDialog.dialog.icon_url);
cy.get('#interactiveDialogModalLabel').should('be.visible').and('have.text', simpleDialog.dialog.title);
cy.wrap($elForm).find('button.close').should('be.visible').and('contain', '×').and('contain', 'Close');
});
// * Verify that the body is not present
cy.get('.modal-body').should('not.exist');
// * Verify that the footer contains cancel and submit buttons
cy.get('.modal-footer').should('be.visible').within(($elForm) => {
cy.wrap($elForm).find('#interactiveDialogCancel').should('be.visible').and('have.text', 'Cancel');
cy.wrap($elForm).find('#interactiveDialogSubmit').should('be.visible').and('have.text', simpleDialog.dialog.submit_label);
});
closeInteractiveDialog();
});
});
it('MM-T2500_2 "X" closes the dialog', () => {
// # Post a slash command
cy.postMessage(`/${createdCommand.trigger} `);
// * Verify that the interactive dialog modal open up
cy.get('#interactiveDialogModal').should('be.visible');
// # Click "X" button from the modal
cy.get('.modal-header').should('be.visible').within(($elForm) => {
cy.wrap($elForm).find('button.close').should('be.visible').click().wait(TIMEOUTS.FIVE_SEC);
});
// * Verify that the interactive dialog modal is closed
cy.get('#interactiveDialogModal').should('not.exist');
// * Verify that the last post states that the dialog is cancelled
cy.getLastPost().should('contain', 'Dialog cancelled');
});
it('MM-T2500_3 Cancel button works', () => {
// # Post a slash command
cy.postMessage(`/${createdCommand.trigger} `);
// * Verify that the interactive dialog modal open up
cy.get('#interactiveDialogModal').should('be.visible');
// # Click cancel from the modal
cy.get('#interactiveDialogCancel').click().wait(TIMEOUTS.FIVE_SEC);
// * Verify that the interactive dialog modal is closed
cy.get('#interactiveDialogModal').should('not.exist');
// * Verify that the last post states that the dialog is cancelled
cy.getLastPost().should('contain', 'Dialog cancelled');
});
it('MM-T2500_4 Submit button works', () => {
// # Post a slash command
cy.postMessage(`/${createdCommand.trigger} `);
// * Verify that the interactive dialog modal open up
cy.get('#interactiveDialogModal').should('be.visible');
// # Click submit from the modal
cy.get('#interactiveDialogSubmit').click();
// * Verify that the interactive dialog modal is closed
cy.get('#interactiveDialogModal').should('not.exist');
// * Verify that the last post states that the dialog is submitted
cy.getLastPost().should('contain', 'Dialog submitted');
});
});
function closeInteractiveDialog() {
cy.get('.modal-header').should('be.visible').within(($elForm) => {
cy.wrap($elForm).find('button.close').should('be.visible').click();
});
cy.get('#interactiveDialogModal').should('not.exist');
}