From db672f46312ea676132123c3cfa5ae42b15ef8fb Mon Sep 17 00:00:00 2001 From: muzaffaryousaf Date: Wed, 6 Apr 2016 20:16:40 +0500 Subject: [PATCH] Karma configurations for common, lms and cms. TNL-4102 --- cms/static/coffee/spec/main.coffee | 86 +++--- cms/static/coffee/spec/main_squire.coffee | 32 ++- cms/static/karma_cms.conf.js | 122 ++++++++ cms/static/karma_cms_squire.conf.js | 113 ++++++++ common/lib/xmodule/xmodule/js/karma_runner.js | 10 + .../xmodule/xmodule/js/karma_xmodule.conf.js | 90 ++++++ .../xmodule/xmodule/js/spec/main_requirejs.js | 3 +- .../static/common/js/jasmine.common.conf.js | 11 + common/static/common/js/karma.common.conf.js | 216 ++++++++++++++ .../static/common/js/spec/main_requirejs.js | 56 ++-- common/static/karma_common.conf.js | 83 ++++++ common/static/karma_common_requirejs.conf.js | 78 ++++++ lms/static/js/spec/main.js | 265 +++++++++--------- lms/static/karma_lms.conf.js | 141 ++++++++++ lms/static/karma_lms_coffee.conf.js | 82 ++++++ lms/static/moment_requirejs.js | 15 + package.json | 13 +- pavelib/paver_tests/test_js_test.py | 53 ++-- pavelib/tests.py | 3 +- pavelib/utils/envs.py | 16 +- pavelib/utils/test/suites/js_suite.py | 61 ++-- requirements/edx/github.txt | 1 - 22 files changed, 1279 insertions(+), 271 deletions(-) create mode 100644 cms/static/karma_cms.conf.js create mode 100644 cms/static/karma_cms_squire.conf.js create mode 100644 common/lib/xmodule/xmodule/js/karma_runner.js create mode 100644 common/lib/xmodule/xmodule/js/karma_xmodule.conf.js create mode 100644 common/static/common/js/jasmine.common.conf.js create mode 100644 common/static/common/js/karma.common.conf.js create mode 100644 common/static/karma_common.conf.js create mode 100644 common/static/karma_common_requirejs.conf.js create mode 100644 lms/static/karma_lms.conf.js create mode 100644 lms/static/karma_lms_coffee.conf.js create mode 100644 lms/static/moment_requirejs.js diff --git a/cms/static/coffee/spec/main.coffee b/cms/static/coffee/spec/main.coffee index b7efe681c3..ee456c3bd5 100644 --- a/cms/static/coffee/spec/main.coffee +++ b/cms/static/coffee/spec/main.coffee @@ -1,4 +1,5 @@ requirejs.config({ + baseUrl: '/base/', paths: { "gettext": "xmodule_js/common_static/js/test/i18n", "mustache": "xmodule_js/common_static/js/vendor/mustache", @@ -42,10 +43,9 @@ requirejs.config({ "accessibility": "xmodule_js/common_static/js/src/accessibility_tools", "sinon": "xmodule_js/common_static/js/vendor/sinon-1.17.0", "squire": "xmodule_js/common_static/js/vendor/Squire", - "jasmine-jquery": "xmodule_js/common_static/js/vendor/jasmine-jquery", "jasmine-imagediff": "xmodule_js/common_static/js/vendor/jasmine-imagediff", - "jasmine-stealth": "xmodule_js/common_static/js/vendor/jasmine-stealth", - "jasmine.async": "xmodule_js/common_static/js/vendor/jasmine.async", + "jasmine-stealth": "xmodule_js/common_static/js/libs/jasmine-stealth", + "jasmine-waituntil": "xmodule_js/common_static/js/libs/jasmine-waituntil", "draggabilly": "xmodule_js/common_static/js/vendor/draggabilly", "domReady": "xmodule_js/common_static/js/vendor/domReady", "URI": "xmodule_js/common_static/js/vendor/URI.min", @@ -158,17 +158,17 @@ requirejs.config({ "mathjax": { exports: "MathJax", init: -> - MathJax.Hub.Config - tex2jax: - inlineMath: [ - ["\\(","\\)"], - ['[mathjaxinline]','[/mathjaxinline]'] - ] - displayMath: [ - ["\\[","\\]"], - ['[mathjax]','[/mathjax]'] - ] - MathJax.Hub.Configured() + MathJax.Hub.Config + tex2jax: + inlineMath: [ + ["\\(", "\\)"], + ['[mathjaxinline]', '[/mathjaxinline]'] + ] + displayMath: [ + ["\\[", "\\]"], + ['[mathjax]', '[/mathjax]'] + ] + MathJax.Hub.Configured() }, "URI": { exports: "URI" @@ -179,18 +179,12 @@ requirejs.config({ "sinon": { exports: "sinon" }, - "jasmine-jquery": { - deps: ["jasmine"] - }, - "jasmine-imagediff": { - deps: ["jasmine"] - }, + "jasmine-imagediff": {}, "jasmine-stealth": { - deps: ["jasmine"] + deps: ["underscore", "underscore.string"] }, - "jasmine.async": { - deps: ["jasmine"], - exports: "AsyncSpec" + "jasmine-waituntil": { + deps: ["jquery"] }, "xblock/core": { exports: "XBlock", @@ -201,7 +195,7 @@ requirejs.config({ deps: ["xblock/core"] }, "mock-ajax": { - deps: ["jasmine", "jquery"] + deps: ["jquery"] } "coffee/src/main": { @@ -221,35 +215,33 @@ requirejs.config({ jasmine.getFixtures().fixturesPath += 'coffee/fixtures' -define([ +testFiles = [ "coffee/spec/main_spec", - - "coffee/spec/models/course_spec", "coffee/spec/models/metadata_spec", + "coffee/spec/models/course_spec", + "coffee/spec/models/metadata_spec", "coffee/spec/models/section_spec", "coffee/spec/models/settings_course_grader_spec", - "coffee/spec/models/settings_grading_spec", "coffee/spec/models/textbook_spec", + "coffee/spec/models/settings_grading_spec", + "coffee/spec/models/textbook_spec", "coffee/spec/models/upload_spec", - "coffee/spec/views/course_info_spec", "coffee/spec/views/metadata_edit_spec", "coffee/spec/views/module_edit_spec", "coffee/spec/views/textbook_spec", "coffee/spec/views/upload_spec", - - "js/spec/video/transcripts/utils_spec", "js/spec/video/transcripts/editor_spec", - "js/spec/video/transcripts/videolist_spec", "js/spec/video/transcripts/message_manager_spec", + "js/spec/video/transcripts/utils_spec", + "js/spec/video/transcripts/editor_spec", + "js/spec/video/transcripts/videolist_spec", + "js/spec/video/transcripts/message_manager_spec", "js/spec/video/transcripts/file_uploader_spec", - "js/spec/models/component_template_spec", "js/spec/models/explicit_url_spec", "js/spec/models/xblock_info_spec", "js/spec/models/xblock_validation_spec", "js/spec/models/license_spec", - "js/spec/utils/drag_and_drop_spec", "js/spec/utils/handle_iframe_binding_spec", "js/spec/utils/module_spec", - "js/spec/views/active_video_upload_list_spec", "js/spec/views/previous_video_upload_spec", "js/spec/views/previous_video_upload_list_spec", @@ -266,7 +258,6 @@ define([ "js/spec/views/license_spec", "js/spec/views/paging_spec", "js/spec/views/login_studio_spec", - "js/spec/views/pages/container_spec", "js/spec/views/pages/container_subviews_spec", "js/spec/views/pages/group_configurations_spec", @@ -274,25 +265,24 @@ define([ "js/spec/views/pages/course_rerun_spec", "js/spec/views/pages/index_spec", "js/spec/views/pages/library_users_spec", - "js/spec/views/modals/base_modal_spec", "js/spec/views/modals/edit_xblock_spec", "js/spec/views/modals/validation_error_modal_spec", - "js/spec/views/settings/main_spec", - "js/spec/factories/xblock_validation_spec", - "js/spec/xblock/cms.runtime.v1_spec", - - # Certificates application test suite mappings "js/certificates/spec/models/certificate_spec", "js/certificates/spec/views/certificate_details_spec", "js/certificates/spec/views/certificate_editor_spec", "js/certificates/spec/views/certificates_list_spec", - "js/certificates/spec/views/certificate_preview_spec", + "js/certificates/spec/views/certificate_preview_spec" +] - # these tests are run separately in the cms-squire suite, due to process - # isolation issues with Squire.js - # "coffee/spec/views/assets_spec" - ]) +i = 0 +while i < testFiles.length + testFiles[i] = '/base/' + testFiles[i] + '.js' + i++ + +require testFiles, -> +# start test run, once Require.js is done + window.__karma__.start() diff --git a/cms/static/coffee/spec/main_squire.coffee b/cms/static/coffee/spec/main_squire.coffee index afd40603df..f82251f597 100644 --- a/cms/static/coffee/spec/main_squire.coffee +++ b/cms/static/coffee/spec/main_squire.coffee @@ -1,4 +1,6 @@ requirejs.config({ + baseUrl: '/base/', + paths: { "gettext": "xmodule_js/common_static/js/test/i18n", "mustache": "xmodule_js/common_static/js/vendor/mustache", @@ -36,11 +38,11 @@ requirejs.config({ "utility": "xmodule_js/common_static/js/src/utility", "sinon": "xmodule_js/common_static/js/vendor/sinon-1.17.0", "squire": "xmodule_js/common_static/js/vendor/Squire", - "jasmine-stealth": "xmodule_js/common_static/js/vendor/jasmine-stealth", - "jasmine.async": "xmodule_js/common_static/js/vendor/jasmine.async", "modernizr": "xmodule_js/common_static/edx-pattern-library/js/modernizr-custom", "afontgarde": "xmodule_js/common_static/edx-pattern-library/js/afontgarde", "edxicons": "xmodule_js/common_static/edx-pattern-library/js/edx-icons", + "jasmine-stealth": "xmodule_js/common_static/js/libs/jasmine-stealth", + "jasmine-waituntil": "xmodule_js/common_static/js/libs/jasmine-waituntil", "draggabilly": "xmodule_js/common_static/js/vendor/draggabilly", "domReady": "xmodule_js/common_static/js/vendor/domReady", "URI": "xmodule_js/common_static/js/vendor/URI.min", @@ -159,11 +161,10 @@ requirejs.config({ exports: "sinon" }, "jasmine-stealth": { - deps: ["jasmine"] + deps: ["underscore", "underscore.string"] }, - "jasmine.async": { - deps: ["jasmine"], - exports: "AsyncSpec" + "jasmine-waituntil": { + deps: ["jquery"] }, "xblock/core": { exports: "XBlock", @@ -191,9 +192,16 @@ requirejs.config({ jasmine.getFixtures().fixturesPath += 'coffee/fixtures' -define([ - "coffee/spec/views/assets_spec", - "js/spec/video/translations_editor_spec", - "js/spec/video/file_uploader_editor_spec", - "js/spec/models/group_configuration_spec" - ]) +testFiles = [ + 'coffee/spec/views/assets_spec', + 'js/spec/video/translations_editor_spec', + 'js/spec/video/file_uploader_editor_spec', + 'js/spec/models/group_configuration_spec' +] +i = 0 +while i < testFiles.length + testFiles[i] = '/base/' + testFiles[i] + '.js' + i++ +require testFiles, -> +# start test run, once Require.js is done + window.__karma__.start() diff --git a/cms/static/karma_cms.conf.js b/cms/static/karma_cms.conf.js new file mode 100644 index 0000000000..871eed5485 --- /dev/null +++ b/cms/static/karma_cms.conf.js @@ -0,0 +1,122 @@ +// Common JavaScript tests, using RequireJS. +// +// To run all the tests and print results to the console: +// +// karma start cms/static/karma_cms.conf.js +// +// +// To run the tests for debugging: Debugging can be done in any browser +// but Chrome's developer console debugging experience is best. +// +// karma start cms/static/karma_cms.conf.js --browsers=BROWSER --single-run=false +// +// +// To run the tests with coverage and junit reports: +// +// karma start cms/static/karma_cms.conf.js --browsers=BROWSER --coverage +// --junitreportpath= --coveragereportpath= +// +// where `BROWSER` could be Chrome or Firefox. +// + +/* jshint node: true */ +/*jshint -W079 */ +'use strict'; +var path = require('path'); +var _ = require('underscore'); +var configModule = require(path.join(__dirname, '../../common/static/common/js/karma.common.conf.js')); + +var files = [ + {pattern: 'xmodule_js/common_static/coffee/src/ajax_prefix.js', included: false}, + {pattern: 'xmodule_js/common_static/js/src/utility.js', included: false}, + {pattern: 'xmodule_js/common_static/js/vendor/jquery.min.js', included: false}, + {pattern: 'xmodule_js/common_static/js/vendor/jquery-ui.min.js', included: false}, + {pattern: 'xmodule_js/common_static/js/vendor/jquery.cookie.js', included: false}, + {pattern: 'xmodule_js/common_static/js/vendor/jquery.simulate.js', included: false}, + {pattern: 'xmodule_js/common_static/common/js/vendor/underscore.js', included: false}, + {pattern: 'xmodule_js/common_static/js/vendor/underscore.string.min.js', included: false}, + {pattern: 'xmodule_js/common_static/js/vendor/backbone-min.js', included: false}, + {pattern: 'xmodule_js/common_static/js/vendor/backbone-associations-min.js', included: false}, + {pattern: 'xmodule_js/common_static/js/vendor/backbone.paginator.min.js', included: false}, + {pattern: 'xmodule_js/common_static/js/vendor/backbone-relational.min.js', included: false}, + {pattern: 'xmodule_js/common_static/js/vendor/timepicker/jquery.timepicker.js', included: false}, + {pattern: 'xmodule_js/common_static/js/vendor/jquery.leanModal.js', included: false}, + {pattern: 'xmodule_js/common_static/js/vendor/jquery.ajaxQueue.js', included: false}, + {pattern: 'xmodule_js/common_static/js/vendor/jquery.form.js', included: false}, + {pattern: 'xmodule_js/common_static/js/vendor/html5-input-polyfills/number-polyfill.js', included: false}, + {pattern: 'xmodule_js/common_static/js/vendor/sinon-1.17.0.js', included: false}, + {pattern: 'xmodule_js/common_static/js/vendor/Squire.js', included: false}, + {pattern: 'xmodule_js/common_static/js/libs/jasmine-stealth.js', included: false}, + {pattern: 'xmodule_js/common_static/js/libs/jasmine-waituntil.js', included: false}, + {pattern: 'xmodule_js/common_static/js/vendor/jasmine-imagediff.js', included: false}, + {pattern: 'xmodule_js/common_static/js/vendor/CodeMirror/codemirror.js', included: false}, + {pattern: 'xmodule_js/common_static/js/vendor/jQuery-File-Upload/js/**/*.js', included: false}, + {pattern: 'xmodule_js/src/xmodule.js', included: false}, + {pattern: 'xmodule_js/common_static/js/test/i18n.js', included: false}, + {pattern: 'xmodule_js/common_static/js/vendor/draggabilly.pkgd.js', included: false}, + {pattern: 'xmodule_js/common_static/js/vendor/date.js', included: false}, + {pattern: 'xmodule_js/common_static/js/vendor/domReady.js', included: false}, + {pattern: 'xmodule_js/common_static/js/vendor/URI.min.js', included: false}, + {pattern: 'xmodule_js/common_static/js/vendor/jquery.smooth-scroll.min.js', included: false}, + {pattern: 'xmodule_js/common_static/coffee/src/jquery.immediateDescendents.js', included: false}, + {pattern: 'xmodule_js/common_static/js/xblock/**/*.js', included: false}, + {pattern: 'xmodule_js/common_static/coffee/src/xblock/**/*.js', included: false}, + { + pattern: 'xmodule_js/common_static/js/vendor/jQuery-File-Upload/js/jquery.iframe-transport.js', + included: false + }, + {pattern: 'xmodule_js/common_static/js/vendor/jQuery-File-Upload/js/jquery.fileupload.js', included: false}, + { + pattern: 'xmodule_js/common_static/js/vendor/jQuery-File-Upload/js/jquery.fileupload-process.js', + included: false + }, + { + pattern: 'xmodule_js/common_static/js/vendor/jQuery-File-Upload/js/jquery.fileupload-validate.js', + included: false + }, + {pattern: 'xmodule_js/common_static/js/vendor/mock-ajax.js', included: false}, + {pattern: 'xmodule_js/common_static/js/vendor/requirejs/text.js', included: false}, + + // Paths to source JavaScript files + {pattern: 'coffee/src/**/*.js', included: false, nocache: true}, + {pattern: 'js/**/*.js', included: false, nocache: true}, + {pattern: 'js/certificates/**/*.js', included: false, nocache: true}, + {pattern: 'js/factories/**/*.js', included: false, nocache: true}, + {pattern: 'common/js/**/*.js', included: false, nocache: true}, + {pattern: 'edx-pattern-library/js/**/*.js', included: false, nocache: true}, + {pattern: 'edx-ui-toolkit/js/**/*.js', included: false, nocache: true}, + + // Paths to spec (test) JavaScript files + {pattern: 'coffee/spec/main.js', included: false, nocache: true}, + {pattern: 'coffee/spec/**/*.js', included: false, nocache: true}, + {pattern: 'js/spec/**/*.js', included: false, nocache: true}, + {pattern: 'js/certificates/spec/**/*.js', included: false, nocache: true}, + + // Paths to fixture files + {pattern: 'coffee/fixtures/**/*.underscore', included: false, nocache: true}, + {pattern: 'templates/**/*.underscore', included: false, nocache: true}, + {pattern: 'common/templates/**/*.underscore', included: false, nocache: true}, + + // override fixture path and other config. + {pattern: path.join(configModule.appRoot, 'common/static/common/js/jasmine.common.conf.js'), included: true}, + 'coffee/spec/main.js' +]; + +var preprocessors = { + // do not include tests or libraries + // (these files will be instrumented by Istanbul) + 'coffee/src/**/*.js': ['coverage'], + 'js/**/!(*spec).js': ['coverage'], + 'common/js/**/*.js': ['coverage'] +}; + +module.exports = function (config) { + var commonConfig = configModule.getConfig(config), + localConfig = { + files: files, + preprocessors: preprocessors + }; + + config.set(_.extend(commonConfig, localConfig)); +}; + diff --git a/cms/static/karma_cms_squire.conf.js b/cms/static/karma_cms_squire.conf.js new file mode 100644 index 0000000000..bd8996038e --- /dev/null +++ b/cms/static/karma_cms_squire.conf.js @@ -0,0 +1,113 @@ +// Common JavaScript tests, using RequireJS. +// +// To run all the tests and print results to the console: +// +// karma start cms/static/karma_cms_squire.conf.js +// +// +// To run the tests for debugging: Debugging can be done in any browser +// but Chrome's developer console debugging experience is best. +// +// karma start cms/static/karma_cms_squire.conf.js --browsers=BROWSER --single-run=false +// +// +// To run the tests with coverage and junit reports: +// +// karma start cms/static/karma_cms_squire.conf.js --browsers=BROWSER --coverage +// --junitreportpath= --coveragereportpath= +// +// where `BROWSER` could be Chrome or Firefox. +// + +/* jshint node: true */ +/*jshint -W079 */ +'use strict'; +var path = require('path'); +var _ = require('underscore'); +var configModule = require(path.join(__dirname, '../../common/static/common/js/karma.common.conf.js')); + +var files = [ + {pattern: 'xmodule_js/common_static/js/vendor/requirejs/require.js', included: false}, + {pattern: 'xmodule_js/common_static/coffee/src/ajax_prefix.js', included: false}, + {pattern: 'xmodule_js/common_static/js/src/utility.js', included: false}, + {pattern: 'xmodule_js/common_static/js/vendor/jquery.min.js', included: false}, + {pattern: 'xmodule_js/common_static/js/vendor/jquery-ui.min.js', included: false}, + {pattern: 'xmodule_js/common_static/js/vendor/jquery.cookie.js', included: false}, + {pattern: 'xmodule_js/common_static/common/js/vendor/underscore.js', included: false}, + {pattern: 'xmodule_js/common_static/js/vendor/underscore.string.min.js', included: false}, + {pattern: 'xmodule_js/common_static/js/vendor/backbone-min.js', included: false}, + {pattern: 'xmodule_js/common_static/js/vendor/backbone-associations-min.js', included: false}, + {pattern: 'xmodule_js/common_static/js/vendor/backbone.paginator.min.js', included: false}, + {pattern: 'xmodule_js/common_static/js/vendor/timepicker/jquery.timepicker.js', included: false}, + {pattern: 'xmodule_js/common_static/js/vendor/jquery.leanModal.js', included: false}, + {pattern: 'xmodule_js/common_static/js/vendor/jquery.form.js', included: false}, + {pattern: 'xmodule_js/common_static/js/vendor/html5-input-polyfills/number-polyfill.js', included: false}, + {pattern: 'xmodule_js/common_static/js/vendor/sinon-1.17.0.js', included: false}, + {pattern: 'xmodule_js/common_static/js/vendor/Squire.js', included: false}, + {pattern: 'xmodule_js/common_static/js/vendor/jasmine-imagediff.js', included: false}, + {pattern: 'xmodule_js/common_static/js/vendor/CodeMirror/codemirror.js', included: false}, + {pattern: 'xmodule_js/common_static/js/vendor/domReady.js', included: false}, + {pattern: 'xmodule_js/common_static/js/vendor/URI.min.js', included: false}, + {pattern: 'xmodule_js/src/xmodule.js', included: false}, + {pattern: 'xmodule_js/common_static/coffee/src/jquery.immediateDescendents.js', included: false}, + {pattern: 'xmodule_js/common_static/js/test/i18n.js', included: false}, + {pattern: 'xmodule_js/common_static/js/xblock/**/*.js', included: false}, + {pattern: 'xmodule_js/common_static/coffee/src/xblock/**/*.js', included: false}, + {pattern: 'xmodule_js/common_static/js/vendor/URI.min.js', included: false}, + { + pattern: 'xmodule_js/common_static/js/vendor/jQuery-File-Upload/js/jquery.iframe-transport.js', + included: false + }, + {pattern: 'xmodule_js/common_static/js/vendor/jQuery-File-Upload/js/jquery.fileupload.js', included: false}, + { + pattern: 'xmodule_js/common_static/js/vendor/jQuery-File-Upload/js/jquery.fileupload-process.js', + included: false + }, + { + pattern: 'xmodule_js/common_static/js/vendor/jQuery-File-Upload/js/jquery.fileupload-validate.js', + included: false + }, + {pattern: 'xmodule_js/common_static/js/vendor/requirejs/text.js', included: false}, + + // Paths to source JavaScript files + {pattern: 'coffee/src/**/*.js', included: false, nocache: true}, + {pattern: 'js/collections/**/*.js', included: false, nocache: true}, + {pattern: 'js/models/**/*.js', included: false, nocache: true}, + {pattern: 'js/utils/**/*.js', included: false, nocache: true}, + {pattern: 'js/views/**/*.js', included: false, nocache: true}, + {pattern: 'common/js/**/*.js', included: false, nocache: true}, + + // Paths to spec (test) JavaScript files + {pattern: 'coffee/spec/**/*.js', included: false, nocache: true}, + {pattern: 'js/spec/**/*.js', included: false, nocache: true}, + + // Paths to fixture files + {pattern: 'coffee/fixtures/**/*.*', included: false, nocache: true}, + {pattern: 'templates/**/*.*', included: false, nocache: true}, + {pattern: 'common/templates/**/*.*', included: false, nocache: true}, + + // override fixture path and other config. + {pattern: path.join(configModule.appRoot, 'common/static/common/js/jasmine.common.conf.js'), included: true}, + 'coffee/spec/main_squire.js' +]; + +var preprocessors = { + // do not include tests or libraries + // (these files will be instrumented by Istanbul) + 'coffee/src/**/*.js': ['coverage'], + 'js/collections/**/*.js': ['coverage'], + 'js/models/**/*.js': ['coverage'], + 'js/utils/**/*.js': ['coverage'], + 'js/views/**/*.js': ['coverage'], + 'common/js/**/*.js': ['coverage'] +}; + +module.exports = function (config) { + var commonConfig = configModule.getConfig(config), + localConfig = { + files: files, + preprocessors: preprocessors + }; + + config.set(_.extend(commonConfig, localConfig)); +}; diff --git a/common/lib/xmodule/xmodule/js/karma_runner.js b/common/lib/xmodule/xmodule/js/karma_runner.js new file mode 100644 index 0000000000..8d416281b7 --- /dev/null +++ b/common/lib/xmodule/xmodule/js/karma_runner.js @@ -0,0 +1,10 @@ +// overwrite the loaded method and manually start the karma after a delay +// Somehow the code initialized in jQuery's onready doesn't get called before karma auto starts + +/* jshint node: true */ +'use strict'; +window.__karma__.loaded = function () { + setTimeout(function () { + window.__karma__.start(); + }, 1000); +}; diff --git a/common/lib/xmodule/xmodule/js/karma_xmodule.conf.js b/common/lib/xmodule/xmodule/js/karma_xmodule.conf.js new file mode 100644 index 0000000000..1dab63f085 --- /dev/null +++ b/common/lib/xmodule/xmodule/js/karma_xmodule.conf.js @@ -0,0 +1,90 @@ +// Xmodule Tests +// +// To run all the tests and print results to the console: +// +// karma start common/lib/xmodule/xmodule/js/karma_xmodule.conf.js +// +// +// To run the tests for debugging: Debugging can be done in any browser +// Chrome's developer console debugging experience is the best though +// +// karma start common/lib/xmodule/xmodule/js/karma-xmodule.conf.js --browsers=BROWSER --single-run=false +// +// +// To run the tests with coverage and junit reports: +// +// karma start common/lib/xmodule/xmodule/js/karma-xmodule.conf.js +// --browsers=BROWSER --coverage --junitreportpath= --coveragereportpath= +// +// where `BROWSER` could be Chrome or Firefox. +// + +/* jshint node: true */ +/*jshint -W079 */ + +'use strict'; +var path = require('path'); +var _ = require('underscore'); +var configModule = require(path.join(__dirname, 'common_static/common/js/karma.common.conf.js')); + +var files = [ + // override fixture path and other config. + {pattern: path.join(configModule.appRoot, 'common/static/common/js/jasmine.common.conf.js'), included: true}, + + {pattern: 'common_static/js/vendor/jquery.min.js', included: true}, + {pattern: 'common_static/js/test/i18n.js', included: true}, + {pattern: 'common_static/coffee/src/ajax_prefix.js', included: true}, + {pattern: 'common_static/js/src/logger.js', included: true}, + {pattern: 'common_static/js/vendor/jasmine-imagediff.js', included: true}, + {pattern: 'common_static/js/libs/jasmine-waituntil.js', included: true}, + {pattern: 'common_static/js/vendor/requirejs/require.js', included: true}, + {pattern: 'RequireJS-namespace-undefine.js', included: true}, + {pattern: 'common_static/js/vendor/jquery-ui.min.js', included: true}, + {pattern: 'common_static/js/vendor/jquery.ui.draggable.js', included: true}, + {pattern: 'common_static/js/vendor/jquery.cookie.js', included: true}, + {pattern: 'common_static/js/vendor/json2.js', included: true}, + {pattern: 'common_static/common/js/vendor/underscore.js', included: true}, + {pattern: 'common_static/js/vendor/backbone-min.js', included: true}, + {pattern: 'common_static/js/vendor/jquery.leanModal.js', included: true}, + {pattern: 'common_static/js/vendor/CodeMirror/codemirror.js', included: true}, + {pattern: 'common_static/js/vendor/tinymce/js/tinymce/jquery.tinymce.min.js', included: true}, + {pattern: 'common_static/js/vendor/tinymce/js/tinymce/tinymce.full.min.js', included: true}, + {pattern: 'common_static/js/vendor/jquery.timeago.js', included: true}, + {pattern: 'common_static/js/vendor/sinon-1.17.0.js', included: true}, + {pattern: 'common_static/js/test/add_ajax_prefix.js', included: true}, + {pattern: 'common_static/js/src/utility.js', included: true}, + {pattern: 'public/js/split_test_staff.js', included: true}, + {pattern: 'common_static/js/src/accessibility_tools.js', included: true}, + {pattern: 'common_static/js/vendor/moment.min.js', included: true}, + {pattern: 'spec/main_requirejs.js', included: true}, + {pattern: 'src/word_cloud/d3.min.js', included: true}, + + // Paths to source JavaScript files + {pattern: 'src/xmodule.js', included: true, nocache: true}, + {pattern: 'src/**/*.js', included: true, nocache: true}, + + // Paths to spec (test) JavaScript files + {pattern: 'spec/helper.js', included: true, nocache: true}, + {pattern: 'spec/**/*.js', included: true, nocache: true}, + + // Paths to fixture files + {pattern: 'fixtures/*.*', included: false, served: true, nocache: true}, + + {pattern: 'karma_runner.js', included: true} +]; + +var preprocessors = { + // do not include tests or libraries + // (these files will be instrumented by Istanbul) + 'src/**/*.js': ['coverage'] +}; + +module.exports = function (config) { + var commonConfig = configModule.getConfig(config, false), + localConfig = { + files: files, + preprocessors: preprocessors + }; + + config.set(_.extend(commonConfig, localConfig)); +}; diff --git a/common/lib/xmodule/xmodule/js/spec/main_requirejs.js b/common/lib/xmodule/xmodule/js/spec/main_requirejs.js index 040d065a72..1716ee3540 100644 --- a/common/lib/xmodule/xmodule/js/spec/main_requirejs.js +++ b/common/lib/xmodule/xmodule/js/spec/main_requirejs.js @@ -1,7 +1,8 @@ (function(requirejs) { requirejs.config({ + baseUrl: '/base/', paths: { - "moment": "xmodule/include/common_static/js/vendor/moment.min", + "moment": "common_static/js/vendor/moment.min", "modernizr": "xmodule/include/common_static/edx-pattern-library/js/modernizr-custom", "afontgarde": "xmodule/include/common_static/edx-pattern-library/js/afontgarde", "edxicons": "xmodule/include/common_static/edx-pattern-library/js/edx-icons", diff --git a/common/static/common/js/jasmine.common.conf.js b/common/static/common/js/jasmine.common.conf.js new file mode 100644 index 0000000000..45df64144b --- /dev/null +++ b/common/static/common/js/jasmine.common.conf.js @@ -0,0 +1,11 @@ +/* jshint node: true */ +'use strict'; + +// By default, fixtures are loaded from spec/javascripts/fixtures but in karma everything gets served from /base +jasmine.getFixtures().fixturesPath = '/base/'; + +// https://github.com/edx/js-test-tool/blob/master/js_test_tool/templates/jasmine_test_runner.html#L10 +// Stub out modal dialog alerts, which will prevent +// us from accessing the test results in the DOM +window.confirm = function(){return true;}; +window.alert = function(){return;}; diff --git a/common/static/common/js/karma.common.conf.js b/common/static/common/js/karma.common.conf.js new file mode 100644 index 0000000000..23ba1ac99c --- /dev/null +++ b/common/static/common/js/karma.common.conf.js @@ -0,0 +1,216 @@ +// Common configuration for Karma +/* jshint node: true */ +'use strict'; + +var path = require('path'); +var appRoot = path.join(__dirname, '../../../../'); + +/** + * Customize the name attribute in xml testcase element + * @param {Object} browser + * @param {Object} result + * @return {String} + */ +function junitNameFormatter(browser, result) { + return result.suite[0] + ': ' + result.description; +} + + +/** + * Customize the classname attribute in xml testcase element + * @param {Object} browser + * @return {String} + */ +function junitClassNameFormatter(browser) { + return "Javascript." + browser.name.split(" ")[0]; +} + + +/** + * Return array containing default and user supplied reporters + * @param {Object} config + * @return {Array} + */ +function reporters(config) { + var defaultReporters = ['dots', 'junit', 'kjhtml']; + if (config.coverage) { + defaultReporters.push('coverage'); + } + return defaultReporters; +} + + +/** + * Split a filepath into basepath and filename + * @param {String} filepath + * @return {Object} + */ +function getBasepathAndFilename(filepath) { + if (!filepath) { + // these will configure the reporters to create report files relative to this karma config file + return { + dir: undefined, + file: undefined + }; + } + + var file = filepath.replace(/^.*[\\\/]/, ''), + dir = filepath.replace(file, ''); + + return { + dir: dir, + file: file + }; +} + + +/** + * Return coverage reporter settings + * @param {String} config + * @return {Object} + */ +function coverageSettings(config) { + var path = getBasepathAndFilename(config.coveragereportpath); + return { + dir: path.dir, + subdir: '.', + reporters: [ + {type: 'cobertura', file: path.file}, + {type: 'text-summary'} + ] + }; +} + + +/** + * Return junit reporter settings + * @param {String} config + * @return {Object} + */ +function junitSettings(config) { + var path = getBasepathAndFilename(config.junitreportpath); + return { + outputDir: path.dir, + outputFile: path.file, + suite: 'javascript', + useBrowserName: false, + nameFormatter: junitNameFormatter, + classNameFormatter: junitClassNameFormatter + }; +} + +var getConfig = function (config, useRequireJs) { + useRequireJs = useRequireJs === undefined ? true : useRequireJs; + + var getFrameworkFiles = function () { + var files = [ + 'node_modules/jquery/dist/jquery.js', + 'node_modules/jasmine-core/lib/jasmine-core/jasmine.js', + 'node_modules/karma-jasmine/lib/boot.js', + 'node_modules/karma-jasmine/lib/adapter.js', + 'node_modules/jasmine-jquery/lib/jasmine-jquery.js' + ]; + + if (useRequireJs) { + files = files.concat([ + 'node_modules/requirejs/require.js', + 'node_modules/karma-requirejs/lib/adapter.js' + ]); + } + + return files; + }; + + // Manually prepends the framework files to the karma files array + // bypassing the karma's framework config. This is necessary if you want + // to add a library or framework that isn't a karma plugin. e.g. we add jasmine-jquery + // which isn't a karma plugin. Though a karma framework for jasmine-jquery is available + // but it's not actively maintained. In future we also wanna add jQuery at the top when + // we upgrade to jQuery 2 + var initFrameworks = function (files) { + getFrameworkFiles().reverse().forEach(function (f) { + files.unshift({ + pattern: path.join(appRoot, f), + included: true, + served: true, + watch: false + }); + }); + }; + + initFrameworks.$inject = ['config.files']; + + var customPlugin = { + 'framework:custom': ['factory', initFrameworks] + }; + + return { + // base path that will be used to resolve all patterns (eg. files, exclude) + basePath: '', + + // frameworks to use + // available frameworks: https://npmjs.org/browse/keyword/karma-adapter + frameworks: ['custom'], + + plugins: [ + 'karma-jasmine', + 'karma-jasmine-html-reporter', + 'karma-requirejs', + 'karma-junit-reporter', + 'karma-coverage', + 'karma-chrome-launcher', + 'karma-firefox-launcher', + customPlugin + ], + + + // list of files to exclude + exclude: [], + + // karma-reporter + reporters: reporters(config), + + + coverageReporter: coverageSettings(config), + + + junitReporter: junitSettings(config), + + + // web server port + port: 9876, + + + // enable / disable colors in the output (reporters and logs) + colors: true, + + + // level of logging + /* possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN + || config.LOG_INFO || config.LOG_DEBUG */ + logLevel: config.LOG_DEBUG, + + + // enable / disable watching file and executing tests whenever any file changes + autoWatch: false, + + + // start these browsers + // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher + browsers: ['Firefox'], + + + // Continuous Integration mode + // if true, Karma captures browsers, runs the tests and exits + singleRun: config.singleRun, + + // Concurrency level + // how many browser should be started simultaneous + concurrency: Infinity + }; +}; + +module.exports = { + getConfig: getConfig, + appRoot: appRoot +}; diff --git a/common/static/common/js/spec/main_requirejs.js b/common/static/common/js/spec/main_requirejs.js index eb8f6b0cf1..13b7349648 100644 --- a/common/static/common/js/spec/main_requirejs.js +++ b/common/static/common/js/spec/main_requirejs.js @@ -1,5 +1,6 @@ (function(requirejs, define) { requirejs.config({ + baseUrl: '/base/', paths: { 'gettext': 'js/test/i18n', 'jquery': 'js/vendor/jquery.min', @@ -27,16 +28,15 @@ 'backbone': 'js/vendor/backbone-min', 'backbone.associations': 'js/vendor/backbone-associations-min', 'backbone.paginator': 'js/vendor/backbone.paginator.min', - "backbone-super": "js/vendor/backbone-super", - 'jasmine-jquery': 'js/vendor/jasmine-jquery', + 'backbone-super': 'js/vendor/backbone-super', 'jasmine-imagediff': 'js/vendor/jasmine-imagediff', - 'jasmine-stealth': 'js/vendor/jasmine-stealth', - 'jasmine.async': 'js/vendor/jasmine.async', 'URI': 'js/vendor/URI.min', 'modernizr': 'edx-pattern-library/js/modernizr-custom', 'afontgarde': 'edx-pattern-library/js/afontgarde', 'edxicons': 'edx-pattern-library/js/edx-icons', 'draggabilly': 'js/vendor/draggabilly', + 'jasmine-stealth': 'js/libs/jasmine-stealth', + 'jasmine-waituntil': 'js/libs/jasmine-waituntil' }, shim: { 'gettext': { @@ -138,18 +138,12 @@ 'URI': { exports: 'URI' }, - 'jasmine-jquery': { - deps: ['jasmine'] - }, - 'jasmine-imagediff': { - deps: ['jasmine'] - }, + 'jasmine-imagediff': {}, 'jasmine-stealth': { - deps: ['jasmine'] + deps: ['underscore', 'underscore.string'] }, - 'jasmine.async': { - deps: ['jasmine'], - exports: 'AsyncSpec' + 'jasmine-waituntil': { + deps: ['jquery'] }, "sinon": { exports: "sinon" @@ -163,18 +157,26 @@ } }); - define([ - // Run the common tests that use RequireJS. - 'common-requirejs/include/common/js/spec/components/tabbed_view_spec.js', - 'common-requirejs/include/common/js/spec/components/feedback_spec.js', - 'common-requirejs/include/common/js/spec/components/list_spec.js', - 'common-requirejs/include/common/js/spec/components/paginated_view_spec.js', - 'common-requirejs/include/common/js/spec/components/paging_collection_spec.js', - 'common-requirejs/include/common/js/spec/components/paging_header_spec.js', - 'common-requirejs/include/common/js/spec/components/paging_footer_spec.js', - 'common-requirejs/include/common/js/spec/components/search_field_spec.js', - 'common-requirejs/include/common/js/spec/components/view_utils_spec.js', - 'common-requirejs/include/common/js/spec/utils/edx.utils.validate_spec.js' - ]); + var testFiles = [ + 'common/js/spec/components/tabbed_view_spec.js', + 'common/js/spec/components/feedback_spec.js', + 'common/js/spec/components/list_spec.js', + 'common/js/spec/components/paginated_view_spec.js', + 'common/js/spec/components/paging_collection_spec.js', + 'common/js/spec/components/paging_header_spec.js', + 'common/js/spec/components/paging_footer_spec.js', + 'common/js/spec/components/search_field_spec.js', + 'common/js/spec/components/view_utils_spec.js', + 'common/js/spec/utils/edx.utils.validate_spec.js' + ]; + + for (var i = 0; i < testFiles.length; i++) { + testFiles[i] = '/base/' + testFiles[i]; + } + + require(testFiles, function () { + // start test run, once Require.js is done + window.__karma__.start(); + }); }).call(this, requirejs, define); diff --git a/common/static/karma_common.conf.js b/common/static/karma_common.conf.js new file mode 100644 index 0000000000..aa57a78cab --- /dev/null +++ b/common/static/karma_common.conf.js @@ -0,0 +1,83 @@ +// Common JavaScript tests +// +// To run all the tests and print results to the console: +// +// karma start common/static/karma_common.conf.js +// +// +// To run the tests for debugging: Debugging can be done in any browser +// but Chrome's developer console debugging experience is best. +// +// karma start common/static/karma_common.conf.js --browsers=BROWSER --single-run=false +// +// +// To run the tests with coverage and junit reports: +// +// karma start common/static/karma_common.conf.js --browsers=BROWSER --coverage +// --junitreportpath= --coveragereportpath= +// +// where `BROWSER` could be Chrome or Firefox. +// + +/* jshint node: true */ +/*jshint -W079 */ +'use strict'; +var path = require('path'); +var _ = require('underscore'); +var configModule = require(path.join(__dirname, '../../common/static/common/js/karma.common.conf.js')); + +// Files to load by Karma +var files = [ + // override fixture path and other config. + {pattern: path.join(configModule.appRoot, 'common/static/common/js/jasmine.common.conf.js'), included: true}, + + {pattern: 'js/vendor/jquery.min.js', included: true}, + {pattern: 'js/vendor/jasmine-imagediff.js', included: true}, + {pattern: 'js/libs/jasmine-waituntil.js', included: true}, + {pattern: 'js/vendor/jquery.truncate.js', included: true}, + {pattern: 'js/vendor/mustache.js', included: true}, + {pattern: 'common/js/vendor/underscore.js', included: true}, + {pattern: 'js/vendor/underscore.string.min.js', included: true}, + {pattern: 'js/vendor/backbone-min.js', included: true}, + {pattern: 'js/vendor/jquery.timeago.js', included: true}, + {pattern: 'js/vendor/URI.min.js', included: true}, + {pattern: 'coffee/src/ajax_prefix.js', included: true}, + {pattern: 'js/test/add_ajax_prefix.js', included: true}, + {pattern: 'js/test/i18n.js', included: true}, + {pattern: 'coffee/src/jquery.immediateDescendents.js', included: true}, + + // Paths to source JavaScript files + {pattern: 'js/xblock/**/*.js', included: true, nocache: true}, + {pattern: 'coffee/src/**/*.js', included: true, nocache: true}, + {pattern: 'js/src/**/*.js', included: true, nocache: true}, + {pattern: 'js/capa/src/**/*.js', included: true, nocache: true}, + + // Paths to spec (test) JavaScript files + {pattern: 'coffee/spec/**/*.js', included: true, nocache: true}, + {pattern: 'js/spec/**/*.js', included: true, nocache: true}, + {pattern: 'js/capa/spec/**/*.js', included: true, nocache: true}, + + // Paths to fixture files + {pattern: 'js/fixtures/**/*.html', included: false, nocache: true}, + {pattern: 'js/capa/fixtures/**/*.html', included: false, nocache: true}, + {pattern: 'common/templates/**/*.underscore', included: false, nocache: true} +]; + +var preprocessors = { + // do not include tests or libraries + // (these files will be instrumented by Istanbul) + 'js/xblock/**/*.js': ['coverage'], + 'coffee/src/**/*.js': ['coverage'], + 'js/src/**/*.js': ['coverage'], + 'js/capa/src/**/*.js': ['coverage'] +}; + +module.exports = function (config) { + var commonConfig = configModule.getConfig(config, false), + localConfig = { + files: files, + preprocessors: preprocessors + }; + + config.set(_.extend(commonConfig, localConfig)); +}; diff --git a/common/static/karma_common_requirejs.conf.js b/common/static/karma_common_requirejs.conf.js new file mode 100644 index 0000000000..0e27aa8b9f --- /dev/null +++ b/common/static/karma_common_requirejs.conf.js @@ -0,0 +1,78 @@ +// Common JavaScript tests, using RequireJS. +// +// To run all the tests and print results to the console: +// +// karma start common/static/karma_common_requirejs.conf.js +// +// +// To run the tests for debugging: Debugging can be done in any browser +// but Chrome's developer console debugging experience is best. +// +// karma start karma_common_requirejs.conf.js --browsers=BROWSER --single-run=false +// +// +// To run the tests with coverage and junit reports: +// +// karma start karma_common_requirejs.conf.js --browsers=BROWSER --coverage +// --junitreportpath= --coveragereportpath= +// +// where `BROWSER` could be Chrome or Firefox. +// + +/* jshint node: true */ +/*jshint -W079 */ + +'use strict'; +var path = require('path'); +var _ = require('underscore'); +var configModule = require(path.join(__dirname, '../../common/static/common/js/karma.common.conf.js')); + +var files = [ + {pattern: 'js/vendor/jquery.min.js', included: false}, + {pattern: 'js/vendor/jasmine-imagediff.js', included: false}, + {pattern: 'js/libs/jasmine-stealth.js', included: false}, + {pattern: 'js/libs/jasmine-waituntil.js', included: false}, + {pattern: 'js/vendor/jquery.simulate.js', included: false}, + {pattern: 'js/vendor/jquery.truncate.js', included: false}, + {pattern: 'common/js/vendor/underscore.js', included: false}, + {pattern: 'js/vendor/underscore.string.min.js', included: false}, + {pattern: 'js/vendor/backbone-min.js', included: false}, + {pattern: 'js/vendor/backbone.paginator.min.js', included: false}, + {pattern: 'js/vendor/jquery.timeago.js', included: false}, + {pattern: 'js/vendor/URI.min.js', included: false}, + {pattern: 'coffee/src/ajax_prefix.js', included: false}, + {pattern: 'js/test/add_ajax_prefix.js', included: false}, + {pattern: 'js/test/i18n.js', included: false}, + {pattern: 'coffee/src/jquery.immediateDescendents.js', included: false}, + {pattern: 'js/vendor/requirejs/text.js', included: false}, + {pattern: 'js/vendor/sinon-1.17.0.js', included: false}, + + // Paths to source JavaScript files + {pattern: 'common/js/**/*.js', included: false, nocache: true}, + + // Paths to spec (test) JavaScript files + {pattern: 'common/js/spec/**/*.js', included: false, nocache: true}, + + // Paths to fixture files + {pattern: 'common/templates/**/*.*', included: false, nocache: true}, + + // override fixture path and other config. + {pattern: path.join(configModule.appRoot, 'common/static/common/js/jasmine.common.conf.js'), included: true}, + 'common/js/spec/main_requirejs.js' +]; + +var preprocessors = { + // do not include tests or libraries + // (these files will be instrumented by Istanbul) + 'common/js/**/*.js': ['coverage'] +}; + +module.exports = function (config) { + var commonConfig = configModule.getConfig(config), + localConfig = { + files: files, + preprocessors: preprocessors + }; + + config.set(_.extend(commonConfig, localConfig)); +}; diff --git a/lms/static/js/spec/main.js b/lms/static/js/spec/main.js index f25edd870b..3e7fa0e844 100644 --- a/lms/static/js/spec/main.js +++ b/lms/static/js/spec/main.js @@ -1,6 +1,8 @@ (function(requirejs, define) { // TODO: how can we share the vast majority of this config that is in common with CMS? requirejs.config({ + baseUrl: '/base/', + paths: { 'gettext': 'xmodule_js/common_static/js/test/i18n', 'codemirror': 'xmodule_js/common_static/js/vendor/CodeMirror/codemirror', @@ -43,10 +45,10 @@ 'accessibility': 'xmodule_js/common_static/js/src/accessibility_tools', 'sinon': 'xmodule_js/common_static/js/vendor/sinon-1.17.0', 'squire': 'xmodule_js/common_static/js/vendor/Squire', - 'jasmine-jquery': 'xmodule_js/common_static/js/vendor/jasmine-jquery', 'jasmine-imagediff': 'xmodule_js/common_static/js/vendor/jasmine-imagediff', 'jasmine-stealth': 'xmodule_js/common_static/js/vendor/jasmine-stealth', - 'jasmine.async': 'xmodule_js/common_static/js/vendor/jasmine.async', + 'jasmine-waituntil': 'xmodule_js/common_static/js/vendor/jasmine-waituntil', + 'draggabilly': 'xmodule_js/common_static/js/vendor/draggabilly.pkgd', 'domReady': 'xmodule_js/common_static/js/vendor/domReady', 'mathjax': '//cdn.mathjax.org/mathjax/2.6-latest/MathJax.js?config=TeX-MML-AM_SVG&delayStartupUntil=configured', // jshint ignore:line 'youtube': '//www.youtube.com/player_api?noext', @@ -256,18 +258,12 @@ 'sinon': { exports: 'sinon' }, - 'jasmine-jquery': { - deps: ['jasmine'] - }, - 'jasmine-imagediff': { - deps: ['jasmine'] - }, + 'jasmine-imagediff': {}, 'jasmine-stealth': { - deps: ['jasmine'] + deps: ['underscore', 'underscore.string'] }, - 'jasmine.async': { - deps: ['jasmine'], - exports: 'AsyncSpec' + 'jasmine-waituntil': { + deps: ['jquery'] }, 'xblock/core': { exports: 'XBlock', @@ -638,124 +634,131 @@ } }); - // TODO: why do these need 'lms/include' at the front but the CMS equivalent logic doesn't? - define([ - // Run the LMS tests - 'lms/include/js/spec/components/header/header_spec.js', - 'lms/include/js/spec/components/card/card_spec.js', - 'lms/include/js/spec/staff_debug_actions_spec.js', - 'lms/include/js/spec/views/notification_spec.js', - 'lms/include/js/spec/views/file_uploader_spec.js', - 'lms/include/js/spec/dashboard/donation.js', - 'lms/include/js/spec/dashboard/dropdown_spec.js', - 'lms/include/js/spec/dashboard/track_events_spec.js', - 'lms/include/js/spec/groups/views/cohorts_spec.js', - 'lms/include/js/spec/shoppingcart/shoppingcart_spec.js', - 'lms/include/js/spec/instructor_dashboard/ecommerce_spec.js', - 'lms/include/js/spec/instructor_dashboard/student_admin_spec.js', - 'lms/include/js/spec/instructor_dashboard/certificates_exception_spec.js', - 'lms/include/js/spec/instructor_dashboard/certificates_invalidation_spec.js', - 'lms/include/js/spec/instructor_dashboard/certificates_bulk_exception_spec.js', - 'lms/include/js/spec/instructor_dashboard/certificates_spec.js', - 'lms/include/js/spec/student_account/account_spec.js', - 'lms/include/js/spec/student_account/access_spec.js', - 'lms/include/js/spec/student_account/logistration_factory_spec.js', - 'lms/include/js/spec/student_account/finish_auth_spec.js', - 'lms/include/js/spec/student_account/hinted_login_spec.js', - 'lms/include/js/spec/student_account/login_spec.js', - 'lms/include/js/spec/student_account/institution_login_spec.js', - 'lms/include/js/spec/student_account/register_spec.js', - 'lms/include/js/spec/student_account/password_reset_spec.js', - 'lms/include/js/spec/student_account/enrollment_spec.js', - 'lms/include/js/spec/student_account/emailoptin_spec.js', - 'lms/include/js/spec/student_account/shoppingcart_spec.js', - 'lms/include/js/spec/student_account/account_settings_factory_spec.js', - 'lms/include/js/spec/student_account/account_settings_fields_spec.js', - 'lms/include/js/spec/student_account/account_settings_view_spec.js', - 'lms/include/js/spec/views/fields_spec.js', - 'lms/include/js/spec/student_profile/learner_profile_factory_spec.js', - 'lms/include/js/spec/student_profile/learner_profile_view_spec.js', - 'lms/include/js/spec/student_profile/learner_profile_fields_spec.js', - 'lms/include/js/spec/student_profile/share_modal_view_spec.js', - 'lms/include/js/spec/student_profile/badge_view_spec.js', - 'lms/include/js/spec/student_profile/section_two_tab_spec.js', - 'lms/include/js/spec/student_profile/badge_list_view_spec.js', - 'lms/include/js/spec/student_profile/badge_list_container_spec.js', - 'lms/include/js/spec/verify_student/pay_and_verify_view_spec.js', - 'lms/include/js/spec/verify_student/reverify_view_spec.js', - 'lms/include/js/spec/verify_student/webcam_photo_view_spec.js', - 'lms/include/js/spec/verify_student/image_input_spec.js', - 'lms/include/js/spec/verify_student/review_photos_step_view_spec.js', - 'lms/include/js/spec/verify_student/make_payment_step_view_spec.js', - 'lms/include/js/spec/verify_student/make_payment_step_view_ab_testing_spec.js', - 'lms/include/js/spec/edxnotes/utils/logger_spec.js', - 'lms/include/js/spec/edxnotes/views/notes_factory_spec.js', - 'lms/include/js/spec/edxnotes/views/shim_spec.js', - 'lms/include/js/spec/edxnotes/views/note_item_spec.js', - 'lms/include/js/spec/edxnotes/views/notes_page_spec.js', - 'lms/include/js/spec/edxnotes/views/search_box_spec.js', - 'lms/include/js/spec/edxnotes/views/tabs_list_spec.js', - 'lms/include/js/spec/edxnotes/views/tab_item_spec.js', - 'lms/include/js/spec/edxnotes/views/tab_view_spec.js', - 'lms/include/js/spec/edxnotes/views/tabs/search_results_spec.js', - 'lms/include/js/spec/edxnotes/views/tabs/recent_activity_spec.js', - 'lms/include/js/spec/edxnotes/views/tabs/course_structure_spec.js', - 'lms/include/js/spec/edxnotes/views/tabs/tags_spec.js', - 'lms/include/js/spec/edxnotes/views/visibility_decorator_spec.js', - 'lms/include/js/spec/edxnotes/views/notes_visibility_factory_spec.js', - 'lms/include/js/spec/edxnotes/models/tab_spec.js', - 'lms/include/js/spec/edxnotes/models/note_spec.js', - 'lms/include/js/spec/edxnotes/plugins/accessibility_spec.js', - 'lms/include/js/spec/edxnotes/plugins/events_spec.js', - 'lms/include/js/spec/edxnotes/plugins/scroller_spec.js', - 'lms/include/js/spec/edxnotes/plugins/caret_navigation_spec.js', - 'lms/include/js/spec/edxnotes/plugins/store_error_handler_spec.js', - 'lms/include/js/spec/edxnotes/collections/notes_spec.js', - 'lms/include/js/spec/search/search_spec.js', - 'lms/include/js/spec/navigation_spec.js', - 'lms/include/js/spec/courseware/updates_visibility.js', - 'lms/include/js/spec/discovery/collections/filters_spec.js', - 'lms/include/js/spec/discovery/models/course_card_spec.js', - 'lms/include/js/spec/discovery/models/course_directory_spec.js', - 'lms/include/js/spec/discovery/models/facet_option_spec.js', - 'lms/include/js/spec/discovery/models/filter_spec.js', - 'lms/include/js/spec/discovery/models/search_state_spec.js', - 'lms/include/js/spec/discovery/views/course_card_spec.js', - 'lms/include/js/spec/discovery/views/courses_listing_spec.js', - 'lms/include/js/spec/discovery/views/filter_bar_spec.js', - 'lms/include/js/spec/discovery/views/refine_sidebar_spec.js', - 'lms/include/js/spec/discovery/views/search_form_spec.js', - 'lms/include/js/spec/discovery/discovery_factory_spec.js', - 'lms/include/js/spec/ccx/schedule_spec.js', - 'lms/include/support/js/spec/collections/enrollment_spec.js', - 'lms/include/support/js/spec/models/enrollment_spec.js', - 'lms/include/support/js/spec/views/enrollment_modal_spec.js', - 'lms/include/support/js/spec/views/enrollment_spec.js', - 'lms/include/support/js/spec/views/certificates_spec.js', - 'lms/include/teams/js/spec/collections/topic_collection_spec.js', - 'lms/include/teams/js/spec/teams_tab_factory_spec.js', - 'lms/include/teams/js/spec/views/edit_team_spec.js', - 'lms/include/teams/js/spec/views/edit_team_members_spec.js', - 'lms/include/teams/js/spec/views/instructor_tools_spec.js', - 'lms/include/teams/js/spec/views/my_teams_spec.js', - 'lms/include/teams/js/spec/views/team_card_spec.js', - 'lms/include/teams/js/spec/views/team_discussion_spec.js', - 'lms/include/teams/js/spec/views/team_profile_spec.js', - 'lms/include/teams/js/spec/views/teams_spec.js', - 'lms/include/teams/js/spec/views/teams_tab_spec.js', - 'lms/include/teams/js/spec/views/topic_card_spec.js', - 'lms/include/teams/js/spec/views/topic_teams_spec.js', - 'lms/include/teams/js/spec/views/topics_spec.js', - 'lms/include/teams/js/spec/views/team_profile_header_actions_spec.js', - 'lms/include/js/spec/financial-assistance/financial_assistance_form_view_spec.js', - 'lms/include/js/spec/bookmarks/bookmarks_list_view_spec.js', - 'lms/include/js/spec/bookmarks/bookmark_button_view_spec.js', - 'lms/include/js/spec/views/message_banner_spec.js', - 'lms/include/js/spec/markdown_editor_spec.js', - 'lms/include/js/spec/learner_dashboard/collection_list_view_spec.js', - 'lms/include/js/spec/learner_dashboard/sidebar_view_spec.js', - 'lms/include/js/spec/learner_dashboard/program_card_view_spec.js', - 'lms/include/js/spec/learner_dashboard/certificate_view_spec.js' - ]); + var testFiles = [ + 'js/spec/components/header/header_spec.js', + 'js/spec/components/card/card_spec.js', + 'js/spec/staff_debug_actions_spec.js', + 'js/spec/views/notification_spec.js', + 'js/spec/views/file_uploader_spec.js', + 'js/spec/dashboard/donation.js', + 'js/spec/dashboard/dropdown_spec.js', + 'js/spec/dashboard/track_events_spec.js', + 'js/spec/groups/views/cohorts_spec.js', + 'js/spec/shoppingcart/shoppingcart_spec.js', + 'js/spec/instructor_dashboard/ecommerce_spec.js', + 'js/spec/instructor_dashboard/student_admin_spec.js', + 'js/spec/instructor_dashboard/certificates_exception_spec.js', + 'js/spec/instructor_dashboard/certificates_invalidation_spec.js', + 'js/spec/instructor_dashboard/certificates_bulk_exception_spec.js', + 'js/spec/instructor_dashboard/certificates_spec.js', + 'js/spec/student_account/account_spec.js', + 'js/spec/student_account/access_spec.js', + 'js/spec/student_account/logistration_factory_spec.js', + 'js/spec/student_account/finish_auth_spec.js', + 'js/spec/student_account/hinted_login_spec.js', + 'js/spec/student_account/login_spec.js', + 'js/spec/student_account/institution_login_spec.js', + 'js/spec/student_account/register_spec.js', + 'js/spec/student_account/password_reset_spec.js', + 'js/spec/student_account/enrollment_spec.js', + 'js/spec/student_account/emailoptin_spec.js', + 'js/spec/student_account/shoppingcart_spec.js', + 'js/spec/student_account/account_settings_factory_spec.js', + 'js/spec/student_account/account_settings_fields_spec.js', + 'js/spec/student_account/account_settings_view_spec.js', + 'js/spec/views/fields_spec.js', + 'js/spec/student_profile/learner_profile_factory_spec.js', + 'js/spec/student_profile/learner_profile_view_spec.js', + 'js/spec/student_profile/learner_profile_fields_spec.js', + 'js/spec/student_profile/share_modal_view_spec.js', + 'js/spec/student_profile/badge_view_spec.js', + 'js/spec/student_profile/section_two_tab_spec.js', + 'js/spec/student_profile/badge_list_view_spec.js', + 'js/spec/student_profile/badge_list_container_spec.js', + 'js/spec/verify_student/pay_and_verify_view_spec.js', + 'js/spec/verify_student/reverify_view_spec.js', + 'js/spec/verify_student/webcam_photo_view_spec.js', + 'js/spec/verify_student/image_input_spec.js', + 'js/spec/verify_student/review_photos_step_view_spec.js', + 'js/spec/verify_student/make_payment_step_view_spec.js', + 'js/spec/verify_student/make_payment_step_view_ab_testing_spec.js', + 'js/spec/edxnotes/utils/logger_spec.js', + 'js/spec/edxnotes/views/notes_factory_spec.js', + 'js/spec/edxnotes/views/shim_spec.js', + 'js/spec/edxnotes/views/note_item_spec.js', + 'js/spec/edxnotes/views/notes_page_spec.js', + 'js/spec/edxnotes/views/search_box_spec.js', + 'js/spec/edxnotes/views/tabs_list_spec.js', + 'js/spec/edxnotes/views/tab_item_spec.js', + 'js/spec/edxnotes/views/tab_view_spec.js', + 'js/spec/edxnotes/views/tabs/search_results_spec.js', + 'js/spec/edxnotes/views/tabs/recent_activity_spec.js', + 'js/spec/edxnotes/views/tabs/course_structure_spec.js', + 'js/spec/edxnotes/views/tabs/tags_spec.js', + 'js/spec/edxnotes/views/visibility_decorator_spec.js', + 'js/spec/edxnotes/views/notes_visibility_factory_spec.js', + 'js/spec/edxnotes/models/tab_spec.js', + 'js/spec/edxnotes/models/note_spec.js', + 'js/spec/edxnotes/plugins/accessibility_spec.js', + 'js/spec/edxnotes/plugins/events_spec.js', + 'js/spec/edxnotes/plugins/scroller_spec.js', + 'js/spec/edxnotes/plugins/caret_navigation_spec.js', + 'js/spec/edxnotes/plugins/store_error_handler_spec.js', + 'js/spec/edxnotes/collections/notes_spec.js', + 'js/spec/search/search_spec.js', + 'js/spec/navigation_spec.js', + 'js/spec/courseware/updates_visibility.js', + 'js/spec/discovery/collections/filters_spec.js', + 'js/spec/discovery/models/course_card_spec.js', + 'js/spec/discovery/models/course_directory_spec.js', + 'js/spec/discovery/models/facet_option_spec.js', + 'js/spec/discovery/models/filter_spec.js', + 'js/spec/discovery/models/search_state_spec.js', + 'js/spec/discovery/views/course_card_spec.js', + 'js/spec/discovery/views/courses_listing_spec.js', + 'js/spec/discovery/views/filter_bar_spec.js', + 'js/spec/discovery/views/refine_sidebar_spec.js', + 'js/spec/discovery/views/search_form_spec.js', + 'js/spec/discovery/discovery_factory_spec.js', + 'js/spec/ccx/schedule_spec.js', + 'support/js/spec/collections/enrollment_spec.js', + 'support/js/spec/models/enrollment_spec.js', + 'support/js/spec/views/enrollment_modal_spec.js', + 'support/js/spec/views/enrollment_spec.js', + 'support/js/spec/views/certificates_spec.js', + 'teams/js/spec/collections/topic_collection_spec.js', + 'teams/js/spec/teams_tab_factory_spec.js', + 'teams/js/spec/views/edit_team_spec.js', + 'teams/js/spec/views/edit_team_members_spec.js', + 'teams/js/spec/views/instructor_tools_spec.js', + 'teams/js/spec/views/my_teams_spec.js', + 'teams/js/spec/views/team_card_spec.js', + 'teams/js/spec/views/team_discussion_spec.js', + 'teams/js/spec/views/team_profile_spec.js', + 'teams/js/spec/views/teams_spec.js', + 'teams/js/spec/views/teams_tab_spec.js', + 'teams/js/spec/views/topic_card_spec.js', + 'teams/js/spec/views/topic_teams_spec.js', + 'teams/js/spec/views/topics_spec.js', + 'teams/js/spec/views/team_profile_header_actions_spec.js', + 'js/spec/financial-assistance/financial_assistance_form_view_spec.js', + 'js/spec/bookmarks/bookmarks_list_view_spec.js', + 'js/spec/bookmarks/bookmark_button_view_spec.js', + 'js/spec/views/message_banner_spec.js', + 'js/spec/markdown_editor_spec.js', + 'js/spec/learner_dashboard/collection_list_view_spec.js', + 'js/spec/learner_dashboard/sidebar_view_spec.js', + 'js/spec/learner_dashboard/program_card_view_spec.js', + 'js/spec/learner_dashboard/certificate_view_spec.js' + ]; + + for (var i = 0; i < testFiles.length; i++) { + testFiles[i] = '/base/' + testFiles[i]; + } + + require(testFiles, function () { + // start test run, once Require.js is done + window.__karma__.start(); + }); }).call(this, requirejs, define); diff --git a/lms/static/karma_lms.conf.js b/lms/static/karma_lms.conf.js new file mode 100644 index 0000000000..684323a9d2 --- /dev/null +++ b/lms/static/karma_lms.conf.js @@ -0,0 +1,141 @@ +// LMS JavaScript tests, using RequireJS. +// +// To run all the tests and print results to the console: +// +// karma start lms/static/karma_lms.conf.js +// +// +// To run the tests for debugging: Debugging can be done in any browser but +// Chrome's developer console debugging experience is best. +// +// karma start lms/static/karma_lms.conf.js --browsers=BROWSER --single-run=false +// +// +// To run the tests with coverage and junit reports: +// +// karma start lms/static/karma_lms.conf.js --browsers=BROWSER +// --coverage --junitreportpath= --coveragereportpath= +// +// where `BROWSER` could be Chrome or Firefox. +// + +/* jshint node: true */ +/*jshint -W079 */ +'use strict'; +var path = require('path'); +var _ = require('underscore'); +var configModule = require(path.join(__dirname, '../../common/static/common/js/karma.common.conf.js')); + +var files = [ + {pattern: 'xmodule_js/common_static/js/test/i18n.js', included: false}, + {pattern: 'xmodule_js/common_static/coffee/src/ajax_prefix.js', included: false}, + {pattern: 'xmodule_js/common_static/js/src/logger.js', included: false}, + {pattern: 'xmodule_js/common_static/js/vendor/jasmine-imagediff.js', included: false}, + {pattern: 'xmodule_js/common_static/js/vendor/requirejs/require.js', included: false}, + {pattern: 'js/RequireJS-namespace-undefine.js', included: false}, + {pattern: 'xmodule_js/common_static/js/vendor/requirejs/text.js', included: false}, + {pattern: 'xmodule_js/common_static/js/vendor/jquery.min.js', included: false}, + {pattern: 'xmodule_js/common_static/js/vendor/jquery-ui.min.js', included: false}, + {pattern: 'xmodule_js/common_static/js/vendor/jquery.simulate.js', included: false}, + {pattern: 'xmodule_js/common_static/js/vendor/jquery.cookie.js', included: false}, + {pattern: 'xmodule_js/common_static/js/vendor/jquery.timeago.js', included: false}, + {pattern: 'xmodule_js/common_static/js/vendor/flot/jquery.flot.js', included: false}, + {pattern: 'xmodule_js/common_static/js/vendor/CodeMirror/codemirror.js', included: false}, + {pattern: 'xmodule_js/common_static/js/vendor/URI.min.js', included: false}, + { + pattern: 'xmodule_js/common_static/js/vendor/jQuery-File-Upload/js/jquery.fileupload.js', + included: false + }, + { + pattern: 'xmodule_js/common_static/js/vendor/jQuery-File-Upload/js/jquery.iframe-transport.js', + included: false + }, + {pattern: 'xmodule_js/common_static/js/vendor/url.min.js', included: false}, + {pattern: 'xmodule_js/common_static/coffee/src/jquery.immediateDescendents.js', included: false}, + {pattern: 'xmodule_js/common_static/js/xblock/**/*.js', included: false}, + {pattern: 'xmodule_js/common_static/coffee/src/xblock/**/*.js', included: false}, + {pattern: 'coffee/src/instructor_dashboard/**/*.js', included: false}, + {pattern: 'xmodule_js/common_static/js/vendor/sinon-1.17.0.js', included: false}, + {pattern: 'xmodule_js/src/capa/**/*.js', included: false}, + {pattern: 'xmodule_js/src/video/**/*.js', included: false}, + {pattern: 'xmodule_js/src/xmodule.js', included: false}, + {pattern: 'xmodule_js/common_static/js/src/**/*.js', included: false}, + {pattern: 'xmodule_js/common_static/common/js/vendor/underscore.js', included: false}, + {pattern: 'xmodule_js/common_static/js/vendor/underscore.string.min.js', included: false}, + {pattern: 'xmodule_js/common_static/js/vendor/backbone-min.js', included: false}, + {pattern: 'xmodule_js/common_static/js/vendor/backbone.paginator.min.js', included: false}, + {pattern: 'xmodule_js/common_static/js/vendor/edxnotes/annotator-full.min.js', included: false}, + {pattern: 'xmodule_js/common_static/js/test/i18n.js', included: false}, + {pattern: 'xmodule_js/common_static/js/vendor/date.js', included: false}, + {pattern: 'xmodule_js/common_static/js/vendor/moment.min.js', included: false}, + {pattern: 'xmodule_js/common_static/js/vendor/moment-with-locales.min.js', included: false}, + {pattern: 'xmodule_js/common_static/common/js/utils/edx.utils.validate.js', included: false}, + {pattern: 'xmodule_js/common_static/js/vendor/slick.core.js', included: false}, + {pattern: 'xmodule_js/common_static/js/vendor/slick.grid.js', included: false}, + {pattern: 'xmodule_js/common_static/js/vendor/jquery.event.drag-2.2.js', included: false}, + {pattern: 'xmodule_js/common_static/js/libs/jasmine-waituntil.js', included: true}, + + // Paths to source JavaScript files + {pattern: 'js/**/*.js', included: false, nocache: true}, + {pattern: 'coffee/src/**/*.js', included: false, nocache: true}, + {pattern: 'common/js/**/*.js', included: false, nocache: true}, + {pattern: 'edx-pattern-library/js/**/*.js', included: false, nocache: true}, + {pattern: 'edx-ui-toolkit/js/**/*.js', included: false, nocache: true}, + {pattern: 'support/js/**/*.js', included: false, nocache: true}, + {pattern: 'teams/js/**/*.js', included: false, nocache: true}, + {pattern: 'xmodule_js/common_static/coffee/**/*.js', included: false, nocache: true}, + + // Paths to spec (test) JavaScript files + {pattern: 'js/spec/**/*.js', included: false, nocache: true}, + {pattern: 'teams/js/spec/**/*.js', included: false, nocache: true}, + {pattern: 'support/js/spec/**/*.js', included: false, nocache: true}, + + // Paths to fixture files + {pattern: 'js/fixtures/**/*.html', included: false, nocache: true}, + {pattern: 'templates/instructor/instructor_dashboard_2/**/*.*', included: false, nocache: true}, + {pattern: 'templates/dashboard/**/*.*', included: false, nocache: true}, + {pattern: 'templates/edxnotes/**/*.*', included: false, nocache: true}, + {pattern: 'templates/fields/**/*.*', included: false, nocache: true}, + {pattern: 'templates/student_account/**/*.*', included: false, nocache: true}, + {pattern: 'templates/student_profile/**/*.*', included: false, nocache: true}, + {pattern: 'templates/verify_student/**/*.*', included: false, nocache: true}, + {pattern: 'templates/file-upload.underscore', included: false, nocache: true}, + {pattern: 'templates/components/header/**/*.*', included: false, nocache: true}, + {pattern: 'templates/components/tabbed/**/*.*', included: false, nocache: true}, + {pattern: 'templates/components/card/**/*.*', included: false, nocache: true}, + {pattern: 'templates/financial-assistance/**/*.*', included: false, nocache: true}, + {pattern: 'templates/search/**/*.*', included: false, nocache: true}, + {pattern: 'templates/discovery/**/*.*', included: false, nocache: true}, + {pattern: 'common/templates/**/*.*', included: false, nocache: true}, + {pattern: 'teams/templates/**/*.*', included: false, nocache: true}, + {pattern: 'support/templates/**/*.*', included: false, nocache: true}, + {pattern: 'templates/bookmarks/**/*.*', included: false, nocache: true}, + {pattern: 'templates/learner_dashboard/**/*.*', included: false, nocache: true}, + {pattern: 'templates/ccx/**/*.*', included: false, nocache: true}, + + // override fixture path and other config. + {pattern: path.join(configModule.appRoot, 'common/static/common/js/jasmine.common.conf.js'), included: true}, + {pattern: 'js/spec/main.js', included: true} +]; + +var preprocessors = { + // do not include tests or libraries + // (these files will be instrumented by Istanbul) + 'js/**/*.js': ['coverage'], + 'coffee/src/**/*.js': ['coverage'], + 'common/js/**/*.js': ['coverage'], + 'support/js/**/*.js': ['coverage'], + 'teams/js/**/*.js': ['coverage'], + 'xmodule_js/common_static/coffee/**/*.js': ['coverage'] +}; + +module.exports = function (config) { + var commonConfig = configModule.getConfig(config), + localConfig = { + files: files, + preprocessors: preprocessors + }; + + config.set(_.extend(commonConfig, localConfig)); +}; + diff --git a/lms/static/karma_lms_coffee.conf.js b/lms/static/karma_lms_coffee.conf.js new file mode 100644 index 0000000000..410477b532 --- /dev/null +++ b/lms/static/karma_lms_coffee.conf.js @@ -0,0 +1,82 @@ +// LMS Coffee Script Tests. +// +// To run all the tests and print results to the console: +// +// karma start lms/static/karma_lms_coffee.conf.js +// +// +// To run the tests for debugging: Debugging can be done in any browser +// but Chrome's developer console debugging experience is best. +// +// karma start lms/static/karma_lms_coffee.conf.js --browsers=BROWSER --single-run=false +// +// +// To run the tests with coverage and junit reports: +// +// karma start lms/static/karma_lms_coffee.conf.js --browsers=BROWSER +// --coverage --junitreportpath= --coveragereportpath= +// +// where `BROWSER` could be Chrome or Firefox. +// + +/* jshint node: true */ +/*jshint -W079 */ + +'use strict'; +var path = require('path'); +var _ = require('underscore'); +var configModule = require(path.join(__dirname, '../../common/static/common/js/karma.common.conf.js')); + +var files = [ + // override fixture path and other config. + {pattern: path.join(configModule.appRoot, 'common/static/common/js/jasmine.common.conf.js'), included: true}, + + // vendor files + {pattern: 'xmodule_js/common_static/js/vendor/jquery.min.js', included: true}, + {pattern: 'xmodule_js/common_static/js/test/i18n.js', included: true}, + {pattern: 'xmodule_js/common_static/coffee/src/ajax_prefix.js', included: true}, + {pattern: 'xmodule_js/common_static/js/src/logger.js', included: true}, + {pattern: 'xmodule_js/common_static/common/js/vendor/underscore.js', included: true}, + {pattern: 'xmodule_js/common_static/js/vendor/jasmine-imagediff.js', included: true}, + {pattern: 'xmodule_js/common_static/js/vendor/requirejs/require.js', included: true}, + {pattern: 'js/RequireJS-namespace-undefine.js', included: true}, + {pattern: 'xmodule_js/common_static/js/vendor/jquery-ui.min.js', included: true}, + {pattern: 'xmodule_js/common_static/js/vendor/jquery.cookie.js', included: true}, + {pattern: 'xmodule_js/common_static/js/vendor/flot/jquery.flot.js', included: true}, + {pattern: 'xmodule_js/common_static/js/vendor/moment.min.js', included: true}, + {pattern: 'xmodule_js/common_static/js/vendor/moment-with-locales.min.js', included: true}, + {pattern: 'xmodule_js/common_static/js/vendor/CodeMirror/codemirror.js', included: true}, + {pattern: 'xmodule_js/common_static/js/vendor/URI.min.js', included: true}, + {pattern: 'xmodule_js/common_static/coffee/src/jquery.immediateDescendents.js', included: true}, + {pattern: 'xmodule_js/common_static/js/xblock/*.js', included: true}, + {pattern: 'xmodule_js/common_static/coffee/src/xblock/*.js', included: true}, + {pattern: 'moment_requirejs.js', included: true}, + {pattern: 'xmodule_js/src/capa/*.js', included: true}, + {pattern: 'xmodule_js/src/video/*.js', included: true}, + {pattern: 'xmodule_js/src/xmodule.js', included: true}, + + // source files + {pattern: 'coffee/src/**/*.js', included: true, nocache: true}, + + // spec files + {pattern: 'coffee/spec/**/*.js', included: true, nocache: true}, + + // Fixtures + {pattern: 'coffee/fixtures/**/*.*', included: true, nocache: true} +]; + +var preprocessors = { + // do not include tests or libraries + // (these files will be instrumented by Istanbul) + 'coffee/src/**/*.js': ['coverage'] +}; + +module.exports = function (config) { + var commonConfig = configModule.getConfig(config, false), + localConfig = { + files: files, + preprocessors: preprocessors + }; + + config.set(_.extend(commonConfig, localConfig)); +}; diff --git a/lms/static/moment_requirejs.js b/lms/static/moment_requirejs.js new file mode 100644 index 0000000000..745cd0b5c1 --- /dev/null +++ b/lms/static/moment_requirejs.js @@ -0,0 +1,15 @@ +(function(requirejs) { + 'use strict'; + + requirejs.config({ + paths: { + "moment": "/base/xmodule_js/common_static/js/vendor/moment.min" + }, + shim:{ + "moment": { + exports: "moment" + } + } + }); + +}).call(this, RequireJS.requirejs); diff --git a/package.json b/package.json index 27ed640abd..2e16022920 100644 --- a/package.json +++ b/package.json @@ -12,10 +12,21 @@ "picturefill": "~3.0.2" }, "devDependencies": { - "jshint": "^2.7.0", "edx-custom-a11y-rules": "edx/edx-custom-a11y-rules", "pa11y": "3.6.0", "pa11y-reporter-1.0-json": "1.0.2", + "jasmine-core": "^2.4.1", + "jasmine-jquery": "^2.1.1", + "jquery": "^2.1.4", + "jshint": "^2.7.0", + "karma": "^0.13.22", + "karma-chrome-launcher": "^0.2.3", + "karma-coverage": "^0.5.5", + "karma-firefox-launcher": "^0.1.7", + "karma-jasmine": "^0.3.8", + "karma-jasmine-html-reporter": "^0.2.0", + "karma-junit-reporter": "^0.4.1", + "karma-requirejs": "^0.2.6", "plato": "1.2.2" } } diff --git a/pavelib/paver_tests/test_js_test.py b/pavelib/paver_tests/test_js_test.py index b14752574c..8689776908 100644 --- a/pavelib/paver_tests/test_js_test.py +++ b/pavelib/paver_tests/test_js_test.py @@ -6,6 +6,7 @@ from paver.easy import call_task import pavelib.js_test from .utils import PaverTestCase +from pavelib.utils.envs import Env @ddt.ddt @@ -20,21 +21,15 @@ class TestPaverJavaScriptTestTasks(PaverTestCase): u'node_modules/.bin/coffee --compile `find {platform_root}/lms {platform_root}/cms ' u'{platform_root}/common -type f -name "*.coffee"`' ) - EXPECTED_JS_TEST_TOOL_OPTIONS = ( - u"{platform_root}/lms/static/js_test.yml " - u"{platform_root}/lms/static/js_test_coffee.yml " - u"{platform_root}/cms/static/js_test.yml " - u"{platform_root}/cms/static/js_test_squire.yml " - u"{platform_root}/common/lib/xmodule/xmodule/js/js_test.yml " - u"{platform_root}/common/static/js_test.yml " - u"{platform_root}/common/static/js_test_requirejs.yml " - u"--use-firefox " - u"--timeout-sec 600 " - u"--xunit-report " - u"{platform_root}/reports/javascript/javascript_xunit.xml" + EXPECTED_KARMA_OPTIONS = ( + u"{config_file} " + u"--single-run={single_run} " + u"--capture-timeout=60000 " + u"--junitreportpath=" + u"{platform_root}/reports/javascript/javascript_xunit-{suite}.xml" ) EXPECTED_COVERAGE_OPTIONS = ( - u' --coverage-xml {platform_root}/reports/javascript/coverage.xml' + u' --coverage --coveragereportpath={platform_root}/reports/javascript/coverage-{suite}.xml' ) EXPECTED_COMMANDS = [ @@ -115,6 +110,8 @@ class TestPaverJavaScriptTestTasks(PaverTestCase): is_coverage = options['coverage'] port = options['port'] expected_messages = [] + suites = Env.JS_TEST_ID_KEYS if options['suite'] == 'all' else [options['suite']] + expected_messages.extend(self.EXPECTED_COMMANDS) if not dev_mode and not is_coverage: expected_messages.append(self.EXPECTED_DELETE_JAVASCRIPT_REPORT_COMMAND.format( @@ -122,13 +119,25 @@ class TestPaverJavaScriptTestTasks(PaverTestCase): )) expected_messages.append(self.EXPECTED_INSTALL_NPM_ASSETS_COMMAND) expected_messages.append(self.EXPECTED_COFFEE_COMMAND.format(platform_root=self.platform_root)) - expected_test_tool_command = u'js-test-tool {command} {options}'.format( - command='dev' if dev_mode else 'run', - options=self.EXPECTED_JS_TEST_TOOL_OPTIONS.format(platform_root=self.platform_root), - ) - if is_coverage: - expected_test_tool_command += self.EXPECTED_COVERAGE_OPTIONS.format(platform_root=self.platform_root) - if port: - expected_test_tool_command += u" -p {port}".format(port=port) - expected_messages.append(expected_test_tool_command) + + for suite in suites: + # Karma test command + karma_config_file = Env.KARMA_CONFIG_FILES[Env.JS_TEST_ID_KEYS.index(suite)] + expected_test_tool_command = u'karma start {options}'.format( + options=self.EXPECTED_KARMA_OPTIONS.format( + config_file=karma_config_file, + single_run='false' if dev_mode else 'true', + suite=suite, + platform_root=self.platform_root, + ), + ) + if is_coverage: + expected_test_tool_command += self.EXPECTED_COVERAGE_OPTIONS.format( + platform_root=self.platform_root, + suite=suite + ) + if port: + expected_test_tool_command += u" --port {port}".format(port=port) + expected_messages.append(expected_test_tool_command) + self.assertEquals(self.task_messages, expected_messages) diff --git a/pavelib/tests.py b/pavelib/tests.py index 9bce602df4..61ca58f5f0 100644 --- a/pavelib/tests.py +++ b/pavelib/tests.py @@ -1,6 +1,7 @@ """ Unit test tasks """ +import re import os import sys from paver.easy import sh, task, cmdopts, needs, call_task @@ -250,7 +251,7 @@ def diff_coverage(options): xml_reports = [] for filepath in Env.REPORT_DIR.walk(): - if filepath.basename() == 'coverage.xml': + if bool(re.match(r'^coverage.*\.xml$', filepath.basename())): xml_reports.append(filepath) if not xml_reports: diff --git a/pavelib/utils/envs.py b/pavelib/utils/envs.py index a47dca9321..1d0e2d5640 100644 --- a/pavelib/utils/envs.py +++ b/pavelib/utils/envs.py @@ -119,14 +119,14 @@ class Env(object): # Files used to run each of the js test suites # TODO: Store this as a dict. Order seems to matter for some # reason. See issue TE-415. - JS_TEST_ID_FILES = [ - REPO_ROOT / 'lms/static/js_test.yml', - REPO_ROOT / 'lms/static/js_test_coffee.yml', - REPO_ROOT / 'cms/static/js_test.yml', - REPO_ROOT / 'cms/static/js_test_squire.yml', - REPO_ROOT / 'common/lib/xmodule/xmodule/js/js_test.yml', - REPO_ROOT / 'common/static/js_test.yml', - REPO_ROOT / 'common/static/js_test_requirejs.yml', + KARMA_CONFIG_FILES = [ + REPO_ROOT / 'lms/static/karma_lms.conf.js', + REPO_ROOT / 'lms/static/karma_lms_coffee.conf.js', + REPO_ROOT / 'cms/static/karma_cms.conf.js', + REPO_ROOT / 'cms/static/karma_cms_squire.conf.js', + REPO_ROOT / 'common/lib/xmodule/xmodule/js/karma_xmodule.conf.js', + REPO_ROOT / 'common/static/karma_common.conf.js', + REPO_ROOT / 'common/static/karma_common_requirejs.conf.js', ] JS_TEST_ID_KEYS = [ diff --git a/pavelib/utils/test/suites/js_suite.py b/pavelib/utils/test/suites/js_suite.py index 6aa5b16096..6d810c4ca6 100644 --- a/pavelib/utils/test/suites/js_suite.py +++ b/pavelib/utils/test/suites/js_suite.py @@ -20,17 +20,11 @@ class JsTestSuite(TestSuite): super(JsTestSuite, self).__init__(*args, **kwargs) self.run_under_coverage = kwargs.get('with_coverage', True) self.mode = kwargs.get('mode', 'run') - self.port = kwargs.get('port') - - try: - self.test_id = (Env.JS_TEST_ID_FILES[Env.JS_TEST_ID_KEYS.index(self.root)]) - except ValueError: - self.test_id = ' '.join(Env.JS_TEST_ID_FILES) - - self.root = self.root + ' javascript' self.report_dir = Env.JS_REPORT_DIR - self.coverage_report = self.report_dir / 'coverage.xml' - self.xunit_report = self.report_dir / 'javascript_xunit.xml' + self.opts = kwargs + + suite = args[0] + self.subsuites = self._default_subsuites if suite == 'all' else [JsTestSubSuite(*args, **kwargs)] def __enter__(self): super(JsTestSuite, self).__enter__() @@ -47,27 +41,56 @@ class JsTestSuite(TestSuite): assets.process_npm_assets() assets.compile_coffeescript("`find lms cms common -type f -name \"*.coffee\"`") + @property + def _default_subsuites(self): + """ + Returns all JS test suites + """ + return [JsTestSubSuite(test_id, **self.opts) for test_id in Env.JS_TEST_ID_KEYS] + + +class JsTestSubSuite(TestSuite): + """ + Class for JS suites like cms, cms-squire, lms, lms-coffee, common, + common-requirejs and xmodule + """ + def __init__(self, *args, **kwargs): + super(JsTestSubSuite, self).__init__(*args, **kwargs) + self.test_id = args[0] + self.run_under_coverage = kwargs.get('with_coverage', True) + self.mode = kwargs.get('mode', 'run') + self.port = kwargs.get('port') + self.root = self.root + ' javascript' + self.report_dir = Env.JS_REPORT_DIR + + try: + self.test_conf_file = Env.KARMA_CONFIG_FILES[Env.JS_TEST_ID_KEYS.index(self.test_id)] + except ValueError: + self.test_conf_file = Env.KARMA_CONFIG_FILES[0] + + self.coverage_report = self.report_dir / 'coverage-{suite}.xml'.format(suite=self.test_id) + self.xunit_report = self.report_dir / 'javascript_xunit-{suite}.xml'.format(suite=self.test_id) + @property def cmd(self): """ - Run the tests using js-test-tool. See js-test-tool docs for - description of different command line arguments. + Run the tests using karma runner. """ cmd = ( - "js-test-tool {mode} {test_id} --use-firefox --timeout-sec " - "600 --xunit-report {xunit_report}".format( - mode=self.mode, - test_id=self.test_id, + "karma start {test_conf_file} --single-run={single_run} --capture-timeout=60000 " + "--junitreportpath={xunit_report}".format( + single_run='false' if self.mode == 'dev' else 'true', + test_conf_file=self.test_conf_file, xunit_report=self.xunit_report, ) ) if self.port: - cmd += " -p {port}".format(port=self.port) + cmd += " --port {port}".format(port=self.port) if self.run_under_coverage: - cmd += " --coverage-xml {report_dir}".format( - report_dir=self.coverage_report + cmd += " --coverage --coveragereportpath={report_path}".format( + report_path=self.coverage_report ) return cmd diff --git a/requirements/edx/github.txt b/requirements/edx/github.txt index 08ea160be1..8c27b921b6 100644 --- a/requirements/edx/github.txt +++ b/requirements/edx/github.txt @@ -72,7 +72,6 @@ git+https://github.com/edx/pa11ycrawler.git@0.0.1#egg=pa11ycrawler # Our libraries: git+https://github.com/edx/XBlock.git@xblock-0.4.8#egg=XBlock==0.4.8 -e git+https://github.com/edx/codejail.git@6b17c33a89bef0ac510926b1d7fea2748b73aadd#egg=codejail --e git+https://github.com/edx/js-test-tool.git@v0.1.6#egg=js_test_tool -e git+https://github.com/edx/event-tracking.git@0.2.1#egg=event-tracking==0.2.1 -e git+https://github.com/edx/django-splash.git@v0.2#egg=django-splash==0.2 -e git+https://github.com/edx/acid-block.git@e46f9cda8a03e121a00c7e347084d142d22ebfb7#egg=acid-xblock