近期打算在之前开发的自动化测试框架中加入对操作Flash的支持,于是开始研究怎么才能操作Flash。
研究了一遍之后发现还是和之前一样,其实在之前本人倒是有过Flash自动化,这次本想看看是否业界有什么新的方法没,貌似还是和09年时差不多。
目前有的方法有2种:
1. 基于图像识别的元素操作方法
2.通过嵌入一段测试代码,通过Flash中的ExternalInterface.addCallback方法,从Flash中对外暴露可通过javascript调用的接口
方法1我是不太喜欢的,一直觉得图像识别不靠谱,识别精度是个问题,精度太低可能识别到错误的元素,精度太高又可能不能识别正确的元素,而且一个显示文字的修改就可能使得元素识别失败。
那么我们就从方法2入手吧。
目前有FlashSelenium(http://code.google.com/p/flash-selenium/),这个项目提供了sfapi.swc和SeleniumFlexAPI.swc,用于编译到测试目标Flash中,对外提供出测试接口。
需要编译测试代码到目标Flash中,这一点还是比较麻烦,要测试的Flash不一定能拿到源码。
那就来探索一下看看有没有可能动态地加载一个测试swf,动态地扩展出ExternalInterface。
先是想到了Flash有一组在Javascript里直接可调用的接口,其中有一个LoadMovie,可以动态地加载一个swf。
那就开始实验了。
先是创建一个普通的测试页面,投放一个普通的swf文件。代码如下:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml" lang="zh-CN" xml:lang="zh-CN"> <head> <title>testFlash</title> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <style type="text/css" media="screen"> html, body { height:100%; background-color: #ffffff;} body { margin:0; padding:0; overflow:hidden; } #flashContent { width:100%; height:100%; } </style> </head> <body> <div id="flashContent"> <object id="testFlash" type="application/x-shockwave-flash" data="material.swf" width="550" height="400"> <param name="movie" value="material.swf" /> <param name="quality" value="high" /> <param name="bgcolor" value="#ffffff" /> <param name="play" value="true" /> <param name="loop" value="true" /> <param name="wmode" value="window" /> <param name="scale" value="showall" /> <param name="menu" value="true" /> <param name="devicefont" value="false" /> <param name="salign" value="" /> <param name="allowScriptAccess" value="always" /> <param name="flashvars" value="testFlashVar=ahaha" /> </object> </div> </body></html> |
然后准备一个扩展用的swf。创建一个fla文件,在时间轴的第1帧上加上ExternalInterface,输出为ext1.swf,代码如下:
import flash.external.ExternalInterface; function extFunc1() { // nothing}ExternalInterface.addCallback("extFunc1", extFunc1); |
我用Chrome进行测试,它的开发者工具还是比较方便的。
在Chrome中打开测试页面,就显示一个flash
------ Test1 开始------
先在控制台输入:document.getElementByIdx_x("testFlash").extFunc1();
恩。。应该的,还没调用ExternalInterface了
然后开始LoadMovie:document.getElementByIdx_x("testFlash").LoadMovie(0,"ext1.swf");
这时原先的flash就变成了播放ext1.swf的状态,因为ext1本来就没东西,就显示为一片空白
接着再调用一下extFunc1(), 这回没有错误了
------ Test1 结束------
但是貌似有缺陷,原来的flash没在播放了,那我还测个啥啊- -!
好吧,那么再看看,LoadMovie的第一个参数指的是要加载的层级,如果不设置为0呢?
------ Test2 开始------
仍然是打开之前的测试页面,开始LoadMovie:document.getElementByIdx_x("testFlash").LoadMovie(1,"ext1.swf");
恩。。Flash展现了,貌似调用LoadMovie也没报错,立刻试试extFunc1();
悲剧了。。提示没有这个方法
------ Test2 结束------
那看来要加载的层级只能是0了?但是0级会改变当前播放的swf。。。那么我再load回原来的swf可以么?
------ Test3 开始------
先LoadMovie:document.getElementByIdx_x("testFlash").LoadMovie(0,"ext1.swf");
再LoadMovie:document.getElementByIdx_x("testFlash").LoadMovie(0,"material.swf");
接着调用extFunc1()
额。。又悲剧了。。还换了个错误。。
------ Test3 结束------
困了,明天再议。。。