cacert-testmgr/external/ZendFramework-1.9.5/externals/dojo/util/doh/robot.js

536 lines
18 KiB
JavaScript
Raw Normal View History

if(window["dojo"]){
dojo.provide("doh.robot");
dojo.experimental("doh.robot");
dojo.require("doh.runner");
}else if(!doh["robot"]){
doh.robot={};
}
if(!doh.robot["_robotLoaded"]){
(function(){
// loading state
var _robot = null;
var isSecure = (function(){
var key = Math.random();
return function(fcn){
return key;
};
})();
// no dojo available
// hijack doh.run instead
var _run = doh.run;
doh.run = function(){
if(!doh.robot._runsemaphore.unlock()){
// hijack doh._onEnd to clear the applet
// have to do it here because _browserRunner sets it in onload in standalone case
var __onEnd = doh._onEnd;
doh._onEnd = function(){
doh.robot.killRobot();
doh._onEnd = __onEnd;
doh._onEnd();
};
doh.robot.startRobot();
}
};
var cleanup=function(){
doh.robot.killRobot();
}
if(typeof dojo !== 'undefined'){
dojo.addOnUnload(cleanup)
}else{
window.onunload=cleanup;
}
var _keyPress = function(/*Number*/ charCode, /*Number*/ keyCode, /*Boolean*/ alt, /*Boolean*/ ctrl, /*Boolean*/ shift, /*Boolean*/ meta, /*Integer, optional*/ delay, /*Boolean*/ async){
// internal function to type one non-modifier key
// typecasting Numbers helps Sun's IE plugin lookup methods that take int arguments
// otherwise JS will send a double and Sun will complain
_robot.typeKey(isSecure(), Number(charCode), Number(keyCode), Boolean(alt), Boolean(ctrl), Boolean(shift), Boolean(meta), Number(delay||0), Boolean(async||false));
};
doh.robot = {
_robotLoaded: true,
_robotInitialized: false,
// prime the event pump for fast browsers like Google Chrome - it's so fast, it doesn't stop to listen for keypresses!
_spaceReceived: false,
_primePump: false,
_killApplet: function(){}, // overridden by Robot.html
killRobot: function(){
if(doh.robot._robotLoaded){
doh.robot._robotLoaded = false;
document.documentElement.className = document.documentElement.className.replace(/ ?dohRobot/);
doh.robot._killApplet();
}
},
// Robot init methods
// controls access to doh.run
// basically, doh.run takes two calls to start the robot:
// one (or more after the robot loads) from the test page
// one from either the applet or an error condition
_runsemaphore: {
lock:["lock"],
unlock:function(){
try{
return this.lock.shift();
}catch(e){
return null;
}
}
},
startRobot: function(){
//startRobot should be called to initialize the robot (after the java applet is loaded).
//one good place to do this is in a dojo.addOnLoad handler. This function will be called
//automatically if it is not already called when doh.run() is invoked.
if(!this._robotInitialized){
this._robotInitialized = true;
// if the iframe requested the applet and got a 404, then _robot is obviously unavailable
// at least run the non-robot tests!
if(doh.robot._appletDead){
doh.robot._onKeyboard();
}else{
_robot._callLoaded(isSecure());
}
}
},
_initRobot: function(r){
// called from Robot
// Robot calls _initRobot in its startup sequence
// Prevent rerunning the whole test (see #8958 for details)
if(doh._initRobotCalled){ return; }
doh._initRobotCalled = true;
// add dohRobot class to HTML element so tests can use that in CSS rules if desired
document.documentElement.className = document.documentElement.className.replace(/\S$/, "& ") + "dohRobot";
window.scrollTo(0, 0);
// document.documentElement.scrollTop = document.documentElement.scrollLeft = 0;
_robot = r;
_robot._setKey(isSecure());
// lazy load
doh.run();
},
// some utility functions to help the iframe use private variables
_run: function(frame){
frame.style.visibility = "hidden";
doh.run = _run;
doh.run();
},
_initKeyboard: function(){
_robot._initKeyboard(isSecure());
},
_initWheel: function(){
_robot._initWheel(isSecure());
},
_setDocumentBounds: function(docScreenX, docScreenY){
var robotView = document.getElementById("dohrobotview");
_robot.setDocumentBounds(isSecure(), Number(docScreenX), Number(docScreenY), Number(robotView.offsetLeft), Number(robotView.offsetTop));
},
_notified: function(keystring){
_robot._notified(isSecure(), keystring);
},
_time:0,
// if the applet is 404 or cert is denied, this becomes true and kills tests
_appletDead:false,
_assertRobot:function(){
// make sure the applet is there and cert accepted
// otherwise, skip the test requesting the robot action
if(doh.robot._appletDead){ throw new Error('doh.robot not available; skipping test.'); }
},
_mouseMove: function(/*Number*/ x, /*Number*/ y, /*Boolean*/ absolute, /*Integer, optional*/ duration){
if(absolute){
var scroll = {y: (window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop || 0),
x: (window.pageXOffset || (window["dojo"]?dojo._fixIeBiDiScrollLeft(document.documentElement.scrollLeft):undefined) || document.body.scrollLeft || 0)};
y -= scroll.y;
x -= scroll.x;
}
_robot.moveMouse(isSecure(), Number(x), Number(y), Number(0), Number(duration||100));
},
// Main doh.robot API
sequence:function(/*Function*/ f, /*Integer, optional*/ delay, /*Integer, optional*/ duration){
// summary:
// Defer an action by adding it to the robot's incrementally delayed queue of actions to execute.
//
// f:
// A function containing actions you want to defer.
//
// delay:
// Delay, in milliseconds, to wait before firing.
// The delay is a delta with respect to the previous automation call.
// For example, the following code ends after 600ms:
// doh.robot.mouseClick({left:true}, 100) // first call; wait 100ms
// doh.robot.typeKeys("dij", 500) // 500ms AFTER previous call; 600ms in all
//
// duration:
// Delay to wait after firing.
//
delay = delay || 1;
doh.robot._time += delay;
setTimeout(function(){
doh.robot._time -= delay;
f();
if(duration){
setTimeout(function(){
doh.robot._time -= duration;
}, duration);
}
}, doh.robot._time);
if(duration){
doh.robot._time += duration;
}
},
typeKeys: function(/*String||Number*/ chars, /*Integer, optional*/ delay, /*Integer, optional*/ duration){
// summary:
// Types a string of characters in order, or types a dojo.keys.* constant.
//
// description:
// Types a string of characters in order, or types a dojo.keys.* constant.
// Example: doh.robot.typeKeys("dijit.ed", 500);
//
// chars:
// String of characters to type, or a dojo.keys.* constant
//
// delay:
// Delay, in milliseconds, to wait before firing.
// The delay is a delta with respect to the previous automation call.
// For example, the following code ends after 600ms:
// doh.robot.mouseClick({left:true}, 100) // first call; wait 100ms
// doh.robot.typeKeys("dij", 500) // 500ms AFTER previous call; 600ms in all
//
// duration:
// Time, in milliseconds, to spend pressing all of the keys.
//
this._assertRobot();
this.sequence(function(){
duration=duration||0;
if(typeof(chars) == Number){
_keyPress(chars, chars, false, false, false, false, delay);
}else if(chars.length){
for(var i = 0; i<chars.length; i++){
_keyPress(chars.charCodeAt(i), 0, false, false, false, false, duration/chars.length);
}
}
}, delay, duration);
},
keyPress: function(/*Integer*/ charOrCode, /*Integer, optional*/ delay, /*Object*/ modifiers, /*Boolean*/ asynchronous){
// summary:
// Types a key combination, like SHIFT-TAB.
//
// description:
// Types a key combination, like SHIFT-TAB.
// Example: to press shift-tab immediately, call doh.robot.keyPress(dojo.keys.TAB, 0, {shift:true})
//
// charOrCode:
// char/JS keyCode/dojo.keys.* constant for the key you want to press
//
// delay:
// Delay, in milliseconds, to wait before firing.
// The delay is a delta with respect to the previous automation call.
// For example, the following code ends after 600ms:
// doh.robot.mouseClick({left:true}, 100) // first call; wait 100ms
// doh.robot.typeKeys("dij", 500) // 500ms AFTER previous call; 600ms in all
//
// modifiers:
// JSON object that represents all of the modifier keys being pressed.
// It takes the following Boolean attributes:
// - shift
// - alt
// - ctrl
//
// asynchronous:
// If true, the delay happens asynchronously and immediately, outside of the browser's JavaScript thread and any previous calls.
// This is useful for interacting with the browser's modal dialogs.
//
this._assertRobot();
if(!modifiers){
modifiers = {alt:false, ctrl:false, shift:false, meta:false};
}else{
// normalize modifiers
var attrs = ["alt", "ctrl", "shift", "meta"];
for(var i = 0; i<attrs.length; i++){
if(!modifiers[attrs[i]]){
modifiers[attrs[i]] = false;
}
}
}
var isChar = typeof(charOrCode)=="string";
if(asynchronous){
_keyPress(isChar?charOrCode.charCodeAt(0):0, isChar?0:charOrCode, modifiers.alt, modifiers.ctrl, modifiers.shift, modifiers.meta, delay, true);
return;
}
this.sequence(function(){
_keyPress(isChar?charOrCode.charCodeAt(0):0, isChar?0:charOrCode, modifiers.alt, modifiers.ctrl, modifiers.shift, modifiers.meta, 0);
},delay);
},
keyDown: function(/*Integer*/ charOrCode, /*Integer, optional*/ delay){
// summary:
// Holds down a single key, like SHIFT or 'a'.
//
// description:
// Holds down a single key, like SHIFT or 'a'.
// Example: to hold down the 'a' key immediately, call doh.robot.keyDown('a')
//
// charOrCode:
// char/JS keyCode/dojo.keys.* constant for the key you want to hold down
// Warning: holding down a shifted key, like 'A', can have unpredictable results.
//
// delay:
// Delay, in milliseconds, to wait before firing.
// The delay is a delta with respect to the previous automation call.
// For example, the following code ends after 600ms:
// doh.robot.mouseClick({left:true}, 100) // first call; wait 100ms
// doh.robot.typeKeys("dij", 500) // 500ms AFTER previous call; 600ms in all
//
this._assertRobot();
this.sequence(function(){
var isChar = typeof(charOrCode)=="string";
_robot.downKey(isSecure(), isChar?charOrCode:0, isChar?0:charOrCode, 0);
},delay);
},
keyUp: function(/*Integer*/ charOrCode, /*Integer, optional*/ delay){
// summary:
// Releases a single key, like SHIFT or 'a'.
//
// description:
// Releases a single key, like SHIFT or 'a'.
// Example: to release the 'a' key immediately, call doh.robot.keyUp('a')
//
// charOrCode:
// char/JS keyCode/dojo.keys.* constant for the key you want to release
// Warning: releasing a shifted key, like 'A', can have unpredictable results.
//
// delay:
// Delay, in milliseconds, to wait before firing.
// The delay is a delta with respect to the previous automation call.
// For example, the following code ends after 600ms:
// doh.robot.mouseClick({left:true}, 100) // first call; wait 100ms
// doh.robot.typeKeys("dij", 500) // 500ms AFTER previous call; 600ms in all
//
this._assertRobot();
this.sequence(function(){
var isChar=typeof(charOrCode)=="string";
_robot.upKey(isSecure(), isChar?charOrCode:0, isChar?0:charOrCode, 0);
},delay);
},
mouseClick: function(/*Object*/ buttons, /*Integer, optional*/ delay){
// summary:
// Convenience function to do a press/release.
// See doh.robot.mousePress for more info.
//
// description:
// Convenience function to do a press/release.
// See doh.robot.mousePress for more info.
//
this._assertRobot();
doh.robot.mousePress(buttons, delay);
doh.robot.mouseRelease(buttons, 1);
},
mousePress: function(/*Object*/ buttons, /*Integer, optional*/ delay){
// summary:
// Presses mouse buttons.
// description:
// Presses the mouse buttons you pass as true.
// Example: to press the left mouse button, pass {left:true}.
// Mouse buttons you don't specify keep their previous pressed state.
//
// buttons: JSON object that represents all of the mouse buttons being pressed.
// It takes the following Boolean attributes:
// - left
// - middle
// - right
//
// delay:
// Delay, in milliseconds, to wait before firing.
// The delay is a delta with respect to the previous automation call.
// For example, the following code ends after 600ms:
// doh.robot.mouseClick({left:true}, 100) // first call; wait 100ms
// doh.robot.typeKeys("dij", 500) // 500ms AFTER previous call; 600ms in all
//
this._assertRobot();
if(!buttons){ return; }
this.sequence(function(){
var attrs = ["left", "middle", "right"];
for(var i = 0; i<attrs.length; i++){
if(!buttons[attrs[i]]){
buttons[attrs[i]] = false;
}
}
_robot.pressMouse(isSecure(), Boolean(buttons.left), Boolean(buttons.middle), Boolean(buttons.right), Number(0));
},delay);
},
mouseMove: function(/*Number*/ x, /*Number*/ y, /*Integer, optional*/ delay, /*Integer, optional*/ duration, /*Boolean*/ absolute){
// summary:
// Moves the mouse to the specified x,y offset relative to the viewport.
//
// x:
// x offset relative to the viewport, in pixels, to move the mouse.
//
// y:
// y offset relative to the viewport, in pixels, to move the mouse.
//
// delay:
// Delay, in milliseconds, to wait before firing.
// The delay is a delta with respect to the previous automation call.
// For example, the following code ends after 600ms:
// doh.robot.mouseClick({left:true}, 100) // first call; wait 100ms
// doh.robot.typeKeys("dij", 500) // 500ms AFTER previous call; 600ms in all
//
// duration:
// Approximate time Robot will spend moving the mouse
// The default is 100ms. This also affects how many mousemove events will
// be generated, which is the log of the duration.
//
// absolute:
// Boolean indicating whether the x and y values are absolute coordinates.
// If false, then mouseMove expects that the x,y will be relative to the window. (clientX/Y)
// If true, then mouseMove expects that the x,y will be absolute. (pageX/Y)
//
this._assertRobot();
duration = duration||100;
this.sequence(function(){
doh.robot._mouseMove(x, y, absolute, duration);
},delay,duration);
},
mouseRelease: function(/*Object*/ buttons, /*Integer, optional*/ delay){
// summary:
// Releases mouse buttons.
//
// description:
// Releases the mouse buttons you pass as true.
// Example: to release the left mouse button, pass {left:true}.
// Mouse buttons you don't specify keep their previous pressed state.
// See doh.robot.mousePress for more info.
//
this._assertRobot();
if(!buttons){ return; }
this.sequence(function(){
var attrs = ["left", "middle", "right"];
for(var i = 0; i<attrs.length; i++){
if(!buttons[attrs[i]]){
buttons[attrs[i]] = false;
}
}
_robot.releaseMouse(isSecure(), Boolean(buttons.left), Boolean(buttons.middle), Boolean(buttons.right), Number(0));
},delay);
},
// mouseWheelSize: Integer value that determines the amount of wheel motion per unit
mouseWheelSize: 1,
mouseWheel: function(/*Number*/ wheelAmt, /*Integer, optional*/ delay, /*Integer, optional*/ duration){
// summary:
// Spins the mouse wheel.
//
// description:
// Spins the wheel wheelAmt "notches."
// Negative wheelAmt scrolls up/away from the user.
// Positive wheelAmt scrolls down/toward the user.
// Note: this will all happen in one event.
// Warning: the size of one mouse wheel notch is an OS setting.
// You can accesss this size from doh.robot.mouseWheelSize
//
// wheelAmt:
// Number of notches to spin the wheel.
// Negative wheelAmt scrolls up/away from the user.
// Positive wheelAmt scrolls down/toward the user.
//
// delay:
// Delay, in milliseconds, to wait before firing.
// The delay is a delta with respect to the previous automation call.
// For example, the following code ends after 600ms:
// doh.robot.mouseClick({left:true}, 100) // first call; wait 100ms
// doh.robot.typeKeys("dij", 500) // 500ms AFTER previous call; 600ms in all
//
// duration:
// Approximate time Robot will spend moving the mouse
// By default, the Robot will wheel the mouse as fast as possible.
//
this._assertRobot();
if(!wheelAmt){ return; }
this.sequence(function(){
_robot.wheelMouse(isSecure(), Number(wheelAmt), Number(0), Number(duration||0));
},delay,duration);
},
setClipboard: function(/*String*/data,/*String, optional*/format){
// summary:
// Set clipboard content.
//
// description:
// Set data as clipboard content, overriding anything already there. The
// data will be put to the clipboard using the given format.
//
// data:
// New clipboard content to set
//
// format:
// Set this to "text/html" to put richtext to the clipboard.
// Otherwise, data is treated as plaintext. By default, plaintext
// is used.
if(format==='text/html'){
_robot.setClipboardHtml(isSecure(),data);
}else{
_robot.setClipboardText(isSecure(),data);
}
}
};
// the applet itself
// needs to be down here so the handlers are set up
var iframesrc;
var scripts = document.getElementsByTagName("script");
for(var x = 0; x<scripts.length; x++){
var s = scripts[x].getAttribute('src');
if(s && (s.substr(s.length-9) == "runner.js")){
iframesrc = s.substr(0, s.length-9)+'Robot.html';
break;
}
}
// if loaded with dojo, there might not be a runner.js!
if(!iframesrc && window["dojo"]){
iframesrc = dojo.moduleUrl("util", "doh/")+"Robot.html";
}
document.writeln('<div id="dohrobotview" style="border:0px none; margin:0px; padding:0px; position:absolute; bottom:0px; right:0px; width:1px; height:1px; overflow:hidden; visibility:hidden; background-color:red;"></div>'+
'<iframe style="border:0px none; z-index:32767; padding:0px; margin:0px; position:absolute; left:0px; top:0px; height:42px; width:200px; overflow:hidden; background-color:transparent;" tabIndex="-1" src="'+iframesrc+'" ALLOWTRANSPARENCY="true"></iframe>');
})();
}