How to Use
Introduction:
This example demonstrates how to fully manage the lifecycle of an automation task using the Tasks API.
The script sequentially completes task creation (tasksCreate), confirms task persistence (tasksGet), and continuously polls task status until execution finishes (RUNNING → STOPPED_*), finally outputting the task execution results and key information.
The example includes standardized step logs (start / end / duration statistics), and in failure scenarios it automatically collects foreground app, Activity, battery level, device information, and evidence screenshots, making issue diagnosis and result auditing easier.
It is suitable for scenarios such as automated test scheduling, batch task execution, platform integration, and execution result monitoring, and can be copied and run directly.
Before Running:
sleep(10000);
print('-tasks-test-');sigmaLoad("D:/scripts/task_create_submit_poll.js");
Notes:
Source Code
/**
* ============================================================
* [TASK] Create -> Submit -> Get Results
* ============================================================
* Objectives:
* 1) Create a task using tasksCreate(...)
* 2) Confirm the task is persisted using tasksGet(...)
* 3) Poll tasksGet(...) until the task finishes (RUNNING -> STOPPED_*)
* 4) Print results (status / errorMessage / execDevice / sigmaTestStatus, etc.)
*
* Output requirements:
* - Print "start / end / duration" for each step
* - On failure: write context (foreground package + activity + battery + device info)
* + capture screenshots + write log files (if fs is available)
*
* Key notes:
* - tasksCreate() validates that the script path must exist; otherwise, "Script path not found"
* - The task "executor" may not run immediately; if planTime is in the future,
* the task will remain in SCHEDULED (-6)
* - This example uses polling with tasksGet to obtain the final status (-2 / -3 / -5, etc.)
*/
// ===================== Imports & Injection =====================
// var tcConst = global.tcConst || {};
// var sigmaConst = global.sigmaConst || {};
var { getDevices } = require("sigma/device");
require("sigma/app");
require("sigma/input");
require("sigma/image");
// tasks module
var tasks = require("sigma/tasks");
// ===================== Configuration =====================
var LOG_DIR = "D:/tc_logs";
var IMG_TYPE = (sigmaConst.IMG_JPG || tcConst.IMG_JPG || sigmaConst.IMG_PNG || tcConst.IMG_PNG);
// Task name must be unique (recommended to include a timestamp)
function pad2(n) { return (n < 10 ? "0" : "") + n; }
function ts() {
var d = new Date();
return (
d.getFullYear() +
pad2(d.getMonth() + 1) +
pad2(d.getDate()) + "_" +
pad2(d.getHours()) +
pad2(d.getMinutes()) +
pad2(d.getSeconds())
);
}
var TASK_NAME = "demo_task_" + ts();
// Script must exist, and the extension must be .js / .tst / .scp
// Example: var SCRIPT_PATH = "E:/file/test.js";
var SCRIPT_PATH = "E:/file/test.js";
// Execution count (iteration / iterCount) >= 1
var ITERATION = 1;
// Execution time strategy:
// 1) Create immediately (now): time = undefined, repeat = undefined
// 2) One-shot scheduled time: time = "YYYY-MM-DD HH:mm[:ss]"
// 3) Recurring: time = "HH:mm[:ss]" + repeat = [0..6]
var TIME_MODE = "now"; // "now" | "oneshot" | "weekly"
// One-shot example (future time)
// var ONE_SHOT_TIME = "2026-01-14 23:50";
// Weekly example: every Monday, Wednesday, Friday at 08:30
// var WEEKLY_TIME = "08:30";
// var WEEKLY_REPEAT = [1,3,5];
// Maximum polling wait time (milliseconds)
var WAIT_TIMEOUT_MS = 3 * 60 * 1000; // 3 minutes
var POLL_INTERVAL_MS = 1500;
// ===================== Utilities =====================
function nowMs() { return Date.now(); }
function sleep(ms) {
if (typeof global.sleep === "function") return global.sleep(ms);
var t = Date.now();
while (Date.now() - t < ms) {}
}
function safeFilePart(s) { return String(s).replace(/[^\w\-.]+/g, "_"); }
function devName(d) { return d.name || (d.getName && d.getName()) || d.SN || "UnknownDevice"; }
function safeGet(fn, fallback) { try { return fn(); } catch (e) { return fallback; } }
// fs (if available, write logs / locks)
var fs = null;
try { fs = require("fs"); } catch (e) { fs = null; }
function ensureDir(path) {
if (!fs) return false;
try { if (!fs.existsSync(path)) fs.mkdirSync(path, { recursive: true }); return true; }
catch (e) { return false; }
}
function appendFile(path, text) {
if (!fs) return false;
try { fs.appendFileSync(path, text, { encoding: "utf8" }); return true; }
catch (e) { return false; }
}
// ===================== Logging Context =====================
function makeCtx() {
ensureDir(LOG_DIR);
var logFile = LOG_DIR + "/TASK__" + safeFilePart(TASK_NAME) + "__" + ts() + ".log";
var canWrite = ensureDir(LOG_DIR) && !!fs;
return {
logFile: logFile,
canWrite: canWrite,
log: function (line) {
var msg = "[TASK] " + line;
print(msg);
if (this.canWrite) appendFile(this.logFile, msg + "\n");
}
};
}
// ===================== stepRun: start / end / duration =====================
function stepRun(ctx, stepName, fn) {
var start = nowMs();
ctx.log(">> START " + stepName);
try {
var ret = fn();
ctx.log("<< END " + stepName + " (cost " + (nowMs() - start) + " ms)");
return { ok: true, ret: ret };
} catch (e) {
ctx.log("<< FAIL " + stepName + " (cost " + (nowMs() - start) + " ms) err=" +
String(e && e.message ? e.message : e));
return { ok: false, err: String(e && e.message ? e.message : e) };
}
}
// ===================== Failure Context + Screenshot =====================
function writeFailContext(ctx, d, stepName, errText) {
ctx.log("---- FAIL CONTEXT (" + devName(d) + ") BEGIN ----");
ctx.log("step=" + stepName);
ctx.log("error=" + (errText || ""));
ctx.log("foregroundApp=" + (safeGet(function () { return d.getForegroundApp(); }, "") || ""));
ctx.log("activity=" + (safeGet(function () { return d.getActivity(); }, "") || ""));
ctx.log("battery=" + (safeGet(function () { return d.battery; }, "") || ""));
ctx.log("manufacturer=" + safeGet(function () { return d.manufacturer; }, ""));
ctx.log("model=" + safeGet(function () { return d.model; }, ""));
ctx.log("SN=" + safeGet(function () { return d.SN; }, ""));
ctx.log("IP=" + safeGet(function () { return d.IP; }, ""));
ctx.log("DPI=" + safeGet(function () { return d.DPI; }, ""));
ctx.log("resolution=" + safeGet(function () { return d.width; }, "") + "x" +
safeGet(function () { return d.height; }, ""));
ctx.log("androidVersionRelease=" + safeGet(function () { return d.androidVersionRelease; }, ""));
ctx.log("androidVersionSdkInt=" + safeGet(function () { return d.androidVersionSdkInt; }, ""));
ctx.log("---- FAIL CONTEXT (" + devName(d) + ") END ----");
}
function screenshotOne(ctx, d, tag) {
var file = LOG_DIR + "/" + safeFilePart(devName(d)) + "__" +
safeFilePart(tag) + "__" + ts() + ".jpg";
var ret = d.screenshot(file, IMG_TYPE);
if (ret === 0) ctx.log("!! Screenshot saved: " + file);
else ctx.log("!! Screenshot failed (" + devName(d) + "): " + lastError());
}
// ===================== Task Status Helpers =====================
function statusToText(code) {
var S = tasks.STATUS || {};
if (code === 0) return "FILE_NOT_FOUND(0)";
if (code === S.RUNNING || code === -1) return "RUNNING(-1)";
if (code === S.STOPPED_NORMAL || code === -2) return "STOPPED_NORMAL(-2)";
if (code === S.STOPPED_ERROR || code === -3) return "STOPPED_ERROR(-3)";
if (code === S.PAUSED || code === -4) return "PAUSED(-4)";
if (code === S.USER_TERMINATED || code === -5) return "USER_TERMINATED(-5)";
if (code === S.SCHEDULED || code === -6) return "SCHEDULED(-6)";
return String(code);
}
function isTerminalStatus(code) {
return code === -2 || code === -3 || code === -5 || code === 0;
}
// ===================== main =====================
function main() {
var ctx = makeCtx();
// Optional: get devices, mainly for failure context / screenshots
var devices = getDevices();
var list = [];
if (devices && devices.length) devices.forEach(function (d) { list.push(d); });
ctx.log("Selected devices: " + list.length);
// Step0: Print script path info
stepRun(ctx, "Step0 Check script path string", function () {
ctx.log("TASK_NAME=" + TASK_NAME);
ctx.log("SCRIPT_PATH=" + SCRIPT_PATH);
ctx.log("ITERATION=" + ITERATION);
ctx.log("TIME_MODE=" + TIME_MODE);
});
// Step1: Create task
var s1 = stepRun(ctx, "Step1 tasksCreate()", function () {
var ret;
if (TIME_MODE === "now") {
ret = tasks.tasksCreate(TASK_NAME, SCRIPT_PATH, ITERATION);
} else if (TIME_MODE === "oneshot") {
ret = tasks.tasksCreate(TASK_NAME, SCRIPT_PATH, ITERATION, ONE_SHOT_TIME);
} else if (TIME_MODE === "weekly") {
ret = tasks.tasksCreate(TASK_NAME, SCRIPT_PATH, ITERATION, WEEKLY_TIME, WEEKLY_REPEAT);
} else {
throw new Error("Unknown TIME_MODE: " + TIME_MODE);
}
if (ret !== true && typeof ret !== "number") {
throw new Error("tasksCreate FAIL: " + lastError());
}
ctx.log("tasksCreate OK, ret=" + ret);
return ret;
});
if (!s1.ok) {
ctx.log("[CREATE] Task create FAIL: " + TASK_NAME);
ctx.log("[CREATE] err=" + s1.err);
for (var i = 0; i < list.length; i++) {
writeFailContext(ctx, list[i], "tasksCreate", s1.err);
screenshotOne(ctx, list[i], "FAIL__tasksCreate");
}
stepRun(ctx, "Step1b tasksList(recent 5)", function () {
var recent = tasks.tasksList({ limit: 5, orderBy: "updatedAt DESC" });
ctx.log("recent tasks:\n" + JSON.stringify(recent, null, 2));
});
return;
}
// Step2: Get task record
var taskRow = null;
var s2 = stepRun(ctx, "Step2 tasksGet(taskName)", function () {
var t = tasks.tasksGet(TASK_NAME);
if (!t) throw new Error("tasksGet returned null (not found)");
taskRow = Array.isArray(t) ? t[0] : t;
ctx.log("task snapshot:\n" + JSON.stringify(taskRow, null, 2));
return taskRow;
});
if (!s2.ok) return;
// Step3: Poll until terminal
stepRun(ctx, "Step3 Poll task until terminal or timeout", function () {
var deadline = nowMs() + WAIT_TIMEOUT_MS;
var lastStatus = null;
while (nowMs() < deadline) {
var t = tasks.tasksGet(TASK_NAME);
t = Array.isArray(t) ? t[0] : t;
if (!t) throw new Error("tasksGet null during polling");
var st = t.status;
if (st !== lastStatus) {
ctx.log("poll: status=" + statusToText(st) +
" startTime=" + t.startTime + " endTime=" + t.endTime);
lastStatus = st;
}
if (isTerminalStatus(st)) {
taskRow = t;
return t;
}
sleep(POLL_INTERVAL_MS);
}
throw new Error("Timeout waiting task finish. lastStatus=" + statusToText(lastStatus));
});
// Step4: Print result summary
stepRun(ctx, "Step4 Print result summary", function () {
var t = taskRow;
ctx.log("===== RESULT =====");
ctx.log("taskName=" + t.taskName);
ctx.log("taskID=" + t.taskID);
ctx.log("status=" + statusToText(t.status));
ctx.log("errorMessage=" + (t.errorMessage || ""));
ctx.log("execDevice=" + (t.execDevice || "-"));
ctx.log("startTime=" + t.startTime);
ctx.log("endTime=" + t.endTime);
ctx.log("sigmaTestStatus=" + (t.sigmaTestStatus || t.sigma_test_status || ""));
if (t.status === -3 || t.status === 0) {
ctx.log("Task ended with error, collecting device evidence...");
for (var i = 0; i < list.length; i++) {
writeFailContext(ctx, list[i],
"taskResult(" + statusToText(t.status) + ")", t.errorMessage || "");
screenshotOne(ctx, list[i], "FAIL__taskResult");
}
}
});
// Step5: Optional - show recent list
stepRun(ctx, "Step5 tasksList(recent 5)", function () {
var recent = tasks.tasksList({ limit: 5, orderBy: "updatedAt DESC" });
ctx.log("recent tasks:\n" + JSON.stringify(recent, null, 2));
});
ctx.log("DONE.");
}
main();