Skip to content

Commit

Permalink
Run DevTools e2e tests on Circle CI
Browse files Browse the repository at this point in the history
  • Loading branch information
Brian Vaughn committed Dec 22, 2021
1 parent bcd24a6 commit a2e1035
Show file tree
Hide file tree
Showing 2 changed files with 185 additions and 0 deletions.
20 changes: 20 additions & 0 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,23 @@ jobs:
- store_artifacts:
path: ./build/devtools.tgz

run_devtools_e2e_tests:
docker: *docker
environment: *environment
steps:
- checkout
- attach_workspace:
at: .
- run: yarn workspaces info | head -n -1 > workspace_info.txt
- *restore_node_modules
- run:
name: Install Packages
command: yarn --frozen-lockfile --cache-folder ~/.cache/yarn
- run:
environment:
RELEASE_CHANNEL: experimental
command: ./scripts/circleci/run_devtools_e2e_tests.js

yarn_lint_build:
docker: *docker
environment: *environment
Expand Down Expand Up @@ -452,6 +469,9 @@ workflows:
- build_devtools_and_process_artifacts:
requires:
- yarn_build_combined
- run_devtools_e2e_tests:
requires:
- build_devtools_and_process_artifacts

fuzz_tests:
unless: << pipeline.parameters.prerelease_commit_sha >>
Expand Down
165 changes: 165 additions & 0 deletions scripts/circleci/run_devtools_e2e_tests.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
#!/usr/bin/env node

'use strict';

const {spawn} = require('child_process');
const {join} = require('path');

const ROOT_PATH = join(__dirname, '..', '..');

const inlinePackagePath = join(ROOT_PATH, 'packages', 'react-devtools-inline');
const shellPackagePath = join(ROOT_PATH, 'packages', 'react-devtools-shell');

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);
}, 30000);

logBright('Starting testing shell server');

serverProcess = spawn('yarn', ['start'], {cwd: shellPackagePath});
serverProcess.stdout.on('data', data => {
if (`${data}`.includes('Compiled successfully.')) {
logBright('Testing shell server running');

clearTimeout(timeoutID);

runEndToEndTests();
}
});
serverProcess.stderr.on('data', data => {
if (`${data}`.includes('EADDRINUSE')) {
// Something is occuprying 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');

testProcess = spawn('yarn', ['test:e2e'], {cwd: inlinePackagePath});
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();

0 comments on commit a2e1035

Please sign in to comment.