Make things much prettier and add some automated tests.

git-svn-id: svn://10.0.0.236/branches/DOM_AGNOSTIC_BRANCH@181848 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
mhammond%skippinet.com.au
2005-10-09 10:43:30 +00:00
parent 97230e2a43
commit b032d89c5f
4 changed files with 166 additions and 53 deletions

View File

@@ -1,14 +1,79 @@
# Runs non-ui related test code.
# Runs test code in a UI environment. Generally anything which can be tested
# without visual confirmation is suitable for running here.
# Note too that the simple fact we *can* display a UI and run tests is
# exercising lots of things.
import sys
from xpcom import components
import xpcom
def do_onload():
# Why can't I get args??
# Intention is to look at window.arguments and determine what 'test'
# we are being asked to run.
print "OnLoad called"
raise "foo"
close_on_success = True
def do_onerror(*arguments):
print "OnError called"
print "Args are", arguments
# Utility functions
# Write something to the textbox - eg, error or trace messages.
def write( msg, *args):
tb = this.document.getElementById("output-box")
val = tb.getAttribute("value")
val += (msg % args) + "\n"
tb.setAttribute("value", val)
def success():
# This gets called if the test works. If it is not called, it must not
# have worked :)
write("The test worked!")
if close_on_success:
print "Closing the window - nothing interesting to see here!"
window.close()
def cause_error():
write("Raising an error")
raise "Testing Testing"
def handle_error_with_cancel(errMsg, source, lineno):
success()
def test_error_explicit():
"Test an explicit assignment of a function object to onerror"
# Assign a function to an onerror attribute
write("Assigning a function to window.onerror")
window.onerror = handle_error_with_cancel
cause_error()
def test_error_explicit_string():
"Test an explicit assignment of a string to onerror"
# Assign a string to an onerror attribute
write("Assigning a string to window.onerror")
window.onerror = "handle_error_with_cancel(event, source, lineno)"
cause_error()
class EventListener:
_com_interfaces_ = components.interfaces.nsIDOMEventListener
def handleEvent(self, event):
write("nsIDOMEventListener caught the event")
success()
def test_error_eventhandler():
"""Test we can explicitly hook the error with our own nsIDOMEventListener"""
write("Creating an nsIDOMEventListener to listen for the event")
window.addEventListener("onerror", EventListener(), False)
write("For some reason 'onerror' is not working. Onload appears to?")
write("I need to check out if this works from JS first")
cause_error()
# The general event handlers and test runner code.
def do_onload(event):
global close_on_success
klasses = []
if len(this.arguments) and this.arguments[0]:
try:
func = globals()[this.arguments[0]]
except KeyError:
print "*** No such test", this.arguments[0]
func = None
else:
func = test_error_explicit_string
close_on_success = False
if len(this.arguments)>1 and this.arguments[1]=="-k":
close_on_success = False
if func:
write(func.__doc__ or func.__name__)
func()

View File

@@ -2,7 +2,8 @@
<?xml-stylesheet href="chrome://communicator/skin/" type="text/css"?>
<!-- A container for general test code. Relies on being passed an argument
for which test to run
for which test to run. Generally it runs the test and closes, only
staying open when something goes wrong.
-->
<window
@@ -11,14 +12,16 @@
screenX="100" screenY="100"
height="300" width="500"
script-type="application/x-python"
onload="do_onload()" onerror="do_onerror(event, source, lineno)"
onload="do_onload(event)"
onunload="print 'The test runner form is unloading'"
title="Test Runner"
>
<script src="chrome://pyxultest/content/pytester.py"/>
<script type="application/javascript">
dump('hello from js\n');
function x_onload() {
dump('JS Args are' + window.arguments + '\n');
}
//window.onload = onload;
dump('hello from js with args ' + window.arguments.length + '\n');
</script>
<textbox id="output-box" style="width:100%" value = ""
rows="15" multiline="true" flex="1"
/>
</window>

View File

@@ -3,10 +3,18 @@
import sys
import xpcom
from xpcom import components
import nsdom
# This EventListener class is to work around the fact that
# addEventListener can not automagically wrap a string or function like
# JS can.
# Utility functions
# Write something to the textbox - eg, error or trace messages.
def write( msg, *args):
tb = this.document.getElementById("output_box")
val = tb.getAttribute("value")
val += (msg % args) + "\n"
tb.setAttribute("value", val)
# An event listener class to test explicit hooking of events via objects.
# Note Python can now just call addEventListener a-la JS
class EventListener:
_com_interfaces_ = components.interfaces.nsIDOMEventListener
def __init__(self, handler, globs = None):
@@ -22,22 +30,25 @@ class EventListener:
# An event function to handle onload - but hooked up manually rather than via
# having the magic name 'onload'
def do_load():
input = this.document.getElementById("input-box")
val = "This is the Python on XUL demo using\nPython " + sys.version
input.setAttribute("value", val)
# Sadly no inline event handlers yet - hook up a click event.
button = this.document.getElementById("button1")
button.addEventListener('click', EventListener('print "hello from the click event"'), False)
input = this.document.getElementById("output_box")
# Clear the text in the XUL
input.setAttribute("value", "")
write("This is the Python on XUL demo using\nPython " + sys.version)
# Add the event listener.
this.window.addEventListener('load', EventListener(do_load), False)
# Sadly no inline event handlers yet - hook up a click event.
button = this.document.getElementById("but_dialog")
button.addEventListener('click', 'write("hello from the click event for the dialog button")', False)
# Add an event listener as a function
this.window.addEventListener('load', do_load, False)
# Add another one just to test passing a string instead of a function.
this.window.addEventListener('load', EventListener('print "hello from the event " + str(this.document)'), False)
this.window.addEventListener('load', "print 'hello from string event handler'", False)
# And yet another with an explicit EventListener instance. (on error tests can't do this?)
this.window.addEventListener('load', EventListener('print "hello from an object event handler"'), False)
# Some other little functions called by the chrome
def on_button_click():
print "Button clicked from", this.window.location.href
def on_but_dialog_click():
write("Button clicked from %s" % this.window.location.href)
# window.open doesn't work as JS has special arg handling :(
# for now, use our hacky (but quite wonderful) JSExec function.
import nsdom
@@ -45,8 +56,19 @@ def on_button_click():
#new = this.window.open("chrome://pyxultest/content/dialog.xul", "my-dialog", "chrome")
#print "The new window is", new
def test_error_event():
import nsdom
nsdom.JSExec(this, 'this.window.openDialog("chrome://pyxultest/content/pytester.xul", "my-dialog", "modal", "test_error_event")')
#new = this.window.open("chrome://pyxultest/content/dialog.xul", "my-dialog", "chrome")
#print "The new window is", new
def run_tests():
tests = """test_error_explicit test_error_explicit_string
test_error_eventhandler""".split()
keep_open = this.document.getElementById("keep_tests_open").getAttribute("checked")
for test in tests:
write("Running test %s" % test)
suffix = ', "%s"' % test
if keep_open:
suffix += ', "-k"'
cmd = 'this.window.openDialog("chrome://pyxultest/content/pytester.xul", "my-dialog", "modal"%s)' % suffix
print "cmd is", cmd
nsdom.JSExec(this, cmd)
if keep_open:
write("Ran all the tests - the windows told you if the tests worked")
else:
write("Ran all the tests - if you saw no window, it worked!")

View File

@@ -8,9 +8,10 @@
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
id="main-window" orient="vertical"
screenX="100" screenY="100"
height="300" width="500"
height="450" width="600"
script-type="application/x-python"
onload="print 'hello from the window load event'"
title="Python in XUL demos and tests"
>
<script type="application/x-python" src="chrome://pyxultest/content/pyxultest.py"/>
<script>
@@ -27,23 +28,45 @@ print "Window location is", this.window.location.href
]]>
</script>
<vbox flex="1">
<textbox id="input-box" style="width:100%" value = "hello there"
rows="5" multiline="true" flex="1"
<textbox id="output_box" style="width:100%"
value = "If you can see this, things aren't working well!"
rows="15" multiline="true" flex="1"
/>
<button id="button1" label="open dialog"
oncommand="on_button_click()"/>
</vbox>
<!-- A box from our overlay - it will have one button using js events
and another using Python events -->
<hbox id="language_box"/>
<button id="but_multi" label="click for both"/>
<!-- Here we have a script element defined at a parent node -->
<hbox oncommand="print 'You clicked on a', event.target.tagName">
<button label = "click here"/>
<button label = "or here"/>
<button id="test_error" label="test error event" oncommand="test_error_event()"/>
</hbox>
<groupbox>
<caption label="Items from Overlays"/>
<!-- A box from our overlay - it will have one button using js events
and another using Python events -->
<hbox>
<hbox id="language_box"/>
<button id="but_multi" label="click for both"/>
</hbox>
</groupbox>
<groupbox>
<caption label="Random Buttons"/>
<hbox>
<!-- Here we have a script element defined at a parent node -->
<hbox oncommand="write('You clicked on a %s with id=%s' % (event.target.tagName, event.target.getAttribute('id')))">
<button id="some-button" label = "click here"/>
<button id="another-button" label = "or here"/>
</hbox>
<button id="but_dialog" label="open dialog"
oncommand="on_but_dialog_click()"/>
</hbox>
</groupbox>
<groupbox>
<caption label="Automated tests"/>
<hbox>
<button id="test_error" label="Run tests" oncommand="run_tests()"/>
<vbox flex="1">
<text class="label" value="The test window is not shown if the tests are successful"/>
<checkbox id="keep_tests_open" label="Always keep test window open"/>
</vbox>
</hbox>>
</groupbox>
</window>