diff options
-rw-r--r-- | .DS_Store | bin | 0 -> 6148 bytes | |||
-rw-r--r-- | .idea/.gitignore | 5 | ||||
-rw-r--r-- | .idea/ABtesting.iml | 12 | ||||
-rw-r--r-- | .idea/modules.xml | 8 | ||||
-rw-r--r-- | .idea/vcs.xml | 6 | ||||
-rw-r--r-- | b.html | 3 | ||||
-rw-r--r-- | record.js | 90 |
7 files changed, 107 insertions, 17 deletions
diff --git a/.DS_Store b/.DS_Store Binary files differnew file mode 100644 index 0000000..5b71036 --- /dev/null +++ b/.DS_Store diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..b58b603 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,5 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ diff --git a/.idea/ABtesting.iml b/.idea/ABtesting.iml new file mode 100644 index 0000000..0c8867d --- /dev/null +++ b/.idea/ABtesting.iml @@ -0,0 +1,12 @@ +<?xml version="1.0" encoding="UTF-8"?> +<module type="WEB_MODULE" version="4"> + <component name="NewModuleRootManager"> + <content url="file://$MODULE_DIR$"> + <excludeFolder url="file://$MODULE_DIR$/temp" /> + <excludeFolder url="file://$MODULE_DIR$/.tmp" /> + <excludeFolder url="file://$MODULE_DIR$/tmp" /> + </content> + <orderEntry type="inheritedJdk" /> + <orderEntry type="sourceFolder" forTests="false" /> + </component> +</module>
\ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..f648f9e --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project version="4"> + <component name="ProjectModuleManager"> + <modules> + <module fileurl="file://$PROJECT_DIR$/.idea/ABtesting.iml" filepath="$PROJECT_DIR$/.idea/ABtesting.iml" /> + </modules> + </component> +</project>
\ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..35eb1dd --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project version="4"> + <component name="VcsDirectoryMappings"> + <mapping directory="" vcs="Git" /> + </component> +</project>
\ No newline at end of file @@ -9,6 +9,7 @@ </head> <body> B -<button onclick="done(event)" id="done">Go Home</button> +<button onclick="suc(event)" id="success1">Success</button> +<button onclick="fail(event)" id="fail1">Fail</button> </body> </html> @@ -1,11 +1,54 @@ // generate a random UID for this user, on page load. const UID = Math.round(Math.random() * 1000000); + +// variables to store user interaction data +let num_clicks = 0; +let timestamp_load; +let timestamp_first_click; +let did_misclick = false; +let did_succeed = false; +let mouse_move_distance = 0; +let mouse_prev_pos; + // takes in an event object and updates local storage to contain that event const recordAction = event => { + switch (event.type) { + case 'click': + if (num_clicks++ === 0) timestamp_first_click = Date.now(); + break; + case 'load': + timestamp_load = Date.now(); + break; + case 'pointermove': + // deconstruct x,y + const {pageX, pageY} = event; + // update distance + if (mouse_prev_pos != null) { + const dist = Math.sqrt((pageX - mouse_prev_pos.pageX)*(pageX - mouse_prev_pos.pageX) + + (pageY - mouse_prev_pos.pageY) * (pageY - mouse_prev_pos.pageY)) + mouse_move_distance += dist; + } + // update prev pos for next + mouse_prev_pos = {pageX, pageY}; + break; + case 'beforeunload': + recordData(); + cleanupHandlers(); + break; + } +} + +// to be called when the user leaves the page to track the user's data in local storage +const recordData = () => { + alert('here'); + const timestamp_unload = Date.now().toString(); + + // get the current data object and parse it let data = localStorage.getItem("cs1300-ab-testing-data"); data = JSON.parse(data); // check if parsing is correct if (!Array.isArray(data)) { + alert("Error storing data!!") console.error("DATA is not an array") return; } @@ -13,31 +56,46 @@ const recordAction = event => { // get version form the meta tag on the html file const version = document.querySelector("meta[name='version']").getAttribute("content"); const uid = UID; - const timestamp = Date.now().toString(); - const action = event.type; - let target = event.target.tagName; - let targetId = event.target.id; - if (target == null) { - target = 'N/A' - } - if (targetId) { - target += `#${targetId}` - } - data.push({uid, version, action, target, timestamp}); + // calculate metrics + const time_to_first_click = timestamp_first_click - timestamp_load; + const time_on_page = timestamp_unload - timestamp_load; + + // update localstorage + data.push({uid, version, timestamp_load, time_on_page, time_to_first_click, mouse_move_distance, num_clicks, did_misclick, did_succeed}); localStorage.setItem("cs1300-ab-testing-data", JSON.stringify(data)); } -// to be called on the click that determined when the task is completed to clean up event listeners -const done = event => { + +// to be called on the click that determined when the task is completed sucessfully +const suc = event => { + // record this event + recordAction(event); + alert("You succeeded in the task :)"); + + // update succeed flag + did_succeed = true; + + // redirect user to home + location.href = 'index.html'; +} + +// to be called on the click that determined when the task is completed on fail +const fail = event => { // record this event recordAction(event); + alert("You failed the task, but keep on trying."); + did_misclick = true; +} - // TODO: remove event listeners +// section for adding/removing handlers +const cleanupHandlers = () => { window.removeEventListener('load', recordAction); window.removeEventListener('click', recordAction); - - location.href = 'index.html'; + window.removeEventListener('pointermove', recordAction); + window.removeEventListener('beforeunload', recordAction); } window.addEventListener('load', recordAction); window.addEventListener('click', recordAction); +window.addEventListener('pointermove', recordAction); +window.addEventListener('beforeunload', recordAction); |