+ * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License
+ */
+class ModuleActionController extends ActionController
+{
+ protected $module;
+ protected $module_dir;
+
+ /**
+ * Gives you this modules base directory
+ *
+ * @return string
+ */
+ public function getModuleDir()
+ {
+ if ($this->module_dir === null) {
+ $this->module_dir = $this->getModule()->getBaseDir();
+ }
+ return $this->module_dir;
+ }
+
+ public function getModule()
+ {
+ if ($this->module === null) {
+ $this->module = Icinga::app()->getModule(
+ $this->module_name
+ );
+ }
+ return $this->module;
+ }
+
+ /**
+ * Translates the given string with the modules translation catalog
+ *
+ * @param string $string The string that should be translated
+ *
+ * @return string
+ */
+ public function translate($string)
+ {
+ return mt($this->module_name, $string);
+ }
+
+ /**
+ * This is where the module configuration is going to be loaded
+ *
+ * @return void
+ */
+ protected function loadConfig()
+ {
+ $this->config = Config::getInstance()->{$this->module_name};
+ }
+
+ /**
+ * Once dispatched we are going to place each modules output in a div
+ * container having the icinga-module and the icinga-$module-name classes
+ *
+ * @return void
+ */
+ public function postDispatch()
+ {
+ parent::postDispatch();
+ $this->_helper->layout()->moduleStart =
+ ''
+ . "\n"
+ ;
+ $this->_helper->layout()->moduleEnd = "
\n";
+ }
+}
diff --git a/library/Icinga/Web/Notification.php b/library/Icinga/Web/Notification.php
new file mode 100644
index 000000000..c14c32ada
--- /dev/null
+++ b/library/Icinga/Web/Notification.php
@@ -0,0 +1,113 @@
+addMessage($msg, 'info');
+ }
+
+ public static function success($msg)
+ {
+ self::getInstance()->addMessage($msg, 'success');
+ }
+
+ public static function warning($msg)
+ {
+ self::getInstance()->addMessage($msg, 'warning');
+ }
+
+ public static function error($msg)
+ {
+ self::getInstance()->addMessage($msg, 'error');
+ }
+
+ protected function addMessage($message, $type = 'info')
+ {
+ if (! in_array(
+ $type,
+ array(
+ 'info',
+ 'error',
+ 'warning',
+ 'success'
+ )
+ )) {
+ throw new ProgrammingError(
+ sprintf(
+ '"%s" is not a valid notification type',
+ $type
+ )
+ );
+ }
+
+ if ($this->is_cli) {
+ $msg = sprintf('[%s] %s', $type, $message);
+ switch ($type) {
+ case 'info':
+ case 'success':
+ Log::info($msg);
+ break;
+ case 'warning':
+ Log::warn($msg);
+ break;
+ case 'error':
+ Log::error($msg);
+ break;
+ }
+ return;
+ }
+
+ $mo = (object) array(
+ 'type' => $type,
+ 'message' => $message,
+ );
+
+ // Get, change, set - just to be on the safe side:
+ $msgs = $this->session->messages;
+ $msgs[] = $mo;
+ $this->session->messages = $msgs;
+ }
+
+ public function hasMessages()
+ {
+ return ! empty($this->session->messages);
+ }
+
+ public function getMessages()
+ {
+ $msgs = $this->session->messages;
+ $this->session->messages = array();
+ return $msgs;
+ }
+
+ final private function __construct()
+ {
+ $this->session = new SessionNamespace('IcingaNotification');
+ if (! is_array($this->session->messages)) {
+ $this->session->messages = array();
+ }
+
+ if (Platform::isCli()) {
+ $this->is_cli = true;
+ }
+ }
+
+ public static function getInstance()
+ {
+ if (self::$instance === null) {
+ self::$instance = new Notification();
+ }
+ return self::$instance;
+ }
+}
diff --git a/library/Icinga/Web/Paginator/Adapter/QueryAdapter.php b/library/Icinga/Web/Paginator/Adapter/QueryAdapter.php
new file mode 100755
index 000000000..14ea80012
--- /dev/null
+++ b/library/Icinga/Web/Paginator/Adapter/QueryAdapter.php
@@ -0,0 +1,62 @@
+query = $query;
+ }
+
+ /**
+ * Returns an array of items for a page.
+ *
+ * @param integer $offset Page offset
+ * @param integer $itemCountPerPage Number of items per page
+ * @return array
+ */
+ public function getItems($offset, $itemCountPerPage)
+ {
+ return $this->query->limit($itemCountPerPage, $offset)->fetchAll();
+ }
+
+ /**
+ * Returns the total number of items in the query result.
+ *
+ * @return integer
+ */
+ public function count()
+ {
+ if ($this->count === null) {
+ $this->count = $this->query->count();
+ }
+ return $this->count;
+ }
+}
+
diff --git a/library/Icinga/Web/Paginator/ScrollingStyle/SlidingWithBorder.php b/library/Icinga/Web/Paginator/ScrollingStyle/SlidingWithBorder.php
new file mode 100755
index 000000000..ff7b7d13c
--- /dev/null
+++ b/library/Icinga/Web/Paginator/ScrollingStyle/SlidingWithBorder.php
@@ -0,0 +1,63 @@
+getPageRange();
+ }
+
+ $pageNumber = $paginator->getCurrentPageNumber();
+ $pageCount = count($paginator);
+ $range = array();
+
+
+
+ if ($pageCount < 15) {
+ for ($i = 1; $i < 15; $i++) {
+ if ($i > $pageCount) break;
+ $range[$i] = $i;
+ }
+ } else {
+ foreach (array(1, 2) as $i) {
+ $range[$i] = $i;
+ }
+ if ($pageNumber > 8) {
+ $range[] = '...';
+ $start = 5;
+ if ($pageCount - $pageNumber < 8) {
+ $start = 9 - ($pageCount - $pageNumber);
+ }
+ for ($i = $pageNumber - $start; $i < $pageNumber + (10 - $start); $i++) {
+ if ($i > $pageCount) break;
+ $range[$i] = $i;
+ }
+ } else {
+ for ($i = 3; $i <= 10; $i++) {
+ $range[$i] = $i;
+ }
+ }
+ if ($pageNumber < ($pageCount - 7)) {
+ $range[] = '...';
+ foreach (array($pageCount - 1, $pageCount) as $i) {
+ $range[$i] = $i;
+ }
+ }
+ }
+ if (empty($range)) $range[] = 1;
+ return $range;
+ }
+}
+
+
diff --git a/library/Icinga/Web/Session.php b/library/Icinga/Web/Session.php
new file mode 100755
index 000000000..224866619
--- /dev/null
+++ b/library/Icinga/Web/Session.php
@@ -0,0 +1,156 @@
+
+ * @author Icinga-Web Team
+ * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License
+ */
+class Session
+{
+ /**
+ * Session is a Singleton stored in $instance
+ *
+ * @var Session
+ */
+ protected static $instance;
+
+ protected $defaultOptions = array(
+ 'use_trans_sid' => false,
+ 'use_cookies' => true,
+ 'use_only_cooies' => true,
+ 'cookie_httponly' => true,
+ 'use_only_cookies' => true,
+ 'hash_function' => true,
+ 'hash_bits_per_character' => 5,
+ );
+
+ /**
+ * The ZF session namespace
+ *
+ * @var \Zend_Session_Namespace
+ */
+ protected $session;
+
+ protected $started = false;
+ protected $closed = true;
+
+ /**
+ * Constructor is protected to enforce singleton usage
+ */
+ protected function __construct()
+ {
+ Zend_Session::start();
+ $this->session = new Zend_Session_Namespace('Icinga');
+ }
+/*
+// Not yet
+ public function start()
+ {
+ if ($this->started) {
+ return $this;
+ }
+ if ($this->closed) {
+ ini_set('session.cache_limiter', null);
+ ini_set('session.use_only_cookies', false);
+ ini_set('session.use_cookies', false);
+ ini_set('session.use_trans_sid', false);
+ }
+ $this->applyOptions();
+ session_start();
+ return $this;
+ }
+
+ protected function applyOptions()
+ {
+ foreach ($this->defaultOptions as $key => $val) {
+ ini_set('session.' . $key => $val);
+ }
+ return $this;
+ }
+*/
+ public static function setOptions($options)
+ {
+ return Zend_Session::setOptions($options);
+ }
+
+ /**
+ * Once authenticated we store the given user(name) to our session
+ *
+ * @param Auth\User $user The user object
+ * // TODO: Useless
+ * @return self
+ */
+ public function setAuthenticatedUser(User $user)
+ {
+ $this->session->userInfo = (string) $user;
+ $this->session->realname = (string) $user; // TODO: getRealName()
+ return $this;
+ }
+
+ /**
+ * Get the user object for the authenticated user
+ *
+ * // TODO: This has not been done yet. Useless?
+ *
+ * @return User $user The user object
+ */
+ public function getUser()
+ {
+ throw new ProgrammingError('Not implemented yet');
+ }
+
+ /**
+ * Whether this session has an authenticated user
+ *
+ * // TODO: remove
+ * @return bool
+ */
+ public function isAuthenticated()
+ {
+ return isset($this->session->username);
+ }
+
+ /**
+ * Forget everything we know about the authenticated user
+ *
+ * // TODO: Remove
+ * @return self
+ */
+ public function discardAuthentication()
+ {
+ unset($this->session->username);
+ unset($this->session->realname);
+ return $this;
+ }
+
+ /**
+ * Get a Singleton instance
+ *
+ * TODO: This doesn't work so yet, it gives you a Zend_Session_Namespace
+ * instance. Facade has to be completed before we can fix this.
+ *
+ * @return Icinga\Web\Session -> not yet
+ */
+ public static function getInstance()
+ {
+ if (self::$instance === null) {
+ self::$instance = new Session();
+ }
+ return self::$instance->session;
+ }
+}
diff --git a/library/Icinga/Web/Widget.php b/library/Icinga/Web/Widget.php
new file mode 100644
index 000000000..bc160dcdb
--- /dev/null
+++ b/library/Icinga/Web/Widget.php
@@ -0,0 +1,53 @@
+
+ * $tabs = Widget::create('tabs');
+ *
+ *
+ * @copyright Copyright (c) 2013 Icinga-Web Team
+ * @author Icinga-Web Team
+ * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License
+ */
+class Widget
+{
+
+ /**
+ * Create a new widget
+ *
+ * @param string $name Widget name
+ * @param array $options Widget constructor options
+ *
+ * @return Icinga\Web\Widget\AbstractWidget
+ */
+ public static function create($name, $options = array())
+ {
+ $class = 'Icinga\\Web\\Widget\\' . ucfirst($name);
+
+ if (! class_exists($class)) {
+ throw new ProgrammingError(
+ sprintf(
+ 'There is no such widget: %s',
+ $name
+ )
+ );
+ }
+
+ $widget = new $class($options);
+ return $widget;
+ }
+}
diff --git a/library/Icinga/Web/Widget/AbstractWidget.php b/library/Icinga/Web/Widget/AbstractWidget.php
new file mode 100644
index 000000000..1698c3dc6
--- /dev/null
+++ b/library/Icinga/Web/Widget/AbstractWidget.php
@@ -0,0 +1,162 @@
+
+ * @author Icinga-Web Team
+ * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License
+ */
+abstract class AbstractWidget
+{
+ /**
+ * If you are going to access the current view with the view() function,
+ * it's instance is stored here for performance reasons.
+ *
+ * @var Zend_View_Abstract
+ */
+ protected static $view;
+
+ /**
+ * Fill $properties with default values for all your valid widget properties
+ *
+ * @var array
+ */
+ protected $properties = array();
+
+ /**
+ * You MUST extend this function. This is where all your HTML voodoo happens
+ *
+ * @return string
+ */
+ abstract public function renderAsHtml();
+
+ /**
+ * You are not allowed to override the constructor, but you can put
+ * initialization stuff in your init() function
+ *
+ * @return void
+ */
+ protected function init()
+ {
+ }
+
+ /**
+ * We are not allowing you to override the constructor unless someone
+ * presents a very good reason for doing so
+ *
+ * @param array $properties An optional properties array
+ */
+ final public function __construct($properties = array())
+ {
+ foreach ($properties as $key => $val) {
+ $this->$key = $val;
+ }
+ $this->init();
+ }
+
+ /**
+ * Getter for widget properties
+ *
+ * @param string $key The option you're interested in
+ *
+ * @throws ProgrammingError for unknown property name
+ *
+ * @return mixed
+ */
+ public function __get($key)
+ {
+ if (array_key_exists($key, $this->properties)) {
+ return $this->properties[$key];
+ }
+
+ throw new ProgrammingError(
+ sprintf(
+ 'Trying to get invalid "%s" property for %s',
+ $key,
+ get_class($this)
+ )
+ );
+ }
+
+ /**
+ * Setter for widget properties
+ *
+ * @param string $key The option you want to set
+ * @param string $val The new value going to be assigned to this option
+ *
+ * @throws ProgrammingError for unknown property name
+ *
+ * @return mixed
+ */
+ public function __set($key, $val)
+ {
+ if (array_key_exists($key, $this->properties)) {
+ $this->properties[$key] = $val;
+ return;
+ }
+
+ throw new ProgrammingError(
+ sprintf(
+ 'Trying to set invalid "%s" property in %s. Allowed are: %s',
+ $key,
+ get_class($this),
+ empty($this->properties)
+ ? 'none'
+ : implode(', ', array_keys($this->properties))
+ )
+ );
+ }
+
+ /**
+ * Access the current view
+ *
+ * Will instantiate a new one if none exists
+ * // TODO: App->getView
+ *
+ * @return Zend_View_Abstract
+ */
+ protected function view()
+ {
+ if (self::$view === null) {
+
+ $renderer = ZfActionHelper::getStaticHelper(
+ 'viewRenderer'
+ );
+
+ if (null === $renderer->view) {
+ $renderer->initView();
+ }
+
+ self::$view = $renderer->view;
+ }
+
+ return self::$view;
+ }
+
+ /**
+ * Cast this widget to a string. Will call your renderAsHtml() function
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return $this->renderAsHtml();
+ }
+}
diff --git a/library/Icinga/Web/Widget/Form.php b/library/Icinga/Web/Widget/Form.php
new file mode 100644
index 000000000..01802379e
--- /dev/null
+++ b/library/Icinga/Web/Widget/Form.php
@@ -0,0 +1,43 @@
+
+ * @author Icinga-Web Team
+ * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License
+ */
+class Form extends AbstractWidget
+{
+ protected $form;
+ protected $properties = array(
+ 'name' => null
+ );
+
+ public function __call($func, $args)
+ {
+ return call_user_func_array(array($this->form, $func), $args);
+ }
+
+ protected function init()
+ {
+ // Load form by name given in props?
+ $class = 'Icinga\\Web\\Form\\' . ucfirst($this->name) . 'Form';
+ $file = ICINGA_APPDIR
+ . '/forms/authentication/'
+ . ucfirst($this->name)
+ . 'Form.php';
+ require_once($file);
+ $this->form = new $class;
+ }
+
+ public function renderAsHtml()
+ {
+ return (string) $this->form;
+ }
+}
diff --git a/library/Icinga/Web/Widget/Tab.php b/library/Icinga/Web/Widget/Tab.php
new file mode 100644
index 000000000..a8ea47f68
--- /dev/null
+++ b/library/Icinga/Web/Widget/Tab.php
@@ -0,0 +1,119 @@
+
+ * @author Icinga-Web Team
+ * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License
+ */
+class Tab extends AbstractWidget
+{
+ /**
+ * Whether this tab is currently active
+ *
+ * @var bool
+ */
+ protected $active = false;
+
+ /**
+ * Default values for widget properties
+ *
+ * @var array
+ */
+ protected $properties = array(
+ 'name' => null,
+ 'title' => '',
+ 'url' => null,
+ 'urlParams' => array(),
+ 'icon' => null,
+ );
+
+ /**
+ * Health check at initialization time
+ *
+ * @throws Icinga\Exception\ProgrammingError if tab name is missing
+ *
+ * @return void
+ */
+ protected function init()
+ {
+ if ($this->name === null) {
+ throw new ProgrammingError(
+ 'Cannot create a nameless tab'
+ );
+ }
+ }
+
+ /**
+ * Set this tab active (default) or inactive
+ *
+ * This is usually done through the tabs container widget, therefore it
+ * is not a good idea to directly call this function
+ *
+ * @param bool $active Whether the tab should be active
+ *
+ * @return self
+ */
+ public function setActive($active = true)
+ {
+ $this->active = (bool) $active;
+ return $this;
+ }
+
+ /**
+ * Whether this tab is currently active
+ *
+ * @return bool
+ */
+ public function isActive()
+ {
+ return $this->active;
+ }
+
+ /**
+ * This is where the list item HTML is created
+ *
+ * @return string
+ */
+ public function renderAsHtml()
+ {
+ $view = $this->view();
+ $class = $this->isActive() ? ' class="active"' : '';
+ $caption = $this->title;
+ if ($this->icon !== null) {
+ $caption = $view->img($this->icon, array(
+ 'width' => 16,
+ 'height' => 16
+ )) . ' ' . $caption;
+ }
+ if ($this->url !== null) {
+ $tab = $view->qlink(
+ $caption,
+ $this->url,
+ $this->urlParams,
+ array('quote' => false)
+ );
+ } else {
+ $tab = $caption;
+ }
+ return "$tab\n";
+ }
+}
diff --git a/library/Icinga/Web/Widget/Tabs.php b/library/Icinga/Web/Widget/Tabs.php
new file mode 100644
index 000000000..98c5534f7
--- /dev/null
+++ b/library/Icinga/Web/Widget/Tabs.php
@@ -0,0 +1,195 @@
+
+ * @author Icinga-Web Team
+ * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License
+ */
+class Tabs extends AbstractWidget
+{
+ /**
+ * This is where single tabs added to this container will be stored
+ *
+ * @var array
+ */
+ protected $tabs = array();
+
+ /**
+ * The name of the currently activated tab
+ *
+ * @var string
+ */
+ protected $active;
+
+ /**
+ * Class name(s) going to be assigned to the <ul> element
+ *
+ * @var string
+ */
+ protected $tab_class = 'nav-tabs';
+
+ /**
+ * Activate the tab with the given name
+ *
+ * If another tab is currently active it will be deactivated
+ *
+ * @param string $name Name of the tab going to be activated
+ *
+ * @throws ProgrammingError if given tab name doesn't exist
+ *
+ * @return self
+ */
+ public function activate($name)
+ {
+ if ($this->has($name)) {
+ if ($this->active !== null) {
+ $this->tabs[$this->active]->setActive(false);
+ }
+ $this->get($name)->setActive();
+ $this->active = $name;
+ return $this;
+ }
+
+ throw new ProgrammingError(
+ sprintf(
+ "Cannot activate a tab that doesn't exist: %s. Available: %s",
+ $name,
+ empty($this->tabs)
+ ? 'none'
+ : implode(', ', array_keys($this->tabs))
+ )
+ );
+ }
+
+ public function getActiveName()
+ {
+ return $this->active;
+ }
+
+ /**
+ * Set the CSS class name(s) for the <ul> element
+ *
+ * @param string $name CSS class name(s)
+ *
+ * @return self
+ */
+ public function setClass($name)
+ {
+ $this->tab_class = $name;
+ return $this;
+ }
+
+ /**
+ * Whether the given tab name exists
+ *
+ * @param string $name Tab name
+ *
+ * @return bool
+ */
+ public function has($name)
+ {
+ return array_key_exists($name, $this->tabs);
+ }
+
+ /**
+ * Whether the given tab name exists
+ *
+ * @param string $name The tab you're interested in
+ *
+ * @throws ProgrammingError if given tab name doesn't exist
+ *
+ * @return Tab
+ */
+ public function get($name)
+ {
+ if (! $this->has($name)) {
+ throw new ProgrammingError(
+ sprintf(
+ 'There is no such tab: %s',
+ $name
+ )
+ );
+ }
+ return $this->tabs[$name];
+ }
+
+ /**
+ * Add a new tab
+ *
+ * A unique tab name is required, the Tab itself can either be an array
+ * with tab properties or an instance of an existing Tab
+ *
+ * @param string $name The new tab name
+ * @param array|Tab The tab itself of it's properties
+ *
+ * @throws ProgrammingError if tab name already exists
+ *
+ * @return self
+ */
+ public function add($name, $tab)
+ {
+ if ($this->has($name)) {
+ throw new ProgrammingError(
+ sprintf(
+ 'Cannot add a tab named "%s" twice"',
+ $name
+ )
+ );
+ }
+ return $this->set($name, $tab);
+ }
+
+ /**
+ * Set a tab
+ *
+ * A unique tab name is required, will be replaced in case it already
+ * exists. The tab can either be an array with tab properties or an instance
+ * of an existing Tab
+ *
+ * @param string $name The new tab name
+ * @param array|Tab The tab itself of it's properties
+ *
+ * @return self
+ */
+ public function set($name, $tab)
+ {
+ if ($tab instanceof Tab) {
+ $this->tabs[$name] = $tab;
+ } else {
+ $this->tabs[$name] = new Tab($tab + array('name' => $name));
+ }
+ return $this;
+ }
+
+ /**
+ * This is where the tabs are going to be rendered
+ *
+ * @return string
+ */
+ public function renderAsHtml()
+ {
+ $view = $this->view();
+
+ if (empty($this->tabs)) {
+ return '';
+ }
+ $html = '' . "\n";
+
+ foreach ($this->tabs as $tab) {
+ $html .= $tab;
+ }
+ $html .= "
\n";
+ return $html;
+ }
+}
diff --git a/test/frontend/cases/static-page-test.js b/test/frontend/cases/static-page-test.js
new file mode 100644
index 000000000..b77496f86
--- /dev/null
+++ b/test/frontend/cases/static-page-test.js
@@ -0,0 +1,19 @@
+/**
+*
+* This test simply checks the icinga build server and tests
+* if the title is correct
+**/
+i2w = require('./i2w-config');
+
+var casper = i2w.getTestEnv();
+
+casper.start("http://build.icinga.org/jenkins");
+
+casper.then(function() {
+ this.test.assertTitle("icinga-web test [Jenkins]", "The jenkins page");
+});
+
+casper.run(function() {
+ this.test.done();
+});
+
diff --git a/test/frontend/casperjs.config b/test/frontend/casperjs.config
new file mode 100644
index 000000000..69c9d4a3b
--- /dev/null
+++ b/test/frontend/casperjs.config
@@ -0,0 +1,5 @@
+{
+ "host": "localhost",
+ "port": 80,
+ "path": "icinga2-web"
+}
diff --git a/test/frontend/i2w-config.js b/test/frontend/i2w-config.js
new file mode 100644
index 000000000..7d54a1a00
--- /dev/null
+++ b/test/frontend/i2w-config.js
@@ -0,0 +1,107 @@
+/**
+* Tools for setting up the casperjs tests
+* mainly setting host, port and path path
+**/
+
+// load config files
+var fs = require('fs');
+var env = require('system').env;
+var args = require('system').args;
+var utils = require('utils');
+
+
+var configFile = fs.absolute('./casperjs.config');
+var host = null;
+var port = null;
+var path = null;
+var verbose = false;
+
+
+if (typeof(env.CASPERJS_HOST) === "string")
+ host = env.CASPERJS_HOST;
+if (typeof(env.CASPERJS_PORT) === "string")
+ port = parseInt(env.CASPERJS_PORT, 10);
+if (typeof(env.CASPERJS_PATH) === "string")
+ path = env.CASPERJS_PATH;
+
+
+for (var i=0;i /dev/null
+DIR=`pwd`
+popd > /dev/null
+CASPER=$(which casperjs)
+INCLUDE=""
+EXCLUDE=""
+VERBOSE=0
+BUILD=0
+
+if [ ! -x $CASPER ]; then
+ echo "CasperJS is not installed but required to run frontend tests\n"\
+"Take a look at http://casperjs.org/installation.html to see how the installation works for your system"
+ exit 1
+fi;
+
+PARAM="0"
+for arg in $@;do
+ if [ ! "$PARAM" == "0" ]; then
+ export $PARAM=$arg
+ PARAM="0"
+ continue
+ fi;
+ case $arg in
+ --verbose)
+ VERBOSE=1
+ ;;
+ --include)
+ PARAM="INCLUDE"
+ continue
+ ;;
+ --exclude)
+ PARAM="EXCLUDE"
+ continue
+ ;;
+ --build)
+ BUILD=1
+ continue
+ ;;
+ **)
+ if [ "$arg" != "--help" ]; then
+ echo "Unknown option $arg"
+ fi;
+ printf "%b" "Testrunner for interface tests\n\n"
+ printf "%b" "Usage: ./$0 [--verbose] [--include %include%] [--exclude %exclude%] [--build]\n\n"
+ printf "%b" " --verbose \t\t\t Print verbose output when testing\n"
+ printf "%b" " --include %filelist%\t\t Include only files matching this patterns\n"
+ printf "%b" " --exclude %filelist%\t\t Exclude files matching this patterns\n"
+ printf "%b" " --build \t\t\t Write test results to ../../build/log/casper_results.xml\n"
+ printf "%b" " --help \t\t\t Print this message\n\n"
+ exit 1
+ esac;
+done;
+
+EXEC="$CASPER test"
+
+#
+# If build is set, the results are written for our jenkins server
+#
+if [ $BUILD -eq 1 ];then
+ mkdir -p $DIR/../../build/log
+ EXEC="$EXEC --xunit=$DIR/../../build/log/casper_results.xml"
+fi;
+if [ "$PARAM" != "0" ]; then
+ echo "Missing parameter for $PARAM"
+ exit 1
+fi;
+
+cd $DIR
+FILELIST=""
+#
+# Default : Run regression and cases directory
+#
+if [ "$INCLUDE" == "" -a "$EXCLUDE" == "" ];then
+ FILELIST="./cases ./regression"
+fi;
+
+#
+# Include patterns set with the --include directive
+#
+if [ "$INCLUDE" != "" ];then
+ NAME="\("
+ GLUE=""
+ for INC in $INCLUDE;do
+ NAME="$NAME${GLUE}${INC}.*js"
+ GLUE="\|"
+ done;
+ NAME=$NAME"\)$"
+ FILELIST=`find . | grep "$NAME"`
+fi;
+
+#
+# Exclude patterns that match the include directive
+#
+if [ "$EXCLUDE" != "" ];then
+ NAME="\("
+ GLUE=""
+ for EXC in $EXCLUDE;do
+ NAME="$NAME${GLUE}${EXC}.*js"
+ GLUE="\|"
+ done;
+ NAME=$NAME"\)$"
+ if [ "$FILELIST" == "" ]; then
+ FILELIST=`find .|grep ".*js$"`
+ fi
+ FILELIST=`echo $FILELIST | grep -v "$NAME"`
+fi;
+
+echo $EXEC $FILELIST
+$EXEC $FILELIST
+
+exit 0