snapshot of https://github.com/mattermost/mattermost.git (master, 2026-09-16; blobs > 131072B omitted)
Some checks failed
Server CI / Postgres (shard 0) (push) Has been skipped
Server CI / Postgres (shard 3) (push) Has been skipped
BuildEnv Docker Image / build-image (push) Failing after 4s
BuildEnv Docker Image / build-image-fips (push) Failing after 4s
Migration Review & Release Notes / Generate migration review & release notes (push) Failing after 3s
Server CI / Build Environment (push) Failing after 3s
Server CI / Postgres (shard 1) (push) Has been skipped
Tools CI / check-style (mattermost-govet) (push) Failing after 4s
Server CI / Postgres (shard 2) (push) Has been skipped
Tools CI / check-style (mmgotool) (push) Failing after 3s
Server CI / Elasticsearch v8 Compatibility (push) Has been skipped
Server CI / OpenSearch v2 Compatibility (push) Has been skipped
Server CI / Postgres FIPS (shard 0) (push) Has been skipped
Tools CI / Test (mattermost-govet) (push) Failing after 3s
Server CI / Postgres FIPS (shard 1) (push) Has been skipped
Server CI / Postgres FIPS (shard 2) (push) Has been skipped
Tools CI / Test (mmgotool) (push) Failing after 3s
Server CI / Postgres FIPS (shard 3) (push) Has been skipped
Server CI / Run mmctl tests (push) Has been skipped
Server CI / Run mmctl tests (FIPS) (push) Has been skipped
Server CI / Merge Postgres Test Results (push) Has been skipped
Server CI / Merge Postgres FIPS Test Results (push) Has been skipped
Server CI / Check backport migrations (push) Has been skipped
Server CI / Check generated files (push) Has been skipped
Server CI / check-style (push) Has been skipped
Server CI / Vet API (push) Has been skipped
Server CI / Build mattermost server app (push) Has been skipped
Server CI / Server CI Complete (push) Failing after 2s
Server CI / Server CI Artifacts (push) Has been skipped
Server CI / Sentry Upload (push) Has been skipped
Server CI / Server CI Report (push) Failing after 5m1s
Server CI Nightly Race / Race Detector (push) Has been skipped
CodeQL / Analyze (go) (push) Has been cancelled
CodeQL / Analyze (javascript) (push) Has been cancelled
Webapp CI Cache Warm / Warm Webapp node_modules Cache (push) Has been cancelled
E2E CI Cache Warm / Warm E2E npm Registry Cache (push) Has been cancelled
API / build (push) Has been cancelled
Web App CI / check-types (push) Has been cancelled
Web App CI / check-lint (push) Has been cancelled
Web App CI / check-i18n (push) Has been cancelled
Web App CI / check-external-links (push) Has been cancelled
Web App CI / test (platform) (push) Has been cancelled
Web App CI / test (mattermost-redux) (push) Has been cancelled
Web App CI / test (channels shard 1/4) (push) Has been cancelled
Web App CI / test (channels shard 2/4) (push) Has been cancelled
Web App CI / test (channels shard 3/4) (push) Has been cancelled
Web App CI / test (channels shard 4/4) (push) Has been cancelled
Web App CI / upload-coverage (push) Has been cancelled
Web App CI / build (push) Has been cancelled
YAML Lint / yamllint (push) Has been cancelled
Push mirrored docker images / cd/Push mirrored docker images (push) Has been cancelled
docs-cd / Build and deploy docs (push) Has been cancelled
Docs CI / build (push) Has been cancelled
E2E Cache Warm: Cypress deps / Warm Cypress deps cache (push) Has been cancelled
Scorecards supply-chain security / Scorecard analysis (push) Has been cancelled
Server CI Weekly / Postgres FIPS (push) Has been skipped
Server CI Weekly / Run mmctl tests (FIPS) (push) Has been skipped
Server CI Weekly / Postgres with binary parameters (push) Has been skipped
Server CI Weekly / Build Environment (push) Failing after 1s
Server CI Cache Warm / Warm Go Module and Build Cache (push) Failing after 2s
Server CI Nightly Race / Build Environment (push) Failing after 1s
Some checks failed
Server CI / Postgres (shard 0) (push) Has been skipped
Server CI / Postgres (shard 3) (push) Has been skipped
BuildEnv Docker Image / build-image (push) Failing after 4s
BuildEnv Docker Image / build-image-fips (push) Failing after 4s
Migration Review & Release Notes / Generate migration review & release notes (push) Failing after 3s
Server CI / Build Environment (push) Failing after 3s
Server CI / Postgres (shard 1) (push) Has been skipped
Tools CI / check-style (mattermost-govet) (push) Failing after 4s
Server CI / Postgres (shard 2) (push) Has been skipped
Tools CI / check-style (mmgotool) (push) Failing after 3s
Server CI / Elasticsearch v8 Compatibility (push) Has been skipped
Server CI / OpenSearch v2 Compatibility (push) Has been skipped
Server CI / Postgres FIPS (shard 0) (push) Has been skipped
Tools CI / Test (mattermost-govet) (push) Failing after 3s
Server CI / Postgres FIPS (shard 1) (push) Has been skipped
Server CI / Postgres FIPS (shard 2) (push) Has been skipped
Tools CI / Test (mmgotool) (push) Failing after 3s
Server CI / Postgres FIPS (shard 3) (push) Has been skipped
Server CI / Run mmctl tests (push) Has been skipped
Server CI / Run mmctl tests (FIPS) (push) Has been skipped
Server CI / Merge Postgres Test Results (push) Has been skipped
Server CI / Merge Postgres FIPS Test Results (push) Has been skipped
Server CI / Check backport migrations (push) Has been skipped
Server CI / Check generated files (push) Has been skipped
Server CI / check-style (push) Has been skipped
Server CI / Vet API (push) Has been skipped
Server CI / Build mattermost server app (push) Has been skipped
Server CI / Server CI Complete (push) Failing after 2s
Server CI / Server CI Artifacts (push) Has been skipped
Server CI / Sentry Upload (push) Has been skipped
Server CI / Server CI Report (push) Failing after 5m1s
Server CI Nightly Race / Race Detector (push) Has been skipped
CodeQL / Analyze (go) (push) Has been cancelled
CodeQL / Analyze (javascript) (push) Has been cancelled
Webapp CI Cache Warm / Warm Webapp node_modules Cache (push) Has been cancelled
E2E CI Cache Warm / Warm E2E npm Registry Cache (push) Has been cancelled
API / build (push) Has been cancelled
Web App CI / check-types (push) Has been cancelled
Web App CI / check-lint (push) Has been cancelled
Web App CI / check-i18n (push) Has been cancelled
Web App CI / check-external-links (push) Has been cancelled
Web App CI / test (platform) (push) Has been cancelled
Web App CI / test (mattermost-redux) (push) Has been cancelled
Web App CI / test (channels shard 1/4) (push) Has been cancelled
Web App CI / test (channels shard 2/4) (push) Has been cancelled
Web App CI / test (channels shard 3/4) (push) Has been cancelled
Web App CI / test (channels shard 4/4) (push) Has been cancelled
Web App CI / upload-coverage (push) Has been cancelled
Web App CI / build (push) Has been cancelled
YAML Lint / yamllint (push) Has been cancelled
Push mirrored docker images / cd/Push mirrored docker images (push) Has been cancelled
docs-cd / Build and deploy docs (push) Has been cancelled
Docs CI / build (push) Has been cancelled
E2E Cache Warm: Cypress deps / Warm Cypress deps cache (push) Has been cancelled
Scorecards supply-chain security / Scorecard analysis (push) Has been cancelled
Server CI Weekly / Postgres FIPS (push) Has been skipped
Server CI Weekly / Run mmctl tests (FIPS) (push) Has been skipped
Server CI Weekly / Postgres with binary parameters (push) Has been skipped
Server CI Weekly / Build Environment (push) Failing after 1s
Server CI Cache Warm / Warm Go Module and Build Cache (push) Failing after 2s
Server CI Nightly Race / Build Environment (push) Failing after 1s
This commit is contained in:
259
e2e-tests/cypress/utils/file.js
Normal file
259
e2e-tests/cypress/utils/file.js
Normal file
@@ -0,0 +1,259 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
/* eslint-disable no-console */
|
||||
|
||||
const fs = require('fs');
|
||||
|
||||
const chalk = require('chalk').default;
|
||||
const intersection = require('lodash.intersection');
|
||||
const without = require('lodash.without');
|
||||
const shell = require('shelljs');
|
||||
const argv = require('yargs')(process.argv.slice(2)).
|
||||
default('includeFile', '').
|
||||
default('excludeFile', '').
|
||||
argv;
|
||||
|
||||
const TEST_DIR = 'tests';
|
||||
|
||||
const grepCommand = (word = '') => {
|
||||
// -r, recursive search on subdirectories
|
||||
// -I, ignore binary
|
||||
// -l, only names of files to stdout/return
|
||||
// -w, expression is searched for as a word
|
||||
return `grep -rIlw '${word}' ${TEST_DIR}`;
|
||||
};
|
||||
|
||||
const grepFiles = (command) => {
|
||||
return shell.exec(command, {silent: true}).stdout.
|
||||
split('\n').
|
||||
filter((f) => f.includes('spec.js') || f.includes('spec.ts'));
|
||||
};
|
||||
|
||||
const findFiles = (pattern) => {
|
||||
function diveOnFiles(dirPath, filesArr) {
|
||||
const files = fs.readdirSync(dirPath);
|
||||
let arrayOfFiles = filesArr || [];
|
||||
|
||||
files.forEach((file) => {
|
||||
const filePath = `${dirPath}/${file}`;
|
||||
if (fs.statSync(filePath).isDirectory()) {
|
||||
arrayOfFiles = diveOnFiles(filePath, arrayOfFiles);
|
||||
} else {
|
||||
arrayOfFiles.push(filePath);
|
||||
}
|
||||
});
|
||||
|
||||
return arrayOfFiles;
|
||||
}
|
||||
|
||||
return shell.exec(`find ${TEST_DIR}/integration -name "${pattern}"`, {silent: true}).stdout.
|
||||
split('\n').
|
||||
filter((matched) => Boolean(matched)).
|
||||
map((fileOrDir) => {
|
||||
if (fs.statSync(`./${fileOrDir}`).isDirectory(fileOrDir)) {
|
||||
return diveOnFiles(`./${fileOrDir}`);
|
||||
}
|
||||
return fileOrDir;
|
||||
}).
|
||||
flat().
|
||||
filter((file) => file.includes('spec.js') || file.includes('spec.ts')).
|
||||
map((file) => file.replace('./', ''));
|
||||
};
|
||||
|
||||
function getBaseTestFiles() {
|
||||
const {invert, group, stage} = argv;
|
||||
|
||||
const allFiles = grepFiles(grepCommand());
|
||||
const stageFiles = getFilesByMetadata(stage);
|
||||
const groupFiles = getFilesByMetadata(group);
|
||||
|
||||
if (invert) {
|
||||
// Return no test file if no stage and withGroup, but inverted
|
||||
if (!stage && !group) {
|
||||
return [];
|
||||
}
|
||||
|
||||
// Return all excluding stage files
|
||||
if (stage && !group) {
|
||||
return without(allFiles, ...stageFiles);
|
||||
}
|
||||
|
||||
// Return all excluding group files
|
||||
if (!stage && group) {
|
||||
return without(allFiles, ...groupFiles);
|
||||
}
|
||||
|
||||
// Return all excluding group and stage files
|
||||
return without(allFiles, ...intersection(stageFiles, groupFiles));
|
||||
}
|
||||
|
||||
// Return all files if no stage and group flags
|
||||
if (!stage && !group) {
|
||||
return allFiles;
|
||||
}
|
||||
|
||||
// Return stage files if no group flag
|
||||
if (stage && !group) {
|
||||
return stageFiles;
|
||||
}
|
||||
|
||||
// Return group files if no stage flag
|
||||
if (!stage && group) {
|
||||
return groupFiles;
|
||||
}
|
||||
|
||||
// Return files if both in stage and group
|
||||
return intersection(stageFiles, groupFiles);
|
||||
}
|
||||
|
||||
function getWeightedFiles(metadata, sortFirst = true) {
|
||||
let weightedFiles = [];
|
||||
if (metadata) {
|
||||
metadata.split(',').forEach((word, i, arr) => {
|
||||
const files = getFilesByMetadata(word).map((file) => {
|
||||
return {
|
||||
file,
|
||||
sortWeight: sortFirst ? (i - arr.length) : (i + 1),
|
||||
};
|
||||
});
|
||||
weightedFiles.push(...files);
|
||||
});
|
||||
}
|
||||
|
||||
if (sortFirst) {
|
||||
weightedFiles = weightedFiles.reverse();
|
||||
}
|
||||
|
||||
return weightedFiles.reduce((acc, f) => {
|
||||
acc[f.file] = f;
|
||||
return acc;
|
||||
}, {});
|
||||
}
|
||||
|
||||
function reorderFiles(files = {}, filesToReorder = {}) {
|
||||
const testFilesObject = Object.assign({}, files);
|
||||
|
||||
const validFiles = intersection(Object.keys(testFilesObject), Object.keys(filesToReorder));
|
||||
Object.entries(filesToReorder).forEach(([k, v]) => {
|
||||
if (validFiles.includes(k)) {
|
||||
testFilesObject[k] = v;
|
||||
}
|
||||
});
|
||||
|
||||
return testFilesObject;
|
||||
}
|
||||
|
||||
function removeFromFiles(files = {}, filesToRemove = []) {
|
||||
const testFilesObject = Object.assign({}, files);
|
||||
|
||||
const removedFiles = intersection(Object.keys(testFilesObject), filesToRemove);
|
||||
removedFiles.forEach((file) => {
|
||||
if (Object.hasOwn(testFilesObject, file)) {
|
||||
delete testFilesObject[file];
|
||||
}
|
||||
});
|
||||
|
||||
return {testFilesObject, removedFiles};
|
||||
}
|
||||
|
||||
function getSortedTestFiles(platform, browser, headless) {
|
||||
// Get test files based on stage, group and/or invert
|
||||
const baseTestFiles = getBaseTestFiles();
|
||||
|
||||
// Add files matched by spec metadata
|
||||
const includeFilesByGroup = getFilesByMetadata(argv.includeGroup);
|
||||
if (includeFilesByGroup.length) {
|
||||
printMessage(includeFilesByGroup, `\nIncluded test files due to --include-group="${argv.includeGroup}"`);
|
||||
}
|
||||
|
||||
// Add files matched by filename
|
||||
const includeFilesByFilename = argv.includeFile.split(',').
|
||||
map((pattern) => findFiles(pattern)).
|
||||
reduce((acc, files) => acc.concat(files), []);
|
||||
if (includeFilesByFilename.length) {
|
||||
printMessage(includeFilesByFilename, `\nIncluded test files due to --include-file="${argv.includeFile}"`);
|
||||
}
|
||||
|
||||
let testFilesObject = baseTestFiles.
|
||||
concat(includeFilesByGroup).
|
||||
concat(includeFilesByFilename).
|
||||
reduce((acc, file) => {
|
||||
acc[file] = {file, sortWeight: 0};
|
||||
return acc;
|
||||
}, {});
|
||||
|
||||
// Remove skipped files due to test environment
|
||||
let removedFiles;
|
||||
const skippedFiles = getSkippedFiles(platform, browser, headless);
|
||||
({testFilesObject, removedFiles} = removeFromFiles(testFilesObject, skippedFiles));
|
||||
printMessage(removedFiles, `\nSkipped test files due to ${platform}/${browser} (${headless ? 'headless' : 'headed'})`);
|
||||
|
||||
// Remove files matched by spec metadata
|
||||
const excludeFilesByGroup = getFilesByMetadata(argv.excludeGroup);
|
||||
({testFilesObject, removedFiles} = removeFromFiles(testFilesObject, excludeFilesByGroup));
|
||||
if (excludeFilesByGroup.length) {
|
||||
printMessage(removedFiles, `\nExcluded test files due to --exclude-group="${argv.excludeGroup}"`);
|
||||
}
|
||||
|
||||
// Remove files matched by filename
|
||||
const excludeFilesByFilename = argv.excludeFile.split(',').
|
||||
map((pattern) => findFiles(pattern)).
|
||||
reduce((acc, files) => acc.concat(files), []);
|
||||
|
||||
({testFilesObject, removedFiles} = removeFromFiles(testFilesObject, excludeFilesByFilename));
|
||||
if (excludeFilesByFilename.length) {
|
||||
printMessage(removedFiles, `\nExcluded test files due to --exclude-file="${argv.excludeFile}"`);
|
||||
}
|
||||
|
||||
// Get files to be sorted first
|
||||
const firstFilesObject = getWeightedFiles(argv.sortFirst, true);
|
||||
testFilesObject = reorderFiles(testFilesObject, firstFilesObject);
|
||||
|
||||
// Get files to be sorted last
|
||||
const lastFilesObject = getWeightedFiles(argv.sortLast, false);
|
||||
testFilesObject = reorderFiles(testFilesObject, lastFilesObject);
|
||||
|
||||
const sortedFiles = Object.values(testFilesObject).
|
||||
sort((a, b) => {
|
||||
if (a.sortWeight > b.sortWeight) {
|
||||
return 1;
|
||||
} else if (a.sortWeight < b.sortWeight) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return a.file.localeCompare(b.file);
|
||||
}).
|
||||
map((sortedObj) => sortedObj.file);
|
||||
|
||||
return {sortedFiles, skippedFiles, weightedTestFiles: Object.values(testFilesObject)};
|
||||
}
|
||||
|
||||
function getFilesByMetadata(metadata) {
|
||||
if (!metadata) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const egc = grepCommand(metadata.split(',').join('\\|'));
|
||||
return grepFiles(egc);
|
||||
}
|
||||
|
||||
function printMessage(files = [], message) {
|
||||
console.log(chalk.cyan(`\n${message}:`));
|
||||
|
||||
files.forEach((file, index) => {
|
||||
console.log(chalk.cyan(`- [${index + 1}] ${file}`));
|
||||
});
|
||||
}
|
||||
|
||||
function getSkippedFiles(platform, browser, headless) {
|
||||
const platformFiles = getFilesByMetadata(`@${platform}`);
|
||||
const browserFiles = getFilesByMetadata(`@${browser}`);
|
||||
const headlessFiles = getFilesByMetadata(`@${headless ? 'headless' : 'headed'}`);
|
||||
|
||||
return platformFiles.concat(browserFiles, headlessFiles);
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
getSortedTestFiles,
|
||||
};
|
||||
Reference in New Issue
Block a user