Skip to content
This repository has been archived by the owner on Sep 25, 2018. It is now read-only.

Commit

Permalink
Bidirectional communication now working with xdotool and ajax. Passes…
Browse files Browse the repository at this point in the history
… simple test. Next step will be to run all tests.
  • Loading branch information
jbeard4 committed Sep 5, 2011
1 parent 021e743 commit 101567f
Show file tree
Hide file tree
Showing 3 changed files with 242 additions and 97 deletions.
@@ -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 src/main/coffeescript/scxml/test/multi-process-browser/harness.coffee
@@ -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)
@@ -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]

0 comments on commit 101567f

Please sign in to comment.