Skip to content

Commit

Permalink
Add action "Test Factory Apps"
Browse files Browse the repository at this point in the history
  • Loading branch information
BartS23 committed Jul 14, 2022
1 parent 2e0502c commit 12e3351
Show file tree
Hide file tree
Showing 13 changed files with 525 additions and 0 deletions.
79 changes: 79 additions & 0 deletions .github/workflows/testFactoryApps.yml
Original file line number Diff line number Diff line change
@@ -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 changes: 103 additions & 0 deletions scripts/factoryTests.js
Original file line number Diff line number Diff line change
@@ -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);
});
35 changes: 35 additions & 0 deletions tests/FactoryApps/about.BANGLEJS.txt
Original file line number Diff line number Diff line change
@@ -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";
35 changes: 35 additions & 0 deletions tests/FactoryApps/about.BANGLEJS2.txt
Original file line number Diff line number Diff line change
@@ -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";
45 changes: 45 additions & 0 deletions tests/FactoryApps/alarm.BANGLEJS.txt
Original file line number Diff line number Diff line change
@@ -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";
15 changes: 15 additions & 0 deletions tests/FactoryApps/alarm.BANGLEJS2.txt
Original file line number Diff line number Diff line change
@@ -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";
14 changes: 14 additions & 0 deletions tests/FactoryApps/health.BANGLEJS2.txt
Original file line number Diff line number Diff line change
@@ -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";
39 changes: 39 additions & 0 deletions tests/FactoryApps/sched.BANGLEJS.txt
Original file line number Diff line number Diff line change
@@ -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";
14 changes: 14 additions & 0 deletions tests/FactoryApps/sched.BANGLEJS2.txt
Original file line number Diff line number Diff line change
@@ -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";
Loading

0 comments on commit 12e3351

Please sign in to comment.