Add support for running JS tests in LOOT from CLI

- Use Karma to run the tests.
- Support specifying LOOT UI index page as CLI argument, and
  treat localhost URLs like http://loot URLs, so that Karma
  can get LOOT to launch the test page.
- Fix the JS query tests when run in LOOT, as window.cefQuery
  can't be stubbed in CEF.
This commit is contained in:
Oliver Hamlet
2016-12-20 15:31:07 +00:00
parent cdad91ffe1
commit 647432fd71
7 changed files with 71 additions and 33 deletions
+35
View File
@@ -0,0 +1,35 @@
const helpers = require('./scripts/helpers');
const path = require('path');
process.env.CHROME_BIN = path.join(helpers.getAppReleasePaths('.')[0].path, 'LOOT');
console.log(`Running tests using browser executable at ${process.env.CHROME_BIN}`);
module.exports = (config) => {
config.set({
basePath: '',
frameworks: ['mocha', 'chai'],
files: [
'bower_components/Jed/jed.js',
'bower_components/jed-gettext-parser/jedGettextParser.js',
'bower_components/lodash/dist/lodash.core.min.js',
'src/tests/gui/html/js/mock_*.js',
'src/gui/html/js/filters.js',
'src/gui/html/js/plugin.js',
'src/gui/html/js/game.js',
'src/gui/html/js/query.js',
'src/gui/html/js/state.js',
'src/gui/html/js/translator.js',
'src/gui/html/js/updateExists.js',
'src/tests/gui/html/js/*.js',
],
exclude: [],
preprocessors: {},
reporters: ['progress'],
port: 9876,
colors: true,
logLevel: config.LOG_INFO,
autoWatch: false,
browsers: ['Chrome'],
singleRun: true,
});
};
+6 -1
View File
@@ -25,13 +25,18 @@
"chai": "^3.5.0",
"eslint": "^3.5.0",
"eslint-config-airbnb-base": "^7.1.0",
"eslint-plugin-import": "^1.15.0",
"eslint-plugin-html": "^1.5.0",
"eslint-plugin-import": "^1.15.0",
"grunt": "^1.0.1",
"grunt-cli": "^1.2.0",
"grunt-contrib-connect": "^1.0.0",
"grunt-contrib-watch": "^1.0.0",
"grunt-saucelabs": "^9.0.0",
"karma": "^1.3.0",
"karma-chai": "^0.1.0",
"karma-chrome-launcher": "^2.0.0",
"karma-cli": "^1.0.1",
"karma-mocha": "^1.3.0",
"mkdirp": "^0.5.1",
"mocha": "^3.0.1"
},
+5 -5
View File
@@ -35,9 +35,12 @@
#include "gui/loot_scheme_handler_factory.h"
namespace loot {
void LootApp::Initialise(const std::string& defaultGame, const std::string& lootDataPath) {
void LootApp::Initialise(const std::string& defaultGame,
const std::string& lootDataPath,
const std::string& url) {
LootPaths::initialise(lootDataPath);
lootState_.init(defaultGame);
url_ = url;
}
void LootApp::OnBeforeCommandLineProcessing(const CefString& process_type,
@@ -93,11 +96,8 @@ void LootApp::OnContextInitialized() {
boost::filesystem::path::imbue(std::locale());
}
// Set URL to load. Ignore any command line values.
const std::string url = "http://loot/ui/index.html";
// Create the first browser window.
CefBrowserHost::CreateBrowser(window_info, handler.get(), url, browser_settings, NULL);
CefBrowserHost::CreateBrowser(window_info, handler.get(), url_, browser_settings, NULL);
}
void LootApp::OnWebKitInitialized() {
+4 -1
View File
@@ -36,7 +36,9 @@ class LootApp : public CefApp,
public CefBrowserProcessHandler,
public CefRenderProcessHandler {
public:
void Initialise(const std::string& defaultGame, const std::string& lootDataPath);
void Initialise(const std::string& defaultGame,
const std::string& lootDataPath,
const std::string& url);
// Override CefApp methods.
virtual void OnBeforeCommandLineProcessing(const CefString& process_type,
@@ -60,6 +62,7 @@ private:
LootState lootState_;
CefRefPtr<CefMessageRouterRendererSide> message_router_;
std::string url_;
IMPLEMENT_REFCOUNTING(LootApp);
};
+5 -1
View File
@@ -224,9 +224,13 @@ bool LootHandler::OnBeforeBrowse(CefRefPtr< CefBrowser > browser,
bool is_redirect) {
BOOST_LOG_TRIVIAL(trace) << "Attempting to open link: " << request->GetURL().ToString();
if (boost::starts_with(request->GetURL().ToString(), "http://loot/")) {
const std::string url = request->GetURL().ToString();
if (boost::starts_with(url, "http://loot/")) {
BOOST_LOG_TRIVIAL(trace) << "Link is to LOOT page, allowing CEF's default handling.";
return false;
} else if (boost::starts_with(url, "http://localhost:")) {
BOOST_LOG_TRIVIAL(warning) << "Link is to a page on localhost, if this isn't happening while running tests, something has gone wrong";
return false;
}
BOOST_LOG_TRIVIAL(info) << "Opening link in Windows' default handler.";
+9 -1
View File
@@ -94,7 +94,15 @@ void processCommandLineArguments(CefRefPtr<loot::LootApp> app) {
lootDataPath = command_line->GetSwitchValue("loot-data-path");
}
app.get()->Initialise(defaultGame, lootDataPath);
std::string url = "http://loot/ui/index.html";
if (command_line->HasArguments()) {
std::vector<CefString> arguments;
command_line->GetArguments(arguments);
url = arguments[0];
BOOST_LOG_TRIVIAL(info) << "Loading homepage using URL " << url;
}
app.get()->Initialise(defaultGame, lootDataPath, url);
}
#ifdef _WIN32
+7 -24
View File
@@ -1,14 +1,5 @@
'use strict';
/* Mock the window.cefQuery method */
window.cefQuery = (obj) => {
if (obj.request === '{"name":"fail","args":[]}') {
obj.onFailure(-1, obj.request);
} else {
obj.onSuccess(obj.request);
}
};
describe('query()', () => {
it('should throw if no arguments are passed', () => {
(() => { loot.query(); }).should.throw();
@@ -19,28 +10,20 @@ describe('query()', () => {
});
it('should succeed if a request name is passed', () =>
loot.query('test').then((result) =>
result.should.equal('{"name":"test","args":[]}')
loot.query('discardUnappliedChanges').then((result) =>
result.should.be.empty
)
);
it('should succeed if a request name and arguments are passed', () =>
loot.query('test', 1, false, ['a']).then((result) =>
result.should.equal(JSON.stringify({
name: 'test',
args: [
1,
false,
['a'],
],
}))
loot.query('copyContent', 'foo').then((result) =>
result.should.be.empty
)
);
it('should fail with an Error object when an error occurs', () =>
loot.query('fail').catch((error) => {
error.should.be.an('error');
return error.message.should.equal('{"name":"fail","args":[]}');
})
loot.query('copyContent').catch((error) =>
error.should.be.an('error')
)
);
});