Intern-based functional tests

This commit makes it possible to execute UI
functional tests either based on Casper or on Intern/Selenium

Change-Id: I21d342093f142a1bbe7b8ae4f2c96fad1c125a0b
This commit is contained in:
Nick Bogdanov 2015-07-08 15:46:09 +03:00
parent ec51a0dfdd
commit 3577169e20
15 changed files with 877 additions and 9 deletions

View File

@ -158,7 +158,7 @@ function runIntern(params) {
return function() {
var baseDir = 'static';
var runner = './node_modules/.bin/intern-runner';
var browser = params.browser || argv.browser || 'phantomjs';
var browser = params.browser || argv.browser || 'firefox';
var options = [['config', 'tests/intern-' + browser + '.js']];
var suiteOptions = [];
['suites', 'functionalSuites'].forEach(function(suiteType) {
@ -181,7 +181,8 @@ function runIntern(params) {
};
}
gulp.task('intern:unit', runIntern({suites: argv.suites || 'static/tests/unit/**/*.js'}));
gulp.task('intern:unit', runIntern({suites: argv.suites || 'static/tests/unit/**/*.js', browser: 'phantomjs'}));
gulp.task('intern:functional', runIntern({functionalSuites: argv.suites || 'static/tests/functional/**/test_*.js'}));
gulp.task('unit-tests', function(cb) {
runSequence('selenium', 'intern:unit', function(err) {
@ -190,6 +191,13 @@ gulp.task('unit-tests', function(cb) {
});
});
gulp.task('functional-tests', function(cb) {
runSequence('selenium', 'intern:functional', function(err) {
shutdownSelenium();
cb(err);
});
});
gulp.task('jison', function() {
return gulp.src('static/expression/parser.jison')
.pipe(jison({moduleType: 'js'}))

View File

@ -35,6 +35,6 @@
"rimraf": "~2.2.8",
"run-sequence": "~1.0.2",
"selenium-standalone": "~4.4.0",
"uglify-js": "~2.4.16"
"uglify-js": "~2.4.21"
}
}

View File

@ -0,0 +1,103 @@
/*
* Copyright 2015 Mirantis, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License. You may obtain
* a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
**/
define(['underscore',
'../../helpers'], function(_, Helpers) {
'use strict';
function ClusterPage(remote) {
this.remote = remote;
}
ClusterPage.prototype = {
constructor: ClusterPage,
goToTab: function(tabName) {
var that = this;
return this.remote
.then(function() {
return Helpers.clickLinkByText(
that.remote,
'.tabs-box .tabs a',
tabName);
});
},
removeCluster: function() {
var that = this;
return this.remote
.then(
function() {
return this.parent
.setFindTimeout(2000)
.then(function() {
return that.goToTab('Actions');
})
.findByCssSelector('button.delete-environment-btn')
.click()
.end()
.setFindTimeout(2000)
.findByCssSelector('div.modal-content')
.findByCssSelector('button.remove-cluster-btn')
.click()
.end()
.setFindTimeout(2000)
.waitForDeletedByCssSelector('div.modal-content');
}
);
},
checkNodeRoles: function(assignRoles) {
return this.remote
.setFindTimeout(2000)
.findAllByCssSelector('div.role-panel label')
.then(function(roles) {
return roles.reduce(
function(result, role) {
return role
.getVisibleText()
.then(function(label) {
var index = assignRoles.indexOf(label.substr(1));
if (index >= 0) {
role.click();
assignRoles.splice(index, 1);
return assignRoles.length == 0;
}
});
},
false
);
});
},
checkNodes: function(amount) {
var that = this;
return this.remote
.setFindTimeout(2000)
.then(function() {
return _.range(amount).reduce(
function(result, index) {
return that.remote
.setFindTimeout(1000)
.findAllByCssSelector('.node.discover > label')
.then(function(nodes) {
return nodes[index].click();
})
.catch(function() {
throw new Error('Failed to add ' + amount + ' nodes to the cluster');
});
},
true);
});
}
};
return ClusterPage;
});

View File

@ -0,0 +1,78 @@
/*
* Copyright 2015 Mirantis, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License. You may obtain
* a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
**/
define([], function() {
'use strict';
function ClustersPage(remote) {
this.remote = remote;
}
ClustersPage.prototype = {
constructor: ClustersPage,
createCluster: function(clusterName) {
return this.remote
.setFindTimeout(1000)
.findByClassName('create-cluster')
.click()
.end()
.setFindTimeout(2000)
.findByCssSelector('div.modal-content')
.findByName('name')
.clearValue()
.type(clusterName)
.pressKeys('\uE007')
.pressKeys('\uE007')
.pressKeys('\uE007')
.pressKeys('\uE007')
.pressKeys('\uE007')
.pressKeys('\uE007')
.pressKeys('\uE007')
.end()
.setFindTimeout(4000)
.waitForDeletedByCssSelector('div.modal-content')
.end();
},
clusterSelector: '.clusterbox div.name',
goToEnvironment: function(clusterName) {
var that = this;
return this.remote
.setFindTimeout(5000)
.findAllByCssSelector(that.clusterSelector)
.then(function(divs) {
return divs.reduce(
function(matchFound, element) {
return element.getVisibleText().then(
function(name) {
if (name === clusterName) {
element.click();
return true;
}
return matchFound;
}
)},
false
);
})
.then(function(result) {
if (!result) {
throw new Error('Cluster ' + clusterName + ' not found');
}
return true;
});
}
};
return ClustersPage;
});

View File

@ -0,0 +1,132 @@
define([
'intern/node_modules/dojo/node!fs',
'../../helpers',
'tests/functional/pages/login',
'tests/functional/pages/welcome',
'tests/functional/pages/cluster',
'tests/functional/pages/clusters'
],
function(fs, Helpers, LoginPage, WelcomePage, ClusterPage, ClustersPage) {
'use strict';
function CommonMethods(remote) {
this.remote = remote;
this.loginPage = new LoginPage(remote);
this.welcomePage = new WelcomePage(remote);
this.clusterPage = new ClusterPage(remote);
this.clustersPage = new ClustersPage(remote);
}
CommonMethods.prototype = {
constructor: CommonMethods,
takeScreenshot: function(filename, error) {
return this.remote
.takeScreenshot()
.then(function(buffer) {
if (!filename) {
filename = new Date().toTimeString();
}
fs.writeFileSync('/tmp/' + filename + '.png', buffer);
if (error) {
throw error;
}
});
},
getOut: function() {
var that = this;
return this.remote
.then(function() {
return that.welcomePage.skip();
})
.then(function() {
return that.loginPage.logout();
});
},
getIn: function() {
var that = this;
return this.remote
.then(function() {
return that.loginPage.logout();
})
.then(function() {
return that.loginPage.login();
})
.waitForDeletedByClassName('login-btn')
.then(function() {
return that.welcomePage.skip();
});
},
clickLink: function(text) {
return this.remote
.setFindTimeout(1000)
.findByLinkText(text)
.click()
.end();
},
waitForModal: function() {
return this.remote
.setTimeout(2000)
.findByCssSelector('div.modal-content')
.end();
},
waitForModalToClose: function() {
return this.remote
.setTimeout(2000)
.waitForDeletedByCssSelector('div.modal-content')
.end();
},
goToEnvironment: function(clusterName) {
var that = this;
return this.remote
.then(function() {
return that.clickLink('Environments');
})
.then(function() {
return that.clustersPage.goToEnvironment(clusterName);
});
},
createCluster: function(clusterName) {
var that = this;
return this.remote
.then(function() {
return that.clickLink('Environments');
})
.then(function() {
return that.clustersPage.createCluster(clusterName);
});
},
removeCluster: function(clusterName, suppressErrors) {
var that = this;
return this.remote
.then(function() {
return that.clickLink('Environments');
})
.then(function() {
return that.clustersPage.goToEnvironment(clusterName);
})
.then(function() {
return that.clusterPage.removeCluster();
})
.catch(function() {
if (!suppressErrors) throw new Error('Unable to delete cluster ' + clusterName);
});
},
doesClusterExist: function(clusterName) {
var that = this;
return this.remote
.setFindTimeout(2000)
.then(function() {
return that.clickLink('Environments');
})
.findAllByCssSelector(that.clustersPage.clusterSelector)
.then(function(divs) {
return divs.reduce(function(matchFound, element) {
return element.getVisibleText().then(
function(name) {
return (name === clusterName) || matchFound;
}
)}, false);
});
}
};
return CommonMethods;
});

View File

@ -0,0 +1,84 @@
/*
* Copyright 2015 Mirantis, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License. You may obtain
* a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
**/
define([
'../../helpers'
], function(Helpers) {
'use strict';
function LoginPage(remote) {
this.remote = remote;
}
LoginPage.prototype = {
constructor: LoginPage,
login: function(username, password) {
username = username || Helpers.username;
password = password || Helpers.password;
var that = this;
return this.remote
.setWindowSize(1280, 1024)
.setTimeout('page load', 20000)
.getCurrentUrl()
.then(function(url) {
if (url !== Helpers.serverUrl + '/#login') {
return that.logout();
}
})
.setFindTimeout(10000)
.findByName('username')
.clearValue()
.type(username)
.end()
.findByName('password')
.clearValue()
.type(password)
.end()
.findByClassName('login-btn')
.click()
.end();
},
logout: function() {
return this.remote
.getCurrentUrl()
.then(function(url) {
if (url.indexOf(Helpers.serverUrl) !== 0) {
return this.parent
.get(Helpers.serverUrl + '/#logout')
.setFindTimeout(10000)
.findByClassName('login-btn')
.then(function() {
return true;
});
}
})
.setFindTimeout(1000)
.findByCssSelector('li.user-icon')
.click()
.end()
.findByCssSelector('.user-popover button.btn-logout')
.click()
.end()
.findByCssSelector('.login-btn')
.then(
function() {return true},
function() {return true}
);
}
};
return LoginPage;
});

View File

@ -0,0 +1,47 @@
/*
* Copyright 2015 Mirantis, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License. You may obtain
* a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
**/
define(['../../helpers'], function(Helpers) {
'use strict';
function WelcomePage(remote) {
this.remote = remote;
}
WelcomePage.prototype = {
constructor: WelcomePage,
skip: function(strictCheck) {
return this.remote
.getCurrentUrl()
.then(function(url) {
if (url == Helpers.serverUrl + '/#welcome') {
return this.parent
.setFindTimeout(2000)
.findByCssSelector('.welcome-button-box button')
.click()
.end()
.waitForDeletedByCssSelector('.welcome-button-box button')
.then(
function() {return true},
function() {return !strictCheck}
);
} else {
return true;
}
});
}
};
return WelcomePage;
});

View File

@ -0,0 +1,129 @@
/*
* Copyright 2015 Mirantis, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License. You may obtain
* a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
**/
define([
'underscore',
'intern!object',
'intern/chai!assert',
'tests/functional/pages/common',
'tests/functional/pages/cluster'
], function(_, registerSuite, assert, Common, ClusterPage) {
'use strict';
registerSuite(function() {
var common,
clusterPage,
clusterName;
return {
name: 'Clusters page',
setup: function() {
common = new Common(this.remote);
clusterPage = new ClusterPage(this.remote);
clusterName = 'Test Cluster #' + Math.round(99999 * Math.random());
},
beforeEach: function() {
return this.remote
.then(function() {
return common.getIn();
})
.then(function() {
return common.createCluster(clusterName);
});
},
afterEach: function() {
return this.remote
.then(function() {
return common.removeCluster(clusterName, true);
});
},
'Remove Cluster': function() {
return this.remote
.then(function() {
return common.doesClusterExist(clusterName);
})
.then(function(result) {
assert.ok(result, 'Cluster exists');
})
.then(function() {
return common.removeCluster(clusterName);
})
.then(function() {
return common.doesClusterExist(clusterName);
})
.then(function(result) {
assert.notOk(result, 'Cluster removed successfully');
});
},
'Add Cluster Nodes': function() {
var nodesAmount = 3,
that = this,
applyButton;
return this.remote
.then(function() {
return common.goToEnvironment(clusterName);
})
.setFindTimeout(5000)
.findByCssSelector('button.btn-add-nodes')
.click()
.end()
.findByCssSelector('button.btn-apply')
.then(function(button) {
applyButton = button;
return applyButton.isEnabled().then(function(isEnabled) {
assert.isFalse(isEnabled, 'Apply button is disabled until both roles and nodes chosen');
return true;
});
})
.end()
.findByCssSelector('div.role-panel')
.end()
.then(function() {
return clusterPage.checkNodeRoles(['Controller', 'Storage - Cinder']);
})
.then(function() {
return applyButton.isEnabled().then(function(isEnabled) {
assert.isFalse(isEnabled, 'Apply button is disabled until both roles and nodes chosen');
return true;
});
})
.then(function() {
return clusterPage.checkNodes(nodesAmount);
})
.then(function() {
applyButton.click();
})
.setFindTimeout(2000)
.findByCssSelector('button.btn-add-nodes')
.end()
.then(function() {
return _.range(1, 1 + nodesAmount).reduce(
function(nodesFound, index) {
return that.remote
.setFindTimeout(1000)
.findByCssSelector('div.node:nth-child(' + index + ')')
.catch(function() {
throw new Error('Unable to find ' + index + ' node in cluster');
});
},
0
);
});
}
};
});
});

View File

@ -0,0 +1,60 @@
/*
* Copyright 2015 Mirantis, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License. You may obtain
* a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
**/
define([
'intern!object',
'intern/chai!assert',
'tests/functional/pages/common'
], function(registerSuite, assert, Common) {
'use strict';
registerSuite(function() {
var common,
clusterName;
return {
name: 'Clusters page',
setup: function() {
common = new Common(this.remote);
clusterName = 'Test Cluster #' + Math.round(99999 * Math.random());
},
beforeEach: function() {
return this.remote
.then(function() {
return common.getIn();
})
.then(function() {
return common.createCluster(clusterName);
});
},
afterEach: function() {
return this.remote
.then(function() {
return common.removeCluster(clusterName, true);
});
},
'Create Cluster': function() {
return this.remote
.then(function() {
return common.doesClusterExist(clusterName);
})
.then(function(result) {
assert.ok(result, 'Newly created cluster name found in the list');
});
}
};
});
});

View File

@ -0,0 +1,59 @@
/*
* Copyright 2014 Mirantis, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License. You may obtain
* a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
**/
define([
'intern!object',
'intern/chai!assert',
'tests/functional/pages/login',
'tests/functional/pages/common'
], function(registerSuite, assert, LoginPage, Common) {
'use strict';
registerSuite(function() {
var loginPage, common;
return {
name: 'Login page',
setup: function() {
loginPage = new LoginPage(this.remote);
common = new Common(this.remote);
},
beforeEach: function() {
this.remote
.then(function() {
return common.getOut();
});
},
'Login with incorrect credentials': function() {
return this.remote
.then(function() {
return loginPage.login('login', '*****');
})
.findByCssSelector('div.login-fields-box p.text-danger')
.isDisplayed()
.then(function(errorShown) {
assert.ok(errorShown, 'Error message is expected to be displayed');
});
},
'Login with proper credentials': function() {
return this.remote
.then(function() {
return loginPage.login();
})
.waitForDeletedByClassName('login-btn');
}
};
});
});

View File

@ -0,0 +1,49 @@
/*
* Copyright 2015 Mirantis, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License. You may obtain
* a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
**/
define([
'intern!object',
'intern/chai!assert',
'tests/functional/pages/login',
'tests/functional/pages/welcome'
], function(registerSuite, assert, LoginPage, WelcomePage) {
'use strict';
registerSuite(function() {
var loginPage,
welcomePage;
return {
name: 'Welcome page',
setup: function() {
loginPage = new LoginPage(this.remote);
welcomePage = new WelcomePage(this.remote);
},
'Skip welcome page': function() {
return this.remote
.then(function() {
return loginPage.login();
})
.then(function() {
return welcomePage.skip(true);
})
.then(function(result) {
assert.ok(result, 'Start using fuel button is present');
});
}
};
});
});

View File

@ -0,0 +1,47 @@
/*
* Copyright 2014 Mirantis, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License. You may obtain
* a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
**/
define(['underscore'], function(_) {
'use strict';
var serverHost = '127.0.0.1',
serverPort = process.env.SERVER_PORT || 5544,
serverUrl = 'http://' + serverHost + ':' + serverPort,
username = 'admin',
password = 'admin';
return {
username: username,
password: password,
serverUrl: serverUrl,
clickLinkByText: function(remote, cssSelector, linkText) {
return remote
.setFindTimeout(1000)
.findAllByCssSelector(cssSelector)
.then(function(links) {
return links.reduce(function(matchFound, link) {
return link.getVisibleText().then(function(text) {
if (_.trim(text) == linkText) {
link.click();
return true;
}
return matchFound;
});
}, false);
});
}
};
});

View File

@ -31,8 +31,9 @@ define(['config'], function(config) {
'host-node': 'requirejs',
'host-browser': '/vendor/bower/requirejs/require.js'
},
// A regular expression matching URLs to files that should not be included in code coverage analysis
grep: /^/,
excludeInstrumentation: /^/,
loader: config
loader: config,
reporters: ['console']
};
});

View File

@ -38,7 +38,7 @@ casper.then(function() {
this.click('.btn-add-nodes');
this.test.assertSelectorAppears('.node', 'Add Nodes screen appeared and unallocated nodes loaded');
this.then(function() {
this.test.assertEvalEquals(function() {return $('.node').length}, 1, 'Number of unallocated nodes is correct');
this.test.assertEvalEquals(function() {return $('.node').length}, 9, 'Number of unallocated nodes is correct');
this.click('input[name=controller]');
this.click('.node input[type=checkbox]');
this.test.assertSelectorAppears('.node .role-list > ul', 'Controller role is applied to the node');
@ -187,4 +187,4 @@ casper.then(function() {
casper.run(function() {
this.test.done();
});
});

View File

@ -43,6 +43,7 @@ function usage {
echo " --no-ui-unit Don't run UI unit tests"
echo " --ui-func Run UI functional tests"
echo " --no-ui-func Don't run UI functional tests"
echo " --ui-selenium Run UI functional selenium tests"
echo ""
echo "Note: with no options specified, the script will try to run all available"
echo " tests with all available checks."
@ -74,6 +75,7 @@ function process_options {
--ui-unit) ui_unit_tests=1;;
--no-ui-unit) no_ui_unit_tests=1;;
--ui-func) ui_func_tests=1;;
--ui-selenium) ui_func_selenium_tests=1;;
--no-ui-func) no_ui_func_tests=1;;
-t|--tests) certain_tests=1;;
-*) testropts="$testropts $arg";;
@ -110,7 +112,7 @@ ARTIFACTS=${ARTIFACTS:-`pwd`/test_run}
TEST_WORKERS=${TEST_WORKERS:-0}
mkdir -p $ARTIFACTS
# disabled/enabled flags that are setted from the cli.
# disabled/enabled flags that are set from the cli.
# used for manipulating run logic.
agent_tests=0
no_agent_tests=0
@ -132,7 +134,7 @@ no_ui_func_tests=0
certain_tests=0
tasklib_tests=0
no_tasklib_tests=0
ui_func_selenium_tests=0
function run_tests {
run_cleanup
@ -163,6 +165,7 @@ function run_tests {
$ui_lint_checks -eq 0 && \
$ui_unit_tests -eq 0 && \
$ui_func_tests -eq 0 && \
$ui_func_selenium_tests -eq 0 && \
$upgrade_system -eq 0 && \
$shotgun_tests -eq 0 && \
$flake8_checks -eq 0 ]]; then
@ -214,6 +217,11 @@ function run_tests {
run_ui_func_tests || errors+=" ui_func_tests"
fi
if [ $ui_func_selenium_tests -eq 1 ]; then
echo "Starting UI functional selenium tests..."
run_ui_func_selenium_tests || errors+=" ui_func_selenium_tests"
fi
if [ $upgrade_system -eq 1 ]; then
echo "Starting upgrade system tests..."
run_upgrade_system_tests || errors+=" upgrade_system_tests"
@ -363,6 +371,66 @@ function run_ui_func_tests {
return $result
}
# Run UI functional tests.
#
# Arguments:
#
# $@ -- tests to be run; with no arguments all tests will be run
function run_ui_func_selenium_tests {
local SERVER_PORT=$UI_SERVER_PORT
local TESTS_DIR=$ROOT/nailgun/static/tests/functional
local TESTS=$TESTS_DIR/test_*.js
local artifacts=$ARTIFACTS/ui_func
local config=$artifacts/test.yaml
prepare_artifacts $artifacts $config
local COMPRESSED_STATIC_DIR=$artifacts/static_compressed
if [ $# -ne 0 ]; then
TESTS=$@
fi
pushd $ROOT/nailgun >> /dev/null
# test compression
echo -n "Compressing UI... "
local output=$(${GULP} build --static-dir=$COMPRESSED_STATIC_DIR 2>&1)
if [ $? -ne 0 ]; then
echo "$output"
popd >> /dev/null
exit 1
fi
echo "done"
# run js testcases
local server_log=`mktemp /tmp/test_nailgun_ui_server.XXXX`
local result=0
local pid
for testcase in $TESTS; do
dropdb $config
syncdb $config true
run_server $SERVER_PORT $server_log $config || \
{ echo 'Failed to start Nailgun'; return 1; }
SERVER_PORT=$SERVER_PORT \
${GULP} functional-tests --suites=$testcase
if [ $? -ne 0 ]; then
result=1
break
fi
kill_server $SERVER_PORT
done
rm $server_log
popd >> /dev/null
return $result
}
# Run tests for fuel upgrade system
#
@ -484,6 +552,7 @@ function syncdb {
if [[ $# -ne 0 && $defaults = true ]]; then
NAILGUN_CONFIG=$config tox -evenv -- python manage.py loaddefault > /dev/null
NAILGUN_CONFIG=$config tox -evenv -- python manage.py loaddata nailgun/fixtures/sample_environment.json > /dev/null
fi
popd >> /dev/null
@ -626,6 +695,8 @@ EOL
function guess_test_run {
if [[ $1 == *ui_tests* && $1 == *.js ]]; then
run_ui_func_tests $1 || echo "ERROR: $1"
elif [[ $1 == *functional* && $1 == *.js ]]; then
run_ui_func_selenium_tests $1 || echo "ERROR: $1"
elif [[ $1 == *fuel_upgrade_system* ]]; then
run_upgrade_system_tests $1 || echo "ERROR: $1"
elif [[ $1 == *shotgun* ]]; then