Move /e2e -> /e2e-tests
Этот коммит содержится в:
@@ -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 = ` 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');
|
||||
});
|
||||
});
|
||||
});
|
||||
Ссылка в новой задаче
Block a user