Created
September 19, 2021 15:18
Patch for Cavy (E2E test framework for React Native) that fixes the bug when CavyTests crashed the app, but CI (Appcenter) would keep hanging
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/node_modules/cavy-cli/cavy.js b/node_modules/cavy-cli/cavy.js | |
index ad2c7e2..8dcc2f1 100755 | |
--- a/node_modules/cavy-cli/cavy.js | |
+++ b/node_modules/cavy-cli/cavy.js | |
@@ -34,7 +34,9 @@ function test(cmd) { | |
const outputAsXml = cmd.xml; | |
const dev = cmd.dev; | |
const bootTimeout = cmd.bootTimeout; | |
- runTests(commandName, entryFile, skipbuild, dev, outputAsXml, bootTimeout, args); | |
+ const allTestRunTimeout = cmd.allTestRunTimeout; | |
+ | |
+ runTests(commandName, entryFile, skipbuild, dev, outputAsXml, bootTimeout, allTestRunTimeout, args); | |
} | |
// Stop quitting unless we want to | |
@@ -63,6 +65,11 @@ program | |
'Set how long the CLI should wait for the RN app to boot ' | |
+ '(is ignored if used with --skipbuild, defaults to 2 minutes, requires Cavy 4.0.0)' | |
) | |
+ .option( | |
+ '-t, --allTestRunTimeout <minutes>', | |
+ 'Set how long the CLI should wait for the RN app for finishing tests ' | |
+ + '(defaults to 2 minutes, requires Cavy 4.0.0)' | |
+ ) | |
.option('--xml', 'Write out test results to cavy_results.xml (requires Cavy 3.3.0)') | |
.allowUnknownOption() | |
.action(cmd => test(cmd)); | |
@@ -81,6 +88,12 @@ program | |
'Set how long the CLI should wait for the RN app to boot ' | |
+ '(is ignored if used with --skipbuild, defaults to 2 minutes, requires Cavy 4.0.0)' | |
) | |
+ .option( | |
+ '-t, --allTestRunTimeout <minutes>', | |
+ 'Set how long the CLI should wait for the RN app for finishing tests ' | |
+ + '(defaults to 2 minutes, requires Cavy 4.0.0)' | |
+ ) | |
+ | |
.option('--xml', 'Write out test results to cavy_results.xml (requires Cavy 3.3.0)') | |
.allowUnknownOption() | |
.action(cmd => test(cmd)); | |
diff --git a/node_modules/cavy-cli/server.js b/node_modules/cavy-cli/server.js | |
index 64faf22..5ad60e8 100644 | |
--- a/node_modules/cavy-cli/server.js | |
+++ b/node_modules/cavy-cli/server.js | |
@@ -9,7 +9,8 @@ const server = http.createServer(); | |
// Setup local variables for server | |
server.locals = { | |
appBooted: false, | |
- testCount: 0 | |
+ testCount: 0, | |
+ testFinished: false | |
}; | |
// Initialize a WebSocket Server instance | |
@@ -27,16 +28,27 @@ wss.on('connection', socket => { | |
case 'singleResult': | |
logTestResult(json.data); | |
break; | |
- case 'testingComplete': | |
+ case 'testingComplete':{ | |
+ server.locals.testFinished = true; | |
finishTesting(json.data); | |
break; | |
+ } | |
+ default: { | |
+ console.log(json.event); | |
+ } | |
} | |
}); | |
+ // socket.onerror = console.error; | |
+ | |
// Now we have made a connection with Cavy, we know the app has booted. | |
server.locals.appBooted = true; | |
}) | |
+wss.on("error", (err) => { | |
+ console.log("Error:",err) | |
+}) | |
+ | |
// Internal: Takes a count and string, returns formatted and pluralized string. | |
// e.g. countString(5, 'failure') => '5 failures' | |
// countString(1, 'failure') => '1 failure' | |
diff --git a/node_modules/cavy-cli/src/runTests.js b/node_modules/cavy-cli/src/runTests.js | |
index 14b4cb1..a880189 100644 | |
--- a/node_modules/cavy-cli/src/runTests.js | |
+++ b/node_modules/cavy-cli/src/runTests.js | |
@@ -7,6 +7,7 @@ const { spawn, execFileSync } = require('child_process'); | |
// Default boot timeout in minutes | |
const BOOT_TIMEOUT = 2; | |
+const ALL_TESTS_RUN_TIMEOUT = 2; | |
let switched = false; | |
@@ -44,7 +45,7 @@ function runAdbReverse() { | |
console.log(`cavy: Running ${adbPath} ${adbArgs.join(' ')}`); | |
execFileSync(adbPath, adbArgs, {stdio: 'inherit'}); | |
} catch(e) { | |
- console.error(`Could not run adb reverse: ${e.message}.`); | |
+ console.log(`Could not run adb reverse: ${e.message}.`); | |
process.exit(1); | |
} | |
} | |
@@ -57,7 +58,7 @@ function getAdbPath() { | |
} | |
// Start test server, listening for test results to be posted. | |
-function runServer({ command, dev, outputAsXml, skipbuild, bootTimeout }) { | |
+function runServer({ command, dev, outputAsXml, skipbuild, bootTimeout, allTestRunTimeout }) { | |
server.locals.dev = dev; | |
server.locals.outputAsXml = outputAsXml; | |
server.listen(8082, () => { | |
@@ -73,6 +74,8 @@ function runServer({ command, dev, outputAsXml, skipbuild, bootTimeout }) { | |
} else { | |
// bootTimeout defaults to two minutes | |
const timeout = bootTimeout || BOOT_TIMEOUT; | |
+ const testsTimeout = allTestRunTimeout || ALL_TESTS_RUN_TIMEOUT | |
+ console.log("Setting timeout to", timeout, new Date().toISOString()) | |
setTimeout(() => { | |
if (!server.locals.appBooted) { | |
console.log(`No response from Cavy within ${timeout} minutes.`); | |
@@ -81,6 +84,16 @@ function runServer({ command, dev, outputAsXml, skipbuild, bootTimeout }) { | |
} | |
// Convert bootTimeout to milliseconds | |
}, minsToMillisecs(timeout)); | |
+ setTimeout(() => { | |
+ if (!server.locals.testFinished) { | |
+ console.log(`No response from Cavy within ${allTestRunTimeout} minutes.`); | |
+ console.log('Terminating processes.'); | |
+ process.exit(1); | |
+ } else { | |
+ console.log("Finished") | |
+ } | |
+ // Convert bootTimeout to milliseconds | |
+ }, minsToMillisecs(testsTimeout)); | |
} | |
}); | |
} | |
@@ -93,7 +106,7 @@ function runServer({ command, dev, outputAsXml, skipbuild, bootTimeout }) { | |
// outputAsXml: whether to write and save the results to XML file | |
// bootTimeout: how long the CLI should wait for the RN app to boot. | |
// args: any extra arguments the user would usually to pass to `react native run...` | |
-function runTests(command, file, skipbuild, dev, outputAsXml, bootTimeout, args) { | |
+function runTests(command, file, skipbuild, dev, outputAsXml, bootTimeout, allTestRunTimeout, args) { | |
// Assume entry file is 'index.js' if user doesn't supply one. | |
const entryFile = file || 'index.js'; | |
@@ -134,14 +147,15 @@ function runTests(command, file, skipbuild, dev, outputAsXml, bootTimeout, args) | |
}); | |
if (skipbuild) { | |
- runServer({ command, dev, outputAsXml, skipbuild, bootTimeout }); | |
+ runServer({ command, dev, outputAsXml, skipbuild, bootTimeout, allTestRunTimeout}); | |
} else { | |
// Build the app, start the test server and wait for results. | |
console.log(`cavy: Running \`react-native ${command}\`...`); | |
let rn = spawn('react-native', [command, ...args], { | |
stdio: 'inherit', | |
- shell: true | |
+ shell: true, | |
+ | |
}); | |
// Wait for the app to build first... | |
@@ -151,7 +165,8 @@ function runTests(command, file, skipbuild, dev, outputAsXml, bootTimeout, args) | |
if (code) { | |
return process.exit(code); | |
} | |
- runServer({ command, dev, outputAsXml, skipbuild, bootTimeout }); | |
+ console.log("cavy: running tests") | |
+ runServer({ command, dev, outputAsXml, skipbuild, bootTimeout, allTestRunTimeout }); | |
}); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment