mirror of
https://github.com/mattermost/mattermost-mobile.git
synced 2026-11-05 18:38:54 +00:00
fix(e2e): stabilize Detox and Maestro test suite Restore main features, and harden the E2E harness against flaky UI, network, retry, synchronization, and classification-lock failures. Stabilize channel creation, saved messages, bookmarks, search, deep links, keyboard dismissal, and post verification. Bound network, transport, health-check, synchronization, and lock retries by elapsed time. Fix iOS and Android Maestro/Detox races and flaky interaction flows. Restore Session Attributes and deep-link fixes lost during merge. Improve test isolation, global-setting cleanup, and Jest/TSIO reporting. Enforce Maestro flow-header validation in local and CI checks.
57 lines
2.3 KiB
JavaScript
57 lines
2.3 KiB
JavaScript
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
|
// See LICENSE.txt for license information.
|
|
|
|
// CI util unit tests: run with `node --test detox/utils/xml_escape.test.js`.
|
|
// Exercises xml_escape() from maestro/scripts/run_ci_batches.sh (Bash 3.2 + 5.x safe).
|
|
|
|
const assert = require('node:assert/strict');
|
|
const {execFileSync} = require('node:child_process');
|
|
const fs = require('node:fs');
|
|
const path = require('node:path');
|
|
const {describe, it} = require('node:test');
|
|
|
|
const SCRIPT_PATH = path.join(__dirname, '../maestro/scripts/run_ci_batches.sh');
|
|
|
|
function extractXmlEscapeFn() {
|
|
const script = fs.readFileSync(SCRIPT_PATH, 'utf8');
|
|
const match = script.match(/xml_escape\(\) \{[\s\S]*?\n\s*\}/);
|
|
assert.ok(match, 'xml_escape() function must exist in run_ci_batches.sh');
|
|
return match[0];
|
|
}
|
|
|
|
function xmlEscape(input) {
|
|
const fn = extractXmlEscapeFn();
|
|
return execFileSync(
|
|
'bash',
|
|
['-c', `${fn}\nprintf '%s' "$(xml_escape "$1")"`, 'xml_escape', input],
|
|
{encoding: 'utf8'},
|
|
);
|
|
}
|
|
|
|
describe('run_ci_batches.sh xml_escape', () => {
|
|
it('should escape < > & " in an order that keeps amp first', () => {
|
|
assert.equal(xmlEscape('<flow>&"'), '<flow>&"');
|
|
assert.equal(xmlEscape('a&b'), 'a&b');
|
|
assert.equal(xmlEscape('x<y>z'), 'x<y>z');
|
|
assert.equal(xmlEscape('say "hi"'), 'say "hi"');
|
|
});
|
|
|
|
it('should produce attribute-safe values for synthetic JUnit XML', () => {
|
|
const label = 'flows/channels/<bookmark>&"link".yml';
|
|
const escaped = xmlEscape(label);
|
|
const xml = `<?xml version='1.0' encoding='UTF-8'?>
|
|
<testsuites>
|
|
<testsuite name="${escaped}" tests="1" failures="1" errors="0" skipped="0" time="0">
|
|
<testcase id="id" name="id" classname="${escaped}" file="${escaped}" time="0" status="ERROR">
|
|
<failure>batch failed (${escaped})</failure>
|
|
</testcase>
|
|
</testsuite>
|
|
</testsuites>
|
|
`;
|
|
assert.equal(escaped, 'flows/channels/<bookmark>&"link".yml');
|
|
assert.doesNotMatch(escaped, /[<>"]/);
|
|
assert.match(xml, /name="flows\/channels\/<bookmark>&"link"\.yml"/);
|
|
assert.ok(!xml.includes('name="<'), 'unescaped < must not appear in attributes');
|
|
});
|
|
});
|