mirror of
https://github.com/mattermost/mattermost-mobile.git
synced 2026-11-13 14:40:25 +00:00
* ci(e2e): triage red Detox and Maestro runs against test history When a Detox or Maestro lane is red, the toolkit's e2e-triage action checks each failure against TSIO history (flaky or broken on main, the same failure on other PRs, environment errors, or caused by this PR) and adds its verdict to the lane's status and the job summary. Report-only unless E2E_TRIAGE_MODE is enforce. - .github/actions/e2e-triage: the per-lane triage steps (evidence download, answers cache, toolkit e2e-triage) as one composite, checked out from the dispatch ref so the branch under test never runs with the API key. - Each lane uploads what it saw at a failure (screenshots, the step it stopped at, the server's answer) as triage evidence. - The TSIO status links name the run only when both the run id and the attempt are known, so triage writes only on statuses its run owns. Toolkit pinned to bdce26e. * ci(e2e): pin the toolkit to 24bf208; use the renamed e2e-test-* actions The toolkit renamed e2e-triage to e2e-test-triage and e2e-status to e2e-test-status; inputs are unchanged. Triage now holds a failure repeated on this PR's last commits and never on the base branch as out of date (merge the base branch and re-run) instead of clearing it, and the status line names each kind: flaky, broken on main, caused by PR, out of date, needs investigation. * ci(e2e): pin the toolkit to main (419b0a9) Toolkit #5 merged; this pins its merge on main instead of the PR branch. * ci(e2e): pin the toolkit to main (b3ca677) Toolkit #6 merged: a run flagged as a whole now says why once instead of repeating "investigation required". * ci(e2e): pin the toolkit to e2e-triage-judge-flagged-runs (f1f5d54, toolkit#8) * ci(e2e): pin the toolkit to e2e-triage-judge-flagged-runs (77c3048, toolkit#8) * ci(e2e): use the toolkit's main while triage is observed toolkit#8 merged (b7757e9). Following review, consumers track main so toolkit changes need no bump here; pin a hash again once stable. --------- Co-authored-by: Mattermost Build <build@mattermost.com>
60 lines
2.1 KiB
JavaScript
60 lines
2.1 KiB
JavaScript
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
|
// See LICENSE.txt for license information.
|
|
/* eslint-disable no-console -- CI evidence capture */
|
|
|
|
const {execFileSync} = require('child_process');
|
|
const fs = require('fs');
|
|
const path = require('path');
|
|
|
|
const {sanitize} = require('./path_builder');
|
|
|
|
const TIMEOUT_RE = /Exceeded timeout of \d+ ms for a test/;
|
|
|
|
// Under artifacts/ so the iOS results upload and TSIO pick it up; the folder
|
|
// is named like Detox's own so TSIO links the screenshot to the test.
|
|
const EVIDENCE_DIR = path.join('artifacts', 'triage-evidence');
|
|
|
|
/** Jest's fullName: describe titles and the test title, space-separated. */
|
|
function fullName(test) {
|
|
const names = [];
|
|
for (let block = test.parent; block && block.parent; block = block.parent) {
|
|
names.unshift(block.name);
|
|
}
|
|
return [...names, test.name].join(' ');
|
|
}
|
|
|
|
/**
|
|
* Screenshots the iOS simulator when a test hits the Jest timeout. Detox's own
|
|
* failure screenshot is discarded on a timeout ("cannot save an already
|
|
* discarded artifact"), so the E2E triage judge saw only "Exceeded timeout"
|
|
* and nothing of where the app was stuck. simctl reads the simulator's screen
|
|
* directly, so it works while the app is still busy.
|
|
*/
|
|
class TimeoutEvidenceListener {
|
|
constructor({env}) {
|
|
this._env = env;
|
|
}
|
|
|
|
test_fn_failure({error, test}) {
|
|
if (process.env.IOS !== 'true' || !TIMEOUT_RE.test(String(error?.message ?? error))) {
|
|
return;
|
|
}
|
|
const udid = this._env.global.device?.id;
|
|
if (!udid) {
|
|
return;
|
|
}
|
|
const name = fullName(test);
|
|
const dir = path.join(EVIDENCE_DIR, sanitize(name));
|
|
try {
|
|
fs.mkdirSync(dir, {recursive: true});
|
|
execFileSync('xcrun', ['simctl', 'io', udid, 'screenshot', '--type=png', path.join(dir, 'timeout.png')], {stdio: 'ignore', timeout: 30000});
|
|
} catch (e) {
|
|
console.warn(`[timeout-evidence] could not screenshot "${name}": ${e.message}`);
|
|
}
|
|
}
|
|
}
|
|
|
|
module.exports = TimeoutEvidenceListener;
|
|
module.exports.fullName = fullName;
|
|
module.exports.EVIDENCE_DIR = EVIDENCE_DIR;
|