mirror of
https://github.com/zebrajr/react.git
synced 2026-01-15 12:15:22 +00:00
Suppose that you have this setup for devtools test: ``` // @reactVersion <= 18.1 // @reactVersion >= 17.1 ``` With previous implementation, the accumulated condition will be `"<= 18.1" && ">= 17.1"`, which is just `">= 17.1"`, when evaluated. That's why we executed some tests for old versions of react on main (and failed). With these changes the resulting condition will be `"<= 18.1 >= 17.1"`, not using `&&`, because semver does not support this operator. All currently failing tests will be skipped now as expected. Also increased timeout value for shell server to start
190 lines
4.5 KiB
JavaScript
Executable File
190 lines
4.5 KiB
JavaScript
Executable File
#!/usr/bin/env node
|
|
|
|
'use strict';
|
|
|
|
const {spawn} = require('child_process');
|
|
const {join} = require('path');
|
|
|
|
const ROOT_PATH = join(__dirname, '..', '..');
|
|
const reactVersion = process.argv[2];
|
|
const inlinePackagePath = join(ROOT_PATH, 'packages', 'react-devtools-inline');
|
|
const shellPackagePath = join(ROOT_PATH, 'packages', 'react-devtools-shell');
|
|
const screenshotPath = join(ROOT_PATH, 'tmp', 'screenshots');
|
|
|
|
const {SUCCESSFUL_COMPILATION_MESSAGE} = require(join(
|
|
shellPackagePath,
|
|
'constants.js'
|
|
));
|
|
|
|
let buildProcess = null;
|
|
let serverProcess = null;
|
|
let testProcess = null;
|
|
|
|
function format(loggable) {
|
|
return `${loggable}`
|
|
.split('\n')
|
|
.filter(line => {
|
|
return line.trim() !== '';
|
|
})
|
|
.map(line => ` ${line}`)
|
|
.join('\n');
|
|
}
|
|
|
|
function logBright(loggable) {
|
|
console.log(`\x1b[1m${loggable}\x1b[0m`);
|
|
}
|
|
|
|
function logDim(loggable) {
|
|
const formatted = format(loggable, 2);
|
|
if (formatted !== '') {
|
|
console.log(`\x1b[2m${formatted}\x1b[0m`);
|
|
}
|
|
}
|
|
|
|
function logError(loggable) {
|
|
const formatted = format(loggable, 2);
|
|
if (formatted !== '') {
|
|
console.error(`\x1b[31m${formatted}\x1b[0m`);
|
|
}
|
|
}
|
|
|
|
function buildInlinePackage() {
|
|
logBright('Building inline packages');
|
|
|
|
buildProcess = spawn('yarn', ['build'], {cwd: inlinePackagePath});
|
|
buildProcess.stdout.on('data', data => {
|
|
logDim(data);
|
|
});
|
|
buildProcess.stderr.on('data', data => {
|
|
if (`${data}`.includes('Warning')) {
|
|
logDim(data);
|
|
} else {
|
|
logError(`Error:\n${data}`);
|
|
|
|
exitWithCode(1);
|
|
}
|
|
});
|
|
buildProcess.on('close', code => {
|
|
logBright('Inline package built');
|
|
|
|
runTestShell();
|
|
});
|
|
}
|
|
|
|
function runTestShell() {
|
|
const timeoutID = setTimeout(() => {
|
|
// Assume the test shell server failed to start.
|
|
logError('Testing shell server failed to start');
|
|
exitWithCode(1);
|
|
}, 60 * 1000);
|
|
|
|
logBright('Starting testing shell server');
|
|
|
|
if (!reactVersion) {
|
|
serverProcess = spawn('yarn', ['start'], {cwd: shellPackagePath});
|
|
} else {
|
|
serverProcess = spawn('yarn', ['start'], {
|
|
cwd: shellPackagePath,
|
|
env: {...process.env, REACT_VERSION: reactVersion},
|
|
});
|
|
}
|
|
|
|
serverProcess.stdout.on('data', data => {
|
|
if (`${data}`.includes(SUCCESSFUL_COMPILATION_MESSAGE)) {
|
|
logBright('Testing shell server running');
|
|
|
|
clearTimeout(timeoutID);
|
|
|
|
runEndToEndTests();
|
|
}
|
|
});
|
|
|
|
serverProcess.stderr.on('data', data => {
|
|
if (`${data}`.includes('EADDRINUSE')) {
|
|
// Something is occupying this port;
|
|
// We could kill the process and restart but probably better to prompt the user to do this.
|
|
|
|
logError('Free up the port and re-run tests:');
|
|
logBright(' kill -9 $(lsof -ti:8080)');
|
|
|
|
exitWithCode(1);
|
|
} else if (`${data}`.includes('ERROR')) {
|
|
logError(`Error:\n${data}`);
|
|
|
|
exitWithCode(1);
|
|
} else {
|
|
// Non-fatal stuff like Babel optimization warnings etc.
|
|
logDim(data);
|
|
}
|
|
});
|
|
}
|
|
|
|
async function runEndToEndTests() {
|
|
logBright('Running e2e tests');
|
|
if (!reactVersion) {
|
|
testProcess = spawn('yarn', ['test:e2e', `--output=${screenshotPath}`], {
|
|
cwd: inlinePackagePath,
|
|
});
|
|
} else {
|
|
testProcess = spawn('yarn', ['test:e2e', `--output=${screenshotPath}`], {
|
|
cwd: inlinePackagePath,
|
|
env: {...process.env, REACT_VERSION: reactVersion},
|
|
});
|
|
}
|
|
|
|
testProcess.stdout.on('data', data => {
|
|
// Log without formatting because Playwright applies its own formatting.
|
|
const formatted = format(data);
|
|
if (formatted !== '') {
|
|
console.log(formatted);
|
|
}
|
|
});
|
|
testProcess.stderr.on('data', data => {
|
|
// Log without formatting because Playwright applies its own formatting.
|
|
const formatted = format(data);
|
|
if (formatted !== '') {
|
|
console.error(formatted);
|
|
}
|
|
|
|
exitWithCode(1);
|
|
});
|
|
testProcess.on('close', code => {
|
|
logBright(`Tests completed with code: ${code}`);
|
|
|
|
exitWithCode(code);
|
|
});
|
|
}
|
|
|
|
function exitWithCode(code) {
|
|
if (buildProcess !== null) {
|
|
try {
|
|
logBright('Shutting down build process');
|
|
buildProcess.kill();
|
|
} catch (error) {
|
|
logError(error);
|
|
}
|
|
}
|
|
|
|
if (serverProcess !== null) {
|
|
try {
|
|
logBright('Shutting down shell server process');
|
|
serverProcess.kill();
|
|
} catch (error) {
|
|
logError(error);
|
|
}
|
|
}
|
|
|
|
if (testProcess !== null) {
|
|
try {
|
|
logBright('Shutting down test process');
|
|
testProcess.kill();
|
|
} catch (error) {
|
|
logError(error);
|
|
}
|
|
}
|
|
|
|
process.exit(code);
|
|
}
|
|
|
|
buildInlinePackage();
|