OWASP O2 Platform Blog

O2 Script to download O2 Reference DLLs from SVN

An O2 user today had a problem that sometimes happens inside networks with’ proxy based internet access’.

The issue is that if an O2 script needs a particular dll to run and it has not been downloaded before, O2 will fail to find it because the ping that it makes to check for online connectity will fail (this is a bug that needs to be fixed in the main O2 ClickOnce version).

So to address his short term need (and to show how easy it is to¬†add new modules anf capabilities to O2), I ‘live coded’ the scrip below using ietherpad.com ūüôā

Here is the link of the Etherpad timeslider (you can go back in time and see how the script evolved): http://ietherpad.com/ep/pad/view/uuSwFWulSf/latest

Here is a screenshot of what it looks like:

Here is the source code of this new O2¬†Util (which is already added to the main O2 Scripts folder (look for the script called ‘Util – Download O2 Reference File.h2’))

//var topPanel = panel.clear().add_Panel();
var topPanel = "Get O2 Reference dll (double click on file to download it)".popupWindow(400,500); 
topPanel.insert_LogViewer();</pre>
&nbsp;

var ie = topPanel.add_IE().silent(true);

var treeView = topPanel.insert_Left().add_TreeView().sort();

Action<string> addUrlMappingsToTreeView =
    (urlWithLinks)=>{
                        ie.open(urlWithLinks);
                        var links = from link in ie.links()
                            where link.text() != ".."
                            select new { filename = link.text() , url = link.url() };
                        foreach(var link in links)
                            treeView.add_Node(link.filename, link.url);
                    };
addUrlMappingsToTreeView("<a href="http://o2platform.googlecode.com/svn/trunk/O2%20-%20All%20Active%20Projects/_3rdPartyDlls/FilesWithNoCode/">http://o2platform.googlecode.com/svn/trunk/O2%20-%20All%20Active%20Projects/_3rdPartyDlls/FilesWithNoCode/</a>");
addUrlMappingsToTreeView("<a href="http://o2platform.googlecode.com/svn/trunk/O2%20-%20All%20Active%20Projects/_3rdPartyDlls/">http://o2platform.googlecode.com/svn/trunk/O2%20-%20All%20Active%20Projects/_3rdPartyDlls/</a>");

topPanel.splitContainer().panel2Collapsed(true);

treeView.onDoubleClick<string>(
    (url)=> {
                treeView.pink();
                "you selected the url: {0}".info(url);
                var localTempFile = url.uri().download();
                var copiedFile = Files.Copy(localTempFile,PublicDI.config.CurrentExecutableDirectory);
                "file was copied to: {0}".info(copiedFile);
                treeView.white();
            });
return "ok";

//O2File:WatiN_IE_ExtensionMethods.cs
//using O2.XRules.Database.Utils.O2
//O2Ref:WatiN.Core.1x.dll

July 13, 2011 Posted by | O2 Internals, WatiN | Leave a comment

Viewing JPetStore Hsqldb database and couple more Autobinding issues

Included in the hsqldb folder is a file called manager.bat which can be used to connect to the live (in memory) JPetStore database.

Here are the settings needed (select ‘HSQL Database Engine Server’ and use jdbc:hsqldb:hsql://localhost:9002¬†as the URL value):

Here is a sample query:

 
Here are a couple more Autobinding issues
var ie = topPanel.add_IE_with_NavigationBar().silent(true); 
 
 Action scrollToTotal = 
    ()=>{
            var tdElement = ie.elements().elements("TD").toList().Where((element)=> element.innerHtml().notNull() && element.innerHtml().contains("Total:")).first();
            tdElement.scrollIntoView();                                                                                                
        };
       
//var _payload = "order.totalPrice=1111&" + "order.lineItems[0].unitPrice=12";  // works
//var _payload = "order.totalPrice=1111&" + "order.lineItems[0].itemId=AA";  // throws error
//var _payload = "order.totalPrice=1111&" + "order.lineItems[0].itemId=EST-6";  // takes the inventory from EST-6 and not EST-4
var _payload = "order.totalPrice=1111&" + "order.lineItems[0].item.product.name=AAAABBBB"; // changes the visible product name</pre>
&nbsp;

var jPetStore = new API_JPetStore(ie);
jPetStore.homePage(); 
jPetStore.loginPlaceAnOrderAndGoToCheckout();
ie.buttons()[1].flash().click(); 
jPetStore.open("/shop/newOrder.do?_finish=true&" + _payload);
scrollToTotal();                   

July 13, 2011 Posted by | JPetStore, Spring MVC | Leave a comment

Writing an O2 ‘IE Automation’ Script for JPetStore Account Creation

Here is a video and script of the interactive process of writing an O2 IE Automation Script for JPetStore.

This is is the original script as shown in the video:

panel.clear();
var ie = panel.add_IE().silent(true);</pre>
&nbsp;

//ie.open("http://localhost:8080/jpetstore");
//ie.link("Enter the Store").click();

ie.open("http://localhost:8080/jpetstore/shop/newAccount.do");
ie.field("account.username").value("a user");
ie.field("account.password").value("pwd");
ie.field("repeatedPassword").value("pwd");
ie.field("account.firstName").value("first");
ie.field("account.lastName").value("name");
ie.field("account.address1").value("1");
ie.field("account.phone").value("2");
ie.field("account.city").value("3");
ie.field("account.state").value("4");
ie.field("account.zip").value("5");
ie.field("account.country").value("6");
ie.field("account.email").value("7");
ie.button("Save Account Information").click();

//return ie.buttons();
//ie.inject_FirebugLite();
//return ie.links();

//O2File:WatiN_IE_ExtensionMethods.cs
//using O2.XRules.Database.Utils.O2
//O2Ref:WatiN.Core.1x.dll

Which was then added to the API_JPetStore.cs as a couple createAccount(…) extension¬†methods:

public static API_JPetStore createAccount(this API_JPetStore jPetStore, string username, string password)
{
return jPetStore.createAccount(username, password, username,10.randomLetters(),10.randomLetters(),
10.randomLetters(),10.randomLetters(),10.randomLetters(),
10.randomLetters(),10.randomLetters(),10.randomLetters());
}

public static API_JPetStore createAccount(this API_JPetStore jPetStore, string username, string password ,
string firstName, string lastName, string address1,
string phone, string city, string state, string zip,
string country, string email)
{
jPetStore.open("/shop/newAccount.do");
var ie = jPetStore.ie;
ie.field("account.username").value(username);
ie.field("account.password").value(password);
ie.field("repeatedPassword").value(password);
ie.field("account.firstName").value(firstName);
ie.field("account.lastName").value(lastName);
ie.field("account.address1").value(address1);
ie.field("account.phone").value(phone);
ie.field("account.city").value(city);
ie.field("account.state").value(state);
ie.field("account.zip").value(zip);
ie.field("account.country").value(country);
ie.field("account.email").value(email);
ie.button("Save Account Information").click();
return jPetStore;
}

So that they can be easily consumed like this:

panel.clear();
var ie = panel.add_IE().silent(true);</pre>
&nbsp;

var jPetStore = new API_JPetStore(ie);

jPetStore.createAccount("user12","pwd"); //create user
jPetStore.logout();                         // logout
jPetStore.login("user12","pwd____");      //should fail (wrong password)
jPetStore.login("user12","pwd");          //should work

//O2File:API_JPetStore.cs
//O2File:WatiN_IE_ExtensionMethods.cs
//using O2.XRules.Database.Utils.O2
//O2Ref:WatiN.Core.1x.dll

Here is a screenshot of the user created with the script above (note the random values)

July 13, 2011 Posted by | IE Automation, JPetStore, Spring MVC, videos, WatiN | Leave a comment

Injecting FirebugLite and jQuery into a IE Automation page (JPetStore Example)

When doing IE Automation, sometimes the best way to find out what is happening at the page we’re working on is to¬†open FireBug on it. A cool (and very powerfull)¬†alternative is to use FirebugLite which can be embeded on any page and works on most browsers.

As you can see here http://getfirebug.com/firebuglite#Stable¬†one way to fireup FirebugLite is to execute that bit of Javascript they show under the ‘Add the following link to your bookmarks:’ section.

When using O2’s IE Automation this can be achieved like this:

var firebugLiteScript = &amp;quot;(function(F,i,r,e,b,u,g,L,I,T,E){if(F.getElementById(b))return;E=F[i+'NS']&amp;amp;&amp;amp;F.documentElement.namespaceURI;E=E?F[i+'NS'](E,'script'):F[i]('script');E[r]('id',b);E[r]('src',I+g+T);E[r](b,u);(F[e]('head')[0]||F[e]('body')[0]).appendChild(E);E=new Image;E[r]('src',I+L);})(document,'createElement','setAttribute','getElementsByTagName','FirebugLite','4','firebug-lite.js','releases/lite/latest/skin/xp/sprite.png','https://getfirebug.com/','#startOpened');&amp;quot;;
ie.eval(firebugLiteScript );

And since that works, let’s add it as an Extension method to the WatiN_ExtensionMethods.cs file that is used on the IE Automation script:

public static class WatiN_IE_ExtensionMethods_FireBugLite
{
public static WatiN_IE inject_FirebugLite(this WatiN_IE ie)
{
var firebugLiteScript = &amp;quot;(function(F,i,r,e,b,u,g,L,I,T,E){if(F.getElementById(b))return;E=F[i+'NS']&amp;amp;&amp;amp;F.documentElement.namespaceURI;E=E?F[i+'NS'](E,'script'):F[i]('script');E[r]('id',b);E[r]('src',I+g+T);E[r](b,u);(F[e]('head')[0]||F[e]('body')[0]).appendChild(E);E=new Image;E[r]('src',I+L);})(document,'createElement','setAttribute','getElementsByTagName','FirebugLite','4','firebug-lite.js','releases/lite/latest/skin/xp/sprite.png','https://getfirebug.com/','#startOpened');&amp;quot;;
ie.eval(firebugLiteScript);
return ie;
}
}

While we are here lets also add jQuery directly (without the need to use the IE_JQuery.cs api)

ie.eval(&amp;quot;&amp;lt;a href=&amp;quot;http://code.jquery.com/jquery-1.6.2.min.js%22.uri().getHtml&amp;quot;&amp;gt;http://code.jquery.com/jquery-1.6.2.min.js&amp;quot;.uri().getHtml&amp;lt;/a&amp;gt;());

or as an extension method:

public static class WatiN_IE_ExtensionMethods_JQuery
{
public static WatiN_IE inject_jQuery(this WatiN_IE ie)
{
ie.eval(&amp;quot;&amp;lt;a href=&amp;quot;http://code.jquery.com/jquery-1.6.2.min.js%22.uri().getHtml&amp;quot;&amp;gt;http://code.jquery.com/jquery-1.6.2.min.js&amp;quot;.uri().getHtml&amp;lt;/a&amp;gt;());
return ie;
}
}

Puting it all together, here is a script that:

  • ¬†opens up JPetStore
  • Injects FirebugLite
  • Injects jQuery
  • runs a jQuery command that:
    • selects an ‘a’ with the content ‘Enter the Store’
    • changes its border to 2px
    • changes it size to 20px
    • fades it out in 2000 ms
    • fades is it in 2000 ms
var topPanel = panel.clear().add_Panel();
var ie = topPanel.add_IE().silent(true);
var jPetStore = new API_JPetStore(ie);

jPetStore.homePage();
ie.inject_FirebugLite();
ie.inject_jQuery();
ie.eval(&amp;quot;jQuery(\&amp;quot;a:contains('Enter the Store')\&amp;quot;).css({'border': 'solid 10px', 'font-size' : 30 } ).fadeOut(2000).fadeIn(2000);&amp;quot;);&amp;lt;/pre&amp;gt;
&amp;amp;nbsp;
//O2File:API_JPetStore.cs
//O2File:WatiN_IE_ExtensionMethods.cs
//using O2.XRules.Database.Utils.O2
//O2Ref:WatiN.Core.1x.dll

Here is a screenshot what what this looks like:

July 13, 2011 Posted by | IE Automation, JPetStore, jQuery, Spring MVC, WatiN | Leave a comment

Creating an API for JPetStore Browser automation

Once we have a number of Lambda functions to perform IE/Web automation, the next step is to create an API so that they can be easily consumed and reused.

This API is going to be called API_JPetStore.cs and will allow the simple invocation of JPetStore commands like this:

var topPanel = panel.clear().add_Panel();
var ie = topPanel.add_IE().silent(true); 
var jPetStore = new API_JPetStore(ie);
 
jPetStore.homePage(); 
jPetStore.login_DefaultValues();
jPetStore.logout();
jPetStore.login("asd","asd"); 
jPetStore.login("j2ee","j2ee");</pre>
&nbsp;

//O2File:API_JPetStore.cs
//O2File:WatiN_IE_ExtensionMethods.cs
//using O2.XRules.Database.Utils.O2
//O2Ref:WatiN.Core.1x.dll

Here is the current source code for the API_JPetStore.cs file (at the moment only implemeting a couple functions (like the login and logout)

// This file is part of the OWASP O2 Platform (<a href="http://www.owasp.org/index.php/OWASP_O2_Platform">http://www.owasp.org/index.php/OWASP_O2_Platform</a>) and is released under the Apache 2.0 License (<a href="http://www.apache.org/licenses/LICENSE-2.0">http://www.apache.org/licenses/LICENSE-2.0</a>)
using System;
using System.Linq;
using System.Collections.Generic;
using O2.Kernel;
using O2.Kernel.ExtensionMethods;
using O2.DotNetWrappers.DotNet;
using O2.DotNetWrappers.ExtensionMethods;
//O2File:WatiN_IE_ExtensionMethods.cs   
//O2File:WatiN_IE.cs
//O2Ref:WatiN.Core.1x.dll</pre>
&nbsp;

namespace O2.XRules.Database.APIs
{
    public class API_JPetStore
    {   
        public WatiN_IE ie;
        public string appUrl = "<a href="http://localhost:8080/jpetstore">http://localhost:8080/jpetstore</a>";
       
        public API_JPetStore(WatiN_IE _ie)
        {
            ie = _ie;
        }           
       
        public API_JPetStore open(string virtualPath)
        {
            if (virtualPath.starts("/").isFalse())
                virtualPath = "/{0}".format(virtualPath);
            var fullUri = "{0}{1}".format(appUrl, virtualPath).uri();
            ie.open(fullUri.str());
            return this;
        }
    }
   
      
    public static class API_JPetStore_ExtensionMethods
    {
        public static API_JPetStore homePage(this API_JPetStore jPetStore)       
        {           
            jPetStore.open("");
            return jPetStore;
        }
       
        public static API_JPetStore login_DefaultValues(this API_JPetStore jPetStore)       
        {           
            jPetStore.open("/shop/signonForm.do");
            jPetStore.ie.buttons()[1].click();
            return jPetStore;
        }
       
        public static bool login(this API_JPetStore jPetStore, string username, string password)       
        {           
            jPetStore.open("/shop/signonForm.do");
            var ie = jPetStore.ie;
            ie.field("username").value(username);
            ie.field("password").value(password);
            jPetStore.ie.buttons()[1].click();
            return ie.IE.Html.contains("Invalid username or password. Signon failed.");
        }
       
        public static API_JPetStore logout(this API_JPetStore jPetStore)       
        {           
            jPetStore.open("/shop/signoff.do");            
            return jPetStore;
        }

       
    }
}

 

July 13, 2011 Posted by | JPetStore, Spring MVC, WatiN | Leave a comment