jSpaghetti 2.0.0
- 2.0.2 error event added.
- 2.0.1 remove onload listener after sequence terminated.
- 2.0.0
28 december 2020
:{"wait": "_forTheSignal"}
removed._exit
replaced by{"exit": <condition>}
,{"gotoif": []}
replaced by{"jumpif": []}
. Exit instruction is not supported by jumpif anymore. - 1.0.1
28 november 2020
SOON:{"wait": "_forTheSignal"}
will be removed._exit
will be replaced byEXIT
._forPageToReload
will be replaced bypage-reload
- 1.0.0
23 november 2020
thenext(message)
hook is added to add a asyncrousness to the states transition. If a state returns nothing, then the transition is not performed automatically. It will be necessary to call the refered function to run the transition.
jSpaghetti is a Javascript API to build automation scripts with sequential and declarative paradigm.
The project came from the necessity of an easy way to write browser javascript bots. The project was generalized to cover other purposes, though.
As this project is actually a huge single js file, it was broken into parts in order to be more readable. To "compile" the project just process the file main.js with Filemash script using the following command:
python3 filemash.py main.js > jSpaghetti.js
Just include the file on document page, like:
<script type="text/javascript" src="jSpaghetti.js"></script>
This code can be also injected on the document page using tools like Greasemonkey or something.
Warning: This manual is just a sketch. Detailed manual coming soon
- To assign a module object to a variable. If the module does not exist yet, it is created before assingment.
var moduleObject = $jSpaghetti.module("myModule")
Procedures are custom functions to be used as a library for the sequences. Each module has its own procedures.
- Defining procedures
$jSpaghetti.module("myModule").procedure("myProcedureFoo", function(){
//Code something in here
})
$jSpaghetti.module("myModule").procedure("myProcedureBar", function(){
//Code something in here
})
//Define as much as you need
A sequence provides a wrapped environment for the execution of the instructions. It manages the execution to provide a shared data between the procedures. The data is not lost when page is reloaded.
- Creating a new sequence
var sequenceObject = $jSpaghetti.module("myModule").sequence("mySequenceBaz")
This is the best part. You can use a declarative way to write the script behavior. Procedures can be arranged to be executed in a defined order:
sequenceObject.intructions = [
{"step1":["myProcedureFoo", "myProcedureBar"]},
{"labelX":"myProcedureBax"}
]
//Define as much as you need
Internal commands can change the script behavior.
{"exit": true} //Finish the sequence execution
{"exit": "2 == 1"} //It does not finish the sequence execution because the condition returns false
{"wait": 1000} //Wait the defined time in ms
{"wait": "page-reload"} //Pause the sequence execution and resume after page is reloaded
{"jumpif":["2 == 1", "step1", "labelX"]} // It redirects the program flow to a sequence (In this case to the "labelX")
- To execute a sequence use something like this:
$jSpaghetti.module("myModule").sequence("mySequence").run()
$jSpaghetti.module("myModule").sequence("mySequence").reset()
To see what is happening during the sequence execution, turn on the debug mode. The debugging log will be shown on browser console. Developer mode show as much details as possible.
$jSpaghetti.module("myModule").config.debugMode = true
$jSpaghetti.module("myModule").config.developerMode = true
Data can be shared between procedures during the sequence execution. The shared object is received as the first parameter on each procedure. If this object is modified, that changes will be available for the next instruction. The previous procedure return value is always available on the "$" attribute of this object.
$jSpaghetti.module("myModule").procedure("myProcedureBar", function(sharedData){
console.log(sharedData.$) //It will show the value returned for the previous procedure
sharedData.foo = "baz" //This attribute and its value will be available for the next procedures
return 2000 //This value will be available on the "$" attribute in the next procedure
})
The sequences return the "terminated" event when the sequence is done. All the events:
$jSpaghetti.module("myModule").procedure("myProcedureBar").events.addEventListener("terminated", function(e){
//Code something in here
})
$jSpaghetti.module("myModule").procedure("myProcedureBar").events.addEventListener("error", function(e){
console.log(e.detail)
})
$jSpaghetti.module("myModule").procedure("myProcedureBar").events.addEventListener("reset", function(e){
//Code something in here
})
var module = $jSpaghetti.module("myModule")
sequence.reset()
module.procedure("A", function(){
console.log("brown fox jumps ")
})
module.procedure("B", function(){
console.log("over the lazy dog")
})
module.procedure("C", function(){
console.log("quick ")
})
var sequence = module.sequence("showPhrase")
sequence.instructions = [
{0: "C"},
{"foo": ["A", "B", {"exit": true}]}
]
sequence.run()
//Output: quick brown fox jumps over the lazy dog