This repository has been archived by the owner on Sep 25, 2018. It is now read-only.
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Bidirectional communication now working with xdotool and ajax. Passes…
… simple test. Next step will be to run all tests.
- Loading branch information
Showing
3 changed files
with
242 additions
and
97 deletions.
There are no files selected for viewing
26 changes: 26 additions & 0 deletions
26
src/main/coffeescript/scxml/test/multi-process-browser/browser-main.coffee
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
setTimeout = (cb,time) -> this.setTimeout cb,time | ||
clearTimeout = (cb,time) -> this.clearTimeout cb,time | ||
|
||
interpreter = null | ||
$(document).ready -> | ||
$(document.documentElement).keypress (e) -> | ||
#send it to statechart instance | ||
console.log "receiving UI event",e | ||
|
||
scEvent = String.fromCharCode e.charCode | ||
console.log "sending event",scEvent | ||
|
||
interpreter.gen scEvent | ||
configuration = interpreter.getConfiguration() | ||
$.post "/check-configuration",JSON.stringify(configuration.iter()),(l) -> console.log l | ||
|
||
require ["scxml/SCXML","scxml/test/multi-process-browser/initialize-json-test-descriptor"],(scxml,initializeJsonTest) -> | ||
|
||
$.getJSON "test",(testJson) -> | ||
initializeJsonTest testJson,([m,model,optimizations]) -> | ||
interpreter = new scxml.SimpleInterpreter model,setTimeout,clearTimeout,optimizations | ||
interpreter.start() | ||
initialConfiguration = interpreter.getConfiguration() | ||
console.log "initialConfiguration",initialConfiguration | ||
$.post "/check-configuration",JSON.stringify(initialConfiguration.iter()),(l) -> console.log l | ||
$.post "/statechart-initialized",(l) -> console.log l |
255 changes: 158 additions & 97 deletions
255
src/main/coffeescript/scxml/test/multi-process-browser/harness.coffee
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,101 +1,162 @@ | ||
spawn = require('child_process').spawn | ||
promiseModule = require('promise') | ||
http = require("http") | ||
urlModule = require('url') | ||
pathModule = require('path') | ||
util = require('util') | ||
fs = require('fs') | ||
|
||
Promise = promiseModule.Promise | ||
|
||
xdt = "xdotool" | ||
xdotool = | ||
search : (promise,s,option="class") -> | ||
console.log "searching window with params:",xdt,["search","--"+option,s] | ||
p = spawn xdt,["search","--"+option,s] | ||
data = "" | ||
p.stdout.setEncoding("utf8") | ||
p.stdout.on "data",(chunk) -> | ||
console.log "received chunk",chunk | ||
data += chunk | ||
|
||
p.stdout.on "end",-> | ||
console.log "resolving promise" | ||
promise.resolve(data.split('\n')[0]) | ||
define ['scxml/test/multi-process-browser/json-tests','util/set/ArraySet','child_process','promise','http','url','path','util','fs'],(jsonTests,Set,child_process,promiseModule,http,urlModule,pathModule,util,fs) -> | ||
|
||
-> | ||
|
||
spawn = child_process.spawn | ||
|
||
Promise = promiseModule.Promise | ||
|
||
xdt = "xdotool" | ||
xdotool = | ||
search : (promise,s,option="class") -> | ||
console.log "searching window with params:",xdt,["search","--"+option,s] | ||
p = spawn xdt,["search","--"+option,s] | ||
data = "" | ||
p.stdout.setEncoding("utf8") | ||
p.stdout.on "data",(chunk) -> | ||
console.log "received chunk",chunk | ||
data += chunk | ||
|
||
move : (id,x,y) -> spawn xdt,["windowmove",id,x,y] | ||
resize : (id,width,height) -> spawn xdt,["windowsize",id,width,height] | ||
focus : (id) -> spawn xdt,["windowfocus",id] | ||
event : (id,e) -> spawn xdt,["type",id,e] | ||
|
||
port = "8888" | ||
serverUrl = "http://localhost:#{port}/runner" | ||
|
||
startBrowser = (promise,browser,url=serverUrl) -> | ||
console.log "spawning browser process" | ||
p = spawn browser,[url] | ||
#wait a second for him to open | ||
setTimeout (-> xdotool.search(promise,browser)),10000 | ||
|
||
p = new Promise() | ||
startBrowser p,"chromium-browser" | ||
|
||
p.then (id) -> | ||
console.log "moving and resizing window with id",id | ||
xdotool.move id,0,0 | ||
xdotool.resize id,500,500 | ||
xdotool.focus id | ||
|
||
fileServerRoot = "/home/jacob/workspace/scion/build" #TODO: customize this | ||
|
||
server = http.createServer (request,response) -> | ||
url = urlModule.parse request.url | ||
|
||
switch url.pathname | ||
when "/runner" | ||
response.writeHead 200,{"Content-Type":"text/html"} | ||
response.write """ | ||
<html> | ||
<head> | ||
<script src="http://code.jquery.com/jquery-1.6.2.min.js"></script> | ||
<script> | ||
$.getJSON("test",function(o){ | ||
console.log(o) | ||
}); | ||
</script> | ||
</head> | ||
<body></body> | ||
</html> | ||
""" | ||
response.end() | ||
when "/test" | ||
response.writeHead 200,{"Content-Type":"text/json"} | ||
response.write JSON.stringify {"hello":"world"} | ||
response.end() | ||
when "/configuration-changed" | ||
"TODO: compare to expected configuration" | ||
response.end() | ||
else | ||
#read and return file | ||
|
||
path = pathModule.join fileServerRoot,url.pathname | ||
|
||
pathModule.exists path,(exists) -> | ||
if exists | ||
console.log "here" | ||
console.log path | ||
stat = fs.statSync(path) | ||
|
||
response.writeHead(200, { | ||
'Content-Type': 'text/plain', | ||
'Content-Length': stat.size | ||
}) | ||
|
||
readStream = fs.createReadStream(path) | ||
util.pump(readStream, response) | ||
p.stdout.on "end",-> | ||
console.log "resolving promise" | ||
promise.resolve(data.split('\n')[0]) | ||
|
||
move : (id,x,y) -> spawn xdt,["windowmove",id,x,y] | ||
resize : (id,width,height) -> spawn xdt,["windowsize",id,width,height] | ||
focus : (id) -> spawn xdt,["windowfocus",id] | ||
type : (id,s) -> | ||
@focus id #first bring him in focus | ||
spawn xdt,["type",id,s] | ||
|
||
port = "8888" | ||
serverUrl = "http://localhost:#{port}/runner" | ||
|
||
startBrowser = (promise,browser,url=serverUrl) -> | ||
console.log "spawning browser process" | ||
p = spawn browser,[url] | ||
#wait a second for him to open | ||
setTimeout (-> xdotool.search(promise,browser)),10000 | ||
|
||
sendEventsToBrowser = (id,events) -> | ||
e = events.shift() | ||
if e | ||
console.log "sending event",e.name | ||
xdotool.type id,e.name | ||
#TODO: parameterize event density | ||
setTimeout (-> sendEventsToBrowser(id,events)),100 | ||
|
||
getContentType = (path) -> | ||
splitPath = path.split('.') | ||
path = splitPath[splitPath.length-1] | ||
switch path | ||
when "js" | ||
"text/javascript" | ||
else | ||
response.writeHead 404 | ||
response.end() | ||
"text/plain" | ||
|
||
p = new Promise() | ||
p2 = new Promise() | ||
xdotool.search(p,"chromium-browser") | ||
|
||
p.then (id) -> if not id then startBrowser p2,"chromium-browser" else p2.resolve(id) | ||
|
||
p2.then (id) -> | ||
console.log "moving and resizing window with id",id | ||
#xdotool.move id,0,0 | ||
#xdotool.resize id,500,500 | ||
xdotool.focus id | ||
|
||
fileServerRoot = "/home/jacob/workspace/scion/build" #TODO: customize this | ||
|
||
currentTest = null | ||
expectedConfigurations = null | ||
|
||
console.log "starting server" | ||
server = http.createServer (request,response) -> | ||
url = urlModule.parse request.url | ||
|
||
console.log "received request for #{url.pathname}" | ||
|
||
switch url.pathname | ||
when "/runner" | ||
response.writeHead 200,{"Content-Type":"text/html"} | ||
response.write """ | ||
<html> | ||
<head> | ||
<script src="lib/json2.js"></script> | ||
<script src="lib/jquery.js"></script> | ||
<script src="lib/require.js"></script> | ||
<script src="scxml/test/multi-process-browser/browser-main.js"></script> | ||
</head> | ||
<body></body> | ||
</html> | ||
""" | ||
response.end() | ||
when "/test" | ||
response.writeHead 200,{"Content-Type":"text/json"} | ||
currentTest = jsonTests.pop() | ||
expectedConfigurations = | ||
[new Set currentTest.testScript.initialConfiguration].concat( | ||
(new Set eventTuple.nextConfiguration for eventTuple in currentTest.testScript.events)) | ||
|
||
response.write JSON.stringify currentTest | ||
response.end() | ||
when "/statechart-initialized" | ||
response.writeHead 200,{"Content-Type":"text/plain"} | ||
response.write "Sending events to browser" | ||
response.end() | ||
sendEventsToBrowser id,(eventTuple.event for eventTuple in currentTest.testScript.events) | ||
when "/check-configuration" | ||
expectedConfiguration = expectedConfigurations.shift() | ||
|
||
jsonData = "" | ||
request.on "data",(data) -> | ||
jsonData += data | ||
|
||
request.on "end",-> | ||
console.log "finished reading json data",jsonData | ||
try | ||
configuration = new Set JSON.parse(jsonData) | ||
|
||
if expectedConfiguration.equals configuration | ||
response.writeHead 200,{"Content-Type":"text/plain"} | ||
#TODO: decide what to send back to client | ||
response.write "Matched expected configuration." | ||
else | ||
response.writeHead 500,{"Content-Type":"text/plain"} | ||
response.write "Did not match expected configuration. Received: #{JSON.stringify(configuration)}. Expected:#{JSON.stringify(expectedConfiguration)}." | ||
catch e | ||
console.error e.message | ||
console.error e.type | ||
console.error e.stack | ||
response.writeHead 500 | ||
|
||
response.end() | ||
|
||
when "/test-complete" | ||
"TODO: compare to expected configuration" | ||
response.end() | ||
else | ||
#read and return file | ||
|
||
path = pathModule.join fileServerRoot,url.pathname | ||
|
||
pathModule.exists path,(exists) -> | ||
if exists | ||
console.log path | ||
stat = fs.statSync(path) | ||
|
||
response.writeHead(200, { | ||
'Content-Type': getContentType(path), | ||
'Content-Length': stat.size | ||
}) | ||
|
||
readStream = fs.createReadStream(path) | ||
util.pump(readStream, response) | ||
else | ||
response.writeHead 404 | ||
response.end() | ||
|
||
|
||
server.listen(8888) | ||
server.listen(8888) |
58 changes: 58 additions & 0 deletions
58
...main/coffeescript/scxml/test/multi-process-browser/initialize-json-test-descriptor.coffee
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
define ["scxml/json2model","scxml/json2extra-model"],(json2model,json2ExtraModel) -> | ||
|
||
(testJson,callback) -> | ||
|
||
mPath = if testJson.extraModelInfo then "scxml/model" else "scxml/extra-model" | ||
|
||
console.log "requiring",mPath,testJson.set.setType,testJson.transitionSelector.selector | ||
|
||
require [mPath,testJson.set.setType,testJson.transitionSelector.selector],(m,setConstructor,transitionSelector) -> | ||
|
||
console.log "imported depenedent modules" | ||
|
||
#parse scxmlJson model | ||
model = json2model testJson.scxmlJson | ||
|
||
transitionSelector = transitionSelector model.transitions,model.events | ||
|
||
flattenedTransitionsRE = /\.flattened-transitions$/ | ||
|
||
onlySelectFromBasicStates = testJson.transitionSelector.selectorKey is "class-transition-lookup" or testJson.name.match flattenedTransitionsRE | ||
|
||
#filter basic states the easy way | ||
basicStates = (state for state in model.states when not (state.basicDocumentOrder is undefined)).sort((s1,s2) -> s1.basicDocumentOrder - s2.basicDocumentOrder) | ||
|
||
setPurposes = | ||
transitions : | ||
keyProp : "documentOrder" | ||
keyValueMap : model.transitions | ||
initializedSetClass : {} | ||
states : | ||
keyProp : "documentOrder" | ||
keyValueMap : model.states | ||
initializedSetClass : {} | ||
basicStates : | ||
keyProp : "basicDocumentOrder" | ||
keyValueMap : basicStates | ||
initializedSetClass : {} | ||
|
||
for purpose,info of setPurposes | ||
info.initializedSetClass = | ||
switch testJson.set.setTypeKey | ||
when "bitVector" | ||
setConstructor info.keyProp,info.keyValueMap | ||
when "boolArray" | ||
setConstructor info.keyProp,info.keyValueMap.length | ||
when "objectSet" | ||
setConstructor info.keyProp | ||
when "arraySet" | ||
setConstructor | ||
|
||
|
||
optimizations = | ||
onlySelectFromBasicStates : onlySelectFromBasicStates | ||
TransitionSet : setPurposes.transitions.initializedSetClass | ||
StateSet : setPurposes.states.initializedSetClass | ||
BasicStateSet : setPurposes.basicStates.initializedSetClass | ||
|
||
callback if testJson.extraModelInfo then [m,model,optimizations] else [m,json2ExtraModel(model),optimizations] |