sku-pg
Version:
Skulpt is a Javascript implementation of Python 2.x. Python that runs in your browser!
339 lines (275 loc) • 8.26 kB
HTML
<!--
Author: bpearcy@google.com (Brandon Pearcy)
-->
<html>
<!--
Copyright 2009 The Closure Library Authors. All Rights Reserved.
Use of this source code is governed by an Apache 2.0 License.
See the COPYING file for details.
-->
<head>
<title>CrossPageChannel: End-to-End Test</title>
<script src="../../base.js"></script>
<script>
goog.require('goog.Disposable');
goog.require('goog.debug.Logger');
goog.require('goog.dom');
goog.require('goog.net.xpc.CrossPageChannel');
goog.require('goog.testing.AsyncTestCase');
goog.require('goog.testing.PropertyReplacer');
goog.require('goog.testing.jsunit');
</script>
</head>
<body>
<script>
var IFRAME_LOAD_WAIT_MS = 2000;
var stubs = new goog.testing.PropertyReplacer();
var asyncTestCase = goog.testing.AsyncTestCase.createAndInstall(
document.title);
var uniqueId = 0;
var driver;
function setUpPage() {
asyncTestCase.stepTimeout = 10 * 1000;
// Show debug log
var debugDiv = goog.dom.getElement('debugDiv');
var logger = goog.debug.Logger.getLogger('goog.net.xpc');
logger.setLevel(goog.debug.Logger.Level.ALL);
logger.addHandler(function(logRecord) {
var msgElm = goog.dom.createDom('div');
msgElm.innerHTML = logRecord.getMessage();
goog.dom.appendChild(debugDiv, msgElm);
});
}
function setUp() {
driver = new Driver();
}
function tearDown() {
stubs.reset();
driver.dispose();
}
function testCreateIframeSpecifyId() {
driver.createPeerIframe('new_iframe');
asyncTestCase.waitForAsync('iframe load');
window.setTimeout(function() {
asyncTestCase.continueTesting();
driver.checkPeerIframe();
}, IFRAME_LOAD_WAIT_MS);
}
function testCreateIframeRandomId() {
driver.createPeerIframe();
asyncTestCase.waitForAsync('iframe load');
window.setTimeout(function() {
asyncTestCase.continueTesting();
driver.checkPeerIframe();
}, IFRAME_LOAD_WAIT_MS);
}
function testCreateIframeAsynchronousConnect() {
driver.createPeerIframe('new_iframe');
asyncTestCase.waitForAsync('iframe load');
window.setTimeout(function() {
driver.connect();
}, IFRAME_LOAD_WAIT_MS);
}
function testCreateIframeSynchronousConnect() {
driver.createPeerIframe('new_iframe');
driver.connect();
}
function testExistingIframeConnect() {
driver.createChannel('test_iframe');
driver.connect();
}
/**
* Driver for the tests for CrossPageChannel.
*
* @constructor
* @extends {goog.Disposable}
*/
Driver = function() {
/**
* The peer iframe.
* @type {!Element}
* @private
*/
this.iframe_ = null;
/**
* The ID of the peer iframe.
* @type {string}
* @private
*/
this.iframeId_ = 'test_iframe';
/**
* Channel configuration object.
* @type {Object}
* @private
*/
this.cfg_ = null;
/**
* The channel to use.
* @type {goog.net.xpc.CrossPageChannel}
* @private
*/
this.channel_ = null;
};
goog.inherits(Driver, goog.Disposable);
/**
* Disposes of the channel.
*/
Driver.prototype.disposeInternal = function() {
goog.net.xpc.CrossPageChannel.superClass_.disposeInternal.call(this);
if (this.channel_) {
this.channel_.dispose();
}
};
/**
* Returns the child peer's window object.
* @return {Window} Child peer's window.
* @private
*/
Driver.prototype.getInnerPeer_ = function() {
return window.frames[this.iframeId_];
};
/**
* Creates the channel.
* @param {string} opt_iframeId If present, the ID of the iframe to use,
* otherwise, tells the channel to generate an iframe ID.
*/
Driver.prototype.createChannel = function(opt_iframeId) {
var cfg = {};
if (opt_iframeId) {
this.iframeId_ = opt_iframeId;
cfg[goog.net.xpc.CfgFields.IFRAME_ID] = opt_iframeId;
}
cfg[goog.net.xpc.CfgFields.PEER_URI] = 'testdata/inner_peer.html';
cfg[goog.net.xpc.CfgFields.CHANNEL_NAME] = 'test_channel' + uniqueId++;
cfg[goog.net.xpc.CfgFields.LOCAL_POLL_URI] = 'does-not-exist.html';
cfg[goog.net.xpc.CfgFields.PEER_POLL_URI] = 'does-not-exist.html';
this.channel_ = new goog.net.xpc.CrossPageChannel(cfg);
this.channel_.registerService('msg', goog.bind(this.msgHandler_, this));
this.cfg_ = cfg;
};
/**
* Creates the peer iframe.
* @param {string} opt_iframeId If present, the ID of the iframe to create,
* otherwise, generates an iframe ID.
*/
Driver.prototype.createPeerIframe = function(opt_iframeId) {
var expectedIframeId;
if (opt_iframeId) {
expectedIframeId = opt_iframeId = opt_iframeId + uniqueId++;
} else {
// Have createPeerIframe() generate an ID
stubs.set(goog.net.xpc, 'getRandomString', function(length) {
return '' + length;
});
expectedIframeId = 'xpcpeer4';
}
assertNull('element[id=' + expectedIframeId + '] exists',
goog.dom.getElement(expectedIframeId));
this.createChannel(opt_iframeId);
this.iframe_ = this.channel_.createPeerIframe(document.body);
assertEquals(expectedIframeId, this.iframe_.id);
this.iframeId_ = expectedIframeId;
};
/**
* Checks if the peer iframe has been created.
*/
Driver.prototype.checkPeerIframe = function() {
assertNotNull(goog.dom.getElement(this.iframeId_));
var peer = this.getInnerPeer_();
assertNotNull(peer);
assertNotNull(peer.document);
};
/**
* Starts the connection. The connection happens asynchronously.
*/
Driver.prototype.connect = function() {
// TODO(user): Get tests to pass for all transports
if (!this.isTransportTestable_()) {
asyncTestCase.continueTesting();
return;
}
if (this.iframe_) {
// When we create an iframe, we send the config
// and it connects itself.
this.childConnected_();
} else {
asyncTestCase.waitForAsync('parent and child connect');
var peer = this.getInnerPeer_();
peer.instantiateChannel(this.cfg_);
peer.connectChannel(goog.bind(this.childConnected_, this));
}
this.channel_.connect(goog.bind(this.parentConnected_, this));
};
/**
* Determines if the transport type for the channel is testable.
* Some transports are misusing global state or making other
* assumptions that cause connections to fail.
* @return {boolean} Whether the transport is testable.
* @private
*/
Driver.prototype.isTransportTestable_ = function() {
var testable = true;
var transportType = this.channel_.determineTransportType_();
switch (transportType) {
case goog.net.xpc.TransportTypes.NATIVE_MESSAGING:
case goog.net.xpc.TransportTypes.IFRAME_RELAY:
case goog.net.xpc.TransportTypes.IFRAME_POLLING:
case goog.net.xpc.TransportTypes.FLASH:
case goog.net.xpc.TransportTypes.NIX:
testable = false;
break;
}
return testable;
};
/**
* Callback for the parent connection.
* @private
*/
Driver.prototype.parentConnected_ = function() {
var peer = this.getInnerPeer_();
if (peer.isConnected()) {
asyncTestCase.waitForAsync('child echo');
} else {
asyncTestCase.waitForAsync('child connect');
}
this.channel_.send('echo', 'hello')
};
/**
* Callback for the child connection.
* @private
*/
Driver.prototype.childConnected_ = function() {
if (this.channel_.isConnected()) {
asyncTestCase.waitForAsync('child echo');
} else {
asyncTestCase.waitForAsync('parent connect');
}
};
/**
* The handler function for incoming msg requests.
* @param {string} payload The message payload.
* @private
*/
Driver.prototype.msgHandler_ = function(payload) {
assertTrue('parent should be connected', this.channel_.isConnected());
var peer = this.getInnerPeer_();
assertTrue('child should be connected', peer.isConnected());
assertEquals('hello', payload);
asyncTestCase.continueTesting();
};
</script>
<!-- Debug box. -->
<div style="position:absolute; float: right; top: 10px; right: 10px">
Debug [<a href="#" onclick="document.getElementById('debugDiv').innerHTML = '';">clear</a>]: <br/>
<div id="debugDiv" style="border: 1px #000000 solid; font-size:xx-small"></div>
</div>
<!--
Setup inner peer. This must be done in the <body>, so that the inner peer iframe
blocks the onload event in this window until it is fully loaded. The JsUnit
tests will execute after the onload event fires.
-->
<iframe name=test_iframe id=test_iframe src=testdata/inner_peer.html width=300 height=250>
</iframe>
</body>
</html>