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

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

@@ -0,0 +1,45 @@
// 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
describe('Upload Files', () => {
before(() => {
// # Create new team and new user and visit off-topic channel
cy.apiInitSetup({loginAfter: true}).then(({offTopicUrl}) => {
cy.visit(offTopicUrl);
});
});
it('MM-T307 Cancel a file upload', () => {
const hugeImage = 'huge-image.jpg';
// # Intercept response of /files endpoint
cy.intercept('POST', '/api/v4/files', {
body: {client_ids: [], file_infos: []},
});
// # Post an image in center channel
cy.get('#advancedTextEditorCell').find('#fileUploadInput').attachFile(hugeImage);
// * Verify thumbnail of ongoing file upload
cy.get('.file-preview__container').should('be.visible').within(() => {
cy.get('.post-image__thumbnail').should('be.visible');
cy.findByText(hugeImage).should('be.visible');
cy.findByText('Processing...').should('be.visible');
});
// # Click the `X` on the file attachment thumbnail
cy.get('.file-preview__remove > .icon').click();
// * Check if thumbnail disappears
cy.get('.post-image').should('not.exist');
cy.findByLabelText('file thumbnail').should('not.exist');
});
});

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

@@ -0,0 +1,90 @@
// 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 @filesearch
import * as TIMEOUTS from '../../../fixtures/timeouts';
import {interceptFileUpload, waitUntilUploadComplete} from './helpers';
describe('Channel files', () => {
const wordFile = 'word-file.doc';
const wordxFile = 'wordx-file.docx';
const imageFile = 'jpg-image-file.jpg';
before(() => {
// # Create new team and new user and visit off-topic channel
cy.apiInitSetup({loginAfter: true}).then(({offTopicUrl}) => {
cy.visit(offTopicUrl);
interceptFileUpload();
});
});
it('MM-T4418 Channel files search', () => {
// # Ensure Direct Message is visible in LHS sidebar
cy.uiGetLhsSection('DIRECT MESSAGES').should('be.visible');
// # Post with word and image files
[wordFile, wordxFile, imageFile].forEach((file) => {
attachFile(file);
});
// # Click the channel files icon
cy.uiGetChannelFileButton().click();
// * Showed all files by default
verifySearchResult([imageFile, wordxFile, wordFile]);
// # Filter by option
[
{option: 'Documents', returnedFiles: [wordxFile, wordFile]},
{option: 'Spreadsheets', returnedFiles: null},
{option: 'Presentations', returnedFiles: null},
{option: 'Code', returnedFiles: null},
{option: 'Images', returnedFiles: [imageFile]},
{option: 'Audio', returnedFiles: null},
{option: 'Videos', returnedFiles: null},
].forEach(({option, returnedFiles}) => {
filterSearchBy(option, returnedFiles);
});
});
});
function attachFile(file) {
// # Post file to user
cy.get('#advancedTextEditorCell').
find('#fileUploadInput').
attachFile(file);
waitUntilUploadComplete();
cy.get('.post-image__thumbnail').should('be.visible');
cy.uiGetPostTextBox().clear().type('{enter}');
}
function filterSearchBy(option, returnedFiles) {
// # Filter by option
cy.uiOpenFileFilterMenu(option);
// # Wait until the list is updated
cy.wait(TIMEOUTS.ONE_SEC);
verifySearchResult(returnedFiles);
}
function verifySearchResult(files) {
if (files) {
cy.get('#search-items-container').should('be.visible').within(() => {
cy.get('.fileDataName').each((el, i) => {
cy.wrap(el).should('have.text', files[i]);
});
});
} else {
cy.get('#search-items-container').findByText('No files found').should('be.visible');
}
}

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

@@ -0,0 +1,170 @@
// 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 @files_and_attachments
import * as TIMEOUTS from '../../../fixtures/timeouts';
import {interceptFileUpload, waitUntilUploadComplete} from './helpers';
function simulateSubscription(subscription, currentStorageUsageBytes, planLimit) {
cy.intercept('GET', '**/api/v4/cloud/subscription', {
statusCode: 200,
body: subscription,
});
cy.intercept('GET', '**/api/v4/usage/storage', {
statusCode: 200,
body: {
bytes: currentStorageUsageBytes,
},
});
cy.intercept('GET', '**/api/v4/cloud/limits', {
statusCode: 200,
body: {
files: {
total_storage: planLimit,
},
},
});
cy.intercept('GET', '**/api/v4/cloud/products', {
statusCode: 200,
body: [
{
id: 'prod_1',
sku: 'cloud-starter',
price_per_seat: 0,
name: 'Cloud Free',
},
{
id: 'prod_2',
sku: 'cloud-professional',
price_per_seat: 10,
name: 'Cloud Professional',
},
{
id: 'prod_3',
sku: 'cloud-enterprise',
price_per_seat: 30,
name: 'Cloud Enterprise',
},
],
});
}
describe('Cloud Freemium limits Upload Files', () => {
let channelUrl;
let createdUser;
before(() => {
// * Check if server has license for Cloud
cy.apiRequireLicenseForFeature('Cloud');
});
beforeEach(() => {
// # Init setup
cy.apiInitSetup().then((out) => {
channelUrl = out.channelUrl;
createdUser = out.user;
cy.visit(channelUrl);
interceptFileUpload();
});
});
it('Show file limits banner for admin uploading files when storage usage above current freemium file storage limit', () => {
// # Login as sysadmin
cy.apiAdminLogin();
const currentsubscription = {
id: 'sub_test1',
product_id: 'prod_1',
is_free_trial: 'false',
};
const currentFileStorageUsageBytes = 11000000000;
const planLimit = 10000000000; // 1.2GB
simulateSubscription(currentsubscription, currentFileStorageUsageBytes, planLimit);
const filename = 'svg.svg';
cy.visit(channelUrl);
cy.get('#post_textbox', {timeout: TIMEOUTS.ONE_MIN}).should('be.visible');
// # Attach file
cy.get('#advancedTextEditorCell').find('#fileUploadInput').attachFile(filename);
waitUntilUploadComplete();
// * Banner shows
cy.get('#cloud_file_limit_banner').should('exist');
cy.get('#cloud_file_limit_banner').contains('Your free plan is limited to 1.2GB of files. New uploads will automatically archive older files');
cy.get('#cloud_file_limit_banner').contains('upgrade to a paid plan');
});
it('Do not show file limits banner for admin uploading files and not above current freemium file storage limit', () => {
// # Login as sysadmin
cy.apiAdminLogin();
const currentsubscription = {
id: 'sub_test1',
product_id: 'prod_1',
is_free_trial: 'false',
};
const currentFileStorageUsageBytes = 900000000;
const planLimit = 10000000000; // 1.2GB
simulateSubscription(currentsubscription, currentFileStorageUsageBytes, planLimit);
const filename = 'svg.svg';
cy.visit(channelUrl);
cy.get('#post_textbox', {timeout: TIMEOUTS.ONE_MIN}).should('be.visible');
// # Attach file
cy.get('#advancedTextEditorCell').find('#fileUploadInput').attachFile(filename);
waitUntilUploadComplete();
// banner does not show
cy.get('#cloud_file_limit_banner').should('not.exist');
});
it('Show file limits banner for non admin uploading files when above current freemium file storage limit', () => {
// # Login user
cy.apiLogin(createdUser);
const currentFileStorageUsageBytes = 11000000000;
const planLimit = 10000000000; // 1.2GB
const currentsubscription = {
id: 'sub_test1',
product_id: 'prod_1',
is_free_trial: 'false',
};
simulateSubscription(currentsubscription, currentFileStorageUsageBytes, planLimit);
const filename = 'svg.svg';
cy.visit(channelUrl);
cy.get('#post_textbox', {timeout: TIMEOUTS.ONE_MIN}).should('be.visible');
// # Attach file
cy.get('#advancedTextEditorCell').find('#fileUploadInput').attachFile(filename);
waitUntilUploadComplete();
// * Banner shows
cy.get('#cloud_file_limit_banner').should('exist');
cy.get('#cloud_file_limit_banner').contains('Your free plan is limited to 1.2GB of files. New uploads will automatically archive older files');
cy.get('#cloud_file_limit_banner').contains('notify your admin to upgrade to a paid plan');
});
});

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

@@ -0,0 +1,185 @@
// 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 @files_and_attachments
import * as TIMEOUTS from '../../../fixtures/timeouts';
describe('Upload Files - Settings', () => {
let channelUrl;
before(() => {
cy.shouldNotRunOnCloudEdition();
// # Go to system admin then verify admin console URL and header
cy.visit('/admin_console/site_config/file_sharing_downloads');
cy.url().should('include', '/admin_console/site_config/file_sharing_downloads');
cy.get('.admin-console__header', {timeout: TIMEOUTS.ONE_MIN}).
should('be.visible').
and('have.text', 'File Sharing and Downloads');
// # Set file sharing to false
cy.findByTestId('FileSettings.EnableFileAttachmentsfalse').click();
cy.get('#saveSetting').click();
// # Create new team and new user and visit test channel
cy.apiInitSetup({loginAfter: true}).then(({channelUrl: url}) => {
channelUrl = url;
});
});
beforeEach(() => {
cy.visit(channelUrl);
});
it('MM-T1147_1 Disallow file sharing in the channel', () => {
cy.get('.post-create__container .AdvancedTextEditor').should('be.visible').within(() => {
// * Attachment input should not exist in the DOM
cy.get('#fileUploadInput').should('not.exist');
// * Paper clip icon should not be visible in the center channel
cy.get('#fileUploadButton').should('not.exist');
});
// * Channel header file icon should not be visible
cy.get('#channel-header').find('#channelHeaderFilesButton').should('not.exist');
// # Post a message
cy.postMessage('sample');
// # Open RHS
cy.getLastPost().click();
cy.get('.post-right-comments-container .AdvancedTextEditor').should('be.visible').within(() => {
// * Attachment input should not exist in the DOM
cy.get('#fileUploadInput').should('not.exist');
// * Paper clip icon should not be visible in the RHS
cy.get('#fileUploadButton').should('not.exist');
});
// # Click on the search input
cy.uiGetSearchBox().click();
// * Verify search hint does not have File button
cy.get('#searchbar-help-popup').find('.search-hint__search-type-selector button > .icon-file-text-outline').should('not.exist');
// # Search for posts
cy.get('#searchBox').type('sample').type('{enter}');
// * Verify search results do not have File button
cy.get('.files-tab').should('not.exist');
// # Delete the post
cy.getLastPostId().then(cy.apiDeletePost);
});
it('MM-T1147_2 drag and drop a file on center and RHS should produce an error', () => {
const filename = 'mattermost-icon.png';
// # Drag and drop file in center channel
cy.get('.row.main').trigger('dragenter');
cy.fixture(filename).then((img) => {
const blob = Cypress.Blob.base64StringToBlob(img, 'image/png');
cy.window().then((win) => {
const file = new win.File([blob], filename);
const dataTransfer = new win.DataTransfer();
dataTransfer.items.add(file);
cy.get('.row.main').trigger('drop', {dataTransfer});
// * An error should be visible saying 'File attachments are disabled'
cy.get('#create_post #postCreateFooter').find('.has-error').should('contain.text', 'File attachments are disabled.');
});
});
// # Post a message
cy.postMessage('sample');
// # Open RHS
cy.getLastPost().click();
// # Drag and drop file in RHS
cy.get('.ThreadViewer').trigger('dragenter');
cy.fixture(filename).then((img) => {
const blob = Cypress.Blob.base64StringToBlob(img, 'image/png');
cy.window().then((win) => {
const file = new win.File([blob], filename);
const dataTransfer = new win.DataTransfer();
dataTransfer.items.add(file);
cy.get('.ThreadViewer').trigger('drop', {dataTransfer});
// * An error should be visible saying 'File attachments are disabled'
cy.get('.ThreadViewer #postCreateFooter').find('.has-error').should('contain.text', 'File attachments are disabled.');
});
});
// # Delete the post
cy.getLastPostId().then(cy.apiDeletePost);
});
it('MM-T1147_3 copy a file and paste in message box and reply box should produce an error', () => {
const filename = 'mattermost-icon.png';
// # Paste a file in the center channel
cy.fixture(filename).then((img) => {
const blob = Cypress.Blob.base64StringToBlob(img, 'image/png');
cy.uiGetPostTextBox().trigger('paste', {clipboardData: {
items: [{
name: filename,
kind: 'file',
type: 'image/png',
getAsFile: () => {
return blob;
},
}],
types: [],
}});
// * An error should be visible saying 'File attachments are disabled'
cy.get('#postCreateFooter').find('.has-error').should('contain.text', 'File attachments are disabled.');
});
// # Post a message
cy.postMessage('sample');
// # Open RHS
cy.getLastPost().click();
// # Paste a file in the RHS
cy.fixture(filename).then((img) => {
const blob = Cypress.Blob.base64StringToBlob(img, 'image/png');
cy.uiGetReplyTextBox().trigger('paste', {clipboardData: {
items: [{
name: filename,
kind: 'file',
type: 'image/png',
getAsFile: () => {
return blob;
},
}],
types: [],
}});
// * An error should be visible saying 'File attachments are disabled'
cy.get('.ThreadViewer #postCreateFooter').find('.has-error').should('contain.text', 'File attachments are disabled.');
});
// # Delete the post
cy.getLastPostId().then(cy.apiDeletePost);
});
it('MM-T1147_4 keyboard shortcut CMD/CTRL+U should produce an error', () => {
// # Type CMD/CRTL+U shortcut
cy.uiGetPostTextBox().cmdOrCtrlShortcut('{U}');
// * An error should be visible saying 'File attachments are disabled'
cy.get('#postCreateFooter').find('.has-error').should('contain.text', 'File attachments are disabled.');
});
});

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

@@ -0,0 +1,69 @@
// 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 @files_and_attachments
import * as TIMEOUTS from '../../../fixtures/timeouts';
describe('Edit Message with Attachment', () => {
before(() => {
// # Enable Link Previews
cy.apiUpdateConfig({
ServiceSettings: {
EnableLinkPreviews: true,
},
});
// # Create new team and new user and visit off-topic channel
cy.apiInitSetup({loginAfter: true}).then(({offTopicUrl}) => {
cy.visit(offTopicUrl);
});
});
it('MM-T2268 - Edit Message with Attachment', () => {
// # Upload file
cy.get('#fileUploadInput').attachFile('mattermost-icon.png');
// # Wait for file to upload
cy.wait(TIMEOUTS.TWO_SEC);
// # Post message
cy.postMessage('Test');
cy.getLastPost().within(() => {
// * Posted message should be correct
cy.get('.post-message__text').should('contain.text', 'Test');
// * Attachment should exist
cy.get('.file-view--single').should('exist');
// * Edited indicator should not exist
cy.get('.post-edited__indicator').should('not.exist');
});
// # Open the edit dialog
cy.uiGetPostTextBox().type('{uparrow}');
// # Add some more text and save
cy.get('#edit_textbox').type(' with some edit');
cy.get('#edit_textbox').type('{enter}').wait(TIMEOUTS.HALF_SEC);
cy.getLastPost().within(() => {
// * New text should show
cy.get('.post-message__text').should('contain.text', 'Test with some edit');
// * Attachment should still exist
cy.get('.file-view--single').should('exist');
// * Edited indicator should exist
cy.get('.post-edited__indicator').should('exist');
});
});
});

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

@@ -0,0 +1,141 @@
// 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 @files_and_attachments
import * as TIMEOUTS from '../../../fixtures/timeouts';
import {
attachFile,
downloadAttachmentAndVerifyItsProperties,
interceptFileUpload,
waitUntilUploadComplete,
} from './helpers';
describe('Upload Files - Audio', () => {
before(() => {
// # Create new team and new user and visit test channel
cy.apiInitSetup({loginAfter: true}).then(({channelUrl}) => {
cy.visit(channelUrl);
cy.postMessage('hello');
});
});
beforeEach(() => {
interceptFileUpload();
});
it('MM-T3825_1 - MP3', () => {
const properties = {
filePath: 'mm_file_testing/Audio/MP3.mp3',
fileName: 'MP3.mp3',
mimeType: 'audio/mpeg',
shouldPreview: true,
};
testAudioFile(properties);
});
it('MM-T3825_2 - M4A', () => {
const properties = {
filePath: 'mm_file_testing/Audio/M4A.m4a',
fileName: 'M4A.m4a',
shouldPreview: false,
};
testAudioFile(properties);
});
it('MM-T3825_3 - AAC', () => {
const properties = {
filePath: 'mm_file_testing/Audio/AAC.aac',
fileName: 'AAC.aac',
mimeType: 'audio/aac',
shouldPreview: false,
};
testAudioFile(properties);
});
it('MM-T3825_4 - FLAC', () => {
const properties = {
filePath: 'mm_file_testing/Audio/FLAC.flac',
fileName: 'FLAC.flac',
shouldPreview: false,
};
testAudioFile(properties);
});
it('MM-T3825_5 - OGG', () => {
const properties = {
filePath: 'mm_file_testing/Audio/OGG.ogg',
fileName: 'OGG.ogg',
mimeType: 'audio/ogg',
shouldPreview: true,
};
testAudioFile(properties);
});
it('MM-T3825_6 - WAV', () => {
const properties = {
filePath: 'mm_file_testing/Audio/WAV.wav',
fileName: 'WAV.wav',
mimeType: 'audio/wav',
shouldPreview: true,
};
testAudioFile(properties);
});
it('MM-T3825_7 - WMA', () => {
const properties = {
filePath: 'mm_file_testing/Audio/WMA.wma',
fileName: 'WMA.wma',
shouldPreview: false,
};
testAudioFile(properties);
});
});
function testAudioFile(properties) {
const {fileName, shouldPreview} = properties;
// # Post any message
cy.postMessage(fileName);
// # Post an image in center channel
attachFile(properties);
// # Wait until file upload is complete then submit
waitUntilUploadComplete();
cy.uiGetPostTextBox().clear().type('{enter}');
cy.wait(TIMEOUTS.ONE_SEC);
// # Open file preview
cy.uiGetFileThumbnail(fileName).click();
// * Verify that the preview modal open up
cy.uiGetFilePreviewModal().as('filePreviewModal');
if (shouldPreview) {
// * Check if the video element exist
// Audio is also played by the video element
cy.get('@filePreviewModal').get('video').should('exist');
}
// * Download button should exist
cy.get('@filePreviewModal').uiGetDownloadFilePreviewModal().then((downloadLink) => {
expect(downloadLink.attr('download')).to.equal(fileName);
const fileAttachmentURL = downloadLink.attr('href');
// * Verify that download link has correct name
downloadAttachmentAndVerifyItsProperties(fileAttachmentURL, fileName, 'attachment');
});
// # Close modal
cy.uiCloseFilePreviewModal();
}

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

@@ -0,0 +1,127 @@
// 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 @files_and_attachments
import * as TIMEOUTS from '../../../fixtures/timeouts';
import {
attachFile,
downloadAttachmentAndVerifyItsProperties,
interceptFileUpload,
waitUntilUploadComplete,
} from './helpers';
describe('Upload Files - Generic', () => {
before(() => {
// # Create new team and new user and visit test channel
cy.apiInitSetup({loginAfter: true}).then(({channelUrl}) => {
cy.visit(channelUrl);
cy.postMessage('hello');
});
});
beforeEach(() => {
interceptFileUpload();
});
it('MM-T3824_1 - PDF', () => {
const properties = {
filePath: 'mm_file_testing/Documents/PDF.pdf',
fileName: 'PDF.pdf',
mimeType: 'application/pdf',
type: 'pdf',
};
testGenericFile(properties);
});
it('MM-T3824_2 - Excel', () => {
const properties = {
filePath: 'mm_file_testing/Documents/Excel.xlsx',
fileName: 'Excel.xlsx',
mimeType: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
type: 'excel',
};
testGenericFile(properties);
});
it('MM-T3824_3 - PPT', () => {
const properties = {
filePath: 'mm_file_testing/Documents/PPT.pptx',
fileName: 'PPT.pptx',
mimeType: 'application/vnd.openxmlformats-officedocument.presentationml.presentation',
type: 'ppt',
};
testGenericFile(properties);
});
it('MM-T3824_4 - Word', () => {
const properties = {
filePath: 'mm_file_testing/Documents/Word.docx',
fileName: 'Word.docx',
mimeType: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
type: 'word',
};
testGenericFile(properties);
});
it('MM-T3824_5 - Text', () => {
const properties = {
filePath: 'mm_file_testing/Documents/Text.txt',
fileName: 'Text.txt',
mimeType: 'txt/plain',
type: 'text',
};
testGenericFile(properties);
});
});
function testGenericFile(properties) {
const {fileName, type} = properties;
// # Post any message
cy.postMessage(fileName);
// # Post an image in center channel
attachFile(properties);
// # Wait until file upload is complete then submit
waitUntilUploadComplete();
cy.uiGetPostTextBox().clear().type('{enter}');
cy.wait(TIMEOUTS.ONE_SEC);
// # Open file preview
cy.uiGetFileThumbnail(fileName).click();
// * Verify that the preview modal open up
cy.uiGetFilePreviewModal().as('filePreviewModal');
switch (type) {
case 'text':
cy.get('@filePreviewModal').get('code').should('exist');
break;
case 'pdf':
cy.get('@filePreviewModal').get('canvas').should('have.length', 10);
break;
default:
}
// * Download button should exist
cy.get('@filePreviewModal').uiGetDownloadFilePreviewModal().then((downloadLink) => {
expect(downloadLink.attr('download')).to.equal(fileName);
const fileAttachmentURL = downloadLink.attr('href');
// * Verify that download link has correct name
downloadAttachmentAndVerifyItsProperties(fileAttachmentURL, fileName, 'attachment');
});
// # Close modal
cy.uiCloseFilePreviewModal();
}

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

@@ -0,0 +1,146 @@
// 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 @files_and_attachments
import * as TIMEOUTS from '../../../fixtures/timeouts';
import {
attachFile,
downloadAttachmentAndVerifyItsProperties,
interceptFileUpload,
waitUntilUploadComplete,
} from './helpers';
describe('Upload Files - Image', () => {
before(() => {
// # Create new team and new user and visit test channel
cy.apiInitSetup({loginAfter: true}).then(({channelUrl}) => {
cy.visit(channelUrl);
cy.postMessage('hello');
});
});
beforeEach(() => {
interceptFileUpload();
});
it('MM-T2264_1 - JPG', () => {
const properties = {
filePath: 'mm_file_testing/Images/JPG.jpg',
fileName: 'JPG.jpg',
originalWidth: 400,
originalHeight: 479,
mimeType: 'image/jpg',
};
testImage(properties);
});
it('MM-T2264_2 - PNG', () => {
const properties = {
filePath: 'mm_file_testing/Images/PNG.png',
fileName: 'PNG.png',
originalWidth: 400,
originalHeight: 479,
mimeType: 'image/png',
};
testImage(properties);
});
it('MM-T2264_3 - BMP', () => {
const properties = {
filePath: 'mm_file_testing/Images/BMP.bmp',
fileName: 'BPM.bmp',
originalWidth: 400,
originalHeight: 479,
mimeType: 'image/bmp',
};
testImage(properties);
});
it('MM-T2264_4 - GIF', () => {
const properties = {
filePath: 'mm_file_testing/Images/GIF.gif',
fileName: 'GIF.gif',
originalWidth: 500,
originalHeight: 500,
mimeType: 'image/gif',
};
testImage(properties);
});
it('MM-T2264_5 - TIFF', () => {
const properties = {
filePath: 'mm_file_testing/Images/TIFF.tif',
fileName: 'TIFF.tif',
originalWidth: 400,
originalHeight: 479,
mimeType: 'image/tiff',
};
testImage(properties);
});
it('MM-T2264_6 - PSD', () => {
const properties = {
filePath: 'mm_file_testing/Images/PSD.psd',
fileName: 'PSD.psd',
originalWidth: 400,
originalHeight: 479,
mimeType: 'application/psd',
};
testImage(properties);
});
});
function testImage(properties) {
const {fileName, originalWidth, originalHeight} = properties;
const aspectRatio = originalWidth / originalHeight;
// # Post any message
cy.postMessage(fileName);
// # Post an image in center channel
attachFile(properties);
// # Wait until file upload is complete then submit
waitUntilUploadComplete();
cy.uiGetPostTextBox().clear().type('{enter}');
cy.wait(TIMEOUTS.FIVE_SEC);
// # Open file preview
cy.uiGetFileThumbnail(fileName).click();
// * Verify that the preview modal open up
cy.uiGetFilePreviewModal().as('filePreviewModal');
cy.get('@filePreviewModal').uiGetContentFilePreviewModal().find('img').should((img) => {
// * Image aspect ratio is maintained
expect(img.width() / img.height()).to.be.closeTo(aspectRatio, 0.01);
});
// * Download button should exist
cy.get('@filePreviewModal').uiGetDownloadFilePreviewModal().then((downloadLink) => {
expect(downloadLink.attr('download')).to.equal(fileName);
const fileAttachmentURL = downloadLink.attr('href');
// * Verify that download link has correct name
downloadAttachmentAndVerifyItsProperties(fileAttachmentURL, fileName, 'attachment');
});
// # Close modal
cy.uiCloseFilePreviewModal();
}

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

@@ -0,0 +1,139 @@
// 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 @files_and_attachments
import * as TIMEOUTS from '../../../fixtures/timeouts';
import {
attachFile,
downloadAttachmentAndVerifyItsProperties,
interceptFileUpload,
waitUntilUploadComplete,
} from './helpers';
describe('Upload Files - Video', () => {
before(() => {
// # Create new team and new user and visit test channel
cy.apiInitSetup({loginAfter: true}).then(({channelUrl}) => {
cy.visit(channelUrl);
cy.postMessage('hello');
});
});
beforeEach(() => {
interceptFileUpload();
});
it('MM-T3826_1 - MP4', () => {
const properties = {
filePath: 'mm_file_testing/Video/MP4.mp4',
fileName: 'MP4.mp4',
shouldPreview: true,
};
testVideoFile(properties);
});
it('MM-T3826_2 - AVI', () => {
const properties = {
filePath: 'mm_file_testing/Video/AVI.avi',
fileName: 'AVI.avi',
mimeType: 'video/x-msvideo',
shouldPreview: false,
};
testVideoFile(properties);
});
it('MM-T3826_3 - MKV', () => {
const properties = {
filePath: 'mm_file_testing/Video/MKV.mkv',
fileName: 'MKV.mkv',
shouldPreview: false,
};
testVideoFile(properties);
});
it('MM-T3826_4 - MOV', () => {
const properties = {
filePath: 'mm_file_testing/Video/MOV.mov',
fileName: 'MOV.mov',
shouldPreview: false,
};
testVideoFile(properties);
});
it('MM-T3826_5 - MPG', () => {
const properties = {
filePath: 'mm_file_testing/Video/MPG.mpg',
fileName: 'MPG.mpg',
mimeType: 'video/mpeg',
shouldPreview: false,
};
testVideoFile(properties);
});
it('MM-T3826_6 - WEBM', () => {
const properties = {
filePath: 'mm_file_testing/Video/WEBM.webm',
fileName: 'WEBM.webm',
mimeType: 'video/webm',
shouldPreview: true,
};
testVideoFile(properties);
});
it('MM-T3826_7 - WMV', () => {
const properties = {
filePath: 'mm_file_testing/Video/WMV.wmv',
fileName: 'WMV.wmv',
shouldPreview: false,
};
testVideoFile(properties);
});
});
export function testVideoFile(properties) {
const {fileName, shouldPreview} = properties;
// # Post any message
cy.postMessage(fileName);
// # Post an image in center channel
attachFile(properties);
// # Wait until file upload is complete then submit
waitUntilUploadComplete();
cy.uiGetPostTextBox().clear().type('{enter}');
cy.wait(TIMEOUTS.ONE_SEC);
// # Open file preview
cy.uiGetFileThumbnail(fileName).click();
// * Verify that the preview modal open up
cy.uiGetFilePreviewModal().as('filePreviewModal');
if (shouldPreview) {
// * Check if the video element exist
cy.get('@filePreviewModal').get('video').should('exist');
}
// * Download button should exist
cy.get('@filePreviewModal').uiGetDownloadFilePreviewModal().then((downloadLink) => {
expect(downloadLink.attr('download')).to.equal(fileName);
const fileAttachmentURL = downloadLink.attr('href');
// * Verify that download link has correct name
downloadAttachmentAndVerifyItsProperties(fileAttachmentURL, fileName, 'attachment');
});
// # Close modal
cy.uiCloseFilePreviewModal();
}

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

@@ -0,0 +1,59 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import * as TIMEOUTS from '../../../fixtures/timeouts';
export function downloadAttachmentAndVerifyItsProperties(fileURL, filename, httpContext) {
// * Verify it has not empty download link
cy.request(fileURL).then((response) => {
// * Verify that link can be downloaded
expect(response.status).to.equal(200);
// * Verify if link is an appropriate httpContext for opening in new tab or same and that can be saved locally
// and it contains the correct filename* which will be used to name the downloaded file
expect(response.headers['content-disposition']).to.
equal(`${httpContext};filename="${filename}"; filename*=UTF-8''${filename}`);
});
}
export function interceptFileUpload() {
cy.intercept({
method: 'POST',
url: '/api/v4/files',
}).as('fileUpload');
}
export function waitUntilUploadComplete() {
cy.wait('@fileUpload', {timeout: TIMEOUTS.TEN_SEC}).then((interception) => {
const fileInfo = interception.response.body.file_infos[0];
cy.log(`file id: ${fileInfo.id}`);
});
cy.wait(TIMEOUTS.ONE_SEC);
const options = {
timeout: TIMEOUTS.HALF_MIN,
interval: TIMEOUTS.HALF_SEC,
errorMsg: 'File upload did not complete in time',
};
// # Wait until file upload processing is complete
cy.waitUntil(() => cy.get('#postCreateFooter').then((el) => {
return el.find('.post-image__uploadingTxt').length === 0;
}), options);
cy.wait(TIMEOUTS.ONE_SEC);
}
export function attachFile({filePath, fileName, mimeType}) {
cy.fixture(filePath, 'binary').
then(Cypress.Blob.binaryStringToBlob).
then((fileContent) => {
cy.get('#advancedTextEditorCell').find('#fileUploadInput').attachFile({
fileContent,
fileName,
mimeType: mimeType || 'application/octet-stream',
encoding: 'utf8',
});
});
}

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

@@ -0,0 +1,73 @@
// 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 @files_and_attachments
describe('Image Link Preview', () => {
let offTopicUrl;
before(() => {
// # Enable Link Previews
cy.apiUpdateConfig({
ServiceSettings: {
EnableLinkPreviews: true,
},
});
// # Create new team and new user and visit off-topic
cy.apiInitSetup({loginAfter: true}).then((out) => {
offTopicUrl = out.offTopicUrl;
// # Enable link previews
cy.apiSaveLinkPreviewsPreference('true');
cy.visit(offTopicUrl);
});
});
beforeEach(() => {
// # Expand image previews
cy.apiSaveCollapsePreviewsPreference('false');
});
it('MM-T332 Image link preview - Bitly links for images and YouTube -- KNOWN ISSUE: MM-40448', () => {
// # Youtube link and image link
const links = ['https://bit.ly/2NlYsOr', 'https://bit.ly/2wqEbjw'];
links.forEach((link) => {
// # Post a link to an externally hosted image
cy.postMessage(link);
cy.getLastPostId().then((postId) => {
// * Verify it renders correctly on center
cy.get(`#post_${postId}`).should('be.visible').within(() => {
cy.findByLabelText('Toggle Embed Visibility').
should('be.visible').and('have.attr', 'data-expanded', 'true');
cy.findByLabelText('file thumbnail').should('be.visible');
});
// # Click the collapse arrows to collapse the image preview
cy.get(`#post_${postId}`).findByLabelText('Toggle Embed Visibility').
click().
should('have.attr', 'data-expanded', 'false');
// * Observe it collapses
cy.get(`#post_${postId}`).findByLabelText('file thumbnail').should('not.exist');
// # Click the expand arrows to expand the image preview again
cy.get(`#post_${postId}`).findByLabelText('Toggle Embed Visibility').
click().
should('have.attr', 'data-expanded', 'true');
// * Observe it expand
cy.get(`#post_${postId}`).findByLabelText('file thumbnail').should('be.visible');
});
});
});
});

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

@@ -0,0 +1,78 @@
// 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 @files_and_attachments
describe('Image Link Preview', () => {
before(() => {
// # Enable Link Previews
cy.apiUpdateConfig({
ServiceSettings: {
EnableLinkPreviews: true,
},
});
// # Create new team and new user and visit test channel
cy.apiInitSetup({loginAfter: true}).then(({channelUrl}) => {
// # For test user, enable link previews and expand image previews
cy.apiSaveLinkPreviewsPreference('true');
cy.apiSaveCollapsePreviewsPreference('false');
cy.visit(channelUrl);
});
});
it('MM-T329 Image link preview', () => {
const link = 'https://raw.githubusercontent.com/furqanmlk/furqanmlk.github.io/main/images/image-small-height.png';
const baseUrl = Cypress.config('baseUrl');
const encodedIconUrl = encodeURIComponent(link);
// # Post a link to an externally hosted image
cy.postMessage(link);
const expectedSrc = `${baseUrl}/api/v4/image?url=${encodedIconUrl}`;
// # Open file preview
cy.uiGetPostEmbedContainer().
find('img').
should('have.attr', 'src', expectedSrc).
click();
// * Verify that the preview modal open up
cy.uiGetFilePreviewModal().as('filePreviewModal');
// * Assert that the image has the correct url
cy.get('@filePreviewModal').findByTestId('imagePreview').should('have.attr', 'src', expectedSrc);
cy.get('@filePreviewModal').uiGetContentFilePreviewModal().find('img').should((img) => {
// * Verify image is rendered
expect(img.height()).to.be.closeTo(25, 2);
expect(img.width()).to.be.closeTo(340, 2);
});
// * Verify "Get Public Link" icon does not exist
cy.get('@filePreviewModal').uiGetPublicLink({exist: false});
// # Close modal
cy.uiCloseFilePreviewModal();
// * Verify modal is closed
cy.uiGetFilePreviewModal({exist: false});
cy.uiGetPostBody().find('.markdown__link').then((el) => {
const href = el.prop('href');
cy.request(href).then((res) => {
expect(res.status).equal(200);
});
expect(link).to.equal(href);
});
});
});

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

@@ -0,0 +1,257 @@
// 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 @files_and_attachments
describe('Image Link Preview', () => {
let offTopicUrl;
before(() => {
// # Enable Link Previews
cy.apiUpdateConfig({
ServiceSettings: {
EnableLinkPreviews: true,
},
});
// # Create new team and new user and visit off-topic
cy.apiInitSetup({loginAfter: true}).then((out) => {
offTopicUrl = out.offTopicUrl;
// # Enable link previews
cy.apiSaveLinkPreviewsPreference('true');
cy.visit(offTopicUrl);
});
});
beforeEach(() => {
// # Expand image previews
cy.apiSaveCollapsePreviewsPreference('false');
});
it('MM-T331 Image link preview - Collapse and expand', () => {
const link = 'https://raw.githubusercontent.com/furqanmlk/furqanmlk.github.io/main/images/small-image.png';
// # Post a link to an externally hosted image
cy.postMessage(link);
// # Click to reply to that post, and post that same link again (so you can see it twice in both center and RHS)
cy.clickPostCommentIcon();
cy.postMessageReplyInRHS(link);
cy.getLastPostId().then((postId) => {
// * Verify it renders correctly both on center and RHS view
cy.get(`#post_${postId}`).should('be.visible').within(() => {
cy.findByLabelText('Toggle Embed Visibility').
should('be.visible').and('have.attr', 'data-expanded', 'true');
cy.findByLabelText('file thumbnail').should('be.visible');
});
cy.get(`#rhsPost_${postId}`).should('be.visible').within(() => {
cy.findByLabelText('Toggle Embed Visibility').
should('be.visible').and('have.attr', 'data-expanded', 'true');
cy.findByLabelText('file thumbnail').should('be.visible');
});
// # In center, click the collapse arrows to collapse the image preview
cy.get(`#post_${postId}`).findByLabelText('Toggle Embed Visibility').
click().
should('have.attr', 'data-expanded', 'false');
// * Observe it collapses in both center and RHS view
cy.get(`#post_${postId}`).findByLabelText('file thumbnail').should('not.exist');
cy.get(`#rhsPost_${postId}`).findByLabelText('file thumbnail').should('not.exist');
// # In RHS, click the expand arrows to expand the image preview again
cy.get(`#rhsPost_${postId}`).findByLabelText('Toggle Embed Visibility').
click().
should('have.attr', 'data-expanded', 'true');
// * Observe it expand in center and RHS
cy.get(`#post_${postId}`).findByLabelText('file thumbnail').should('be.visible');
cy.get(`#rhsPost_${postId}`).findByLabelText('file thumbnail').should('be.visible');
});
// # In center message box, post slash command /collapse
cy.postMessage('/collapse ');
// # Observe all image previews collapse
cy.findByLabelText('file thumbnail').should('not.exist');
// # In RHS reply box, post slash command /expand
cy.postMessageReplyInRHS('/expand ');
// # All image previews expand back open
cy.findAllByLabelText('file thumbnail').should('be.visible').and('have.length', 4);
});
it('MM-T2389 Inline markdown image links open with preview modal', () => {
// Go to home channel
cy.visit(offTopicUrl);
const markdownImageText = 'exampleImage';
const markdownImageSrc = 'https://docs.mattermost.com/_images/icon-76x76.png';
const markdownImageSrcEncoded = encodeURIComponent(markdownImageSrc); // Since the url preview will be encoded string
const messageWithMarkdownImage = `![${markdownImageText}](${markdownImageSrc}) an image plus some text that has [a link](https://example.com/)`;
// # Post a message with markdown image and link
cy.postMessage(messageWithMarkdownImage);
// # Get the post id of last message with image and link
cy.getLastPostId().then((postWithMarkdownImage) => {
// # Scan inside the last post for checking the image
cy.get(`#${postWithMarkdownImage}_message`).should('exist').and('be.visible').within(() => {
// * Find the inline image of the markdown text and verify its clickable
// Image can be found by its alt text is same as the one passed in markdown image title
cy.findByAltText(markdownImageText).should('exist').and('be.visible').
and('have.css', 'cursor', 'pointer').
and('have.attr', 'src').should('include', markdownImageSrcEncoded);
// # Click on the image
cy.findByAltText(markdownImageText).click();
});
});
const baseUrl = Cypress.config('baseUrl');
const expectedSrc = `${baseUrl}/api/v4/image?url=${markdownImageSrcEncoded}`;
// * Verify that the preview modal open up
cy.uiGetFilePreviewModal().as('filePreviewModal');
// * Verify we have the image inside the modal
cy.get('@filePreviewModal').uiGetContentFilePreviewModal().
find('img').
should('be.visible').
and('have.attr', 'alt', 'preview url image').
and('have.attr', 'src', expectedSrc);
// # Close the image preview modal
cy.uiCloseFilePreviewModal();
});
it('MM-T1447 Images below a min-width and min-height are posted in a container that is clickable', () => {
const listOfMinWidthHeightImages = [
{
filename: 'image-20x20.jpg',
originalSize: {width: 20, height: 20},
thumbnailSize: {width: 20, height: 20},
containerSize: {height: 46},
},
{
filename: 'image-50x50.jpg',
originalSize: {width: 50, height: 50},
thumbnailSize: {width: 50, height: 50},
},
{
filename: 'image-60x60.jpg',
originalSize: {width: 60, height: 60},
thumbnailSize: {width: 60, height: 60},
},
{
filename: 'image-400x400.jpg',
originalSize: {width: 400, height: 400},
thumbnailSize: {width: 350, height: 350},
},
{
filename: 'image-40x400.jpg',
originalSize: {width: 40, height: 400},
thumbnailSize: {width: 35, height: 350},
containerSize: {width: 46},
},
{
filename: 'image-400x40.jpg',
originalSize: {width: 400, height: 40},
thumbnailSize: {width: 400, height: 40},
containerSize: {height: 46},
},
{
filename: 'image-1000x40.jpg',
originalSize: {width: 1000, height: 40},
thumbnailSize: {width: 948, height: 38},
containerSize: {height: 46},
},
{
filename: 'image-1600x40.jpg',
originalSize: {width: 1600, height: 40},
thumbnailSize: {width: 948, height: 24},
previewSize: {width: 1204, height: 30},
containerSize: {height: 46},
},
];
listOfMinWidthHeightImages.forEach(({
filename,
originalSize,
thumbnailSize,
previewSize,
containerSize,
}) => {
// # Upload Image as attachment and post it
cy.get('#fileUploadInput').attachFile(filename);
cy.postMessage(`file uploaded-${filename}`);
// # If image is below min dimensions then do checks for image container dimensions
if (containerSize) {
// * Check if container is rendered for preview of image
cy.uiGetPostEmbedContainer().
find('.small-image__container').
should((imageContainer) => {
if (containerSize.height) {
// * Should match thumbnail's container height
expect(imageContainer.height()).to.closeTo(containerSize.height, 1);
} else {
// * Should match thumbnail's container width
expect(imageContainer.width()).to.closeTo(containerSize.width, 1);
}
});
}
// # Get the last uploaded image post
cy.uiGetPostBody().within(() => {
// # Find the attached image and verify its dimensions and click on it to open preview modal
// # Open file preview
cy.uiGetFileThumbnail(filename).
should((imageAttachment) => {
// * Check the dimensions of image's dimensions is almost equal to its thumbnail dimensions
expect(imageAttachment.height()).to.closeTo(thumbnailSize.height, 1);
expect(imageAttachment.width()).to.be.closeTo(thumbnailSize.width, 1);
}).
click();
});
//* Verify image preview modal is opened
cy.uiGetFilePreviewModal().as('filePreviewModal');
// * Verify we have the image inside the modal
cy.get('@filePreviewModal').uiGetContentFilePreviewModal().find('img').should((imagePreview) => {
// * Verify that preview has correct alt text
expect(imagePreview.attr('alt')).equals('preview url image');
// # If image is bigger than viewport, then its preview will be check for dimensions
if (previewSize) {
// * It should match preview dimension for images bigger than viewport
expect(imagePreview.height()).to.closeTo(previewSize.height, 1);
expect(imagePreview.width()).to.be.closeTo(previewSize.width, 1);
} else {
// * It should match original dimension for images less than viewport size
expect(imagePreview.height()).to.closeTo(originalSize.height, 1);
expect(imagePreview.width()).to.be.closeTo(originalSize.width, 1);
}
});
// # Close modal
cy.uiCloseFilePreviewModal();
});
});
});

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

@@ -0,0 +1,86 @@
// 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 @files_and_attachments
describe('Paste Image', () => {
before(() => {
// # Enable Link Previews
cy.apiUpdateConfig({
ServiceSettings: {
EnableLinkPreviews: true,
},
});
// # Create new team and new user and visit off-topic
cy.apiInitSetup({loginAfter: true}).then(({offTopicUrl}) => {
cy.visit(offTopicUrl);
});
});
it('MM-T2263 - Paste image in message box and post', () => {
const filename = 'mattermost-icon.png';
// # Paste image
cy.fixture(filename).then((img) => {
const blob = Cypress.Blob.base64StringToBlob(img, 'image/png');
cy.uiGetPostTextBox().trigger('paste', {clipboardData: {
items: [{
name: filename,
kind: 'file',
type: 'image/png',
getAsFile: () => {
return blob;
},
}],
types: [],
}});
cy.uiWaitForFileUploadPreview();
});
cy.uiGetFileUploadPreview().should('be.visible').within(() => {
// * Type is correct
cy.get('.post-image__type').should('contain.text', 'PNG');
// * Size is correct
cy.get('.post-image__size').should('contain.text', '13KB');
// * Img thumbnail exist
cy.get('.post-image__thumbnail > .post-image').should('exist');
});
// # Post message
cy.postMessage('hello');
cy.uiGetPostBody().
find('.file-view--single').
find('img').
should(maintainAspectRatio);
// # Open RHS
cy.clickPostCommentIcon();
cy.getLastPostId().then((id) => {
cy.get(`#rhsPost_${id}`).within(() => {
cy.get('.file-view--single').
find('img').
should(maintainAspectRatio);
});
});
});
});
function maintainAspectRatio(img) {
const aspectRatio = 1;
// * Image aspect ratio is maintained
expect(img.width() / img.height()).to.be.closeTo(aspectRatio, 0.01);
}

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

@@ -0,0 +1,207 @@
// 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 @files_and_attachments
import * as TIMEOUTS from '../../../fixtures/timeouts';
import {stubClipboard} from '../../../utils';
import {downloadAttachmentAndVerifyItsProperties} from './helpers';
describe('Upload Files', () => {
let testTeam;
let testChannel;
let otherUser;
before(() => {
cy.shouldNotRunOnCloudEdition();
});
beforeEach(() => {
// # Login as sysadmin
cy.apiAdminLogin();
// # Create new team and new user and visit test channel
cy.apiInitSetup().then(({team, channel, channelUrl}) => {
testTeam = team;
testChannel = channel;
cy.apiCreateUser().then(({user: user2}) => {
otherUser = user2;
cy.apiAddUserToTeam(testTeam.id, otherUser.id).then(() => {
cy.apiAddUserToChannel(testChannel.id, otherUser.id);
});
});
cy.visit(channelUrl);
});
});
it('MM-T346 Public link related to a deleted post should no longer open the file', () => {
// # Enable option for public file links
cy.apiUpdateConfig({
FileSettings: {
EnablePublicLink: true,
},
}).then(({config}) => {
expect(config.FileSettings.EnablePublicLink).to.be.true;
// # Reload then stub the clipboard
cy.reload();
stubClipboard().as('clipboard');
const filename = 'jpg-image-file.jpg';
// # Make a post with a file attached
cy.get('#fileUploadInput').attachFile(filename);
cy.postMessage('Post with attachment to be deleted');
// # Open file preview
cy.uiGetFileThumbnail(filename).click();
// * Verify preview modal is opened
cy.uiGetFilePreviewModal();
// # Hover over the downlink button and verify that tooltip is shown
cy.uiGetDownloadLinkFilePreviewModal().trigger('mouseover');
cy.uiGetToolTip('Get a public link');
// # Copy download link
cy.uiGetDownloadLinkFilePreviewModal().click();
// Ensure that the clipboard is called then save its content
cy.get('@clipboard').its('wasCalled').should('eq', true);
cy.get('@clipboard').
its('contents').
as('publicLinkOfAttachment').
then((url) => {
cy.request({url}).then((response) => {
// * Verify that the link no longer exists in the system
expect(response.status).to.be.equal(200);
});
});
// # Wait a little for link to get generate
cy.wait(TIMEOUTS.ONE_SEC);
// # Close the image preview modal
cy.uiCloseFilePreviewModal();
// # Once again get the last post with attachment, this time to delete it
cy.getLastPostId().then((lastPostId) => {
// # Click post dot menu in center.
cy.clickPostDotMenu(lastPostId);
// # Scan inside the post menu dropdown
cy.get(`#CENTER_dropdown_${lastPostId}`).
should('exist').
within(() => {
// # Click on the delete post button from the dropdown
cy.findByText('Delete').click();
});
});
// * Verify caution dialog for delete post is visible
cy.get('.modal-dialog').
should('be.visible').
within(() => {
// # Confirm click on the delete button for the post
cy.findByText('Delete').click();
});
// # Try to fetch the url of the attachment we previously deleted
cy.get('@publicLinkOfAttachment').then((url) => {
cy.request({url, failOnStatusCode: false}).then((response) => {
// * Verify that the link no longer exists in the system
expect(response.status).to.be.equal(404);
});
// # Open the deleted link in the browser
cy.visit(url, {failOnStatusCode: false});
});
// * Verify that we land on attachment not found page
cy.findByText('Error');
cy.findByText('Unable to get the file info.');
cy.findByText('Back to Mattermost').
parent().
should('have.attr', 'href', '/').
click();
});
});
it('MM-T345 Public links for common file types should open in a new browser tab', () => {
// # Enable option for public file links
cy.apiUpdateConfig({
FileSettings: {
EnablePublicLink: true,
},
});
cy.reload();
stubClipboard().as('clipboard');
// # Save Show Preview Preference to true
cy.apiSaveLinkPreviewsPreference('true');
// # Save Preview Collapsed Preference to false
cy.apiSaveCollapsePreviewsPreference('false');
const commonTypeFiles = [
'jpg-image-file.jpg',
'gif-image-file.gif',
'png-image-file.png',
'tiff-image-file.tif',
'mp3-audio-file.mp3',
'mp4-video-file.mp4',
'mpeg-video-file.mpg',
];
commonTypeFiles.forEach((filename) => {
// # Make a post with a file attached
cy.get('#fileUploadInput').attachFile(filename);
cy.wait(TIMEOUTS.ONE_SEC);
cy.postMessage(filename);
// # Open file preview
cy.uiGetFileThumbnail(filename).click();
// * Verify preview modal is opened
cy.uiGetFilePreviewModal();
// # Hover over the downlink button and verify that tooltip is shown
cy.uiGetDownloadLinkFilePreviewModal().trigger('mouseover');
cy.uiGetToolTip('Get a public link');
// # Click to copy download link
cy.uiGetDownloadLinkFilePreviewModal().click({force: true});
// # Wait a little for url to be (re)generated
cy.wait(TIMEOUTS.ONE_SEC);
// Ensure that the clipboard is called then save its content
cy.get('@clipboard').its('wasCalled').should('eq', true);
cy.get('@clipboard').
its('contents').
as('link').
then((publicLinkOfAttachment) => {
// # Close the image preview modal
cy.uiCloseFilePreviewModal();
// # Post the link of attachment as a message
cy.uiPostMessageQuickly(publicLinkOfAttachment);
// * Check the attachment url contains the attachment
downloadAttachmentAndVerifyItsProperties(publicLinkOfAttachment, filename, 'inline');
});
});
});
});

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

@@ -0,0 +1,422 @@
// 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 @files_and_attachments
import * as TIMEOUTS from '../../../fixtures/timeouts';
import {
downloadAttachmentAndVerifyItsProperties,
interceptFileUpload,
waitUntilUploadComplete,
} from './helpers';
describe('Upload Files', () => {
let channelUrl;
let channelId;
let testUser;
beforeEach(() => {
// # Login as sysadmin
cy.apiAdminLogin();
// # Init setup
cy.apiInitSetup().then((out) => {
channelUrl = out.channelUrl;
channelId = out.channel.id;
testUser = out.user;
cy.visit(channelUrl);
interceptFileUpload();
});
});
it('MM-T336 Image thumbnail - expanded RHS', () => {
const filename = 'huge-image.jpg';
const originalWidth = 1920;
const originalHeight = 1280;
const aspectRatio = originalWidth / originalHeight;
// # Post an image in center channel
cy.get('#advancedTextEditorCell').find('#fileUploadInput').attachFile(filename);
waitUntilUploadComplete();
cy.uiGetPostTextBox().clear().type('{enter}');
// # Click reply arrow to open the reply thread in RHS
cy.clickPostCommentIcon();
cy.uiGetRHS().within(() => {
// # Observe image thumbnail displays the same
cy.uiGetFileThumbnail(filename).should((img) => {
expect(img.width() / img.height()).to.be.closeTo(aspectRatio, 1);
});
// # In the RHS, click the expand arrows to expand the RHS
cy.uiExpandRHS();
});
cy.uiGetRHS().isExpanded().within(() => {
// * Observe image thumbnail displays the same
cy.uiGetFileThumbnail(filename).should((img) => {
expect(img.width() / img.height()).to.be.closeTo(aspectRatio, 1);
});
});
// # Close the RHS panel
cy.uiCloseRHS();
});
it('MM-T340 Download - File name link on thumbnail', () => {
const attachmentFilesList = [
{
filename: 'word-file.doc',
extensions: 'DOC',
type: 'document',
},
{
filename: 'wordx-file.docx',
extensions: 'DOCX',
type: 'document',
},
{
filename: 'powerpoint-file.ppt',
extensions: 'PPT',
type: 'document',
},
{
filename: 'powerpointx-file.pptx',
extensions: 'PPTX',
type: 'document',
},
{
filename: 'jpg-image-file.jpg',
extensions: 'JPG',
type: 'image',
},
];
attachmentFilesList.forEach((file) => {
// # Attach the file as attachment and post a message
cy.get('#fileUploadInput').attachFile(file.filename);
waitUntilUploadComplete();
cy.postMessage('hello');
cy.uiWaitUntilMessagePostedIncludes('hello');
// # Get the body of the last post
cy.uiGetPostBody().within(() => {
// # If file type is document then file container will be rendered
if (file.type === 'document') {
// * Check if the download icon exists
cy.findByLabelText('download').then((fileAttachment) => {
// * Verify if download attribute exists which allows to download instead of navigation
expect(fileAttachment.attr('download')).to.equal(file.filename);
const fileAttachmentURL = fileAttachment.attr('href');
// * Verify that download link has correct name
downloadAttachmentAndVerifyItsProperties(fileAttachmentURL, file.filename, 'attachment');
});
// * Check if the file name is shown in the attachment
cy.findByText(file.filename);
// * Check if correct extension is shown in the attachment and click to open preview
cy.findByText(file.extensions).click();
} else if (file.type === 'image') {
// # Check that image is shown and then click to open the preview
cy.uiGetFileThumbnail(file.filename).click();
}
});
// * Verify image preview modal is opened
cy.uiGetFilePreviewModal().as('filePreviewModal');
// * Download button should exist
cy.get('@filePreviewModal').uiGetDownloadFilePreviewModal().then((downloadLink) => {
expect(downloadLink.attr('download')).to.equal(file.filename);
const fileAttachmentURL = downloadLink.attr('href');
// * Verify that download link has correct name
downloadAttachmentAndVerifyItsProperties(fileAttachmentURL, file.filename, 'attachment');
});
// # Close the modal
cy.uiCloseFilePreviewModal();
});
});
it('MM-T341 Download link on preview - Image file (non SVG)', () => {
const imageFilenames = [
'bmp-image-file.bmp',
'png-image-file.png',
'jpg-image-file.jpg',
'gif-image-file.gif',
'tiff-image-file.tif',
];
imageFilenames.forEach((filename) => {
cy.get('#advancedTextEditorCell').find('#fileUploadInput').attachFile(filename);
waitUntilUploadComplete();
cy.postMessage('hello');
cy.uiWaitUntilMessagePostedIncludes('hello');
cy.uiGetFileThumbnail(filename).click();
// * Verify image preview modal is opened
cy.uiGetFilePreviewModal().as('filePreviewModal');
// * Download button should exist
cy.get('@filePreviewModal').uiGetDownloadFilePreviewModal().then((downloadLink) => {
expect(downloadLink.attr('download')).to.equal(filename);
const fileAttachmentURL = downloadLink.attr('href');
// * Verify that download link has correct name
downloadAttachmentAndVerifyItsProperties(fileAttachmentURL, filename, 'attachment');
});
// # Close the modal
cy.uiCloseFilePreviewModal();
});
});
it('MM-T12 Loading indicator when posting images', () => {
const filename = 'huge-image.jpg';
// # Post an image in center channel
cy.get('#advancedTextEditorCell').find('#fileUploadInput').attachFile(filename);
waitUntilUploadComplete();
cy.uiGetPostTextBox().clear().type('{enter}');
// # Login as testUser
cy.apiLogin(testUser);
// # Reload the page
cy.reload();
// * Verify the image container is visible
cy.get('.image-container').should('be.visible');
Cypress._.times(5, () => {
// # OtherUser creates posts in the channel
cy.postMessageAs({
sender: testUser,
message: 'message',
channelId,
});
// * Verify image is not loading for each posts
cy.get('.image-container').should('be.visible').find('.image-loading__container').should('not.exist');
cy.wait(TIMEOUTS.HALF_SEC);
});
});
it('MM-T337 CTRL/CMD+U - Five files on one message, thumbnails while uploading', () => {
cy.visit(channelUrl);
const filename = 'huge-image.jpg';
Cypress._.times(5, () => {
cy.get('#fileUploadInput').attachFile(filename);
waitUntilUploadComplete();
});
for (let i = 1; i < 4; i++) {
cy.get(`:nth-child(${i}) > .post-image__thumbnail > .post-image`).should('be.visible');
}
cy.get(':nth-child(5) > .post-image__thumbnail > .post-image').should('not.be.visible');
cy.get('.file-preview__container').scrollTo('right');
for (let i = 1; i < 3; i++) {
cy.get(`:nth-child(${i}) > .post-image__thumbnail > .post-image`).should('not.be.visible');
}
cy.get(':nth-child(5) > .post-image__thumbnail > .post-image').should('be.visible');
cy.postMessage('test');
cy.findByTestId('fileAttachmentList').find('.post-image').should('have.length', 5);
});
it('MM-T338 Image Attachment Upload in Mobile View', () => {
// # Set the viewport to mobile
cy.viewport('iphone-6');
// # Scan inside of the message input region
cy.findByLabelText('Login Successful message input complimentary region').should('be.visible').within(() => {
// * Check if the attachment button is present
cy.findByLabelText('Attachment Icon').should('be.visible').and('have.css', 'cursor', 'pointer');
});
const imageFilename = 'jpg-image-file.jpg';
const imageType = 'JPG';
// # Attach an image but don't post it yet
cy.get('#fileUploadInput').attachFile(imageFilename);
waitUntilUploadComplete();
// # Scan inside of the message footer region
cy.get('#advancedTextEditorCell').should('be.visible').within(() => {
// * Verify that image name is present
cy.findByText(imageFilename).should('be.visible');
// * Verify that image type is present
cy.findByText(imageType).should('be.visible');
// # Get the image preview div
cy.get('.post-image.normal').then((imageDiv) => {
// # Filter out the url from the css background property
// url("https://imageurl") => https://imageurl
const imageURL = imageDiv.css('background-image').split('"')[1];
downloadAttachmentAndVerifyItsProperties(imageURL, imageFilename, 'inline');
});
});
// # Now post with the message attachment
cy.uiGetPostTextBox().clear().type('{enter}');
// * Check that the image in the post is with valid source link
cy.uiGetFileThumbnail(imageFilename).should('have.attr', 'src').then((src) => {
downloadAttachmentAndVerifyItsProperties(src, imageFilename, 'inline');
});
});
it('MM-T2265 Multiple File Upload - 5 is successful (image, video, code, pdf, audio, other)', () => {
const attachmentFilesList = [
{
filename: 'word-file.doc',
extensions: 'DOC',
type: 'document',
},
{
filename: 'wordx-file.docx',
extensions: 'DOCX',
type: 'document',
},
{
filename: 'powerpoint-file.ppt',
extensions: 'PPT',
type: 'document',
},
{
filename: 'powerpointx-file.pptx',
extensions: 'PPTX',
type: 'document',
},
{
filename: 'jpg-image-file.jpg',
extensions: 'JPG',
type: 'image',
},
];
const minimumSeparation = 5;
cy.visit(channelUrl);
cy.uiGetPostTextBox();
// # Upload files
Cypress._.forEach(attachmentFilesList, ({filename}) => {
cy.get('#fileUploadInput').attachFile(filename);
waitUntilUploadComplete();
});
// # Wait for files to finish uploading
cy.wait(TIMEOUTS.THREE_SEC);
// # Post message
cy.postMessage('test');
cy.findByTestId('fileAttachmentList').within(() => {
for (let i = 1; i < 5; i++) {
// * Elements should have space between them
cy.get(`:nth-child(${i}) > .post-image__details`).then((firstAttachment) => {
cy.get(`:nth-child(${i + 1}) > .post-image__thumbnail`).then((secondAttachment) => {
expect(firstAttachment[0].getBoundingClientRect().right + minimumSeparation < secondAttachment[0].getBoundingClientRect().left ||
firstAttachment[0].getBoundingClientRect().bottom + minimumSeparation < secondAttachment[0].getBoundingClientRect().top).to.be.true;
});
});
}
});
cy.uiOpenFilePreviewModal();
// * Verify image preview modal is opened
cy.uiGetFilePreviewModal().as('filePreviewModal');
// * Should show first file
cy.get('@filePreviewModal').uiGetHeaderFilePreviewModal().within(() => {
cy.findByText(attachmentFilesList[0].filename);
});
// # Move to the next element using right arrow
cy.get('@filePreviewModal').uiGetArrowRightFilePreviewModal().click();
// * Should show second file
cy.get('@filePreviewModal').uiGetHeaderFilePreviewModal().within(() => {
cy.findByText(attachmentFilesList[1].filename);
});
// # Move back to the previous element using left arrow
cy.get('@filePreviewModal').uiGetArrowLeftFilePreviewModal().click();
// * Should show first file again
cy.get('@filePreviewModal').uiGetHeaderFilePreviewModal().within(() => {
cy.findByText(attachmentFilesList[0].filename);
});
});
it('MM-T2261 Upload SVG and post', () => {
const filename = 'svg.svg';
const aspectRatio = 1;
cy.visit(channelUrl);
cy.uiGetPostTextBox();
// # Attach file
cy.get('#advancedTextEditorCell').find('#fileUploadInput').attachFile(filename);
waitUntilUploadComplete();
cy.get('#create_post').find('.file-preview').within(() => {
// * Filename is correct
cy.get('.post-image__name').should('contain.text', filename);
// * Type is correct
cy.get('.post-image__type').should('contain.text', 'SVG');
// * Size is correct
cy.get('.post-image__size').should('contain.text', '6KB');
// * Img thumbnail exist
cy.get('.post-image__thumbnail > img').should('exist');
});
// # Post message
cy.postMessage('hello');
cy.uiWaitUntilMessagePostedIncludes('hello');
// # Open file preview
cy.uiGetFileThumbnail(filename).click();
// * Verify image preview modal is opened
cy.uiGetFilePreviewModal().as('filePreviewModal');
cy.get('@filePreviewModal').uiGetContentFilePreviewModal().find('img').should((img) => {
// * Image aspect ratio is maintained
expect(img.width() / img.height()).to.be.closeTo(aspectRatio, 1);
});
// * Download button should exist
cy.get('@filePreviewModal').uiGetDownloadFilePreviewModal().then((downloadLink) => {
expect(downloadLink.attr('download')).to.equal(filename);
const fileAttachmentURL = downloadLink.attr('href');
// * Verify that download link has correct name
downloadAttachmentAndVerifyItsProperties(fileAttachmentURL, filename, 'attachment');
});
// # Close modal
cy.uiCloseFilePreviewModal();
});
});

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

@@ -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 @files_and_attachments
describe('YouTube Video', () => {
before(() => {
// # Enable Link Previews
cy.apiUpdateConfig({
ServiceSettings: {
EnableLinkPreviews: true,
},
});
// # Create new team and new user and visit off-topic
cy.apiInitSetup({loginAfter: true}).then(({offTopicUrl}) => {
cy.visit(offTopicUrl);
});
});
it('MM-T2258 YouTube Video play, collapse', () => {
// # Post message
cy.postMessage('https://www.youtube.com/watch?v=gLNmtUEvI5A');
cy.getLastPost().within(() => {
// # Click play button
cy.get('.play-button').click();
// * Video should be loaded in the iframe
cy.get('.video-div > iframe').should('exist');
// # Collapse video
cy.get('.post__embed-visibility').click();
// * Embed container should not exist
cy.get('.post__embed-container').should('not.exist');
// # Expand video
cy.get('.post__embed-visibility').click();
// * Play button should exist
cy.get('.play-button').should('exist');
// * Video should not be played in the iframe
cy.get('.video-div > iframe').should('not.exist');
});
});
});