A few years ago I was privileged to be on a team with some excellent developers where I currently work, SolutionsIQ. One of whom saw the need to stabilize development on an incredibly unstable codebase with no tests. He came to the team with a proposed tool that he slapped together in his free time. It was a mashup of Selenium and FitNesse along with some modifications to support some special needs we had on the project. His name was Paul Dupuy and the entire team, including Mickey Phoenix, Rand Huso, Jonathon Golden, and Charles Liu, spent some time working on enhancing the tool, now called StoryTestIQ (aka ‘STIQ’), to make it what it is today. Other teams at SolutionsIQ have been using StoryTestIQ, as well, and helping to enhance its capabilities from time to time.
One issue that we have had is that the visual testing portion of StoryTestIQ runs inside a web browser. The security models for each browser is a little bit different but for the most part they restrict cross-site scripting. For most of the projects we have used StoryTestIQ on the customer’s browser was always Microsoft Internet Explorer (IE). Given this constraint we were able to run in a special non-secured mode of IE called HTML Applications (HTA). This mode of IE also has a problem. The browser history is not retained while in HTA mode therefore some JavaScript functions will not work if used in your application.
Recently I have been working on a project that must work in multiple browsers. Also, I have a Mac so the constraint of using IE is not necessarily reasonable without some coaxing. Instead I decided to take on a quick Apache2 with mod_proxy experiment to see if I could serve both StoryTestIQ, which serves its pages from the FitNesse server inside, and the project’s web application server. It worked and so now I will share it with you.
I will assume that you are already using StoryTestIQ and have Apache2 installed already. If not, please make sure each of these run within your environment before moving on. In my first configuration the project I was developing is running on the Jetty web application server on port 8080. I started up StoryTestIQ on port 9999 and left my project’s web application up and running while I configured Apache2. I used MacPorts to install apache2 in the /opt/local/apache2 directory. In my environment the httpd.conf, Apache2 main configuration file, was located at /opt/local/apache2/conf/httpd.conf. In your own Apache2 installation find the default httpd.conf file for configuring the server. Inside the httpd.conf configuration file make sure that mod_proxy is installed and loaded by searching for a line similar to this:
LoadModule proxy_module modules/mod_proxy.so
If you are not currently using mod_proxy then please review their web site to install and configure mod_proxy for your environment. If mod_proxy is successfully installed then you can add the following lines to the httpd.conf file below all of the LoadModule entries:
#
# Proxy configuration for STIQ and local Jetty application
#
ProxyPass /stiq http://localhost:9999/stiq
ProxyPassReverse /stiq http://localhost:9999/stiq
ProxyPass /files http://localhost:9999/files
ProxyPassReverse /files http://localhost:9999/files
ProxyPass /STIQResults http://localhost:9999/STIQResults
ProxyPassReverse /STIQResults http://localhost:9999/STIQResults
ProxyPass /myapp http://localhost:8080/myapp
ProxyPassReverse /myapp http://localhost:8080/myapp
#
# Rewrite ProjectRoot, STIQ repository main content page, to STIQ server
#
RewriteEngine On
RewriteLog “/opt/local/apache2/logs/rewrite.log”
RewriteRule ^/ProjectRoot(.*) http://localhost:9999/ProjectRoot$1 [P]
There are multiple directories which can be easily proxied using basic ProxyPass and ProxyPassReverse directives. These are /stiq, /files, and /STIQResults. Due to the wiki page URL construction the main content page within the STIQ repository cannot use these basic directives. Instead you must use the RewriteEngine with a rule to map any URL starting with /ProjectRoot* to the STIQ Server. The problem was that the wiki page would ask for a URL such as http://localhost:9999/ProjectRoot.StoryTests and the basic proxy directives would see this as a new URL compared to basic /ProjectRoot. The use of the RewriteRule allows anything that starts with /ProjectRoot to get proxied across.
Once you have these configurations added to the httpd.conf you can restart the Apache2 server. In my environment the command was:
/opt/local/apache2/bin/httpd -k restart
After the web server is restarted you can launch StoryTestIQ inside your browser using a URL similar to this one:
http://localhost/stiq/runner.html?startPage=/ProjectRoot&suite=StoryTests
You’ll notice that this is going through the default HTTP port 80 instead of STIQ’s port 9999. We are now proxied on port 80 to port 9999 for STIQ related URL. You can write automated acceptance tests opening a URL starting with http://localhost/myapp and it will proxy to port 8080 where your web application is running. Make sure to have all of the port numbers correct in your configurations if your environment differs from mine.
I have also configured a Ruby on Rails application for automated acceptance tests against with STIQ. In that case I had to configure mod_proxy with the following directive adding an application name to the Apache2 URL to proxy:
ProxyPass /myapp http://localhost:3000
ProxyPassReverse /myapp http://localhost:3000
You can see the welcome page for your application using this basic configuration but once you have any URL locations identified in your web pages that start with ‘/’ they will not be found. In order to support URL which start with ‘/’ you must modify the appropriate environment configuration inside your Ruby on Rails application. The environment configuration are found in the ${project_root}/config/environments directory by default. I added the following to my development.rb environment configuration file which is what I use with STIQ:
# This allows me to run using mod_proxy on Apache2
# Using StoryTestIQ for automated acceptance testing
# It runs in a browser and therefore cross-site scripting is not allowed
# which the mod_proxy allows me to get around by passing both the StoryTestIQ
# server and the application under test through the same root URL
ActionController::AbstractRequest.relative_url_root = “/myapp”
This will cause all requests for URL starting with a ‘/’ to become ‘/myapp/’. This allows them to be found through the Apache2 proxy.
If you are interested in beating the cross-site scripting restrictions of most major browsers for use with StoryTestIQ I hope this blog entry will help you out. This same mechanism could help with other tools out there who have browser restriction issues. Let me know through your comments if this worked for you or if you have any suggestions on modifications that could make this easier.





It is also necessary to uncomment the LoadModule line for mod_rewrite.so:
LoadModule rewrite_module modules/mod_rewrite.so
It may also be necessary to uncomment the sub-modules for mod_proxy.so:
LoadModule proxy_ajp_module modules/mod_proxy_ajp.so
LoadModule proxy_balancer_module modules/mod_proxy_balancer.so
LoadModule proxy_connect_module modules/mod_proxy_connect.so
LoadModule proxy_ftp_module modules/mod_proxy_ftp.so
LoadModule proxy_http_module modules/mod_proxy_http.so
June 2, 2009 @ 22:13
Also, you need to add the following line to httpd.conf:
RewriteRule ^/~extensions(.*) http://localhost:9999/~extensions$1 [P]
This enables STIQ to load the project-specific and STIQ-specific extensions files in the extensions directory through the proxy.
June 4, 2009 @ 19:58