Tuesday, March 9, 2010

How to Automate YouTube Player

I was asked by one of my colleges ‘How to automate web based players like YouTube’.

Most of the player are Flash based application embedded in an HTML pages.

Found nice blog Altom blog that explore the issue:

The main issue with RIA Flex applications is that the Flash player is basically a runtime, which makes its objects invisible to its container (e.g. browser's html or javascript code), unless explicitly exposed from within

I was able to identify three ways to add automation support for Flex applications:

  1. using the Flex Automation Framework (+ExternalInterface). Adobe has developed this framework to provide a way for developing ActionScript automation-agents that facilitate the communication between the automation tools and the Flex objects. This is possible using the ExternalInterface API. I couldn't find a way of using the Automation Framework without the ExternalInterface, although it is not specified as the only option for establishing the communication. Even though the Flex SDK is open-source, the Automation Framework is not: the trial version can be used for scripts with up to 30 actions. One would have to pay 499€ (VAT not included) for the FlexBuilder Pro license in order to create larger scripts.
  2. by developing your own framework in ActionScript and make it visible through the ExternalInterface - more info about the API can be found here.
  3. IAccessible interface and MSAA. Not all the objects support the IAccessible interface by default; here you can find more info on how it can be added.

Altom blog

I’m going to try deferent approach using SeeTest from Experitest. I wrote few posts about he tool in the past but I would like to give it test drive with YouTube and test it multi browser capabilities.

The automatic test will check the play/pause capabilities, and will change movie quality.

I will execute it both on Chrome and on Internet Explorer.

Let start:

1. Set a new project, Set the application window title name to ‘YouTube’ and capture a scene:

image

image

I assume in my test that the browser is already open. So first I have to navigate to the current url.

I extract the star icon (image ). I do it by marking it on the capture scene and press the right mouse button:

image

I will use it to identify the url text field, following is the Python code as I export it from the studio.

def testUntitled(self):
    self.client.click("default", "start", 0, 1, 30, 0)
    self.client.sendText("^a")
    self.client.sendText("http://www.youtube.com/watch?v=d1_JBMrrYw8")
    self.client.sendText("{ENTER}")

You can see I clicked 30 pixels to the left of the ‘start’ element. Then sent ctrl+a to select all. Then type the url and then press Enter.

2. OK that part was easy. Now I would like to extract the play and pause buttons. To do it I just take additional scene capture when the movie is playing and extract the 2 buttons:

image

I have to set the element name to be able to use it in my scripts.

From what I understand the ‘Main color’ is used to accelerate the element identification in runtime.

image

When selecting the extracted element it can be identify in the captured scene.

3. Now let finish the script, this how the python export look like:

def testUntitled(self):
    self.client.click("default", "start", 0, 1, 30, 0)
    self.client.sendText("^a")
    self.client.sendText("http://www.youtube.com/watch?v=d1_JBMrrYw8")
    self.client.sendText("{ENTER}")
    self.client.waitForElement("default", "pause", 0, 10000)
    self.client.click("default", "pause", 0, 1)
    self.client.verifyElementFound("default", "paly")
    self.client.click("default", "paly", 0, 1)
    self.client.verifyElementFound("default", "pause")

4. Now come the part were I would like to to change the movie quality and check it changed. I extracted image element and name it ‘quality’, I change the scan algorithm to similarity with 80% identity factor:

image

I did the same to for all the quality possibilities:

image

Now I can finish the test:

def testUntitled(self):
    self.client.click("default", "start", 0, 1, 30, 0)
    self.client.sendText("^a")
    self.client.sendText("http://www.youtube.com/watch?v=d1_JBMrrYw8")
    self.client.sendText("{ENTER}")
    self.client.waitForElement("default", "pause", 0, 10000)
    self.client.click("default", "pause", 0, 1)
    self.client.verifyElementFound("default", "paly")
    self.client.click("default", "paly", 0, 1)
    self.client.verifyElementFound("default", "pause")
    self.client.click("default", "quality", 0, 0)
    self.client.click("default", "360p", 0, 1)
    self.client.click("default", "quality", 0, 0)
    self.client.verifyTextFound("default", "*360p", false)

You can see that the verification uses composition of 2 elements. It’s nice because I can extract the element once and create any composition I like (*360p, *480p and *720p).

The only part that is browser dependent in our case is the start (image) that is unique to Chrome.

To support Internet Explorer I will use overloading capability, I will extract the relevant element in IE (image ) and name is ‘start’ same as in Chrome.

Overloading is the capability to assign the same name to multiple elements. Any operation that uses the assign name will be perform on the first to found element.

So now we have a single script that can run both on Chrome and on IE. Let see how the execution and reports look like:

The main advantages are that it’s both robust and non-intrusive.

No comments:

Post a Comment