Skip to content

Commit

Permalink
Custom Status E2E tests (mattermost#7564)
Browse files Browse the repository at this point in the history
* * Added e2e tests for Custom Status modal
Added cypress tests for status dropdown and custom status modal
Added two support functions in cypress with documentation
Added some more tests in status dropdown
Added some more tests in custom status modal
Added documentation above the custom status modal file and moved it to match the group
Refactored and added 3 major tests for the custom status tests
Added some classes in custom status modal
Refactored and removed some tests from the status dropdown spec

* Update e2e/cypress/integration/menus/status_dropdown_spec.js

Co-authored-by: Harrison Healey <[email protected]>

* Custom Status e2e tests (mattermost#38)

- MM-T3851 Custom status CTAs for new users
- MM-T3850 Verifying where the custom status appears
- MM-T3852 Custom Status slash commands

- Reverted changes of package-lock.json
- Changed className to id in custom status modal and profile popover

* Revert changes to package-lock.json

* Update e2e/cypress/integration/custom_status/custom_status_spec.js

Co-authored-by: Joseph Baylon <[email protected]>

* Apply suggestions from code review

Co-authored-by: Joseph Baylon <[email protected]>

* Refactor to multiple spec files

* Fixed the E2E tests

Fixed post header CSS which does not work in Electron
Fixed issue with the recent custom statuses tests

* Cypress/E2E: Fix channel name tooltips (mattermost#7633)

Co-authored-by: Manoj <[email protected]>
Co-authored-by: Harrison Healey <[email protected]>
Co-authored-by: Joseph Baylon <[email protected]>
Co-authored-by: Manoj <[email protected]>
  • Loading branch information
5 people committed Mar 15, 2021
1 parent 51a2d83 commit 0918d78
Show file tree
Hide file tree
Showing 14 changed files with 685 additions and 3 deletions.
4 changes: 2 additions & 2 deletions components/custom_status/custom_status_modal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ const CustomStatusModal: React.FC<Props> = (props: Props) => {
};

const recentStatuses = (
<div>
<div id='statusSuggestion__recents'>
<div className='statusSuggestion__title'>
{formatMessage({id: 'custom_status.suggestions.recent_title', defaultMessage: 'RECENT'})}
</div>
Expand Down Expand Up @@ -182,7 +182,7 @@ const CustomStatusModal: React.FC<Props> = (props: Props) => {
<div className='statusSuggestion'>
<div className='statusSuggestion__content'>
{recentCustomStatuses.length > 0 && recentStatuses}
<div>
<div id='statusSuggestion__suggestions'>
{renderCustomStatusSuggestions()}
</div>
</div>
Expand Down
2 changes: 1 addition & 1 deletion components/post_view/post_header/post_header.scss
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
.post.current--user {
&.other--root, &.post--root, &.post--comment {
.post__header-set-custom-status {
display: revert;
display: block;
background: rgba(var(--center-channel-color-rgb), 0.08);
padding: 0 6px;
border-radius: 4px;
Expand Down
1 change: 1 addition & 0 deletions components/profile_popover/profile_popover.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -466,6 +466,7 @@ class ProfilePopover extends React.PureComponent {
dataContent.push(
<div
key='user-popover-status'
id='user-popover-status'
className='pb-1'
>
<span className='user-profile-popover__heading'>
Expand Down
53 changes: 53 additions & 0 deletions e2e/cypress/integration/custom_status/custom_status_1_spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
// 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: @custom_status

describe('Custom Status - CTAs for New Users', () => {
before(() => {
cy.apiUpdateConfig({TeamSettings: {EnableCustomUserStatuses: true}});

// # Login as test user and visit channel
cy.apiInitSetup({loginAfter: true}).then(({team, channel}) => {
cy.visit(`/${team.name}/channels/${channel.name}`);
});
});

it('MM-T3851_1 should show Update your status in the post header', () => {
// # Post a message in the channel
cy.postMessage('Hello World!');

// * Check if the post header contains "Update your status" button
cy.get('.post.current--user .post__header').findByText('Update your status').should('exist').and('be.visible');
});

it('MM-T3851_2 should open status dropdown with pulsating dot when clicked on Update your status post header', () => {
// # Click the "Update your status" button
cy.get('.post.current--user .post__header').findByText('Update your status').click();

// * Status dropdown should open
cy.get('#statusDropdownMenu').should('exist');

// * Pulsating dot should be visible in the status dropdown
cy.get('#statusDropdownMenu .custom_status__row .pulsating_dot').should('exist');
});

it('MM-T3851_3 should remove pulsating dot and Update your status post header after opening modal', () => {
// # Open custom status modal and close it
cy.get('#statusDropdownMenu .custom_status__row .pulsating_dot').click();
cy.get('#custom_status_modal').should('exist').get('button.close').click();

// * Check if the post header contains "Update your status" button
cy.get('.post.current--user .post__header').findByText('Update your status').should('not.exist');

// * Check if the pulsating dot exists by opening status dropdown
cy.get('.MenuWrapper .status-wrapper').click();
cy.get('#statusDropdownMenu .custom_status__row .pulsating_dot').should('not.exist');
});
});
128 changes: 128 additions & 0 deletions e2e/cypress/integration/custom_status/custom_status_2_spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
// 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: @custom_status

describe('Custom Status - Setting a Custom Status', () => {
before(() => {
cy.apiUpdateConfig({TeamSettings: {EnableCustomUserStatuses: true}});

// # Login as test user and visit channel
cy.apiInitSetup({loginAfter: true}).then(({team, channel}) => {
cy.visit(`/${team.name}/channels/${channel.name}`);
});
});

const defaultCustomStatuses = ['In a meeting', 'Out for lunch', 'Out sick', 'Working from home', 'On a vacation'];
const customStatus = {
emoji: 'calendar',
text: 'In a meeting',
};

it('MM-T3836_1 should open status dropdown', () => {
// # Click on the sidebar header to open status dropdown
cy.get('.MenuWrapper .status-wrapper').click();

// * Check if the status dropdown opens
cy.get('#statusDropdownMenu').should('exist');
});

it('MM-T3836_2 Custom status modal opens with 5 default statuses listed', () => {
// # Open custom status modal
cy.get('#statusDropdownMenu li#status-menu-custom-status').click();
cy.get('#custom_status_modal').should('exist');

// * Check if all the default suggestions exist
defaultCustomStatuses.map((statusText) => cy.get('#custom_status_modal .statusSuggestion__content').contains('span', statusText));
});

it('MM-T3836_3 "In a meeting" is selected with the calendar emoji', () => {
// * Default emoji is currently visible in the custom status input
cy.get('#custom_status_modal .StatusModal__emoji-button span').should('have.class', 'icon--emoji');

// * Input should be empty
cy.get('#custom_status_modal input.form-control').should('have.value', '');

// # Select a custom status from the suggestions
cy.get('#custom_status_modal .statusSuggestion__content').contains('span', customStatus.text).click();

// * Emoji in the custom status input should be changed
cy.get('#custom_status_modal .StatusModal__emoji-button span').invoke('attr', 'data-emoticon').should('contain', customStatus.emoji);

// * Selected custom status text should be in the input
cy.get('#custom_status_modal input.form-control').should('have.value', customStatus.text);
});

it('MM-T3836_4 In a meeting is cleared when clicked on "x" in the input', () => {
// * Suggestions should not be visible
cy.get('#custom_status_modal .statusSuggestion').should('not.exist');

// # Click on the clear button
cy.get('#custom_status_modal .StatusModal__clear-container').click();

// * Input should be empty
cy.get('#custom_status_modal input.form-control').should('have.value', '');

// * All the suggestions should be visible again
defaultCustomStatuses.map((statusText) => cy.get('#custom_status_modal .statusSuggestion__content').contains('span', statusText));
});

it('MM-T3836_5 "In a meeting" is selected with the calendar emoji', () => {
// * Default emoji is currently visible in the custom status input
cy.get('#custom_status_modal .StatusModal__emoji-button span').should('have.class', 'icon--emoji');

// * Input should be empty
cy.get('#custom_status_modal input.form-control').should('have.value', '');

// # Select a custom status from the suggestions
cy.get('#custom_status_modal .statusSuggestion__content').contains('span', customStatus.text).click();

// * Emoji in the custom status input should be changed
cy.get('#custom_status_modal .StatusModal__emoji-button span').invoke('attr', 'data-emoticon').should('contain', customStatus.emoji);

// * Selected custom status text should be in the input
cy.get('#custom_status_modal input.form-control').should('have.value', customStatus.text);
});

it('MM-T3836_6 should set custom status when click on Set Status', () => {
// # Click on the Set Status button
cy.get('#custom_status_modal .GenericModal__button.confirm').click();

// * Modal should be closed
cy.get('#custom_status_modal').should('not.exist');

// * Status should be set and the emoji should be visible in the sidebar header
cy.get('#headerInfoContent span.emoticon').invoke('attr', 'data-emoticon').should('contain', customStatus.emoji);
});

it('MM-T3836_7 should display the custom status tooltip when hover on the emoji in LHS header', () => {
// # Hover on the custom status emoji in the sidebar header
cy.get('#headerInfoContent span.emoticon').trigger('mouseover');

// * Custom status tooltip should be visible
cy.get('#custom-status-tooltip').should('exist');

// * Tooltip should contain the correct custom status emoji
cy.get('#custom-status-tooltip .custom-status span.emoticon').invoke('attr', 'data-emoticon').should('contain', customStatus.emoji);

// * Tooltip should contain the correct custom status text
cy.get('#custom-status-tooltip .custom-status span.custom-status-text').should('have.text', customStatus.text);
});

it('MM-T3836_8 should open custom status modal when emoji in LHS header is clicked', () => {
// * Check that the custom status modal is not open
cy.get('#custom_status_modal').should('not.exist');

// # Click on the custom status emoji in the sidebar header
cy.get('#headerInfoContent span.emoticon').click();

// * Check that the custom status modal should be open
cy.get('#custom_status_modal').should('exist');
});
});
135 changes: 135 additions & 0 deletions e2e/cypress/integration/custom_status/custom_status_3_spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
// 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: @custom_status

import {openCustomStatusModal} from './helper';

describe('Custom Status - Setting Your Own Custom Status', () => {
before(() => {
cy.apiUpdateConfig({TeamSettings: {EnableCustomUserStatuses: true}});

// # Login as test user and visit channel
cy.apiInitSetup({loginAfter: true}).then(({team, channel}) => {
cy.visit(`/${team.name}/channels/${channel.name}`);
});
});

const customStatus = {
emoji: 'grinning',
text: 'Busy',
};

it('MM-T3846_1 should change the emoji to speech balloon when typed in the input', () => {
// # Open the custom status modal
openCustomStatusModal();

// * Default emoji is currently visible in the custom status input
cy.get('#custom_status_modal .StatusModal__emoji-button span').should('have.class', 'icon--emoji');

// # Type the status text in the input
cy.get('#custom_status_modal .StatusModal__input input').type(customStatus.text);

// * Speech balloon emoji should now be visible in the custom status input
cy.get('#custom_status_modal .StatusModal__emoji-button span').invoke('attr', 'data-emoticon').should('contain', 'speech_balloon');
});

it('MM-T3846_2 should display the emoji picker when clicked on the emoji button', () => {
// # Click on the emoji button in the custom status input
cy.get('#custom_status_modal .StatusModal__emoji-button').click();

// * Emoji picker overlay should be opened
cy.get('#emojiPicker').should('exist');
});

it('MM_T3846_3 should select the emoji from the emoji picker', () => {
// * Check that the emoji picker is open
cy.get('#emojiPicker').should('exist');

// # Select the emoji from the emoji picker overlay
cy.get(`#emojiPicker .emoji-picker-items__container .emoji-picker__item img[data-testid="${customStatus.emoji}"]`).click();

// * Emoji picker should be closed
cy.get('#emojiPicker').should('not.exist');

// * Selected emoji should be set in the custom status input emoji button
cy.get('#custom_status_modal .StatusModal__emoji-button span').invoke('attr', 'data-emoticon').should('contain', customStatus.emoji);
});

it('MM-T3846_4 should set custom status when click on Set Status', () => {
// # Click on the Set Status button
cy.get('#custom_status_modal .GenericModal__button.confirm').click();

// * Custom status modal should be closed
cy.get('#custom_status_modal').should('not.exist');

// * Correct custom status emoji should be displayed in the sidebar header
cy.get('#headerInfoContent span.emoticon').invoke('attr', 'data-emoticon').should('contain', customStatus.emoji);
});

it('MM-T3846_5 should show custom status with emoji and clear button in the status dropdown', () => {
// # Click on the sidebar header to open status dropdown
cy.get('.MenuWrapper .status-wrapper').click();

// * Status dropdown should be open
cy.get('#statusDropdownMenu').should('exist');

// * Correct custom status text and emoji should be displayed in the status dropdown
cy.get('.status-dropdown-menu .custom_status__row').should('have.text', customStatus.text);
cy.get('.status-dropdown-menu .custom_status__row span.emoticon').invoke('attr', 'data-emoticon').should('contain', customStatus.emoji);

// * Clear button should be visible in the status dropdown
cy.get('.status-dropdown-menu #custom_status__clear').should('exist');
});

it('MM-T3846_6 should clear the custom status text when clear button is clicked', () => {
// # Click on the clear button in the status dropdown
cy.get('.status-dropdown-menu #custom_status__clear').click();

// * Custom status text should be removed and "Set a Custom Status" should be displayed in the status dropdown
cy.get('.status-dropdown-menu .custom_status__row').should('have.text', 'Set a Custom Status');
});

it('MM-T3846_7 should show previosly set status in the first position in Recents list', () => {
// # Click on the "Set a Custom Status" option in the status dropdown
cy.get('.status-dropdown-menu li#status-menu-custom-status').click();

// * Custom status modal should open
cy.get('#custom_status_modal').should('exist');

// * Previously set status should be first in the recents list along with the correct emoji
cy.get('#custom_status_modal .statusSuggestion__row').first().find('.statusSuggestion__text').should('have.text', customStatus.text);
cy.get('#custom_status_modal .statusSuggestion__row').first().find('span.emoticon').invoke('attr', 'data-emoticon').should('contain', customStatus.emoji);
});

it('MM-T3846_8 should set the same status again when clicked on the Set status', () => {
// # Select the first suggestion from the list and set the status
cy.get('#custom_status_modal .statusSuggestion__row').first().click();
cy.get('#custom_status_modal .GenericModal__button.confirm').click();

// * Custom status modal should be closed
cy.get('#custom_status_modal').should('not.exist');

// * Correct custom status emoji should be displayed in the sidebar header
cy.get('#headerInfoContent span.emoticon').invoke('attr', 'data-emoticon').should('contain', customStatus.emoji);
});

it('MM-T3846_9 should clear the status when clicked on Clear status button', () => {
openCustomStatusModal();

// # Click on the Clear status button
cy.get('#custom_status_modal').findByText('Clear Status').click();

// # Open status dropdown
cy.get('.MenuWrapper .status-wrapper').click();

// * Custom status text should not be displayed in the status dropdown
cy.get('.status-dropdown-menu .custom_status__row').should('not.have.text', customStatus.text);
});
});
Loading

0 comments on commit 0918d78

Please sign in to comment.