Permalink
Browse files

Functional testing improvements

* Refactored the public/*.erb and app/compiler.js.erb files so that a single public erb file handles all the build cases, and to allow for a target namespace to be passed to the compiler via the querystring.
* Added 'functionals' test shortcuts section to development dashboard.
* Updated cucumber tests to use functional test code.
* Include a simple cucumber test to verify that all Jasmine specs pass, in preparation for automated post-receive hook continuous integration with Jenkins. Use `cucumber --drb -n spec` to run this.
  • Loading branch information...
1 parent adb022f commit 218cf00e0a828f31b41beaa38ac98752dfe705ee @robert-stuttaford committed Jan 15, 2012
View
@@ -53,6 +53,7 @@ The left column has a couple sections:
* Links to Jasmine specs:
* A link to run all the _spec.js files found inside `app/` (regardless of depth) at the same time. Shortcut key 'a'.
* A dynamic list of all those _spec.js files, nicely formatted for readability. My own project uses short filenames, so I chose to allow more than one spec per line for compactness.
+* Links to functionals. Development largely consists of building model code (tested with Jasmine unit tests) and UI code, which we test with Cucumber/Capybara. As one's app grows, we often like to construct only parts of the interface as so to reduce development grunt work, for example, to exclude having to sign in, or navigate several times to reach the component/view that we are building. This is a list of the functional mini-apps that focus on just part of the apps UI, suitable for capybara tests to run against directly.
* Links to view the app itself:
* Development version (uncompiled).
* Compiled debug version, and the compile-on-demand debug version, which produces the app.debug.js used by the compiled version.
@@ -85,6 +86,15 @@ Alter the deploy script to suit your own requirements. I target this script in m
A great big thank you to all the fine folks who put everything that I am using together!
+## Changelog
+
+* 15 Jan 2012.
+ * Refactored the public/*.erb and app/compiler.js.erb files so that a single public erb file handles all the build cases, and to allow for a target namespace to be passed to the compiler via the querystring.
+ * Added 'functionals' test shortcuts section to development dashboard.
+ * Updated cucumber tests to use functional test code.
+ * Include a simple cucumber test to verify that all Jasmine specs pass, in preparation for automated post-receive hook continuous integration with Jenkins. Use `cucumber --drb -n spec` to run this.
+* 11 Jan 2012. Initial release.
+
## License
Do as you please.
View
@@ -1,18 +1,41 @@
<%
-args = %w{
- --summary_detail_level 3
- --ns app.App
+# options
+options = {
+ 'build' => 'raw',
+ 'ns' => 'app.App'
}
-compiled = %w{
- --compilation_level ADVANCED_OPTIMIZATIONS
- --warning_level VERBOSE
- --language_in ECMASCRIPT5_STRICT
+query_string.split('/').each do |item|
+ item = item.split(':')
+ options[item[0]] = item[1]
+end if query_string.length
+# closure templates
+goog.soy_to_js %w{
+ --cssHandlingScheme goog
+ --shouldGenerateJsdoc
+ --shouldProvideRequireSoyNamespaces
+ --outputPathFormat {INPUT_DIRECTORY}{INPUT_FILE_NAME}.js
+ **/*.soy
+}
+# closure compiler
+args = %w{
+ --summary_detail_level 3 --ns
}
-compiled += Dir.glob( expand_path('../externs/*.externs.js') ).map { |x| ['--externs',x] }
-compiled.flatten!
+args << options['ns']
-args += case query_string
-when 'build' then compiled + %w{
+# production and debug only
+unless options['build'] == 'raw'
+ compiled = %w{
+ --compilation_level ADVANCED_OPTIMIZATIONS
+ --warning_level VERBOSE
+ --language_in ECMASCRIPT5_STRICT
+ }
+ # ensure externs are included
+ compiled += Dir.glob( expand_path('../externs/*.externs.js') ).map { |x| ['--externs',x] }
+ compiled.flatten!
+end
+
+args += case options['build']
+when 'production' then compiled + %w{
--js_output_file ../public/js/app.js
--create_source_map ../public/js/app.map
}
@@ -22,12 +45,5 @@ when 'debug' then compiled + %w{
--formatting PRETTY_PRINT
}
else;[];end
-goog.soy_to_js %w{
- --cssHandlingScheme goog
- --shouldGenerateJsdoc
- --shouldProvideRequireSoyNamespaces
- --outputPathFormat {INPUT_DIRECTORY}{INPUT_FILE_NAME}.js
- **/*.soy
-}
@response = goog.compile(args).to_response
%>
View
@@ -0,0 +1,61 @@
+goog.provide('app.functionals.Widget');
+
+// require this so that the jasmine tests work
+goog.require('app.model.util');
+goog.require('app.services.ConfigService');
+goog.require('app.ui.common.templates');
+goog.require('app.ui.Widget');
+goog.require('app.ui.Main');
+goog.require('goog.events');
+goog.require('goog.events.EventTarget');
+goog.require('goog.style');
+
+/**
+ * The App application.
+ * @constructor
+ * @extends {goog.events.EventTarget}
+ */
+app.functionals.Widget = function() {
+ goog.events.EventTarget.call(this);
+
+ var div = document.createElement('div');
+ div.style.cssText = 'height:100%';
+ div.innerHTML = app.ui.common.templates.app();
+ document.body.appendChild(div);
+
+ /** @type {app.services.ConfigService} */
+ var configService = new app.services.ConfigService();
+ goog.events.listenOnce(configService, app.services.ConfigService.EventType.CONFIG_LOADED, this.startUp_, false, this);
+ configService.loadConfig();
+
+ /**
+ * The Main view
+ * @type {app.ui.Main}
+ * @private
+ */
+ this.main_ = new app.ui.Main();
+ this.main_.decorate(goog.dom.getElement('main'));
+};
+goog.inherits(app.functionals.Widget, goog.events.EventTarget);
+
+/**
+ * Starts App after loading the config
+ * @param {goog.events.Event=} opt_event Event.
+ * @private
+ */
+app.functionals.Widget.prototype.startUp_ = function(opt_event) {
+ /**
+ * The Widget
+ * @type {app.ui.Widget}
+ * @private
+ */
+ this.widget_ = new app.ui.Widget();
+ this.main_.addChild(this.widget_, true);
+};
+
+/** Start the app */
+app.functionals.Widget.start = function() {
+ app.functionals.Widget.app = new app.functionals.Widget();
+};
+
+goog.exportSymbol('start', app.functionals.Widget.start);
View
@@ -2,7 +2,7 @@
<!--[if lt IE 7]> <html class="no-js ie6 oldie" lang="en"> <![endif]-->
<!--[if IE 7]> <html class="no-js ie7 oldie" lang="en"> <![endif]-->
<!--[if IE 8]> <html class="no-js ie8 oldie" lang="en"> <![endif]-->
-<!--[if gt IE 8]><!--> <html class="no-js" lang="en"> <!--<![endif]-->
+<!--[if gt IE 8]> <html class="no-js" lang="en"> <!--<![endif]-->
<head>
<meta charset="utf-8">
<title>Closure-Script Boilerplate</title>
View
@@ -2,7 +2,7 @@
<!--[if lt IE 7]> <html class="no-js ie6 oldie" lang="en"> <![endif]-->
<!--[if IE 7]> <html class="no-js ie7 oldie" lang="en"> <![endif]-->
<!--[if IE 8]> <html class="no-js ie8 oldie" lang="en"> <![endif]-->
-<!--[if gt IE 8]><!--> <html class="no-js" lang="en"> <!--<![endif]-->
+<!--[if gt IE 8]> <html class="no-js" lang="en"> <!--<![endif]-->
<head>
<meta charset="utf-8">
<title>Closure-Script Boilerplate</title>
View
@@ -0,0 +1,6 @@
+@javascript
+Feature: Jasmine Unit-testing Specs
+
+ Scenario: View all specs and see no failures
+ When I visit the all-specs page
+ Then I should see no failing specs
@@ -1,7 +0,0 @@
-When /^I visit the app$/ do
- visit '/dev'
-end
-
-Then /^I should see "(.*)\."$/ do |text|
- page.has_content? text
-end
@@ -0,0 +1,7 @@
+When /^I visit the all\-specs page$/ do
+ visit '/spec.html'
+end
+
+Then /^I should see no failing specs$/ do
+ page.has_content? 'specs, 0 failures in'
+end
@@ -0,0 +1,7 @@
+When /^I visit the "(.*)" functional test/ do |test|
+ visit '/dev?ns:app.functionals.' + test
+end
+
+Then /^I should see "(.*)\."$/ do |text|
+ page.has_content? text
+end
@@ -1,8 +1,8 @@
@javascript
-Feature: Start Feature
+Feature: Widget Feature
Background:
Scenario: See the widget
- When I visit the app
+ When I visit the "Widget" functional test
Then I should see "A Widget."
View
@@ -1,17 +0,0 @@
-<!doctype html>
-<!--[if lt IE 7]> <html class="no-js ie6 oldie" lang="en"> <![endif]-->
-<!--[if IE 7]> <html class="no-js ie7 oldie" lang="en"> <![endif]-->
-<!--[if IE 8]> <html class="no-js ie8 oldie" lang="en"> <![endif]-->
-<!--[if gt IE 8]><!--> <html class="no-js" lang="en"> <!--<![endif]-->
-<head>
- <meta charset="utf-8">
- <title>Closure-Script Boilerplate</title>
- <meta name="viewport" content="width=device-width,initial-scale=1">
- <link rel="stylesheet" href="css/style.css">
- <script type="text/javascript" src="js/modernizr-2.0.6.js"></script>
-</head>
-<body>
- <script src="js/app.debug.js"></script>
- <script>start();</script>
-</body>
-</html>
View
@@ -1,17 +0,0 @@
-<!doctype html>
-<!--[if lt IE 7]> <html class="no-js ie6 oldie" lang="en"> <![endif]-->
-<!--[if IE 7]> <html class="no-js ie7 oldie" lang="en"> <![endif]-->
-<!--[if IE 8]> <html class="no-js ie8 oldie" lang="en"> <![endif]-->
-<!--[if gt IE 8]><!--> <html class="no-js" lang="en"> <!--<![endif]-->
-<head>
- <meta charset="utf-8">
- <title>Closure-Script Boilerplate</title>
- <meta name="viewport" content="width=device-width,initial-scale=1">
- <link rel="stylesheet" href="css/style.css">
- <script type="text/javascript" src="js/modernizr-2.0.6.js"></script>
-</head>
-<body>
- <script src="app/compiler.js?debug"></script>
- <script>start();</script>
-</body>
-</html>
View
@@ -1,8 +1,17 @@
+<%
+if query_string == 'production_static' then
+ js = 'js/app.js'
+elsif query_string == 'debug_static' then
+ js = 'js/app.debug.js'
+elsif query_string.length then
+ js = 'app/compiler.js?' + query_string
+end
+%>
<!doctype html>
<!--[if lt IE 7]> <html class="no-js ie6 oldie" lang="en"> <![endif]-->
<!--[if IE 7]> <html class="no-js ie7 oldie" lang="en"> <![endif]-->
<!--[if IE 8]> <html class="no-js ie8 oldie" lang="en"> <![endif]-->
-<!--[if gt IE 8]><!--> <html class="no-js" lang="en"> <!--<![endif]-->
+<!--[if gt IE 8]> <html class="no-js" lang="en"> <!--<![endif]-->
<head>
<meta charset="utf-8">
<title>Closure-Script Boilerplate</title>
@@ -11,7 +20,7 @@
<script type="text/javascript" src="js/modernizr-2.0.6.js"></script>
</head>
<body>
- <script src="app/compiler.js"></script>
+ <script src="<%= js %>"></script>
<script>start();</script>
</body>
</html>
Oops, something went wrong.

0 comments on commit 218cf00

Please sign in to comment.