FlexMonkey compatibility with Flex 4.12
New here? Learn about Bountify and follow @bountify to get notified of new bounties! x

FlexMonkey does not work with Apache Flex V.4.12
The Automation Library that is a part of the Flex SDK has changed since it was donated by Adobe and the tool itself throws errors/exceptions with previously working test scripts.

We would like to find all the differences in the Flex Automation Library between V.4.6 and V.4.12 and point to the code that is now incompatible.

Note: This is not a fixing task, just finding the exact place of the problem...

Can you provide a dummy file that throws the errors you mentioned? Also, what version of FlexMonkey are you using?
alixaxel over 5 years ago
You can look at this link and see the error description there: https://www.bountysource.com/issues/2933435-flexmonkey-incompatible-with-flex-4-12 You can also find the source code of the latest FlexMonkey here: https://github.com/BAXTER-IT/FlexMonkey
skyone over 5 years ago
Hi Axel, let us know if we can be more specific, we can post more code errors or anything else you need.
mikmik over 5 years ago
awarded to alixaxel

Crowdsource coding tasks.

1 Solution

Winning solution

I spent about 5 hours going through the code but I couldn't really pinpoint the origin of the bugs. :-(

I started by downloading Flex 4.6 and 4.12.1, removed all the comments with pmccabe (the copyright always differs) from both files and analyzed the differences, first with Meld and then with a wrapper around ssdeep.

I didn't learn much with this approach since 4.12.1/frameworks/projects/automation_agent is a whole new package structure that doesn't exist in Flex 4.6, I would bet the cause is somewhere in there as pretty much all the other files remain the same, with small changes to the code logic here and there (nothing that I saw hinted as being the cause of the incompatibility). Apache also renamed the mx.automation.qtp.IQTP* classes to mx.automation.tool.ITool* -- mx.automation.tool is defined in ActionScript but mx.automation.qtp seems to be pre-compiled in .swc files (which I don't know how to inspect).

I tried to trace the exception you posted on the GitHub issue and a file stroke me as potentially suspicious - I don't really know enough about AS / Flex to be sure, so you'll have to be the judge.

/Flex/4.6/frameworks/projects/framework/src/mx/automation/Automation.as (same as below)

package mx.automation
{

import flash.display.DisplayObject;
import flash.utils.getQualifiedClassName;

import mx.automation.IAutomationMouseSimulator;
import mx.automation.IAutomationObjectHelper;
import mx.core.IUIComponent;
import mx.core.mx_internal;

use namespace mx_internal;

/**
 * The Automation class defines the entry point for the Flex Automation framework.
 */
public class Automation
...

/Flex/4.12.1/frameworks/projects/framework/src/mx/automation/Automation.as (same as above)

package mx.automation
{

import flash.display.DisplayObject;
import flash.utils.getQualifiedClassName;

import mx.automation.IAutomationMouseSimulator;
import mx.automation.IAutomationObjectHelper;
import mx.core.IUIComponent;
import mx.core.mx_internal;

use namespace mx_internal;

/**
 * The Automation class defines the entry point for the Flex Automation framework.
 */
public class Automation
...

/Flex/4.12.1/frameworks/projects/automation_agent/src/mx/automation/Automation.as

package mx.automation 
{

import flash.utils.Dictionary;

import mx.core.Application;
import mx.core.FlexGlobals;
import mx.core.mx_internal;

use namespace mx_internal;

/**
 * The Automation class defines the entry point for the Flex Automation framework.
 */
public class Automation
...

The second is a verbatim copy of the first/old one, but the third has a very different interface.

Having two mx.automation.Automation classes seems weird / wrong (but then again maybe not in AS?), furthermore the last one is not importing IAutomationMouseSimulator and IAutomationObjectHelper used by 4.6. According to the exception, automation_agent is being used by SparkButtonBaseAutomationImpl.

Then again the /Flex/4.12.1/frameworks/projects/automation_agent/compile-config.xml file references both ./src and ../automation/src as it's source-paths so maybe the class is combined or overridden??


The definition for recordAutomatableEvent() in 4.6 is consistent across 7 files:

  • frameworks/projects/automation/src/mx/automation/delegates/TextFieldAutomationHelper.as
  • frameworks/projects/automation/src/mx/automation/delegates/controls/ButtonBarAutomationImpl.as
  • frameworks/projects/automation/src/mx/automation/delegates/controls/LinkBarAutomationImpl.as
  • frameworks/projects/automation/src/mx/automation/delegates/controls/MenuAutomationImpl.as
  • frameworks/projects/automation/src/mx/automation/delegates/core/UIComponentAutomationImpl.as
  • frameworks/projects/automation_flashflexkit/src/mx/automation/delegates/flashflexkit/UIMovieClipAutomationImpl.as
  • frameworks/projects/automation_spark/src/spark/automation/delegates/SparkRichEditableTextAutomationHelper.as

public function recordAutomatableEvent(event:Event, cacheable:Boolean = false):void


In 4.12.1, AutomationManager.as uses a different definition from the remaining files:

public function recordAutomatableEvent(recorder:IAutomationObject, event:Event, cacheable:Boolean = false):void

Looking at line 2037 where the exception is thrown, we can see it's because eventDescriptor is null.

var eventDescriptor:IAutomationEventDescriptor =
    automationClass.getDescriptorForEvent(re.replayableEvent);

And a few lines above:

var automationClass:IAutomationClass =
    automationEnvironment.getAutomationClassByInstance(re.automationObject as IAutomationObject);

At this point we know that automationClass is not null, otherwise it would throw another exception.

We also know that automationEnvironment is not falsy, otherwise the method would return a nil value.

Checking where re.automationObject is defined:

var re:AutomationRecordEvent;

if (event is AutomationRecordEvent)
    re = event as AutomationRecordEvent;
else
{
    re = new AutomationRecordEvent(AutomationRecordEvent.RECORD);
    re.automationObject = recorder;
    re.replayableEvent = event;
    re.cacheable = cacheable;
}

We go back to the recorder argument of the updated recordAutomatableEvent() definition.

My guess is that for that particular error, FlexMonkey is not using the correct (updated) argument. I would try and add some debug output to that method to inspect what arguments are being passed and go from there.


Sorry I couldn't help much, and good luck figuring this out!

Hi Axel, I see the deadline on the system shows 2h left. Will you post your ideas in time ? http://www.wired.com/images_blogs/underwire/2011/10/in-time-arm.jpg
mikmik over 5 years ago
You still have ~48h to accept an answer, I'm still going through the code (it's massive). If you can share additional errors that could help.
alixaxel over 5 years ago
This is top class, thanks for this findings. I think we will have another question coming soon...
mikmik over 5 years ago