You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
166 lines
5.5 KiB
166 lines
5.5 KiB
define([ |
|
"require", |
|
"doh/main", |
|
"./aspect", |
|
"./dom-construct", |
|
"./dom-style", |
|
"./_base/kernel", |
|
"./_base/lang", |
|
"./on", |
|
"./robot", |
|
"./sniff", |
|
"./_base/window" |
|
], function(require, doh, aspect, construct, style, kernel, lang, on, robot, has, win){ |
|
|
|
kernel.experimental("dojo.robotx"); |
|
|
|
// module: |
|
// dojo.robotx |
|
// description: |
|
// loads an external app into an iframe and points dojo.doc to the iframe document, allowing the robot to control it |
|
// to use: set robotURL in djConfig to the URL you want to load |
|
// dojo.require this file |
|
|
|
// The iframe containing the external app |
|
var iframe = null; |
|
|
|
// urlLoaded is a Deferred that will be resolved whenever the iframe passed to initRobot() finishes loading, or reloads |
|
var urlLoaded; |
|
|
|
function attachIframe(url){ |
|
// summary: |
|
// Create iframe to load external app at specified url. Iframe gets onload handler to call onIframeLoad() |
|
// when specified URL finishes loading, and also if the iframe loads a different URL in the future. |
|
// returns: |
|
// A Deferred that fires when everything has finished initializing |
|
|
|
require(["./domReady!"], function(){ |
|
var emptyStyle = { |
|
overflow: "hidden", |
|
margin: "0px", |
|
borderWidth: "0px", |
|
height: "100%", |
|
width: "100%" |
|
}; |
|
style.set(document.documentElement, emptyStyle); |
|
style.set(document.body, emptyStyle); |
|
|
|
// Create the iframe for the external document. |
|
// console.log("creating iframe for external document"); |
|
iframe = document.createElement("iframe"); |
|
iframe.setAttribute("ALLOWTRANSPARENCY","true"); |
|
iframe.scrolling = has("ie") ? "yes" : "auto"; |
|
var scrollRoot = document.compatMode == "BackCompat" ? document.body : document.documentElement; |
|
style.set(iframe, { |
|
border: "0px none", |
|
padding: "0px", |
|
margin: "0px", |
|
width: "100%", |
|
height: "100%" |
|
}); |
|
iframe.src = url; |
|
|
|
// Code to handle load event on iframe. Seems like this should happen before setting iframe src on line above? |
|
// Also, can't we use on() in all cases, even for old IE? |
|
if(iframe.attachEvent !== undefined){ |
|
iframe.attachEvent("onload", onIframeLoad); |
|
}else{ |
|
on(iframe, "load", onIframeLoad); |
|
} |
|
|
|
construct.place(iframe, win.body(), "first"); |
|
}); |
|
} |
|
|
|
function onIframeLoad(){ |
|
// summary: |
|
// Load handler when iframe specified to initRobot() finishes loading, or when it reloads. |
|
// It resolves the urlLoaded Deferred to make the rests of the tests runs. |
|
|
|
robot._updateDocument(); |
|
|
|
// If dojo is present in the test case, then at least make a best effort to wait for it to load. |
|
// The test must handle other race conditions like initial data queries or asynchronous parses by itself. |
|
if(iframe.contentWindow.require){ |
|
iframe.contentWindow.require(["dojo/ready"], function(ready){ |
|
ready(Infinity, function(){ |
|
setTimeout(function(){ |
|
urlLoaded.resolve(true); |
|
}, 500); // 500ms fudge factor; otherwise focus doesn't work on IE8, see ValidationTextBox.js, TimeTextBox.js, etc. |
|
}); |
|
}); |
|
}else{ |
|
urlLoaded.resolve(true); |
|
} |
|
} |
|
|
|
lang.mixin(robot, { |
|
_updateDocument: function(){ |
|
// summary: |
|
// Called every time a new page is loaded into the iframe, to setup variables |
|
// Point dojo.global, dojo.publish, etc. to refer to iframe. |
|
// Remove for 2.0? |
|
|
|
kernel.setContext(iframe.contentWindow, iframe.contentWindow.document); |
|
|
|
// Also set pointers inside robot, for easy access via AMD (where there is no dojo variable) |
|
robot.window = iframe.contentWindow; |
|
robot.doc = iframe.contentWindow.document; |
|
|
|
// TODO: shouldn't this wait until dojo has finished loading in the iframe? See require code in onIframeLoad(). |
|
var win = kernel.global; |
|
if(win.dojo){ |
|
// allow the tests to subscribe to topics published by the iframe |
|
kernel.publish = win.dojo.publish; |
|
kernel.subscribe = win.dojo.subscribe; |
|
kernel.connectPublisher = win.dojo.connectPublisher; |
|
} |
|
}, |
|
|
|
initRobot: function(/*String*/ url){ |
|
// summary: |
|
// Opens the application at the specified URL for testing, redirecting dojo to point to the application |
|
// environment instead of the test environment. |
|
// url: |
|
// URL to open. Any of the test's dojo.doc calls (e.g. dojo.byId()), and any dijit.registry calls |
|
// (e.g. dijit.byId()) will point to elements and widgets inside this application. |
|
|
|
doh.registerGroup("initialize robot", { |
|
name: "load " + url, |
|
timeout: 100000, // could take more than 10s so setting to 100s |
|
runTest: function(){ |
|
// Setup module level urlLoaded Deferred that will be resolved by onIframeLoad(), after the iframe |
|
// has finished loading |
|
urlLoaded = new doh.Deferred(); |
|
attachIframe(url); |
|
|
|
return urlLoaded; |
|
} |
|
}); |
|
}, |
|
|
|
waitForPageToLoad: function(/*Function*/ submitActions){ |
|
// summary: |
|
// Notifies DOH that the doh.robot is about to make a page change in the application it is driving, |
|
// returning a doh.Deferred object the user should return in their runTest function as part of a DOH test. |
|
// example: |
|
// | runTest: function(){ |
|
// | return waitForPageLoad(function(){ doh.robot.keyPress(keys.ENTER, 500); }); |
|
// | } |
|
// submitActions: |
|
// The doh.robot will execute the actions the test passes into the submitActions argument (like clicking the submit button), |
|
// expecting these actions to create a page change (like a form submit). |
|
// After these actions execute and the resulting page loads, the next test will start. |
|
|
|
// Setup a new Deferred that onIframeLoad() will resolve when the iframe finishes loading |
|
urlLoaded = new doh.Deferred(); |
|
|
|
submitActions(); |
|
|
|
return urlLoaded; |
|
} |
|
|
|
}); |
|
|
|
return robot; |
|
});
|
|
|