diff --git a/common/test/acceptance/tests/lms/test_lms_courseware.py b/common/test/acceptance/tests/lms/test_lms_courseware.py
index 33dd35f9bd..9e0e43240b 100644
--- a/common/test/acceptance/tests/lms/test_lms_courseware.py
+++ b/common/test/acceptance/tests/lms/test_lms_courseware.py
@@ -507,15 +507,14 @@ class CoursewareMultipleVerticalsTest(UniqueCourseTest, EventsTestMixin):
sequence_ui_events
)
- def test_accordion_events(self):
+ def test_outline_selected_events(self):
self.course_nav.go_to_section('Test Section 1', 'Test Subsection 1,2')
self.course_nav.go_to_section('Test Section 2', 'Test Subsection 2,1')
# test UI events emitted by navigating via the course outline
- filter_outline_ui_event = lambda event: event.get('name', '') == 'edx.ui.lms.outline.selected'
-
- outline_ui_events = self.wait_for_events(event_filter=filter_outline_ui_event, timeout=2)
+ filter_selected_events = lambda event: event.get('name', '') == 'edx.ui.lms.outline.selected'
+ selected_events = self.wait_for_events(event_filter=filter_selected_events, timeout=2)
# note: target_url is tested in unit tests, as the url changes here with every test (it includes GUIDs).
self.assert_events_match(
@@ -534,12 +533,26 @@ class CoursewareMultipleVerticalsTest(UniqueCourseTest, EventsTestMixin):
'event': {
'target_name': 'Test Subsection 2,1 ',
'widget_placement': 'accordion',
+
}
},
],
- outline_ui_events
+ selected_events
)
+ def test_link_clicked_events(self):
+ """
+ Given that I am a user in the courseware
+ When I navigate via the left-hand nav
+ Then a link clicked event is logged
+ """
+ self.course_nav.go_to_section('Test Section 1', 'Test Subsection 1,2')
+ self.course_nav.go_to_section('Test Section 2', 'Test Subsection 2,1')
+
+ filter_link_clicked = lambda event: event.get('name', '') == 'edx.ui.lms.link_clicked'
+ link_clicked_events = self.wait_for_events(event_filter=filter_link_clicked, timeout=2)
+ self.assertEqual(len(link_clicked_events), 2)
+
def assert_navigation_state(
self, section_title, subsection_title, subsection_position, next_enabled, prev_enabled
):
diff --git a/lms/envs/common.py b/lms/envs/common.py
index 208475768f..9aab836eb9 100644
--- a/lms/envs/common.py
+++ b/lms/envs/common.py
@@ -1672,10 +1672,11 @@ REQUIRE_JS_PATH_OVERRIDES = {
'jquery.url': 'js/vendor/url.min.js',
'js/courseware/course_home_events': 'js/courseware/course_home_events.js',
'js/courseware/accordion_events': 'js/courseware/accordion_events.js',
+ 'js/courseware/link_clicked_events': 'js/courseware/link_clicked_events.js',
'js/courseware/toggle_element_visibility': 'js/courseware/toggle_element_visibility.js',
'js/student_account/logistration_factory': 'js/student_account/logistration_factory.js',
'js/student_profile/views/learner_profile_factory': 'js/student_profile/views/learner_profile_factory.js',
- 'js/bookmarks/bookmarks_factory': 'js/bookmarks/bookmarks_factory.js',
+ 'js/courseware/courseware_factory': 'js/courseware/courseware_factory.js',
'js/groups/views/cohorts_dashboard_factory': 'js/groups/views/cohorts_dashboard_factory.js',
'afontgarde': 'edx-pattern-library/js/afontgarde.js',
'edxicons': 'edx-pattern-library/js/edx-icons.js',
diff --git a/lms/static/js/bookmarks/bookmarks_factory.js b/lms/static/js/bookmarks/bookmarks_factory.js
deleted file mode 100644
index d8f444b26c..0000000000
--- a/lms/static/js/bookmarks/bookmarks_factory.js
+++ /dev/null
@@ -1,12 +0,0 @@
-;(function (define) {
- 'use strict';
- define([
- 'js/bookmarks/views/bookmarks_list_button'
- ],
- function(BookmarksListButton) {
- return function() {
- return new BookmarksListButton();
- };
- }
- );
-}).call(this, define || RequireJS.define);
diff --git a/lms/static/js/courseware/courseware_factory.js b/lms/static/js/courseware/courseware_factory.js
new file mode 100644
index 0000000000..d45d87d367
--- /dev/null
+++ b/lms/static/js/courseware/courseware_factory.js
@@ -0,0 +1,27 @@
+;(function (define) {
+ 'use strict';
+
+ define([
+ 'jquery',
+ 'logger',
+ 'js/bookmarks/views/bookmarks_list_button'
+ ],
+ function($, Logger, BookmarksListButton) {
+ return function() {
+ // This function performs all actions common to all courseware.
+ // 1. adding an event to all link clicks.
+ $('a:not([href^="#"])').click(function(event) {
+ Logger.log(
+ "edx.ui.lms.link_clicked",
+ {
+ current_url: window.location.href,
+ target_url: event.currentTarget.href
+ });
+ });
+
+ // 2. instantiating this button attaches events to all buttons in the courseware.
+ new BookmarksListButton(); // jshint ignore:line
+ };
+ }
+ );
+}).call(this, define || RequireJS.define);
diff --git a/lms/static/js/fixtures/courseware/link_clicked_events.html b/lms/static/js/fixtures/courseware/link_clicked_events.html
new file mode 100644
index 0000000000..b5aaf67e16
--- /dev/null
+++ b/lms/static/js/fixtures/courseware/link_clicked_events.html
@@ -0,0 +1,3 @@
+
+
+
diff --git a/lms/static/js/spec/bookmarks/bookmark_button_view_spec.js b/lms/static/js/spec/courseware/bookmark_button_view_spec.js
similarity index 100%
rename from lms/static/js/spec/bookmarks/bookmark_button_view_spec.js
rename to lms/static/js/spec/courseware/bookmark_button_view_spec.js
diff --git a/lms/static/js/spec/bookmarks/bookmarks_list_view_spec.js b/lms/static/js/spec/courseware/bookmarks_list_view_spec.js
similarity index 100%
rename from lms/static/js/spec/bookmarks/bookmarks_list_view_spec.js
rename to lms/static/js/spec/courseware/bookmarks_list_view_spec.js
diff --git a/lms/static/js/spec/courseware/course_home_events.js b/lms/static/js/spec/courseware/course_home_events_spec.js
similarity index 83%
rename from lms/static/js/spec/courseware/course_home_events.js
rename to lms/static/js/spec/courseware/course_home_events_spec.js
index 64eac2e901..6702577627 100644
--- a/lms/static/js/spec/courseware/course_home_events.js
+++ b/lms/static/js/spec/courseware/course_home_events_spec.js
@@ -11,7 +11,9 @@ define(['jquery', 'logger', 'js/courseware/course_home_events'], function ($, Lo
it('sends an event when "Resume Course" is clicked', function () {
$('.last-accessed-link').click();
expect(Logger.log).toHaveBeenCalledWith('edx.course.home.resume_course.clicked', {
- url: "/courses/course-v1:edX+DemoX+Demo_Course/courseware/19a30717eff543078a5d94ae9d6c18a5/"
+ url: "http://" +
+ window.location.host +
+ "/courses/course-v1:edX+DemoX+Demo_Course/courseware/19a30717eff543078a5d94ae9d6c18a5/"
});
});
diff --git a/lms/static/js/spec/courseware/link_clicked_events_spec.js b/lms/static/js/spec/courseware/link_clicked_events_spec.js
new file mode 100644
index 0000000000..bec1181d5c
--- /dev/null
+++ b/lms/static/js/spec/courseware/link_clicked_events_spec.js
@@ -0,0 +1,32 @@
+define(['jquery', 'logger', 'js/courseware/courseware_factory'], function ($, Logger, coursewareFactory) {
+ 'use strict';
+
+ describe('Courseware link click eventing', function () {
+ beforeEach(function () {
+ loadFixtures('js/fixtures/courseware/link_clicked_events.html');
+ coursewareFactory();
+ spyOn(Logger, 'log');
+ });
+
+ it('sends an event when an external link is clicked', function () {
+ $('.external-link').click();
+ expect(Logger.log).toHaveBeenCalledWith('edx.ui.lms.link_clicked', {
+ target_url: "http://example.com/",
+ current_url: "http://" + window.location.host + "/context.html"
+ });
+ });
+
+ it('sends an event when an internal link is clicked', function () {
+ $('.internal-link').click();
+ expect(Logger.log).toHaveBeenCalledWith('edx.ui.lms.link_clicked', {
+ target_url: "http://" + window.location.host + "/some/internal/link",
+ current_url: "http://" + window.location.host + "/context.html"
+ });
+ });
+
+ it('does not send an event when a page navigation link is clicked', function () {
+ $('.page-nav').click();
+ expect(Logger.log).not.toHaveBeenCalledWith('edx.ui.lms.link_clicked');
+ });
+ });
+});
diff --git a/lms/static/js/spec/courseware/updates_visibility.js b/lms/static/js/spec/courseware/updates_visibility_spec.js
similarity index 100%
rename from lms/static/js/spec/courseware/updates_visibility.js
rename to lms/static/js/spec/courseware/updates_visibility_spec.js
diff --git a/lms/static/js/spec/main.js b/lms/static/js/spec/main.js
index ee455085fc..2fc72c9332 100644
--- a/lms/static/js/spec/main.js
+++ b/lms/static/js/spec/main.js
@@ -92,7 +92,7 @@
// Discussion classes loaded explicitly until they are converted to use RequireJS
'DiscussionModuleView': 'xmodule_js/common_static/coffee/src/discussion/discussion_module_view',
-
+
'js/bookmarks/collections/bookmarks': 'js/bookmarks/collections/bookmarks',
'js/bookmarks/models/bookmark': 'js/bookmarks/models/bookmark',
'js/bookmarks/views/bookmarks_list_button': 'js/bookmarks/views/bookmarks_list_button',
@@ -655,13 +655,15 @@
var testFiles = [
'js/spec/api_admin/catalog_preview_spec.js',
- 'js/spec/bookmarks/bookmark_button_view_spec.js',
- 'js/spec/bookmarks/bookmarks_list_view_spec.js',
+ 'js/spec/courseware/bookmark_button_view_spec.js',
+ 'js/spec/courseware/bookmarks_list_view_spec.js',
'js/spec/ccx/schedule_spec.js',
'js/spec/commerce/receipt_view_spec.js',
'js/spec/components/card/card_spec.js',
'js/spec/components/header/header_spec.js',
- 'js/spec/courseware/updates_visibility.js',
+ 'js/spec/courseware/course_home_events_spec.js',
+ 'js/spec/courseware/link_clicked_events_spec.js',
+ 'js/spec/courseware/updates_visibility_spec.js',
'js/spec/dashboard/donation.js',
'js/spec/dashboard/dropdown_spec.js',
'js/spec/dashboard/track_events_spec.js',
diff --git a/lms/static/lms/js/build.js b/lms/static/lms/js/build.js
index 1135da85e1..2412b0312e 100644
--- a/lms/static/lms/js/build.js
+++ b/lms/static/lms/js/build.js
@@ -34,7 +34,7 @@
'teams/js/teams_tab_factory',
'support/js/certificates_factory',
'support/js/enrollment_factory',
- 'js/bookmarks/bookmarks_factory',
+ 'js/courseware/courseware_factory',
'js/learner_dashboard/program_details_factory',
'js/learner_dashboard/program_list_factory',
'js/api_admin/catalog_preview_factory'
diff --git a/lms/templates/courseware/courseware.html b/lms/templates/courseware/courseware.html
index 5ac6ec893f..a5a9d525c3 100644
--- a/lms/templates/courseware/courseware.html
+++ b/lms/templates/courseware/courseware.html
@@ -80,8 +80,8 @@ ${static.get_page_title_breadcrumbs(course_name())}
%static:require_module>
% endif
- <%static:require_module module_name="js/bookmarks/bookmarks_factory" class_name="BookmarksFactory">
- BookmarksFactory();
+ <%static:require_module module_name="js/courseware/courseware_factory" class_name="CoursewareFactory">
+ CoursewareFactory();
%static:require_module>
<%include file="../discussion/_js_body_dependencies.html" />