Add action "Test Factory Apps"

This commit is contained in:
BartS23 2022-07-14 12:36:08 +02:00
parent 2e0502cbb7
commit 12e33519cf
13 changed files with 525 additions and 0 deletions

79
.github/workflows/testFactoryApps.yml vendored Normal file
View File

@ -0,0 +1,79 @@
name: Test Factory Apps
on:
push:
branches: [ master ]
pull_request:
branches: [ master ]
# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:
inputs:
git-ref:
description: Git Ref (Optional)
required: false
permissions:
contents: read
jobs:
# This workflow contains a single job called "build"
tests:
runs-on: ubuntu-latest
steps:
- name: Checkout Espruino
uses: actions/checkout@v3
with:
submodules: recursive
path: 'Espruino'
ref: ${{ github.event.inputs.git-ref }}
- name: Checkout EspruinoWebIDE
uses: actions/checkout@v3
with:
repository: espruino/EspruinoWebIDE
submodules: recursive
path: 'EspruinoWebIDE'
- name: Checkout EspruinoAppLoaderCore
uses: actions/checkout@v3
with:
repository: espruino/EspruinoAppLoaderCore
submodules: recursive
path: 'EspruinoAppLoaderCore'
- name: Setup emsdk
uses: mymindstorm/setup-emsdk@v11
with:
# Make sure to set a version number!
version: 3.1.12
# This is the name of the cache folder.
# The cache folder will be placed in the build directory,
# so make sure it doesn't conflict with anything!
actions-cache-folder: 'emsdk'
- name: Use Node.js
uses: actions/setup-node@v3
- name: Create Emulator
run: |
cd $GITHUB_WORKSPACE/Espruino
make clean
BOARD=EMSCRIPTEN make || exit 1
make clean
BOARD=EMSCRIPTEN2 make || exit 1
cp $GITHUB_WORKSPACE/Espruino/emulator_banglejs*.js $GITHUB_WORKSPACE/EspruinoWebIDE/emu/ -v
- name: Run Tests Bangle.js
run: node $GITHUB_WORKSPACE/Espruino/scripts/factoryTests.js BANGLEJS
id: TestBangle1
continue-on-error: true
- name: Run Tests Bangle.js2
run: node $GITHUB_WORKSPACE/Espruino/scripts/factoryTests.js BANGLEJS2
id: TestBangle2
continue-on-error: true
- name: Fail test
if: (steps.TestBangle1.outcome != 'skipped' && steps.TestBangle1.outcome != 'success') || (steps.TestBangle2.outcome != 'skipped' && steps.TestBangle2.outcome != 'success')
run: exit 1

103
scripts/factoryTests.js Executable file
View File

@ -0,0 +1,103 @@
#!/usr/bin/node
if (process.argv.length == 3 && process.argv[2] == "BANGLEJS") {
var EMULATOR = "banglejs1";
var DEVICEID = "BANGLEJS";
} else if (process.argv.length == 3 && process.argv[2] == "BANGLEJS2") {
var EMULATOR = "banglejs2";
var DEVICEID = "BANGLEJS2";
} else {
console.log("USAGE:");
console.log(" factoryTests.js BANGLEJS");
console.log(" or");
console.log(" factoryTests.js BANGLEJS2");
process.exit(1);
}
const TESTS_DIR = __dirname + "/../tests/FactoryApps";
if (!require("fs").existsSync(__dirname + "/../../EspruinoWebIDE")) {
console.log("You need to:");
console.log(" git clone https://github.com/espruino/EspruinoWebIDE");
console.log("At the same level as this project");
process.exit(1);
}
eval(require("fs").readFileSync(__dirname + "/../../EspruinoWebIDE/emu/emulator_"+EMULATOR+".js").toString());
eval(require("fs").readFileSync(__dirname + "/../../EspruinoWebIDE/emu/emu_"+EMULATOR+".js").toString());
eval(require("fs").readFileSync(__dirname + "/../../EspruinoWebIDE/emu/common.js").toString().replace('console.log("EMSCRIPTEN:"', '//console.log("EMSCRIPTEN:"'));
var Const = {};
var module = undefined;
var Espruino = require(__dirname + "/../../EspruinoAppLoaderCore/lib/espruinotools.js");
/* we factory reset ONCE, get this, then we can use it to reset
state quickly for each new app */
var factoryFlashMemory = new Uint8Array(FLASH_SIZE);
// Log of messages from app
var appLog = "";
// List of apps that errored
var erroredApps = [];
jsRXCallback = function() {};
jsUpdateGfx = function() {};
function ERROR(s) {
console.error(s);
process.exit(1);
}
var lastTxt;
function onConsoleOutput(txt) {
if (txt == "\r" && lastTxt == "\r") return;
if (txt && !txt.startsWith("=") ) {
appLog += txt + "\n";
lastTxt = txt;
}
}
function runTest(file) {
let testLog = "";
flashMemory.set(factoryFlashMemory);
jsTransmitString("reset()\n");
console.log(`Load steps from ${file}`);
var steps = require("fs").readFileSync(TESTS_DIR + '/' + file).toString().split("\n");
steps.forEach(step => {
if (!step) {
return;
}
// console.log("run: " , step);
appLog = "";
jsTransmitString(step + "\n");
testLog += appLog;
});
if (testLog.replace("Uncaught Storage Updated!", "").indexOf("Uncaught")>=0) {
erroredApps.push( { id : file, log : testLog } );
}
}
// wait until loaded...
setTimeout(function() {
console.log("Loaded...");
jsInit();
jsIdle();
console.log("Factory reset");
jsTransmitString("Bangle.factoryReset()\n");
factoryFlashMemory.set(flashMemory);
console.log("Ready!");
appLog = "";
require("fs").readdirSync(TESTS_DIR).forEach(file => file.endsWith(`.${DEVICEID}.txt`) && runTest(file));
console.log("Finish");
jsStopIdle();
if (erroredApps.length) {
erroredApps.forEach(app => {
console.log(`::error file=${app.id}::${app.id}`);
console.log("::group::Log");
app.log.split("\n").forEach(line => console.log(`\u001b[38;2;255;0;0m${line}`));
console.log("::endgroup::");
});
process.exit(1);
}
process.exit(0);
});

View File

@ -0,0 +1,35 @@
// arrange
var bootCode = "";
bootCode += "var setWatchOrg = setWatch;";
bootCode += "var callBacks = [];";
bootCode += "var setWatch = (callBack, btn) => {";
bootCode += " let watchNo = setWatchOrg.apply(null, arguments);";
bootCode += " callBacks[watchNo] = {btn: btn, callBack: callBack};";
bootCode += " return watchNo;";
bootCode += "};";
bootCode += "var clearWatchOrg = clearWatch;";
bootCode += "var clearWatch = (watchNo) => {";
bootCode += " if (watchNo) {";
bootCode += " clearWatchOrg(watchNo);";
bootCode += " delete callBacks[watchNo];";
bootCode += " } else {";
bootCode += " clearWatchOrg();";
bootCode += " callBacks = [];";
bootCode += " }";
bootCode += "};";
bootCode += "press = (btn) => callBacks";
bootCode += " .filter(callBack => callBack.btn == btn)";
bootCode += " .forEach(callBack => callBack.callBack());";
bootCode += "var loadCalled = false;";
bootCode += "var load = () => loadCalled = true;";
require("Storage").write(".boot1", bootCode);
// act
load("about.app.js");
press(BTN1); // quit
// assert
if (!loadCalled) throw "Error";

View File

@ -0,0 +1,35 @@
// arrange
var bootCode = "";
bootCode += "var setWatchOrg = setWatch;";
bootCode += "var callBacks = [];";
bootCode += "var setWatch = (callBack, btn) => {";
bootCode += " let watchNo = setWatchOrg.apply(null, arguments);";
bootCode += " callBacks[watchNo] = {btn: btn, callBack: callBack};";
bootCode += " return watchNo;";
bootCode += "};";
bootCode += "var clearWatchOrg = clearWatch;";
bootCode += "var clearWatch = (watchNo) => {";
bootCode += " if (watchNo) {";
bootCode += " clearWatchOrg(watchNo);";
bootCode += " delete callBacks[watchNo];";
bootCode += " } else {";
bootCode += " clearWatchOrg();";
bootCode += " callBacks = [];";
bootCode += " }";
bootCode += "};";
bootCode += "press = (btn) => callBacks";
bootCode += " .filter(callBack => callBack.btn == btn)";
bootCode += " .forEach(callBack => callBack.callBack());";
bootCode += "var loadCalled = false;";
bootCode += "var load = () => loadCalled = true;";
require("Storage").write(".boot1", bootCode);
// act
load("about.app.js");
press(BTN1); // quit
// assert
if (!loadCalled) throw "Error";

View File

@ -0,0 +1,45 @@
// arrange
var bootCode = "";
bootCode += "var setWatchOrg = setWatch;";
bootCode += "var callBacks = [];";
bootCode += "var setWatch = (callBack, btn) => {";
bootCode += " let watchNo = setWatchOrg.apply(null, arguments);";
bootCode += " callBacks[watchNo] = {btn: btn, callBack: callBack};";
bootCode += " return watchNo;";
bootCode += "};";
bootCode += "var clearWatchOrg = clearWatch;";
bootCode += "var clearWatch = (watchNo) => {";
bootCode += " if (watchNo) {";
bootCode += " clearWatchOrg(watchNo);";
bootCode += " delete callBacks[watchNo];";
bootCode += " } else {";
bootCode += " clearWatchOrg();";
bootCode += " callBacks = [];";
bootCode += " }";
bootCode += "};";
bootCode += "press = (btn) => callBacks";
bootCode += " .filter(callBack => callBack.btn == btn)";
bootCode += " .forEach(callBack => callBack.callBack());";
require("Storage").write(".boot1", bootCode);
require("Storage").erase("sched.json");
// act
load("alarm.app.js");
press(BTN3); // down to new
press(BTN2); // OK
press(BTN3); // down to alarm
press(BTN2); // OK
press(BTN2); // Back
press(BTN3); // down to new
press(BTN2); // OK
press(BTN3); // down to alarm
press(BTN3); // down to timer
press(BTN2); // OK
press(BTN2); // Back
press(BTN2); // Back
// assert
if (!require("Storage").list("sched.json").length) throw "Error";

View File

@ -0,0 +1,15 @@
// arrange
require("Storage").erase("sched.json");
// act
load("alarm.app.js");
Bangle.emit("touch", 0, { x: 0, y: 80 }); // new
Bangle.emit("touch", 0, { x: 0, y: 80 }); // alarm
Bangle.emit("touch", 0, { x: 0, y: 0 }); // back
Bangle.emit("touch", 0, { x: 0, y: 80 }); // new
Bangle.emit("touch", 0, { x: 0, y: 100 }); // timer
Bangle.emit("touch", 0, { x: 0, y: 0 }); // back
Bangle.emit("touch", 0, { x: 0, y: 0 }); // back
// assert
if (!require("Storage").list("sched.json").length) throw "Error";

View File

@ -0,0 +1,14 @@
// arrange
require("Storage").erase("health.json");
// act
load("health.app.js");
Bangle.emit("drag", { "dx": 0, "dy": -30 }); // scroll down
Bangle.emit("touch", 0, { x: 0, y: 150 }); // Settings
Bangle.emit("touch", 0, { x: 0, y: 80 }); // HRM Interval
Bangle.emit("touch", 0, { x: 0, y: 100 }); // 3 min
Bangle.emit("touch", 0, { x: 0, y: 0 }); // back
Bangle.emit("touch", 0, { x: 0, y: 0 }); // back
// assert
if (!require("Storage").list("health.json").length) throw "Error";

View File

@ -0,0 +1,39 @@
// arrange
var bootCode = "";
bootCode += "var setWatchOrg = setWatch;";
bootCode += "var callBacks = [];";
bootCode += "var setWatch = (callBack, btn) => {";
bootCode += " let watchNo = setWatchOrg.apply(null, arguments);";
bootCode += " callBacks[watchNo] = {btn: btn, callBack: callBack};";
bootCode += " return watchNo;";
bootCode += "};";
bootCode += "var clearWatchOrg = clearWatch;";
bootCode += "var clearWatch = (watchNo) => {";
bootCode += " if (watchNo) {";
bootCode += " clearWatchOrg(watchNo);";
bootCode += " delete callBacks[watchNo];";
bootCode += " } else {";
bootCode += " clearWatchOrg();";
bootCode += " callBacks = [];";
bootCode += " }";
bootCode += "};";
bootCode += "press = (btn) => callBacks";
bootCode += " .filter(callBack => callBack.btn == btn)";
bootCode += " .forEach(callBack => callBack.callBack());";
require("Storage").write(".boot1", bootCode);
require("Storage").erase("sched.json");
var timer = require("sched").newDefaultTimer();
timer.timer = 1;
timer.del = false;
require("sched").setAlarm("unitTest", timer);
// act
load("sched.js");
press(BTN3); // right to stop
press(BTN2); // stop
// assert
if (!require("Storage").readJSON("sched.json") || !require("Storage").readJSON("sched.json").some(alarm => !alarm.on)) throw "Error";

View File

@ -0,0 +1,14 @@
// arrange
require("Storage").erase("sched.json");
var timer = require("sched").newDefaultTimer();
timer.timer = 1;
timer.del = false;
require("sched").setAlarm("unitTest", timer);
// act
load("sched.js");
Bangle.emit("touch", 1, { x: 140, y: 140 }); // Stop
// assert
if (!require("Storage").readJSON("sched.json") || !require("Storage").readJSON("sched.json").some(alarm => !alarm.on)) throw "Error";

View File

@ -0,0 +1,40 @@
// arrange
var bootCode = "";
bootCode += "var setWatchOrg = setWatch;";
bootCode += "var callBacks = [];";
bootCode += "var setWatch = (callBack, btn) => {";
bootCode += " let watchNo = setWatchOrg.apply(null, arguments);";
bootCode += " callBacks[watchNo] = {btn: btn, callBack: callBack};";
bootCode += " return watchNo;";
bootCode += "};";
bootCode += "var clearWatchOrg = clearWatch;";
bootCode += "var clearWatch = (watchNo) => {";
bootCode += " if (watchNo) {";
bootCode += " clearWatchOrg(watchNo);";
bootCode += " delete callBacks[watchNo];";
bootCode += " } else {";
bootCode += " clearWatchOrg();";
bootCode += " callBacks = [];";
bootCode += " }";
bootCode += "};";
bootCode += "press = (btn) => callBacks";
bootCode += " .filter(callBack => callBack.btn == btn)";
bootCode += " .forEach(callBack => callBack.callBack());";
require("Storage").write(".boot1", bootCode);
require("Storage").erase(".boot0");
// act
load("setting.app.js");
press(BTN1); // Up to Utils
press(BTN2); // OK
press(BTN3); // Down to debug
press(BTN3); // Down to compact
press(BTN3); // Down to rewrite settings
press(BTN2); // OK
press(BTN2); // Back
// assert
if (!require("Storage").list(".boot0").length) throw "Error";

View File

@ -0,0 +1,15 @@
// arrange
require("Storage").erase(".boot0");
// act
load("setting.app.js");
Bangle.emit("drag", { "dx": 0, "dy": -70 }); // scroll down
Bangle.emit("touch", 0, { x: 0, y: 150 }); // utils
Bangle.emit("touch", 0, { x: 0, y: 150 }); // rewrite settings
Bangle.emit("touch", 0, { x: 0, y: 0 }); // back
Bangle.emit("touch", 0, { x: 0, y: 0 }); // back
// assert
if (!require("Storage").list(".boot0").length) throw "Error";

View File

@ -0,0 +1,46 @@
// arrange
var bootCode = "";
bootCode += "var setWatchOrg = setWatch;";
bootCode += "var callBacks = [];";
bootCode += "var setWatch = (callBack, btn) => {";
bootCode += " let watchNo = setWatchOrg.apply(null, arguments);";
bootCode += " callBacks[watchNo] = {btn: btn, callBack: callBack};";
bootCode += " return watchNo;";
bootCode += "};";
bootCode += "var clearWatchOrg = clearWatch;";
bootCode += "var clearWatch = (watchNo) => {";
bootCode += " if (watchNo) {";
bootCode += " clearWatchOrg(watchNo);";
bootCode += " delete callBacks[watchNo];";
bootCode += " } else {";
bootCode += " clearWatchOrg();";
bootCode += " callBacks = [];";
bootCode += " }";
bootCode += "};";
bootCode += "press = (btn) => callBacks";
bootCode += " .filter(callBack => callBack.btn == btn)";
bootCode += " .forEach(callBack => callBack.callBack());";
bootCode += "var load = () => require('welcome.boot.js');";
require("Storage").write(".boot1", bootCode);
require("Storage").erase("welcome.json");
// act
load("welcome.app.js");
press(BTN3); // next scene
press(BTN3); // next scene
press(BTN3); // next scene
press(BTN3); // next scene
press(BTN3); // next scene
press(BTN3); // next scene
press(BTN3); // next scene
press(BTN3); // next scene
press(BTN3); // next scene
press(BTN3); // next scene
press(BTN2); // back
// assert
if (!require("Storage").list("welcome.json").length) throw "Error";

View File

@ -0,0 +1,45 @@
// arrange
var bootCode = "";
bootCode += "var setWatchOrg = setWatch;";
bootCode += "var callBacks = [];";
bootCode += "var setWatch = (callBack, btn) => {";
bootCode += " let watchNo = setWatchOrg.apply(null, arguments);";
bootCode += " callBacks[watchNo] = {btn: btn, callBack: callBack};";
bootCode += " return watchNo;";
bootCode += "};";
bootCode += "var clearWatchOrg = clearWatch;";
bootCode += "var clearWatch = (watchNo) => {";
bootCode += " if (watchNo) {";
bootCode += " clearWatchOrg(watchNo);";
bootCode += " delete callBacks[watchNo];";
bootCode += " } else {";
bootCode += " clearWatchOrg();";
bootCode += " callBacks = [];";
bootCode += " }";
bootCode += "};";
bootCode += "press = (btn) => callBacks";
bootCode += " .filter(callBack => callBack.btn == btn)";
bootCode += " .forEach(callBack => callBack.callBack());";
bootCode += "var load = () => require('welcome.boot.js');";
require("Storage").write(".boot1", bootCode);
require("Storage").erase("welcome.json");
// act
load("welcome.app.js");
press(BTN1); // to scene 2
press(BTN1); // to scene 3
press(BTN1); // to scene 4
press(BTN1); // to scene 5
press(BTN1); // to scene 6
press(BTN1); // to scene 7
press(BTN1); // to scene 8
press(BTN1); // to scene 9
press(BTN1); // to scene 10
press(BTN1); // back
// assert
if (!require("Storage").list("welcome.json").length) throw "Error";