http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/27eb06f5/mustella/src/main/flex/PixelSnifferRemote.as ---------------------------------------------------------------------- diff --git a/mustella/src/main/flex/PixelSnifferRemote.as b/mustella/src/main/flex/PixelSnifferRemote.as new file mode 100644 index 0000000..f3d567c --- /dev/null +++ b/mustella/src/main/flex/PixelSnifferRemote.as @@ -0,0 +1,205 @@ +//////////////////////////////////////////////////////////////////////////////// +// +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. +// The ASF licenses this file to You under the Apache License, Version 2.0 +// (the "License"); you may not use this file except in compliance with +// the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//////////////////////////////////////////////////////////////////////////////// +package +{ +import flash.display.BitmapData; +import flash.display.DisplayObject; +import flash.events.Event; +import flash.events.MouseEvent; +import flash.events.StatusEvent; +import flash.geom.Matrix; +import flash.geom.Point; +import flash.net.LocalConnection; + +import mx.managers.IFocusManagerComponent; +import mx.managers.SystemManager; +import mx.core.FlexGlobals; +import mx.core.IFlexDisplayObject; +import mx.core.IMXMLObject; +import mx.core.UIComponent; +import mx.core.IVisualElementContainer; +import mx.core.mx_internal; +use namespace mx_internal; + +[Mixin] +/** + * Displays positions and pixel colors to SnifferRemoteClient.swf + */ +public class PixelSnifferRemote +{ + public function PixelSnifferRemote() + { + } + + public static function init(root:Object):void + { + document = root; + if (document) + document.addEventListener("applicationComplete", initHandler); + + connection = new LocalConnection(); + connection.allowDomain("*"); + connection.addEventListener(StatusEvent.STATUS, statusHandler); + + pixelcommandconnection = new LocalConnection(); + pixelcommandconnection.allowDomain("*"); + pixelcommandconnection.client = PixelSnifferRemote; + pixelcommandconnection.connect("_PixelSnifferCommands"); + } + + // Turn on only if the SnifferRemoteClient app's checkbox + // for this item is checked. + private static function initHandler(event:Event):void + { + connection.send("_PixelSniffer", "toggleSniffersEnabled"); + } + + private static function statusHandler(event:Event):void + { + } + + /** + * @private + * The document containing a reference to this object + */ + private static var document:Object; + + /** + * @private + * The local connection to the remote client + */ + private static var connection:LocalConnection; + private static var pixelcommandconnection:LocalConnection; + + + public static function enableSniffer():void + { + + // hook UIComponent so we can see all events + document.stage.addEventListener("mouseMove", mouseMoveHandler); + } + + public static function disableSniffer():void + { + //trace("PixelSnifferRemote disabled"); + + document.stage.removeEventListener("mouseMove", mouseMoveHandler); + } + + private static function mouseMoveHandler(event:MouseEvent):void + { + var c:DisplayObject = findComponent(DisplayObject(event.target)); + var pt:Point = c.globalToLocal(new Point(event.stageX, event.stageY)); + /// we're combining these (perhaps for now) because the other side only + /// really cares about event Name, not event + appendLog(c.toString(), "[mousedata] "+ pt.toString() + " " + pixelValue(c, pt), ""); + } + + /* a heuristic for figuring out which component should be the target */ + private static function findComponent(target:DisplayObject):DisplayObject + { + var o:DisplayObject = target; + while (o) + { + if (o is IFocusManagerComponent && IFocusManagerComponent(o).focusEnabled) + return o; + + + + /* was: (before the spark -only universe) + if (o.parent is Container) + { + var c:Container = o.parent as Container; + var children:Array = c.createdComponents; + var numChildren:int = children.length; + for (var i:int = 0; i < numChildren; i++) + { + if (children[i] == o) + return o; + } + } + */ + + + /// post-mobile universe + if (o.parent is IVisualElementContainer) + { + + var c:IVisualElementContainer = o.parent as IVisualElementContainer; + var numChildren:int = c.numElements; + for (var i:int = 0; i < numChildren; i++) + { + if (c.getElementAt(i) == o) + { + return o; + } + + } + } + else if (o.parent is SystemManager) + { + return o; + } + o = o.parent; + } + return target; + } + + private static function pixelValue(target:DisplayObject, pt:Point):String + { + var stagePt:Point = target.localToGlobal(new Point(0, 0)); + var screenBits:BitmapData = new BitmapData(target.width, target.height); + screenBits.draw(document.stage, new Matrix(1, 0, 0, 1, -stagePt.x, -stagePt.y)); + + var clr:uint = screenBits.getPixel(pt.x, pt.y); + var s:String = clr.toString(16); + while (s.length < 6) + { + s = "0" + s; + } + + return s.toUpperCase(); + } + + private static function appendLog(c:String, s:String, col:String):void + { +// connection.send("_PixelSniffer", "appendLog", "Pixel", c, s, col); + + var info:Object = new Object(); + + info.dataSource = "Pixel"; + info.target = c; + info.eventName = s; + info.event = col; + + /** + trace("PixelSniffer is sending: "); + trace (" info.dataSource: " + info.dataSource); + trace (" info.target: " + info.target); + trace (" info.eventName: " + info.eventName); + trace (" info.event: " + info.event); + **/ + + connection.send("_PixelSniffer", "appendLog", info); + + } + +} + +}
http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/27eb06f5/mustella/src/main/flex/PlaybackControl.as ---------------------------------------------------------------------- diff --git a/mustella/src/main/flex/PlaybackControl.as b/mustella/src/main/flex/PlaybackControl.as new file mode 100644 index 0000000..b926f4b --- /dev/null +++ b/mustella/src/main/flex/PlaybackControl.as @@ -0,0 +1,91 @@ +//////////////////////////////////////////////////////////////////////////////// +// +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. +// The ASF licenses this file to You under the Apache License, Version 2.0 +// (the "License"); you may not use this file except in compliance with +// the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//////////////////////////////////////////////////////////////////////////////// +package { + +import flash.display.DisplayObject; +import flash.net.*; +import flash.events.Event; +import flash.events.StatusEvent; + +[Mixin] +/** + * A "marker" class that causes test scripts to write out + * bitmaps to the urls instead of reading and comparing + * so that baselines/reference-points can be created for + * future comparing. + */ +public class PlaybackControl +{ + + /** + * Mixin callback that gets everything ready to go. + * The UnitTester waits for an event before starting + */ + public static function init(root:DisplayObject):void + { + connection = new LocalConnection(); + connection.allowDomain("*"); + connection.addEventListener(StatusEvent.STATUS, statusHandler); + + commandconnection = new LocalConnection(); + connection.allowDomain("*"); + commandconnection.client = PlaybackControl; + commandconnection.connect("_PlaybackCommands"); + + connection.send("_PlaybackSniffer", "getPausedState"); + + } + + private static function statusHandler(event:Event):void + { + + } + + /** + * @private + * The document containing a reference to this object + */ + private static var document:Object; + private static var _root:Object; + + /** + * @private + * The local connection to the remote client + */ + private static var connection:LocalConnection; + private static var commandconnection:LocalConnection; + + + public static function pause():void + { + UnitTester.playbackControl = "pause"; + } + + public static function playback():void + { + UnitTester.playbackControl = "play"; + } + + public static function step():void + { + UnitTester.playbackControl = "step"; + } + +} +} http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/27eb06f5/mustella/src/main/flex/README ---------------------------------------------------------------------- diff --git a/mustella/src/main/flex/README b/mustella/src/main/flex/README new file mode 100644 index 0000000..46aee94 --- /dev/null +++ b/mustella/src/main/flex/README @@ -0,0 +1,271 @@ + +Prototype of new test framework. + + +Example test: CBTester.mxml + +Example test-swf: main.mxml + + + +To compile the sample: + + mxmlc -includes=CBTester main.mxml + +To run: + + SAFlashPlayer.exe main.swf + + +Multiple scripts can be applied to a single Test swf, as in + + mxmlc -includes=CBTester main.mxml -includes=CBTester2 + + +Currently, output goes only to trace. + + + +What's in a test file? There are some mandatory items: notice the top of CBTester.mxml + + <mx:Script> + <![CDATA[ + public static function init(o:DisplayObject):void + { + } + ]]> + </mx:Script> + <mx:Metadata> + <![CDATA[ + [Mixin] + ]]> + </mx:Metadata> + + +These need not vary. + +The init function is called by the swf under test. You can add things here if you like, +but do so carefully. Note that the application isn't complete by the time this is called. + +The [Mixin] is required by the compiler to include this class as a Mixin. + + + +The UnitTester tag must name what swf it is associated with, using the testSWF tag. +in CBTester: + testSWF="main.mxml" + + + +TestCases must have a testID attribute: for example, + + <TestCase testID="myTest1"> + + +The testID should be unique. + + + +Description of Available Tags + + + +<testCases> - no attributes. children are of type TestCase + + +<TestCase testID="myTest1"> + attributes: + + testID - a unique identifier for the TestCase + + child elements: + + <setup> - no attributes + <body> - no attributes + <cleanup>- no attributes + + + setup, body, and cleanup may have the following elements: + + AssertPixelValue + attributes: + target - the object that has the property to verify + x - the X coordinate, relative to the target. + y - the Y coordinate, relative to the target. + value - the expected value (eg, 0XFFFFFF) + valueExpression - a code expression, generally setting value=<code> + waitEvent - (optional) - the event to wait for. The test will not + advance until this event is received, or a timeout occurs. + waitTarget - the object that will dispatch the waitEvent event + timeout - in milliseconds. default is 3000 milliseconds. + + AssertPropertyValue + attributes: + target - the object that has the property to verify + propertyName - the property to verify + value - the expected value + valueExpression - a code expression, generally setting value=<code> + waitEvent - (optional) - the event to wait for. The test will not + advance until this event is received, or a timeout occurs. + waitTarget - the object that will dispatch the waitEvent event + timeout - in milliseconds. default is 3000 milliseconds. + + AssertMethodValue + attributes: + target - the object that has the property to verify + propertyName - the property to verify + value - the expected value + valueExpression - a code expression, generally setting value=<code> + waitEvent - (optional) - the event to wait for. The test will not + advance until this event is received, or a timeout occurs. + waitTarget - the object that will dispatch the waitEvent event + timeout - in milliseconds. default is 3000 milliseconds. + + AssertStyleValue + attributes: + target - the object on which to assert the style + styleName - the name of the style to verify + value - the expected value + valueExpression - a code expression, generally setting value=<code> + waitEvent - (optional) - the event to wait for. The test will not advance + until this event is received or a timeout occurs. + waitTarget - the object that will dispatch the waitEvent event + timeout - in milliseconds. default is 3000 milliseconds. + + CompareBitmap (see below for more description) + attributes: + target - the object on which to assert the style + url - the name of the file to save/read + waitEvent - do not use! + waitTarget - do not use! + timeout - in milliseconds. default is 3000 milliseconds. + + + DispatchKeyEvent + + key - the key to press + char - the character to enter + waitEvent - (optional) - the event to wait for. The test will not + advance until this event is received, or a timeout occurs. + waitTarget - the object that will dispatch the waitEvent event + timeout - in milliseconds. default is 3000 milliseconds. + + + + DispatchMouseEvent + target - the object on which to target the event. + type - the type of MouseEvent to dispatch. For instance, "mouseUp" + localX - the X coordinate, relative to the target. + localY - the Y coordinate, relative to the target. + waitEvent - (optional) - the event to wait for. The test will not + advance until this event is received, or a timeout occurs. + waitTarget - the object that will dispatch the waitEvent event + timeout - in milliseconds. default is 3000 milliseconds. + + Pause + timeout - how long to wait. (Does not cause an error) + + + RunCode + attributes: + code - the code to run. This might be a method call or the actual code. + waitEvent - (optional) - the event to wait for. The test will not + advance until this event is received, or a timeout occurs. + waitTarget - the object that will dispatch the waitEvent event + timeout - in milliseconds. default is 3000 milliseconds. + + + SetProperty + attributes: + target - the object on which to set the style + propertyName - the name of the style to set + value - the value to set the property to + waitEvent - (optional) - the event to wait for. The test will not + advance until this event is received, or a timeout occurs. + waitTarget - the object that will dispatch the waitEvent event + timeout - in milliseconds. default is 3000 milliseconds. + + example: + + <SetProperty target="cb" propertyName="dataProvider" value="[1,2,3,4]" waitEvent="updateComplete" waitTarget="cb" /> +:w + + + SetStyle + attributes: + target - the object whose style you will set + styleName - the style you want to set + value - the value to set the property to + waitEvent - (optional) - the event to wait for. The test will not + advance until this event is received, or a timeout occurs. + waitTarget - the object that will dispatch the waitEvent event + + + + <AssertPropertyValue target="cb" propertyName="selectedItem" value="3" /> + + + + + + + + + + + + +Bitmap Comparison: + + +To use bitmap verification, use the CompareBitmap tag: + +for instance: + + <CompareBitmap target="cb" url="myTest4.png" timeout="4500" /> + +This associates a bitmap of cb to save in a file names myTest4.png. + +It is safest to preceed the bitmap call with a call that synchronizes (using waitFor and waitTarget). Do not use waitFor and WaitTarget on the bitmap call itself! + + +To write new bitmaps, it is necessary to mixin the CreateBitmapReferences class. + + + mxmlc -includes=CBTester -includes=CreateBitmapReferences main.mxml + + +(and, because of the current bug, it is necessary to have a reference to CreateBitmapReferences in main.mxml). + + +Because writing to the local disk is a security violation, a server is required. The server is available in ~depot/flex/qa/skunkworks/baselinewriter/baselinewriter.zip. + + +This is meant to be run by jrun. To install, unzip it under servers/default in a jrun installation. + + +The root url that mustella writes bitmaps to is defined in CreateBitmapReferences.as; very likely you will have to alter the server port, local directory location, and the base url to make this work. + + +Let me know of any difficulties setting up the server: bolaughl∂adobe.com + + + +issues: + + mixin currently requires a reference to the mixin file(s). (bug) + + + + + + + +USEFUL TOOLS + + +EventSniffer - include an EventSniffer tag in your test swf. This sniffs all events and displays them. Start, stop, mark and clear controls. + +PixelSniffer - include a PixelSniffer tag in your test swf. This sniffs all mouse locations and pixel values under the mouse. Start, stop, mark and clear controls. +ca +going http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/27eb06f5/mustella/src/main/flex/ResetComponent.as ---------------------------------------------------------------------- diff --git a/mustella/src/main/flex/ResetComponent.as b/mustella/src/main/flex/ResetComponent.as new file mode 100644 index 0000000..5e42af1 --- /dev/null +++ b/mustella/src/main/flex/ResetComponent.as @@ -0,0 +1,476 @@ +//////////////////////////////////////////////////////////////////////////////// +// +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. +// The ASF licenses this file to You under the Apache License, Version 2.0 +// (the "License"); you may not use this file except in compliance with +// the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//////////////////////////////////////////////////////////////////////////////// +package { + +import flash.display.DisplayObject; +import flash.display.DisplayObjectContainer; +import flash.display.InteractiveObject; +import flash.events.KeyboardEvent; +import flash.events.FocusEvent; +import flash.net.LocalConnection; +import flash.system.ApplicationDomain; +import flash.system.Capabilities; +import flash.system.System; +import flash.ui.Keyboard; +import flash.utils.getQualifiedClassName; +import flash.utils.getTimer; + +import mx.core.mx_internal; +use namespace mx_internal; + +/** + * The test step that fakes a keyboard event + * MXML attributes: + * target + * className + * waitTarget + * waitEvent + * timeout + */ +public class ResetComponent extends TestStep +{ + private static var effectsInEffect:QName = new QName(mx_internal, "effectsInEffect"); + private static var activeTweens:QName = new QName(mx_internal, "activeTweens"); + private static var tooltipReset:QName = new QName(mx_internal, "reset"); + + private var actualWaitEvent:String; + + private var waited:Boolean = false; + + /** + * Called by the TestCase when it is time to start this step + * fake waitEvent because we don't want to listen to the old one + */ + override public function execute(root:DisplayObject, context:UnitTester, testCase:TestCase, testResult:TestResult):Boolean + { + if (waitTarget == null) + waitTarget = target; + + // let super think there is no waitEvent + if (waitEvent && waitTarget == target) + { + actualWaitEvent = waitEvent; + waitEvent = null; + } + var val:Boolean = super.execute(root, context, testCase, testResult); + if (actualWaitEvent && !waited) + { + var actualTarget:Object = context.stringToObject(waitTarget); + if (!actualTarget) + { + testResult.doFail("Target " + waitTarget + " not found"); + return true; + } + waitEvent = actualWaitEvent; + actualTarget.addEventListener(actualWaitEvent, waitEventHandler); + testCase.setExpirationTime(getTimer() + timeout); + } + return (actualWaitEvent || waited) ? false : val; + } + + /** + * Set the target's property to the specified value + */ + override protected function doStep():void + { + var effects:Boolean = false; + + var appDom:ApplicationDomain = root["topLevelSystemManager"]["info"]().currentDomain; + if (!appDom) + appDom = ApplicationDomain.currentDomain; + + var effectMgr:Class = Class(appDom.getDefinition("mx.effects.EffectManager")); + + if (effectMgr) + { + effects = effectMgr[effectsInEffect](); + } + if (!effects) + { + effectMgr = Class(appDom.getDefinition("mx.effects.Tween")); + if (effectMgr) + { + effects = effectMgr[activeTweens].length > 0; + } + } + if (!effects) + effects = UnitTester.getSandboxedEffects(); + + if (!effects) + { + actuallyDoStep(waited); + waited = false; + } + else + { + UnitTester.callback = doStep; + waited = true; + } + } + + private function actuallyDoStep(addListener:Boolean):void + { + + var actualTarget:Object = context.stringToObject(target); + if (!actualTarget) + { + testResult.doFail("Target " + target + " not found"); + return; + } + + // Introspect target type. + var targetType:TypeInfo = context.getTypeInfo(actualTarget); + var targetIsGraphic:Boolean = targetType.implementsInterface("spark.core::IGraphicElement"); + + // Save id to apply later. + if (actualTarget is DisplayObject) + { + var id:String = actualTarget.id; + } + + try + { + // Save parent context. + if (actualTarget is DisplayObject || targetIsGraphic) + { + var parent:Object = actualTarget.parent; + + if (!parent) + { + testResult.doFail("Target " + target + " not parented"); + return; + } + } + } + catch (se:SecurityError) + { + UnitTester.resetSandboxedComponent(target, className); + return; + } + + // Garbage collect. + attemptGC(); + + // Introspect parent type. + if (parent) + { + var parentType:TypeInfo = context.getTypeInfo(parent); + var parentIsGroup:Boolean = parentType.isAssignableTo("spark.components::Group"); + } + + // Ensure parent of graphic primitive is a Group. + if (targetIsGraphic && !parentIsGroup) + { + testResult.doFail("Graphic primitive " + target + " not parented by a Group."); + return; + } + + // Infer className is none provided. + className = className != null ? className : targetType.className; + + var targetClass:Class; + var child:Object; + var appdom:ApplicationDomain = UnitTester.getApplicationDomain(target, actualTarget, className); + if (!appdom) + { + UnitTester.resetSandboxedComponent(target, className); + return; + } + + if (actualTarget is DisplayObject || targetIsGraphic) + { + // Remove original instance + if (parentIsGroup) + { + var index:int = parent.getElementIndex(actualTarget); + parent.removeElement(actualTarget); + } + else + { + index = parent.getChildIndex(actualTarget); + parent.removeChild(actualTarget); + } + + // Cleanup any related or housekeeping objects. + cleanupOtherDisplayObjects(); + + // Lookup requested type for new instance. + targetClass = Class(appdom.getDefinition(className)); + if (!targetClass) + { + testResult.doFail("className " + className + " is not a valid class"); + return; + } + + // Create new instance. + child = new targetClass(); + var childType:TypeInfo = context.getTypeInfo(child); + if (!(child is DisplayObject) && !childType.implementsInterface("spark.core::IGraphicElement")) + { + testResult.doFail("className " + className + " is not a DisplayObject or GraphicElement primitive."); + return; + } + + // Re-add new instance to visual DOM. + if (parentIsGroup) + parent.addElementAt(child, index); + else + parent.addChildAt(child as DisplayObject, index); + } + else + { + // Fallback for non-DOM component instances. + targetClass = Class(appdom.getDefinition(className)); + if (!targetClass) + { + testResult.doFail("className " + className + " is not a valid class"); + return; + } + + child = new targetClass(); + } + + // Update top level document slots with reference to new instance. + var obj:Object; + var varName:String; + if (target.indexOf(".") == -1) + { + if (target.indexOf("script:") == 0) + { + obj = context; + varName = target.substring(7); + } + else + { + obj = root["document"]; + varName = target; + } + } + else + { + var path:String = target.substring(0, target.lastIndexOf(".")); + obj = context.stringToObject(path); + varName = target.substring(target.lastIndexOf(".") + 1); + } + if (!obj) + { + testResult.doFail("path " + path + " is not valid"); + return; + } + if (!(varName in obj)) + { + testResult.doFail("property " + varName + " is not valid"); + return; + } + + if (actualTarget is DisplayObject) + if (id && child) + Object(child).id = id; + + try + { + obj[varName] = child; + } + catch (e1:Error) + { + TestOutput.logResult("Exception thrown setting path to new class instance."); + testResult.doFail (e1.getStackTrace()); + } + + // Initiate wait if requested, otherwise complete step. + if (actualWaitEvent && addListener) + { + actualTarget = context.stringToObject(waitTarget); + if (!actualTarget) + { + testResult.doFail("Target " + waitTarget + " not found"); + stepComplete(); + return; + } + waitEvent = actualWaitEvent; + actualTarget.addEventListener(actualWaitEvent, waitEventHandler); + testCase.setExpirationTime(getTimer() + timeout); + } + else if (addListener) + { + stepComplete(); + } + + } + + private function cleanupOtherDisplayObjects():void + { + var r:Object; + var i:int; + var n:int; + var c:Object; + + var appDom:ApplicationDomain = root["info"]().currentDomain; + if (!appDom) + appDom = ApplicationDomain.currentDomain; + + r = root; + r = root["topLevelSystemManager"]; + + UnitTester.blockFocusEvents = false; + r.stage.focus = null; + UnitTester.blockFocusEvents = true; + + n = r.numChildren; + for (i = 0; i < n; i++) + { + if (context.knownDisplayObjects[r.getChildAt(i)] == null) + { + c = r.getChildAt(i); + if (getQualifiedClassName(c) == "mx.managers::SystemManagerProxy") + { + while (c.rawChildren.numChildren) + c.rawChildren.removeChildAt(c.rawChildren.numChildren - 1); + } + else + r.removeChildAt(i); + i--; + n--; + } + } + + r = root; + r = root["topLevelSystemManager"]; + r = r.popUpChildren; + n = r.numChildren; + for (i = 0; i < n; i++) + { + if (context.knownDisplayObjects[r.getChildAt(i)] == null) + { + c = r.getChildAt(i); + if (getQualifiedClassName(c) == "mx.managers::SystemManagerProxy") + { + while (c.rawChildren.numChildren) + c.rawChildren.removeChildAt(c.rawChildren.numChildren - 1); + } + else + r.removeChildAt(i); + + i--; + n--; + } + } + + r = root; + r = root["topLevelSystemManager"]; + r = r.toolTipChildren; + n = r.numChildren; + if (n > 0) + { + var mgr:Class = Class(appDom.getDefinition("mx.core.Singleton")); + var impl:Object = mgr["getInstance"]("mx.managers::IToolTipManager2"); + try + { + impl[tooltipReset](); + } + catch (e:Error) + { + // ignore, chart datatips don't setup tooltipmanager so reset will RTE. + } + } + n = r.numChildren; + for (i = 0; i < n; i++) + { + if (context.knownDisplayObjects[r.getChildAt(i)] == null) + { + r.removeChildAt(i); + i--; + n--; + } + } + + r = root; + r = root["topLevelSystemManager"]; + r = r.cursorChildren; + n = r.numChildren; + if (n > 0) + { + var cmgr:Class = Class(appDom.getDefinition("mx.core.Singleton")); + var cimpl:Object = cmgr["getInstance"]("mx.managers::ICursorManager"); + cimpl["removeAllCursors"](); + } + n = r.numChildren; + for (i = 0; i < n; i++) + { + var o:DisplayObject = r.getChildAt(i); + if (context.knownDisplayObjects[o] == null) + { + if (o.name == "cursorHolder") + continue; + + r.removeChildAt(i); + i--; + n--; + } + } + + } + + private function attemptGC():void + { + if (Capabilities.isDebugger) + { + System.gc(); + return; + } + // unsupported hack that seems to force a full GC + try + { + var lc1:LocalConnection = new LocalConnection(); + var lc2:LocalConnection = new LocalConnection(); + + lc1.connect('name'); + lc2.connect('name'); + } + catch (e:Error) + { + } + } + + /** + * The type of the event to send (keyUp, keyDown, etc). + * If not set, we'll send both a keyDown and a keyUp + */ + public var target:String; + + /** + * The char to send as a string/char if you don't know the charCode (optional) + */ + public var className:String; + + /** + * customize string representation + */ + override public function toString():String + { + var s:String = "ResetComponent"; + if (target) + s += ": target = " + target; + if (className) + s += ", className = " + className; + return s; + } +} + +} http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/27eb06f5/mustella/src/main/flex/RunCode.as ---------------------------------------------------------------------- diff --git a/mustella/src/main/flex/RunCode.as b/mustella/src/main/flex/RunCode.as new file mode 100644 index 0000000..c985dd8 --- /dev/null +++ b/mustella/src/main/flex/RunCode.as @@ -0,0 +1,77 @@ +//////////////////////////////////////////////////////////////////////////////// +// +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. +// The ASF licenses this file to You under the Apache License, Version 2.0 +// (the "License"); you may not use this file except in compliance with +// the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//////////////////////////////////////////////////////////////////////////////// +package { + +COMPILE::SWF +{ +import flash.display.DisplayObject; +import flash.events.Event; +import flash.events.EventDispatcher; +} + +/** + * Instead of a property, we use an event so the MXML + * compiler will wrap the code in a function for us + */ +[Event(name="code", type="flash.events.Event")] + +/** + * A test step that runs an arbitrary set of actionscript + * MXML attributes + * code (a sequence of actionscript) + */ +public class RunCode extends TestStep +{ + /** + * Execute the code by passing it an event. + */ + COMPILE::SWF + override protected function doStep():void + { + UnitTester.blockFocusEvents = false; + try + { + dispatchEvent(new RunCodeEvent("code", root["document"], context, testCase, testResult)); + } + catch (e1:Error) + { + TestOutput.logResult("Exception thrown in RunCode."); + testResult.doFail (e1.getStackTrace()); + UnitTester.blockFocusEvents = true; + return; + } + UnitTester.blockFocusEvents = true; + } + + /* + public var code:Function; // Event metadata takes care of this + */ + + /** + * customize string representation + */ + COMPILE::SWF + override public function toString():String + { + var s:String = "RunCode: (code attribute cannot be shown)"; + return s; + } +} + +} http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/27eb06f5/mustella/src/main/flex/RunCodeEvent.as ---------------------------------------------------------------------- diff --git a/mustella/src/main/flex/RunCodeEvent.as b/mustella/src/main/flex/RunCodeEvent.as new file mode 100644 index 0000000..00dcd01 --- /dev/null +++ b/mustella/src/main/flex/RunCodeEvent.as @@ -0,0 +1,68 @@ +//////////////////////////////////////////////////////////////////////////////// +// +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. +// The ASF licenses this file to You under the Apache License, Version 2.0 +// (the "License"); you may not use this file except in compliance with +// the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//////////////////////////////////////////////////////////////////////////////// +package { + +COMPILE::SWF +{ +import flash.events.Event; +} +COMPILE::JS +{ + import org.apache.flex.events.Event; +} + +/** + * The event passed into any code being + * run in a RunCode step. It supplies + * some useful references + */ +public class RunCodeEvent extends Event +{ + public function RunCodeEvent(type:String, application:Object, context:UnitTester, testCase:TestCase, testResult:TestResult) + { + super(type); + this.context = context; + this.application = application; + this.testCase = testCase; + this.testResult = testResult; + } + + /** + * The test script where any variables in the script block can be found + */ + public var context:UnitTester; + + /** + * The application being tested + */ + public var application:Object; + + /** + * The testCase being tested + */ + public var testCase:TestCase; + + /** + * The application being tested + */ + public var testResult:TestResult; + +} + +} http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/27eb06f5/mustella/src/main/flex/RunnerPortAlt.as ---------------------------------------------------------------------- diff --git a/mustella/src/main/flex/RunnerPortAlt.as b/mustella/src/main/flex/RunnerPortAlt.as new file mode 100644 index 0000000..7cbd073 --- /dev/null +++ b/mustella/src/main/flex/RunnerPortAlt.as @@ -0,0 +1,46 @@ +//////////////////////////////////////////////////////////////////////////////// +// +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. +// The ASF licenses this file to You under the Apache License, Version 2.0 +// (the "License"); you may not use this file except in compliance with +// the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//////////////////////////////////////////////////////////////////////////////// +package { + +import flash.display.DisplayObject; +import flash.net.*; +import flash.events.Event; + +[Mixin] +/** + * A "marker" class that causes test scripts to write out + * bitmaps to the urls instead of reading and comparing + * so that baselines/reference-points can be created for + * future comparing. + */ +public class RunnerPortAlt +{ + + /** + * Mixin callback that gets everything ready to go. + * The UnitTester waits for an event before starting + */ + public static function init(root:DisplayObject):void + { + UnitTester.runnerPort = 10001; + } + + +} +} http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/27eb06f5/mustella/src/main/flex/SaveBitmapFailures.as ---------------------------------------------------------------------- diff --git a/mustella/src/main/flex/SaveBitmapFailures.as b/mustella/src/main/flex/SaveBitmapFailures.as new file mode 100644 index 0000000..babd76e --- /dev/null +++ b/mustella/src/main/flex/SaveBitmapFailures.as @@ -0,0 +1,62 @@ +//////////////////////////////////////////////////////////////////////////////// +// +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. +// The ASF licenses this file to You under the Apache License, Version 2.0 +// (the "License"); you may not use this file except in compliance with +// the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//////////////////////////////////////////////////////////////////////////////// +package { + +import flash.display.DisplayObject; + +[Mixin] +/** + * A "marker" class that causes test scripts to write out + * bitmaps to the urls if the comparison fails. + */ +public class SaveBitmapFailures +{ + + /** + * Mixin callback + */ + public static function init(root:DisplayObject):void + { + CompareBitmap.fileSuffix = ".bad.png"; + UnitTester.bitmapServerPrefix = "http://localhost:9998/baselines/baseline.jsp?filename="; + UnitTester.serverCopy = "http://flexqa01/FlexFiles/Uploader.upbmp?"; + + if (UnitTester.isVettingRun) + UnitTester.bitmapServerPrefix = "http://localhost:9995/baselines/baseline.jsp?filename="; + } + + + public static function urlAssemble (type:String, testDir:String, testFile:String, testCase:String, run_id:String):String + { + + testDir=encodeURIComponent(testDir); + testFile = encodeURIComponent(testFile); + testCase = encodeURIComponent(testCase); + + var back:String = "type=" + type + "&testFile="+ testDir + testFile + "&testCase=" + testCase + "&runid=" + run_id; + + return UnitTester.serverCopy + back; + + + + } + +} + +} http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/27eb06f5/mustella/src/main/flex/SaveBitmapFailuresDistServer.as ---------------------------------------------------------------------- diff --git a/mustella/src/main/flex/SaveBitmapFailuresDistServer.as b/mustella/src/main/flex/SaveBitmapFailuresDistServer.as new file mode 100644 index 0000000..fe1436d --- /dev/null +++ b/mustella/src/main/flex/SaveBitmapFailuresDistServer.as @@ -0,0 +1,62 @@ +//////////////////////////////////////////////////////////////////////////////// +// +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. +// The ASF licenses this file to You under the Apache License, Version 2.0 +// (the "License"); you may not use this file except in compliance with +// the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//////////////////////////////////////////////////////////////////////////////// +package { + +import flash.display.DisplayObject; + +[Mixin] +/** + * A "marker" class that causes test scripts to write out + * bitmaps to the urls if the comparison fails. + */ +public class SaveBitmapFailuresDistServer +{ + + /** + * Mixin callback + */ + public static function init(root:DisplayObject):void + { + CompareBitmap.fileSuffix = ".bad.png"; + UnitTester.bitmapServerPrefix = "http://localhost:8700/baselines/baseline.jsp?filename="; + UnitTester.serverCopy = "http://flexqa01/FlexFiles/Uploader.upbmp?"; + + if (UnitTester.isVettingRun) + UnitTester.bitmapServerPrefix = "http://localhost:9995/baselines/baseline.jsp?filename="; + } + + + public static function urlAssemble (type:String, testDir:String, testFile:String, testCase:String, run_id:String):String + { + + testDir=encodeURIComponent(testDir); + testFile = encodeURIComponent(testFile); + testCase = encodeURIComponent(testCase); + + var back:String = "type=" + type + "&testFile="+ testDir + testFile + "&testCase=" + testCase + "&runid=" + run_id; + + return UnitTester.serverCopy + back; + + + + } + +} + +} http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/27eb06f5/mustella/src/main/flex/ScriptRunner.as ---------------------------------------------------------------------- diff --git a/mustella/src/main/flex/ScriptRunner.as b/mustella/src/main/flex/ScriptRunner.as new file mode 100644 index 0000000..cb252de --- /dev/null +++ b/mustella/src/main/flex/ScriptRunner.as @@ -0,0 +1,53 @@ +//////////////////////////////////////////////////////////////////////////////// +// +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. +// The ASF licenses this file to You under the Apache License, Version 2.0 +// (the "License"); you may not use this file except in compliance with +// the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//////////////////////////////////////////////////////////////////////////////// +package +{ +import flash.events.Event; +import flash.events.EventDispatcher; + +public class ScriptRunner extends EventDispatcher +{ + + public var scripts:Array; + public var currentScript:int = 0; + + public function isDone():Boolean + { + return (currentScript == scripts.length) || (UnitTester.hasRTE); + } + + public function runScripts():void + { + while (currentScript < scripts.length) + { + var script:UnitTester = scripts[currentScript++]; + script.addEventListener("testComplete", testCompleteHandler); + script.startTests(); + return; + } + dispatchEvent(new Event("scriptsComplete")); + } + + private function testCompleteHandler(event:Event):void + { + UnitTester.callback = runScripts; + } +} + +} http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/27eb06f5/mustella/src/main/flex/SendFormattedResultsToLog.as ---------------------------------------------------------------------- diff --git a/mustella/src/main/flex/SendFormattedResultsToLog.as b/mustella/src/main/flex/SendFormattedResultsToLog.as new file mode 100644 index 0000000..957d021 --- /dev/null +++ b/mustella/src/main/flex/SendFormattedResultsToLog.as @@ -0,0 +1,121 @@ +//////////////////////////////////////////////////////////////////////////////// +// +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. +// The ASF licenses this file to You under the Apache License, Version 2.0 +// (the "License"); you may not use this file except in compliance with +// the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//////////////////////////////////////////////////////////////////////////////// +package { + +COMPILE::SWF +{ +import flash.display.DisplayObject; +import flash.net.*; +import flash.events.Event; +} + +[Mixin] +/** + * Write formatted results to log for easy parsing + */ +public class SendFormattedResultsToLog +{ + + /** + * Mixin callback that gets everything ready to go. + * The UnitTester waits for an event before starting + */ + COMPILE::SWF + public static function init(root:DisplayObject):void + { + TestOutput.getInstance().addEventListener ("result", outputWriter); + } + + + public static var midURL:String = ""; + + + public static var regExp5:RegExp = /%3D/g; + + + + /** + * the way out for the result data + */ + COMPILE::SWF + public static function outputWriter (event:Event):void + { + + var s:String = (event as MustellaLogEvent).msg; + + + var loc:uint; + var final:String = ""; + + var skip:Boolean = false; + var noSend:Boolean = false; + + /// this should be something like |, because it is confusing this way + /// putting it on, taking it off + s=s.replace (" msg=", "|msg="); + + s=s.replace (" result=", "|result="); + s=s.replace (" phase=", "|phase="); + s=s.replace (" id=", "|id="); + s=s.replace (" elapsed=", "|elapsed="); + s=s.replace (" started=", "|started="); + s=s.replace (" extraInfo=", "|extraInfo="); + + var hdrs:Array = s.split ("|"); + + var i:uint; + // rebuild url encoded + for (i=0;i<hdrs.length;i++) + { + if (final == "") + final += hdrs[i]; + else + final+="&" + hdrs[i]; + } + + final = final.replace (regExp5, "="); + + trace (final); + + + // exitWhenDone mixin doesn't really work with browsers. + // Tell the Runner that we're ending + if (s.indexOf ("ScriptComplete") != -1 ) + { + + trace ("Send ScriptComplete to runner block"); + var u:URLLoader = new URLLoader (); + u.addEventListener("complete", httpEvents); + u.addEventListener("ioError", httpEvents); + u.load(new URLRequest ("http://localhost:" + UnitTester.runnerPort + "/ScriptComplete")); + } + + + + } + + COMPILE::SWF + public static function httpEvents (e:Event):void { + trace (e); + } + + + +} +} http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/27eb06f5/mustella/src/main/flex/SendResultsToRunner.as ---------------------------------------------------------------------- diff --git a/mustella/src/main/flex/SendResultsToRunner.as b/mustella/src/main/flex/SendResultsToRunner.as new file mode 100644 index 0000000..a63a00f --- /dev/null +++ b/mustella/src/main/flex/SendResultsToRunner.as @@ -0,0 +1,192 @@ +//////////////////////////////////////////////////////////////////////////////// +// +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. +// The ASF licenses this file to You under the Apache License, Version 2.0 +// (the "License"); you may not use this file except in compliance with +// the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//////////////////////////////////////////////////////////////////////////////// +package { + +COMPILE::SWF +{ +import flash.display.DisplayObject; +import flash.net.*; +import flash.utils.*; +import flash.events.Event; +} + +[Mixin] +/** + * A "marker" class that causes test scripts to write out + * bitmaps to the urls instead of reading and comparing + * so that baselines/reference-points can be created for + * future comparing. + */ +public class SendResultsToRunner +{ + + /** + * Mixin callback that gets everything ready to go. + * The UnitTester waits for an event before starting + */ + COMPILE::SWF + public static function init(root:DisplayObject):void + { + TestOutput.getInstance().addEventListener ("result", urlSender); + } + + + public static var midURL:String = ""; + + + public static var regExp5:RegExp = /%3D/g; + + public static var msgQueue:Array = []; + + COMPILE::SWF + public static var u:URLLoader; + + /** + * the way out for the result data + */ + COMPILE::SWF + public static function urlSender (event:Event):void + { + + var s:String = (event as MustellaLogEvent).msg; + + var baseURL:String = "http://localhost:" + UnitTester.runnerPort; + + /// trace it anyway + trace (s); + + /// Notice what we've got. Send along to Runner if relevant + var loc:uint; + var final:String = ""; + + var skip:Boolean = false; + var noSend:Boolean = false; + + if ( (loc = s.indexOf ("RESULT: ")) != -1) { + s = s.substr (loc + 8); + midURL = "/testCaseResult"; + } else if ( (loc = s.indexOf ("ScriptComplete:")) != -1) { + midURL = "/ScriptComplete"; + final = "?" + UnitTester.excludedCount; + skip = true; + } else if ( (loc = s.indexOf ("LengthOfTestcases:")) != -1) { + midURL = "/testCaseLength?"; + final = s.substring (loc+ "LengthOfTestcases:".length+1); + skip = true; + } else if ( (loc = s.indexOf ("TestCase Start:")) != -1) { + /// not relevant + s = s.substr (loc + 15); + s = s.replace (" ", ""); + midURL = "/testCaseStart?" + s ; + skip = true; + } else { + noSend = true; + } + + + if (!skip) { + + /// this should be something like |, because it is confusing this way + /// putting it on, taking it off + s=s.replace (" msg=", "|msg="); + s=s.replace (" result=", "|result="); + s=s.replace (" phase=", "|phase="); + s=s.replace (" id=", "|id="); + s=s.replace (" elapsed=", "|elapsed="); + s=s.replace (" started=", "|started="); + s=s.replace (" extraInfo=", "|extraInfo="); + + var hdrs:Array = s.split ("|"); + + var i:uint; + // rebuild url encoded + for (i=0;i<hdrs.length;i++) { + + if (final =="") + final="?" + escape(hdrs[i]); + else + final+="&" + escape(hdrs[i]); + } + + final = final.replace (regExp5, "="); + + } + + /** + * Probably we don't need to use URLLoader, since we don't care + * about the response, but for now, for debugging, using it + */ + if (!noSend) { + // var u:String= baseURL + midURL + final; + if (!u) + { + u = new URLLoader (); + + /* + var sock:Socket = new Socket ("localhost", UnitTester.runnerPort); + sock.writeUTFBytes(u); + sock.flush(); + sock.flush(); + */ + + u.addEventListener("complete", completeHandler); + u.addEventListener("complete", httpEvents); + u.addEventListener("ioError", httpEvents); + u.addEventListener("open", httpEvents); + u.addEventListener("progress", httpEvents); + u.addEventListener("httpStatus", httpEvents); + u.addEventListener("securityError", httpEvents); + } + queueMsg(baseURL + midURL + final); + UnitTester.pendingOutput++; + } + } + + COMPILE::SWF + public static function queueMsg(s:String):void + { + msgQueue.push(s); + if (msgQueue.length == 1) + { + trace ("sending: " + s + " at: " + new Date()); + u.load (new URLRequest (s)); + } + else + trace ("queuing: " + s + " at: " + new Date()); + } + + COMPILE::SWF + public static function completeHandler (e:Event):void { + UnitTester.pendingOutput--; + msgQueue.shift(); + if (msgQueue.length > 0) + { + var s:String = msgQueue[0]; + u.load (new URLRequest (s)); + trace ("sending: " + s + " at: " + new Date()); + } + } + + COMPILE::SWF + public static function httpEvents (e:Event):void { + trace (e); + } + +} +} http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/27eb06f5/mustella/src/main/flex/SendResultsToSnifferClient.as ---------------------------------------------------------------------- diff --git a/mustella/src/main/flex/SendResultsToSnifferClient.as b/mustella/src/main/flex/SendResultsToSnifferClient.as new file mode 100644 index 0000000..c302692 --- /dev/null +++ b/mustella/src/main/flex/SendResultsToSnifferClient.as @@ -0,0 +1,83 @@ +//////////////////////////////////////////////////////////////////////////////// +// +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. +// The ASF licenses this file to You under the Apache License, Version 2.0 +// (the "License"); you may not use this file except in compliance with +// the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//////////////////////////////////////////////////////////////////////////////// +package { + +import flash.display.DisplayObject; +import flash.net.*; +import flash.events.StatusEvent; +import flash.events.Event; + +[Mixin] +/** + * A "marker" class that causes test scripts to write out + * bitmaps to the urls instead of reading and comparing + * so that baselines/reference-points can be created for + * future comparing. + */ +public class SendResultsToSnifferClient +{ + + /** + * Mixin callback that gets everything ready to go. + * The UnitTester waits for an event before starting + */ + public static function init(root:DisplayObject):void + { + TestOutput.getInstance().addEventListener ("result", snifferSender); + + /// other required: + connection = new LocalConnection(); + connection.allowDomain("*"); + connection.addEventListener(StatusEvent.STATUS, statusHandler); + } + + private static function statusHandler(event:Event):void + { + } + + /** + * @private + * The local connection to the remote client + */ + private static var connection:LocalConnection; + + /** + * the way out for the result data + */ + public static function snifferSender (event:Event):void + { + + var s:String = (event as MustellaLogEvent).msg; + +// connection.send("_EventSniffer", "appendLog", "Mustella_Output", "Mustella_Output", s, ""); + + var info:Object = new Object(); + + info.dataSource = "Mustella_Output"; + info.target = "Mustella_Output"; + info.eventName = s; + info.event = ""; + + connection.send("_EventSniffer", "appendLog", info); + + } + + +} +} http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/27eb06f5/mustella/src/main/flex/SetProperty.as ---------------------------------------------------------------------- diff --git a/mustella/src/main/flex/SetProperty.as b/mustella/src/main/flex/SetProperty.as new file mode 100644 index 0000000..e3a05a0 --- /dev/null +++ b/mustella/src/main/flex/SetProperty.as @@ -0,0 +1,144 @@ +//////////////////////////////////////////////////////////////////////////////// +// +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. +// The ASF licenses this file to You under the Apache License, Version 2.0 +// (the "License"); you may not use this file except in compliance with +// the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//////////////////////////////////////////////////////////////////////////////// +package { + +COMPILE::SWF +{ +import flash.display.DisplayObject; +} + +/** + * Instead of a property, we use an event so the MXML + * compiler will wrap the code in a function for us + */ +[Event(name="valueExpression", type="flash.events.Event")] + +/** + * The test step that sets a property to some value + * MXML attributes: + * target + * propertyName + * value + * waitTarget (optional) + * waitEvent (optional) + * timeout (optional); + */ +public class SetProperty extends TestStep +{ + /** + * @private + */ + COMPILE::SWF + override public function execute(root:Object, context:UnitTester, testCase:TestCase, testResult:TestResult):Boolean + { + if (waitEvent && waitTarget == null) + waitTarget = target; + return super.execute(root, context, testCase, testResult); + } + + /** + * Set the target's property to the specified value + */ + COMPILE::SWF + override protected function doStep():void + { + if (expectError) + testCase.lastError = null; + + var actualTarget:Object = context.stringToObject(target); + if (!actualTarget) + { + testResult.doFail("Target " + target + " not found"); + return; + } + try + { + if (hasEventListener("valueExpression")) + { + context.resetValue(); + dispatchEvent(new RunCodeEvent("valueExpression", root["document"], context, testCase, testResult)); + value = context.value; + if (!context.valueChanged) + TestOutput.logResult("WARNING: value was not set by valueExpression. 'value=' missing from expression?"); + } + } + catch (e:Error) + { + TestOutput.logResult("Exception thrown evaluating value expression."); + testResult.doFail (e.getStackTrace()); + return; + } + + try + { + actualTarget[propertyName] = value; + } + catch (e1:Error) + { + if (expectError) + testCase.lastError = e1; + else + { + if (!(propertyName in actualTarget)) + { + testResult.doFail ("target does not have property " + propertyName); + return; + } + + TestOutput.logResult("Exception thrown setting property."); + testResult.doFail (e1.getStackTrace()); + } + } + } + + /** + * The object to set a property on + */ + public var target:String; + + /** + * The name of the property to set + */ + public var propertyName:String; + + /** + * The value to set + */ + public var value:Object; + + /** + * If we should expect an error + */ + public var expectError:Boolean; + + /** + * customize string representation + */ + override public function toString():String + { + var s:String = "SetProperty"; + if (target) + s += ": target = " + target; + if (propertyName) + s += ", propertyName = " + propertyName; + return s; + } +} + +} http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/27eb06f5/mustella/src/main/flex/SetShowRTE.as ---------------------------------------------------------------------- diff --git a/mustella/src/main/flex/SetShowRTE.as b/mustella/src/main/flex/SetShowRTE.as new file mode 100644 index 0000000..886a4ac --- /dev/null +++ b/mustella/src/main/flex/SetShowRTE.as @@ -0,0 +1,43 @@ +//////////////////////////////////////////////////////////////////////////////// +// +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. +// The ASF licenses this file to You under the Apache License, Version 2.0 +// (the "License"); you may not use this file except in compliance with +// the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//////////////////////////////////////////////////////////////////////////////// +package { + +import flash.display.DisplayObject; + +[Mixin] +/** + * A "marker" class that tells us to show RTEs + */ +public class SetShowRTE +{ + + /** + * Mixin callback + */ + public static function init(root:DisplayObject):void + { + UnitTester.showRTE = true; + + } + + + +} + +} http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/27eb06f5/mustella/src/main/flex/SetStyle.as ---------------------------------------------------------------------- diff --git a/mustella/src/main/flex/SetStyle.as b/mustella/src/main/flex/SetStyle.as new file mode 100644 index 0000000..0fb72e0 --- /dev/null +++ b/mustella/src/main/flex/SetStyle.as @@ -0,0 +1,118 @@ +//////////////////////////////////////////////////////////////////////////////// +// +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. +// The ASF licenses this file to You under the Apache License, Version 2.0 +// (the "License"); you may not use this file except in compliance with +// the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//////////////////////////////////////////////////////////////////////////////// +package { + +import flash.display.DisplayObject; + +import mx.core.mx_internal; +use namespace mx_internal; + +/** + * Instead of a property, we use an event so the MXML + * compiler will wrap the code in a function for us + */ +[Event(name="valueExpression", type="flash.events.Event")] + +/** + * The test step that sets a property to some value + * MXML attributes: + * target + * styleName + * value + * waitTarget (optional) + * waitEvent (optional) + * timeout (optional); + */ +public class SetStyle extends TestStep +{ + + /** + * @private + */ + override public function execute(root:DisplayObject, context:UnitTester, testCase:TestCase, testResult:TestResult):Boolean + { + if (waitEvent && waitTarget == null) + waitTarget = target; + return super.execute(root, context, testCase, testResult); + } + + /** + * Set the target's property to the specified value + */ + override protected function doStep():void + { + var actualTarget:Object = context.stringToObject(target); + if (!actualTarget) + { + testResult.doFail("Target " + target + " not found"); + return; + } + + try + { + if (hasEventListener("valueExpression")) + { + context.resetValue(); + dispatchEvent(new RunCodeEvent("valueExpression", root["document"], context, testCase, testResult)); + value = context.value; + if (!context.valueChanged) + TestOutput.logResult("WARNING: value was not set by valueExpression. 'value=' missing from expression?"); + } + + } + catch (e:Error) + { + TestOutput.logResult("Exception thrown evaluating value expression."); + testResult.doFail (e.getStackTrace()); + return; + } + + actualTarget.setStyle (styleName, value); + } + + /** + * The object to set a property on + */ + public var target:String; + + /** + * The name of the property to set + */ + public var styleName:String; + + /** + * The value to set + */ + public var value:Object; + + /** + * customize string representation + */ + override public function toString():String + { + var s:String = "SetStyle"; + if (target) + s += ": target = " + target; + if (styleName) + s += ", styleName = " + styleName; + return s; + } +} + +} http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/27eb06f5/mustella/src/main/flex/SetURL.as ---------------------------------------------------------------------- diff --git a/mustella/src/main/flex/SetURL.as b/mustella/src/main/flex/SetURL.as new file mode 100644 index 0000000..7357c3c --- /dev/null +++ b/mustella/src/main/flex/SetURL.as @@ -0,0 +1,95 @@ +//////////////////////////////////////////////////////////////////////////////// +// +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. +// The ASF licenses this file to You under the Apache License, Version 2.0 +// (the "License"); you may not use this file except in compliance with +// the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//////////////////////////////////////////////////////////////////////////////// +package { + +import flash.display.DisplayObject; +import flash.external.ExternalInterface; + +import mx.core.mx_internal; +use namespace mx_internal; + +/** + * Instead of a property, we use an event so the MXML + * compiler will wrap the code in a function for us + */ +[Event(name="valueExpression", type="flash.events.Event")] + +/** + * The test step that sets the browser to a specific URL + * MXML attributes: + * url + * waitTarget (optional) + * waitEvent (optional) + * timeout (optional); + */ +public class SetURL extends TestStep +{ + + /** + * Set the target's property to the specified value + */ + override protected function doStep():void + { + var count:int = 0; + if (url.indexOf("BACK") == 0) + { + if (url.length > 4) + count = parseInt(url.substring(4)); + + if (count > 0) + ExternalInterface.call("goForwardOrBackInHistory", -count); + else + ExternalInterface.call("backButton"); + + } + else if (url.indexOf("FORWARD") == 0) + { + if (url.length > 7) + count = parseInt(url.substring(7)); + + if (count > 0) + ExternalInterface.call("goForwardOrBackInHistory", count); + else + ExternalInterface.call("forwardButton"); + + } + else + { + ExternalInterface.call("setURL", url); + } + } + + /** + * The url to navigate to. Can also be "BACK" or "FORWARD" + */ + public var url:String; + + /** + * customize string representation + */ + override public function toString():String + { + var s:String = "SetURL"; + if (url) + s += ", url = " + url; + return s; + } +} + +} http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/27eb06f5/mustella/src/main/flex/SetVettingRun.as ---------------------------------------------------------------------- diff --git a/mustella/src/main/flex/SetVettingRun.as b/mustella/src/main/flex/SetVettingRun.as new file mode 100644 index 0000000..273f143 --- /dev/null +++ b/mustella/src/main/flex/SetVettingRun.as @@ -0,0 +1,44 @@ +//////////////////////////////////////////////////////////////////////////////// +// +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. +// The ASF licenses this file to You under the Apache License, Version 2.0 +// (the "License"); you may not use this file except in compliance with +// the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//////////////////////////////////////////////////////////////////////////////// +package { + +import flash.display.DisplayObject; + +[Mixin] +/** + * A "marker" class that tells us this is a vetting run. + */ +public class SetVettingRun +{ + + /** + * Mixin callback + */ + public static function init(root:DisplayObject):void + { + UnitTester.isVettingRun = true; + UnitTester.bitmapServerPrefix = "http://localhost:9995/baselines/baseline.jsp?filename="; + + } + + + +} + +} http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/27eb06f5/mustella/src/main/flex/SnifferCellRenderer.mxml ---------------------------------------------------------------------- diff --git a/mustella/src/main/flex/SnifferCellRenderer.mxml b/mustella/src/main/flex/SnifferCellRenderer.mxml new file mode 100644 index 0000000..e20c64a --- /dev/null +++ b/mustella/src/main/flex/SnifferCellRenderer.mxml @@ -0,0 +1,75 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +--> +<mx:Label xmlns:mx="http://www.adobe.com/2006/mxml" width="100%" height="100%"> +<mx:Script> +<![CDATA[ + import mx.controls.*; + import mx.controls.dataGridClasses.*; + + private var theData:Object; + + override public function set data(obj:Object):void { + + theData = obj; + + if (obj && obj.eventName) { + text = obj.eventName as String; + }else{ + text = ""; + } + + /** + if(obj){ + trace ("Rendering item: "); + trace (" obj.dataSource: " + obj.dataSource); // Event, Object, Mouse... + trace (" obj.target: " + obj.target); + trace (" obj.eventName: " + obj.eventName); + trace (" obj.event: " + obj.event); + } + **/ + + } + + // Paint red if there's a failure. Code lifted from Joan's blog. + override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void{ + + var g:Graphics = graphics; + var grid1:DataGrid = DataGrid(DataGridListData(listData).owner); + + super.updateDisplayList(unscaledWidth, unscaledHeight); + + g.clear(); + + if (grid1.isItemSelected(theData) || grid1.isItemHighlighted(theData)) + return; + + if(theData && theData.eventName){ + if(theData.eventName.indexOf ("result=fail") != -1){ + g.beginFill(0xff0000); + g.drawRect(0, 0, unscaledWidth, unscaledHeight); + g.endFill(); + } + } + } + +]]> +</mx:Script> + +</mx:Label>