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:
273
e2e-tests/cypress/run_test_cycle.js
Normal file
273
e2e-tests/cypress/run_test_cycle.js
Normal file
@@ -0,0 +1,273 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
/* eslint-disable no-console */
|
||||
|
||||
/*
|
||||
* This command, which is normally used in CI, runs Cypress test in full or partial
|
||||
* depending on test metadata and environment capabilities.
|
||||
* Spec file to run is dependent from Test Automation Dashboard and each test result is being
|
||||
* recorded on a per spec file basis.
|
||||
*
|
||||
* Usage: [ENVIRONMENT] node run_test_cycle.js
|
||||
*
|
||||
* Environment:
|
||||
* AUTOMATION_DASHBOARD_URL : Dashboard URL
|
||||
* AUTOMATION_DASHBOARD_TOKEN : Dashboard token
|
||||
* REPO : Project repository, ex. mattermost-webapp
|
||||
* BRANCH : Branch identifier from CI
|
||||
* BUILD_ID : Build identifier from CI
|
||||
* CI_BASE_URL : Test server base URL in CI
|
||||
*
|
||||
* Example:
|
||||
* 1. "node run_test_cycle.js"
|
||||
* - will run all the specs available from the Automation dashboard
|
||||
*/
|
||||
|
||||
const chalk = require('chalk').default;
|
||||
const cypress = require('cypress');
|
||||
|
||||
const {
|
||||
getSpecToTest,
|
||||
recordSpecResult,
|
||||
updateCycle,
|
||||
uploadScreenshot,
|
||||
} = require('./utils/dashboard');
|
||||
const {writeJsonToFile} = require('./utils/report');
|
||||
const {MOCHAWESOME_REPORT_DIR, RESULTS_DIR} = require('./utils/constants');
|
||||
|
||||
require('dotenv').config();
|
||||
|
||||
const {
|
||||
BRANCH,
|
||||
BROWSER,
|
||||
BUILD_ID,
|
||||
CI_BASE_URL,
|
||||
HEADLESS,
|
||||
REPO,
|
||||
} = process.env;
|
||||
|
||||
async function runCypressTest(specExecution) {
|
||||
const browser = BROWSER || 'chrome';
|
||||
const headless = isHeadless();
|
||||
|
||||
const result = await cypress.run({
|
||||
browser,
|
||||
headless,
|
||||
spec: specExecution.file,
|
||||
config: {
|
||||
screenshotsFolder: `${MOCHAWESOME_REPORT_DIR}/screenshots`,
|
||||
videosFolder: `${MOCHAWESOME_REPORT_DIR}/videos`,
|
||||
trashAssetsBeforeRuns: false,
|
||||
},
|
||||
reporter: 'cypress-multi-reporters',
|
||||
reporterOptions: {
|
||||
reporterEnabled: 'mocha-junit-reporter, mochawesome',
|
||||
mochaJunitReporterReporterOptions: {
|
||||
mochaFile: 'results/junit/test_results[hash].xml',
|
||||
toConsole: false,
|
||||
},
|
||||
mochawesomeReporterOptions: {
|
||||
reportDir: MOCHAWESOME_REPORT_DIR,
|
||||
reportFilename: `json/${specExecution.file}`,
|
||||
quiet: true,
|
||||
overwrite: false,
|
||||
html: false,
|
||||
json: true,
|
||||
testMeta: {
|
||||
browser,
|
||||
headless,
|
||||
branch: BRANCH,
|
||||
buildId: BUILD_ID,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
async function saveResult(specExecution, result, testIndex) {
|
||||
// Write and update test environment details once
|
||||
if (testIndex === 0) {
|
||||
const environment = {
|
||||
cypress_version: result.cypressVersion,
|
||||
browser_name: result.browserName,
|
||||
browser_version: result.browserVersion,
|
||||
headless: isHeadless(),
|
||||
os_name: result.osName,
|
||||
os_version: result.osVersion,
|
||||
node_version: process.version,
|
||||
};
|
||||
|
||||
writeJsonToFile(environment, 'environment.json', RESULTS_DIR);
|
||||
await updateCycle(specExecution.cycle_id, environment);
|
||||
}
|
||||
|
||||
const {stats, tests, spec} = result.runs[0];
|
||||
|
||||
const specPatch = {
|
||||
file: spec.relative,
|
||||
tests: spec.tests,
|
||||
pass: stats.passes,
|
||||
fail: stats.failures,
|
||||
pending: stats.pending,
|
||||
skipped: stats.skipped,
|
||||
duration: stats.duration || 0,
|
||||
test_start_at: stats.startedAt,
|
||||
test_end_at: stats.endedAt,
|
||||
};
|
||||
|
||||
const testCases = [];
|
||||
for (let i = 0; i < tests.length; i++) {
|
||||
const test = tests[i];
|
||||
const attempts = test.attempts.pop();
|
||||
|
||||
const testCase = {
|
||||
title: test.title,
|
||||
full_title: test.title.join(' '),
|
||||
state: attempts.state,
|
||||
duration: attempts.duration || 0,
|
||||
code: trimToMaxLength(test.body),
|
||||
};
|
||||
|
||||
if (attempts.startedAt) {
|
||||
testCase.test_start_at = attempts.startedAt;
|
||||
}
|
||||
|
||||
if (test.displayError) {
|
||||
testCase.error_display = trimToMaxLength(test.displayError);
|
||||
}
|
||||
|
||||
const errorFrame = attempts.error && attempts.error.codeFrame && attempts.error.codeFrame.frame;
|
||||
if (errorFrame) {
|
||||
testCase.error_frame = trimToMaxLength(errorFrame);
|
||||
}
|
||||
|
||||
if (attempts.screenshots && attempts.screenshots.length > 0) {
|
||||
const path = attempts.screenshots[0].path;
|
||||
const screenshotUrl = await uploadScreenshot(path, REPO, BRANCH, BUILD_ID);
|
||||
if (typeof screenshotUrl === 'string' && !screenshotUrl.error) {
|
||||
testCase.screenshot = {url: screenshotUrl};
|
||||
}
|
||||
}
|
||||
|
||||
testCases.push(testCase);
|
||||
}
|
||||
|
||||
await recordSpecResult(specExecution.id, specPatch, testCases);
|
||||
}
|
||||
|
||||
function isHeadless() {
|
||||
return typeof HEADLESS === 'undefined' ? true : HEADLESS === 'true';
|
||||
}
|
||||
|
||||
function trimToMaxLength(text) {
|
||||
const maxLength = 5000;
|
||||
return text && text.length > maxLength ? text.substring(0, maxLength) : text;
|
||||
}
|
||||
|
||||
function printSummary(summary) {
|
||||
const obj = summary.reduce((acc, item) => {
|
||||
const {server, state, count} = item;
|
||||
if (!server) {
|
||||
return acc;
|
||||
}
|
||||
|
||||
if (acc[server]) {
|
||||
acc[server][state] = count;
|
||||
} else {
|
||||
acc[server] = {[state]: count, server};
|
||||
}
|
||||
|
||||
return acc;
|
||||
}, {});
|
||||
|
||||
Object.values(obj).sort((a, b) => {
|
||||
return a.server.localeCompare(b.server);
|
||||
}).forEach((item) => {
|
||||
const {server, done, started} = item;
|
||||
console.log(chalk.magenta(`${server}: done: ${done || 0}, started: ${started || 0}`));
|
||||
});
|
||||
}
|
||||
|
||||
const maxRetryCount = 5;
|
||||
async function runSpecFragment(count, retry) {
|
||||
console.log(chalk.magenta(`Preparing for: ${count + 1}`));
|
||||
|
||||
const spec = await getSpecToTest({
|
||||
repo: REPO,
|
||||
branch: BRANCH,
|
||||
build: BUILD_ID,
|
||||
server: CI_BASE_URL,
|
||||
});
|
||||
|
||||
// Retry on connection/timeout errors
|
||||
if (!spec || spec.code) {
|
||||
if (retry >= maxRetryCount) {
|
||||
return {
|
||||
tryNext: false,
|
||||
count,
|
||||
message: `Test ended due to multiple (${retry}) connection/timeout errors with the dashboard server.`,
|
||||
};
|
||||
}
|
||||
|
||||
console.log(chalk.red(`Retry count: ${retry}`));
|
||||
return runSpecFragment(count, retry + 1);
|
||||
}
|
||||
|
||||
if (!spec.execution || !spec.execution.file) {
|
||||
return {
|
||||
tryNext: false,
|
||||
count,
|
||||
message: spec.message,
|
||||
};
|
||||
}
|
||||
|
||||
const currentTestCount = spec.summary.reduce((total, item) => {
|
||||
return total + parseInt(item.count, 10);
|
||||
}, 0);
|
||||
|
||||
printSummary(spec.summary);
|
||||
console.log(chalk.magenta(`\n(Testing ${currentTestCount} of ${spec.cycle.specs_registered}) - ${spec.execution.file}`));
|
||||
console.log(chalk.magenta(`At "${process.env.CI_BASE_URL}" server`));
|
||||
|
||||
const result = await runCypressTest(spec.execution);
|
||||
await saveResult(spec.execution, result, count);
|
||||
|
||||
const newCount = count + 1;
|
||||
|
||||
if (spec.cycle.specs_registered === currentTestCount) {
|
||||
return {
|
||||
tryNext: false,
|
||||
count: newCount,
|
||||
message: `Completed testing of all registered ${currentTestCount} spec/s.`,
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
tryNext: true,
|
||||
count: newCount,
|
||||
retry: 0,
|
||||
message: 'Continue testing',
|
||||
};
|
||||
}
|
||||
|
||||
async function runSpec(count = 0, retry = 0) {
|
||||
const fragment = await runSpecFragment(count, retry);
|
||||
if (fragment.tryNext) {
|
||||
return runSpec(fragment.count, fragment.retry);
|
||||
}
|
||||
|
||||
return {
|
||||
count: fragment.count,
|
||||
message: fragment.message,
|
||||
};
|
||||
}
|
||||
|
||||
runSpec().then(({count, message}) => {
|
||||
console.log(chalk.magenta(message));
|
||||
if (count > 0) {
|
||||
console.log(chalk.magenta(`This test runner has completed ${count} spec file/s.`));
|
||||
}
|
||||
});
|
||||
Reference in New Issue
Block a user