<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Miti&#039;s Blog &#187; air</title>
	<atom:link href="http://miti.pricope.com/category/air/feed/" rel="self" type="application/rss+xml" />
	<link>http://miti.pricope.com</link>
	<description>about technology</description>
	<lastBuildDate>Sat, 06 Feb 2010 10:08:13 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Integrating PayPal Express Checkout with AIR and Flex</title>
		<link>http://miti.pricope.com/2009/07/30/integrating-paypal-express-checkout-with-air-and-flex/</link>
		<comments>http://miti.pricope.com/2009/07/30/integrating-paypal-express-checkout-with-air-and-flex/#comments</comments>
		<pubDate>Thu, 30 Jul 2009 10:13:45 +0000</pubDate>
		<dc:creator>mpricope</dc:creator>
				<category><![CDATA[air]]></category>
		<category><![CDATA[flex]]></category>
		<category><![CDATA[payment gateways]]></category>
		<category><![CDATA[tutorials]]></category>

		<guid isPermaLink="false">http://miti.pricope.com/2009/07/31/integrating-paypal-express-checkout-with-air-and-flex/</guid>
		<description><![CDATA[This article continues the series about integrating Flex and AIR with payment gateway services. Parts of this article are very similar with the other posts about this subject: Integrating PayPal Express Checkout with Flex(which I recommend reading before this article),Using Amazon Flexible Payment System with Flex and Using Amazon Flexible Payment System with Flex &#38; [...]]]></description>
			<content:encoded><![CDATA[<p><font color="#999999">This article continues the series about integrating Flex and AIR with payment gateway services. Parts of this article are very similar with the other posts about this subject: <br />
		      <a href="http://miti.pricope.com/2009/07/19/integrating-paypal-express-checkout-with-flex/">Integrating PayPal Express Checkout with Flex</a>(which I recommend reading before this article),<a href="http://miti.pricope.com/2009/07/11/using-amazon-flexible-payment-system-with-flex/">Using Amazon Flexible Payment System with Flex</a> and <a href="http://miti.pricope.com/2009/07/26/using-amazon-flexible-payment-system-with-flex-air/">Using Amazon Flexible Payment System with Flex &amp; AIR</a>.</font></p>
<p>I will focus mainly on how to take the PayPal + Flex workflow (described <a href="http://miti.pricope.com/2009/07/19/integrating-paypal-express-checkout-with-flex/">here</a>) out of the browser and into an AIR application. </p>
<p>Although AIR applications run on the desktop and the local security constraints are different from those in the browser, from a payment gateway point of view things don’t change at all. As a result, we can conclude that because AIR is a client technology hardcoding sensitive information into an AIR app is highly insecure (even though the code is compiled into bytecode). This means that any credential related info (like API_USERNAME, API_PASSWORD and API_SIGNATURE) should NOT be stored in the AIR application.</p>
<h3>Architectural Approach and UI solutions</h3>
<p>Summing this up, our architectural solution has to comply with some concurrent demands:</p>
<ul>
<li> an AIR front-end that is stateful and is built following the single page app paradigm</li>
<li>the need for security that requires that the AIR app should NOT deal with PayPal API credentials</li>
<li>The payment workflow has a part that is hosted on the PayPal servers and that is a standard request-response web application</li>
</ul>
<p>In order to address these I propose the following approach:</p>
<ul>
<li> all PayPal API calls should be done on the server side so that API credentials will be protected</li>
<li>the access to the PayPal web application should be done in a browser page. <font color="#FF0000"><strong>IMPORTANT SECURITY NOTE:</strong></font>  Although technically it might be possible to use the HTML container of the AIR runtime this is an unsecure practice because the end user cannot visually verify that he is entering his credentials on the PayPal site. In the browser he can check the URL and the security certificate.</li>
</ul>
<p>So the buyer workflow becomes:</p>
<ol>
<li>(Step 1) Chooses to checkout using PayPal in the AIR application (<font color="#FF0000">Security Note</font>: Starting from this point it is mandatory that all requests are done through https)</li>
<li>(Step 2) Sees a browser window open and logs into PayPal to authenticate his/her identity</li>
<li>(Step 3) Reviews the transaction on PayPal</li>
<li>(Step 4) Confirms the order and pays from your site</li>
<li>(Step 5) Reviews the order confirmation on your site</li>
<li>(Step 6) Returns to the AIR application</li>
</ol>
<p>&#160;</p>
<p>
<h3>Calling the PayPal part of the checkout process</h3>
</p>
<p>So the PayPal workflow should be open in a browser window. Here is how to do that in the AIR app:</p>
<p><pre class="brush: as3;">
var url:URLRequest = new URLRequest(URL_ROOT + &quot;/payPalAIR/startPaymentFlex.php&quot;);
url.data = new URLVariables();
var obj:URLVariables = new URLVariables();
url.data.movieId = '1';
url.data.paymentReason = 'Enter The Matrix';
url.method = &quot;GET&quot;;

navigateToURL(url, &quot;new&quot;);
currentState='Wait';
</pre>
</p>
<p>Everything else is pretty similar with how you <a href="2009/07/19/integrating-paypal-express-checkout-with-flex/#callPayPal">call the PayPal workflow from a Flex app</a>.</p>
<h3>Returning from PayPal and notifying the AIR application</h3>
<p>Here again we follow an approach similar with how you <a href="2009/07/19/integrating-paypal-express-checkout-with-flex/#returnFromPayPal">return from PayPal to a Flex application</a> (Step 4 and Step 5). </p>
<p>The only thing that differs is how we get back to the AIR application (Step 6). ExternalInterface is not suited for this job but we can use instead the LocalConnection to make the browser application communicate with the AIR one. LocalConnection, while being more secure than ExternalIterface, can still be exploited using techniques like DNS rewriting so we can&#8217;t pass sensitive information through it. Furthermore, since the AIR app is independent from the browser this means that our browser app has a different server session than the AIR App. So a simple notification is not enough: we need to also pass the session id. This is not sensitive information, but it will allow the AIR application to retrieve from the server any sensitive information that the browser application has set.</p>
<p>Let&#8217;s take a look on what we need to do right after we call the PAY operation in our return page. In the transaction detail page we will link to a little Flex application that will only communicate with the AIR application. We can use this little application to also forward the error and cancel messages. We will call it using an anchor parameter:</p>
<p><pre class="brush: xml;">
&lt;a class=&quot;home&quot; id=&quot;CallsLink&quot; href=&quot;payPalAIRReturn.html#method=doStatus&quot;&gt;Return to AIR&lt;/a&gt;
</pre>
</p>
<p>This little application will only contain some code that will get the cookie string from the browser (remember we need this to make the AIR application connect to the same server session) and send a message through LocalConnection to the AIR application:</p>
<p><pre class="brush: as3;">
private var outbound:LocalConnection = new LocalConnection();
protected function application1_applicationCompleteHandler(event:FlexEvent):void
{
	var browserManager:IBrowserManager = BrowserManager.getInstance();
	browserManager.init();
	var urlObj:Object = URLUtil.stringToObject(browserManager.fragment);
	if (urlObj.method) {
		//get the cookie string
		ExternalInterface.call('eval','window.cookieStr = function () {return document.cookie};')
			var cookieStr:String = ExternalInterface.call('cookieStr');
		outbound.connect(&quot;paymentSample&quot;);
		outbound.send(&quot;app#payPalAIR:paymentSample&quot;,urlObj.method,cookieStr);
		outbound.close();
	}
}
</pre>
</p>
<p>Please notice that when launching from Flex Builder the AIR Application has no Publisher ID so the connection name is “app#payPalAIR:paymentSample”. After packaging and installation the AIR app will get a Publisher ID so the connection name becomes something like this: app#payPalAIR.F0B3F68E1857B8A07069FED1D0638CAF200F76EB.1:paymentSample</p>
<p>You can get the publisher ID of the installed AIR app by looking at the META-INF/AIR/publisherid file within the application install directory.</p>
<p>Back in the AIR application we need to expose the functions through local connection:</p>
<p><pre class="brush: as3;">
private function initApp():void {
	//only allow connections from localhost
	//you need to replace &quot;localhost&quot; with the final domain
	//where your application will be hosted
	inbound.allowDomain(&quot;localhost&quot;);
	inbound.client = new Object();
	//this is the function that will be called by the Browser App
	inbound.client.doStatus = doStatus;
	inbound.client.doError = doError;
	inbound.client.doCancel = doCancel;

	//inbound.client.
	inbound.connect(&quot;paymentSample&quot;);

}
</pre>
</p>
<p>All methods (doStatus, do Error and doCancel) will receive the cookie string as a parameter. In do Status we need to check the transaction status on the server:</p>
<p><pre class="brush: as3;">
private function doStatus(cookieStr:String):void {
	var srv:HTTPService = new HTTPService();
	srv.headers.Cookie = cookieStr;
	srv.url = URL_ROOT + &quot;/payPalAIR/getPaymentStatus.php&quot;;
	srv.addEventListener(ResultEvent.RESULT,function (event:ResultEvent):void {

		Alert.show(event.result.status.type);
		nativeApplication.activate();
		if (event.result.status.type == 'SUCCESS') {
			currentState = 'Succes';
		} else {
			currentState = 'Fail';
		}
	});
	srv.addEventListener(FaultEvent.FAULT,function (event:FaultEvent):void {
		nativeApplication.activate();
		currentState = 'Fail';
		Alert.show(event.message.toString());
	});
	srv.send();
}
</pre>
</p>
<p>where getPaymentStatus.php is just a simple page that gets the status from the session and serialize it in a simple XML format:</p>
<p><pre class="brush: php;">
&lt;?php
session_start();
?&gt;
&lt;status&gt;
	&lt;type&gt;&lt;?php echo strtoupper ($_SESSION ['reshash'] [&quot;ACK&quot;] ) ?&gt;&lt;/type&gt;
&lt;/status&gt;
</pre>
</p>
<p>
<h3>Installing the sample files</h3>
</p>
<ol>
<li> In Flash Builder click File-&gt;Import .. and choose Flash Builder Project</li>
<li> Choose <a href="http://miti.pricope.com/samples/payPalAIRFiles/payPalAIR.fxp">payPalAIR.fxp</a></li>
<li> Unzip <a href="http://miti.pricope.com/samples/payPalAIRFiles/payPalAIR.zip"> payPalAIR.zip</a> into your Web Root folder (For example: /work/www).</li>
<li> Edit payPalAIR/ppNVP/constants.php and replace</li>
<p><pre class="brush: php;">
define('API_USERNAME', 'sdk-three_api1.sdk.com');
define('API_PASSWORD', 'QFZCWN5HZM8VBG7Q');
define('API_SIGNATURE', 'A.d9eRKfd1yVkRrtmMfCFLTqa6M9AyodL0SJkhYztxUi8W9pCXF6.4NI');
</pre>
</p>
<p>with your ownPayPal API_USERNAME, API_PASSWORD and API_SIGNATURE </p>
<li>In Flash Builder click File-&gt;Import … and choose Flash Builder Project.</li>
<li> Choose <a href="http://miti.pricope.com/samples/payPalAIRFiles/payPalAIRReturn.fxp">payPalAIRReturn.fxp</a></li>
<li> Fill the Output Folder Location (this one should point to where you have unzipped payPalAIR.zip, in your web root), Web Root and Root URL with your values. It should look something like this:</li>
<p>		    <img src="http://miti.pricope.com/wp-content/uploads/2009/07/Picture8.png" width="600" height="404" />
		  </ol>
<p><br/>
		    </p>
]]></content:encoded>
			<wfw:commentRss>http://miti.pricope.com/2009/07/30/integrating-paypal-express-checkout-with-air-and-flex/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Using Amazon Flexible Payment System with Flex &amp; AIR</title>
		<link>http://miti.pricope.com/2009/07/26/using-amazon-flexible-payment-system-with-flex-air/</link>
		<comments>http://miti.pricope.com/2009/07/26/using-amazon-flexible-payment-system-with-flex-air/#comments</comments>
		<pubDate>Sun, 26 Jul 2009 12:16:31 +0000</pubDate>
		<dc:creator>mpricope</dc:creator>
				<category><![CDATA[air]]></category>
		<category><![CDATA[flex]]></category>
		<category><![CDATA[payment gateways]]></category>
		<category><![CDATA[tutorials]]></category>

		<guid isPermaLink="false">http://miti.pricope.com/?p=181</guid>
		<description><![CDATA[I&#8217;ve already talked about using Flex with Amazon FPS, so now let&#8217;s see what is involved in taking this out of the browser into an AIR app. I recommend reading that article before reading this one, since many of the security considerations described there in detail are valid for AIR applications also. In this article [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve already talked about <a href="http://miti.pricope.com/2009/07/11/using-amazon-flexible-payment-system-with-flex/">using Flex with Amazon FPS</a>, so now let&#8217;s see what is involved in taking this out of the browser into an AIR app. I recommend reading that article before reading this one, since many of the security considerations described there in detail are valid for AIR applications also. In this article I will only highlight the differences between building a Flex application that runs in the browser and one that runs on the desktop.</p>
<p>Although AIR applications run on the desktop and the local security constraints are different from those in the browser, from a payment gateway point of view things don&#8217;t change at all. As a result, we can conclude that because AIR is a client technology  hardcoding sensitive information into an AIR app is highly insecure (even though the code is compiled into bytecode). This means that any signature related computation should NOT be made in AIR and the Amazon Secret Key should NOT under any circumstance be put into an AIR App.</p>
<h3>Architectural Approach and UI solutions</h3>
<p>Summing this up, our architectural solution has to comply with two concurrent demands:</p>
<ul>
<li>an AIR front-end that is stateful and is built following the single page app paradigm </li>
<li>the security need that the AIR app should NOT deal with Amazon Security Key plus the need to go to the Amazon co-branded page to authenticate the users </li>
</ul>
<ul>In order to address these I propose the following approach:    </p>
<li>All payment related processing should be done on the server side to protect the Amazon Secret Key. Of course this means that the AIR app must be on-line when the payment takes place. </li>
<li>The access to the co-branded page should be done in a browser page. <font color="#ff0000"><strong>IMPORTANT SECURITY NOTE:</strong></font>&#160; Although technically it might be possible to use the HTML container of the AIR runtime this is an unsecure practice because the end user cannot visually verify that he is entering his credentials on the Amazon site. In the browser he can check the URL and the security certificate.</li>
</ul>
<h3><b>Calling the Amazon Co-Branded User Interface</b></h3>
<p>So the Amazon co-branded UI should be open in a browser window. Here is how to do that in the AIR app.</p>
<p><pre class="brush: as3;">
var url:URLRequest = new URLRequest(&quot;http://localhost/amazonAIR/startPayment.php&quot;);
url.data = new URLVariables();
var obj:URLVariables = new URLVariables();
url.data.movieId = 1;
url.data.paymentReason = 'Enter The Matrix';
url.method = &quot;GET&quot;;
navigateToURL(url, &quot;new&quot;);
</pre>
</p>
<p>Everything else is pretty similar with how <a href="http://miti.pricope.com/2009/07/11/using-amazon-flexible-payment-system-with-flex/#callingAmazonUI">you call the Amazon co-branded UI from a Flex app that runs in the browser</a>.</p>
<p>Exactly the same goes with <a href="http://miti.pricope.com/2009/07/11/using-amazon-flexible-payment-system-with-flex/#returnFromAmazon">returning from Amazon and making the Pay request</a>.</p>
<h3><b>Using LocalConnection to notify the AIR App</b></h3>
<p>The only thing left now is to notify the AIR application and bring it to front.</p>
<p>To do that we need to communicate between the browser app  and the AIR app. In order to achieve this we can use the LocalConnection  mechanism. LocalConnection objects can communicate among files that are running  on the same client computer, but they can be running in different applications  — for example, a file running in a browser and a SWF file running in Adobe AIR.</p>
<p>Now there is one important thing to remember about LocalConnection. It can be tricked using techniques like DNS rewriting. So we will not pass any sensitive information through LocalConnection. However, since the AIR app is independent from the browser this means that our browser app has a different server session than the AIR App. So a simple notification is not enough, we need to also pass the session id. This is not sensitive information, but it will allow the AIR application to retrieve from the server any sensitive information that the browser application has set.</p>
<p>Let&#8217;s take a look what we need to do right after the return.php page made the PAY operation.</p>
<p>For simplicity the returnAir.php page will have a link to a little Flex app that will communicate with the AIR app. All it needs to do is to get the cookie information and send it through LocalConnection to the AIR app:</p>
<p><pre class="brush: as3;">
private var outbound:LocalConnection = new LocalConnection();

private function gotoAIR():void {
	//get the cookie string
	ExternalInterface.call('eval','window.cookieStr = function () {return document.cookie};')
	var cookieStr:String = ExternalInterface.call('cookieStr');

	outbound.connect(&quot;paymentSample&quot;);
	outbound.send(&quot;app#amazonAIR:paymentSample&quot;,&quot;notifyPayment&quot;,cookieStr);
	//outbound.send(&quot;app#testAmazonAir.F0B3F68E1857B8A07069FED1D0638CAF200F76EB.1:paymentSample&quot;,&quot;notifyPayment&quot;,cookieStr);
	outbound.close();
}
</pre>
</p>
<p>Please notice that when launching from Flex Builder the AIR  Application has no Publisher ID so the connection name is &ldquo;app#amazonAIR:paymentSample&rdquo;.  After packaging and installation the AIR app will get a Publisher ID so the  connection name becomes something like this: app#amazonAIR.F0B3F68E1857B8A07069FED1D0638CAF200F76EB.1:paymentSample</p>
<p>You can get the publisher ID of the installed AIR App by  looking at the META-INF/AIR/publisherid file within the  application install directory.</p>
</p>
<p>Back in our AIR app we need to expose a function to be available  on LocalConnection.</p>
<p><pre class="brush: as3;">
//This will be used by return.php to notify the AIR App
//that the payment has been made
private var inbound:LocalConnection = new LocalConnection();

private function initApp():void {
	//only allow connections from localhost
	//you need to replace &quot;localhost&quot; with the final domain
	//where your application will be hosted
	inbound.allowDomain(&quot;localhost&quot;);
	inbound.client = new Object();
	//this is the function that will be called by the Browser App
	inbound.client.notifyPayment = paymentNotification;
	inbound.connect(&quot;paymentSample&quot;);
}
</pre>
</p>
<p>Where paymentNotification is a function that receives the cookie string as parameters and queries the server to check the transaction status:</p>
<p><pre class="brush: as3;">
public function paymentNotification(cookieStr:String):void {
	var srv:HTTPService = new HTTPService();
	srv.headers.Cookie = cookieStr;
	srv.url = &quot;http://localhost/amazonAIR/paymentStatus.php&quot;;
	srv.addEventListener(ResultEvent.RESULT,function (event:ResultEvent):void {
		nativeApplication.activate();
		if (event.result.status == 'OK') {
			currentState = 'Succes';
		} else {
			currentState = 'Fail';
		}
	});
	srv.send();
}
</pre>
</p>
<h3>Installing the sample files</h3>
<ol>
<li>In Flash Builder click File-&gt;Import .. and choose Flash Builder Project</li>
<li>Choose <a href="http://miti.pricope.com/samples/amazonAIRFiles/amazonAIR.fxp">AmazonAIR.fxp</a></li>
<li>Unzip <a href="http://miti.pricope.com/samples/amazonAIRFiles/amazonAIR.zip">amazonAIR.zip</a> into your Web Root folder (For example: /work/www).</li>
<li>Edit amazonAIR/amazon-fps/src/Amazon/FPS/Samples/.config.inc.php and replace
	          </li>
<p><pre class="brush: php;">
define('AWS_ACCESS_KEY_ID', 'YOUR ACCESS KEY');
define('AWS_SECRET_ACCESS_KEY', 'YOUR SECRET ACCESS KEY');
</pre>
</p>
<p>with your own Amazon ACCESS key and SECRET_ACCESS_KEY.</p>
<li>In Flash Builder click File-&gt;Import … and choose Flash Builder Project.</li>
<li>Choose <a href="http://miti.pricope.com/samples/amazonAIRFiles/amazonAIRReturn.fxp">amazonAIRReturn.fxp</a></li>
<li>Fill the Output Folder Location (this one should point to where you have unzipped amazonAIR.zip, in your web root), Web Root and Root URL with your values. It should look something like this:</li>
</ol>
<p><img src="http://miti.pricope.com/wp-content/uploads/2009/07/Picture7.png" width="600" height="431" /></p>
]]></content:encoded>
			<wfw:commentRss>http://miti.pricope.com/2009/07/26/using-amazon-flexible-payment-system-with-flex-air/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Adding Desktop functionality to Web Applications (My MAX Milan DW + AIR sample)</title>
		<link>http://miti.pricope.com/2008/12/10/adding-desktop-functionality-to-web-applications-my-max-milan-dw-air-sample/</link>
		<comments>http://miti.pricope.com/2008/12/10/adding-desktop-functionality-to-web-applications-my-max-milan-dw-air-sample/#comments</comments>
		<pubDate>Wed, 10 Dec 2008 10:53:15 +0000</pubDate>
		<dc:creator>mpricope</dc:creator>
				<category><![CDATA[air]]></category>
		<category><![CDATA[ajax]]></category>
		<category><![CDATA[tips & tricks]]></category>

		<guid isPermaLink="false">http://miti.pricope.com/2008/12/10/adding-desktop-functionality-to-web-applications-my-max-milan-dw-air-sample/</guid>
		<description><![CDATA[One of my MAX Milan session was on how you develop AIR applications using Dreamweaver CS4. During this talk I&#8217;ve took a web application (actually I copy paste a sample of using the MSN Messenger JavaScript API) and add it some Desktop capabilities. So the little sample AIR MSN messenger now display notification when your [...]]]></description>
			<content:encoded><![CDATA[<p>One of my MAX Milan session was on how you develop AIR applications using Dreamweaver CS4. During this talk I&#8217;ve took a web application (actually I copy paste <a href="http://messenger.mslivelabs.com/samples/HelloWorld/JavaScript/WebSite/default.htm">a sample</a> of using the MSN Messenger JavaScript API) and add it some Desktop capabilities. So the little sample AIR MSN messenger now display notification when your friends will change their status message. The notification library I used is <a href="http://code.google.com/p/as3notificationlib/">as3notificationlib</a> done by <a href="http://weblogs.macromedia.com/cantrell/">Christian Cantrell</a> so you can see how easy is to call Flash code from JavaScript inside the AIR runtime.</p>
<p>You can also test the msg.html (sandbox/msg.html) file inside a browser (doesn&#8217;t seems to work on Mozilla, or on my Mozilla). The code that pushes the notification in AIR is located at line 204 and is the only modification that I&#8217;ve done to the original MSN Messenger sample.</p>
<p>You can download the code from <a href="http://miti.pricope.com/samples/msnonAir/msnonAir.zip">here</a>. </p>
]]></content:encoded>
			<wfw:commentRss>http://miti.pricope.com/2008/12/10/adding-desktop-functionality-to-web-applications-my-max-milan-dw-air-sample/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Selenium on AIR</title>
		<link>http://miti.pricope.com/2008/08/17/selenium-on-air/</link>
		<comments>http://miti.pricope.com/2008/08/17/selenium-on-air/#comments</comments>
		<pubDate>Sun, 17 Aug 2008 09:18:38 +0000</pubDate>
		<dc:creator>mpricope</dc:creator>
				<category><![CDATA[air]]></category>
		<category><![CDATA[ajax]]></category>

		<guid isPermaLink="false">http://miti.pricope.com/?p=7</guid>
		<description><![CDATA[Are you using HTML/JS to build AIR Applications and wondering how to automate functional testing for your app? Here is some news that might put a smile on your face. In few words, the guys across my desk have been tweaking Selenium to work on AIR. Mihai wrote a cool blog post about how you [...]]]></description>
			<content:encoded><![CDATA[<p>Are you using HTML/JS to build AIR Applications and wondering how to automate functional testing for your app? <a href="http://corlan.org/2008/08/15/functional-testing-framework-for-air-ajax-apps-based-on-selenium/">Here</a> is some news that might put a smile on your face. In few words, the guys across my desk have been tweaking Selenium to work on AIR. Mihai wrote a cool blog post about how you can test drive this bit of code so if you are interested please take it for a spin. Don&#8217;t forget to tell us how it was!</p>
]]></content:encoded>
			<wfw:commentRss>http://miti.pricope.com/2008/08/17/selenium-on-air/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
