mirror of
https://github.com/hanzoai/hanzo-analytics.git
synced 2026-09-30 22:38:56 +00:00
things
This commit is contained in:
@@ -2,7 +2,7 @@ Iexec = require('shortcake').exec
|
||||
|
||||
option '-b', '--browser [browserName]', 'browser to test with'
|
||||
|
||||
task 'build', 'Build module and bundled crowdcontrol.js', ->
|
||||
task 'build', 'Build module and bundled espy.js', ->
|
||||
exec 'node_modules/.bin/requisite src/index.coffee -o espy.js'
|
||||
|
||||
task 'build-min', 'Build minified espy.min.js', ->
|
||||
|
||||
+85
-53
@@ -6,8 +6,8 @@ if window?
|
||||
window.console.log = ()->
|
||||
|
||||
store = require 'store'
|
||||
cookie = require 'cookies-js'
|
||||
useragent = require 'ua-parser-js'
|
||||
cookies = require 'cookies-js'
|
||||
userAgent = require 'ua-parser-js'
|
||||
qs = require 'query-string'
|
||||
|
||||
uuid = require 'node-uuid'
|
||||
@@ -15,7 +15,7 @@ if window?
|
||||
userIdCookie = '__cs-uid'
|
||||
sessionIdCookie = '__cs-sid'
|
||||
|
||||
class Record
|
||||
newRecord =
|
||||
pageId: ''
|
||||
lastPageId: ''
|
||||
pageViewId: ''
|
||||
@@ -27,44 +27,55 @@ if window?
|
||||
getTimestamp = ()->
|
||||
return (new Date).getMilliseconds()
|
||||
|
||||
cachedDomain = ''
|
||||
getDomain = ()->
|
||||
if !cachedDomain
|
||||
cachedDomain = if document.domain != 'localhost' then '.' + document.domain else ''
|
||||
return cachedDomain
|
||||
|
||||
# Local Storage Record Management
|
||||
useRecord = (fn)->
|
||||
record = store.get(getSessionId()) ? new Record
|
||||
fn record
|
||||
getRecord = ()->
|
||||
store.get(getSessionId()) ? newRecord
|
||||
|
||||
saveRecord = (record)->
|
||||
store.set getSessionId(), record
|
||||
|
||||
# User/Session Id Management (on cookies)
|
||||
cachedUserId
|
||||
cachedUserId = ''
|
||||
getUserId = ()->
|
||||
if cachedUserId?
|
||||
if cachedUserId
|
||||
return cachedUserId
|
||||
|
||||
userId = cookie.get userIdCookie
|
||||
if !userId?
|
||||
userId = cookies.get userIdCookie
|
||||
if !userId
|
||||
userId = uuid.v4()
|
||||
cookies.set userIdCookie, userId,
|
||||
domain: '.' + document.domain
|
||||
domain: getDomain()
|
||||
|
||||
cachedUserId = userId
|
||||
return userId
|
||||
|
||||
# cache the session id so we can resume if user leaves and returns to browser
|
||||
cachedSessionId
|
||||
cachedSessionId = ''
|
||||
getSessionId = ()->
|
||||
if cachedSessionId?
|
||||
if cachedSessionId
|
||||
return cachedSessionId
|
||||
|
||||
sessionId = cookie.get sessionIdCookie
|
||||
if !sessionId?
|
||||
sessionId = cookies.get sessionIdCookie
|
||||
if !sessionId
|
||||
sessionId = getUserId() + '_' + getTimestamp()
|
||||
cookies.set sessionIdCookie, sessionId,
|
||||
domain: '.' + document.domain
|
||||
domain: getDomain()
|
||||
expires: 1800
|
||||
|
||||
useRecord (record)->
|
||||
cachedSessionId = sessionId
|
||||
|
||||
record = getRecord()
|
||||
record.count = 0
|
||||
saveRecord(record)
|
||||
|
||||
cachedSessionId = sessionId
|
||||
|
||||
return sessionId
|
||||
|
||||
refreshSession = ()->
|
||||
@@ -75,8 +86,8 @@ if window?
|
||||
expires: 1800
|
||||
|
||||
# Page Transitions (in localstorage)
|
||||
cachedPageId
|
||||
cachedPageViewId
|
||||
cachedPageId = ''
|
||||
cachedPageViewId = ''
|
||||
getPageId = ()->
|
||||
return cachedPageId
|
||||
|
||||
@@ -84,19 +95,22 @@ if window?
|
||||
return cachedPageViewId
|
||||
|
||||
getQueryParams = ()->
|
||||
return qs.parse window.location.search
|
||||
return qs.parse(window.location.search || window.location.hash.split('?')[1])
|
||||
|
||||
updatePage = ()->
|
||||
record = getRecord()
|
||||
|
||||
newPageId = window.location.pathname + window.location.hash
|
||||
if newPageId != cachedPageId
|
||||
if newPageId != record.pageId
|
||||
cachedPageId = newPageId
|
||||
cachedPageViewId = cachedPageId + '_' + getTimestamp()
|
||||
|
||||
useRecord (record)->
|
||||
record.lastPageId = record.pageId
|
||||
record.lastPageViewId = record.pageViewId
|
||||
record.pageId = cachedPageId
|
||||
record.pageViewId = cachedPageViewId
|
||||
record = getRecord()
|
||||
record.lastPageId = record.pageId
|
||||
record.lastPageViewId = record.pageViewId
|
||||
record.pageId = cachedPageId
|
||||
record.pageViewId = cachedPageViewId
|
||||
saveRecord record
|
||||
|
||||
Espy 'PageView',
|
||||
lastPageId: record.lastPageId
|
||||
@@ -108,59 +122,77 @@ if window?
|
||||
Espy = (name, data)->
|
||||
ua = window.navigator.userAgent
|
||||
|
||||
useRecord (record)->
|
||||
record.queue.push
|
||||
userId: getUserId()
|
||||
sessionId: getSessionId()
|
||||
record = getRecord()
|
||||
record.queue.push
|
||||
userId: getUserId()
|
||||
sessionId: getSessionId()
|
||||
|
||||
pageId: record.pageId
|
||||
pageViewId: record.pageViewId
|
||||
pageId: record.pageId
|
||||
pageViewId: record.pageViewId
|
||||
|
||||
uaString: ua
|
||||
ua: userAgent ua
|
||||
timestamp: new Date()
|
||||
uaString: ua
|
||||
ua: userAgent ua
|
||||
timestamp: new Date()
|
||||
|
||||
event: name
|
||||
data: data
|
||||
count: record.count
|
||||
event: name
|
||||
data: data
|
||||
count: record.count
|
||||
|
||||
record.count++
|
||||
record.count++
|
||||
saveRecord record
|
||||
|
||||
refreshSession()
|
||||
|
||||
# Flush Queue
|
||||
flush = ()->
|
||||
useRecord (record)->
|
||||
record = getRecord()
|
||||
if record.queue.length > 0
|
||||
Espy.onflush record
|
||||
retry = 0
|
||||
data = record.queue.slice(0)
|
||||
data = JSON.stringify record.queue
|
||||
|
||||
xhr = new XMLHttpRequest
|
||||
xhr.onreadystatechange = ()->
|
||||
if xhr.readyState == 4
|
||||
if xhr.status != 200
|
||||
if xhr.status != 204
|
||||
retry++
|
||||
if retry == 3
|
||||
console.log('Espy: failed to send', data)
|
||||
console.log 'Espy: failed to send', JSON.parse data
|
||||
else
|
||||
console.log('Espy: retrying send x' + retry)
|
||||
xhr.open 'POST', Espy.url
|
||||
xhr.send data
|
||||
console.log 'Espy: retrying send x' + retry
|
||||
xhr.open 'POST', Espy.url
|
||||
xhr.send(data)
|
||||
xhr.setRequestHeader 'Content-Type', 'application/json'
|
||||
xhr.send data
|
||||
|
||||
record.queue.length = 0
|
||||
saveRecord record
|
||||
|
||||
# Bind Page Transitions
|
||||
window.addEspyListener 'hashchange', updatePage
|
||||
window.addEspyListener 'popstate', updatePage
|
||||
window.addEventListener 'hashchange', updatePage
|
||||
window.addEventListener 'popstate', updatePage
|
||||
|
||||
window.beforeUnload 'beforeunload', ()->
|
||||
Espy 'PageLeave'
|
||||
window.addEventListener 'beforeunload', ()->
|
||||
Espy 'PageChange'
|
||||
|
||||
flush()
|
||||
updatePage()
|
||||
|
||||
setInterval ()->
|
||||
flush()
|
||||
, 2000
|
||||
next = ()->
|
||||
setTimeout ()->
|
||||
flush()
|
||||
next()
|
||||
Espy.flushRate || 200
|
||||
|
||||
# prevent blocking page load
|
||||
setTimeout ()->
|
||||
next()
|
||||
, 1
|
||||
|
||||
window.Espy = Espy
|
||||
|
||||
Espy.url = 'https://analytics.crowdstart.com/'
|
||||
Espy.onflush = ()->
|
||||
Espy.flushRate = 200
|
||||
|
||||
module.exports = Espy
|
||||
|
||||
+39
-41
@@ -3,55 +3,53 @@ should = require('chai').should()
|
||||
|
||||
{getBrowser} = require './util'
|
||||
|
||||
describe "Cuckoo (#{process.env.BROWSER})", ->
|
||||
describe "Espy (#{process.env.BROWSER})", ->
|
||||
@timeout 90000
|
||||
browser = getBrowser()
|
||||
testPage = "http://localhost:#{process.env.PORT ? 3333}/test.html"
|
||||
|
||||
describe 'Cuckoo can capture uncaptured events', ->
|
||||
it 'should capture a click on an element without a handler', (done) ->
|
||||
describe 'Espy should queue events', ->
|
||||
it 'should capture page view', (done) ->
|
||||
browser
|
||||
.url testPage
|
||||
.waitForExist '#somelink', 5000
|
||||
.click '#somelink'
|
||||
.getText '#result', (err, res) ->
|
||||
res.should.equal 'clicked: somelink'
|
||||
.waitForExist '#flush'
|
||||
.getText '#flush', (err, res) ->
|
||||
record = JSON.parse(res)
|
||||
|
||||
queue = record.queue
|
||||
queue.length.should.equal 1
|
||||
event = queue[0]
|
||||
event.userId.should.exist
|
||||
event.sessionId.should.exist
|
||||
event.pageId.should.equal '/test.html'
|
||||
event.pageViewId.substring(0, 11).should.equal '/test.html_'
|
||||
event.uaString.should.exist
|
||||
event.ua.should.exist
|
||||
event.timestamp.should.exist
|
||||
event.event.should.equal 'PageView'
|
||||
event.data.should.exist
|
||||
event.data.queryParams.should.exist
|
||||
event.data.lastPageId.should.equal ''
|
||||
event.data.lastPageViewId.should.equal ''
|
||||
event.data.referrerUrl.should.equal ''
|
||||
event.data.url.should.equal 'http://localhost:3333/test.html'
|
||||
|
||||
.call done
|
||||
|
||||
it 'should capture window events like hashchange', (done) ->
|
||||
it 'should capture query params', (done) ->
|
||||
browser
|
||||
.url testPage
|
||||
.waitForExist '#linktobookmark', 5000
|
||||
.click '#linktobookmark'
|
||||
.getText '#result', (err, res) ->
|
||||
res.should.equal 'hashchangeed: undefined'
|
||||
.url testPage + '#test?q=1'
|
||||
.waitForExist '#flush'
|
||||
.getText '#flush', (err, res) ->
|
||||
record = JSON.parse(res)
|
||||
|
||||
queue = record.queue
|
||||
queue.length.should.equal 1
|
||||
event = queue[0]
|
||||
event.event.should.equal 'PageView'
|
||||
event.data.url.should.equal 'http://localhost:3333/test.html#test?q=1'
|
||||
event.data.queryParams.q.should.equal '1'
|
||||
|
||||
.call done
|
||||
|
||||
it 'should filter events', (done) ->
|
||||
browser
|
||||
.url testPage
|
||||
.setValue '#changeinput', 'somethingelse'
|
||||
.getValue '#changeinput', (err, res) ->
|
||||
res.should.equal('somethingelse')
|
||||
.getText '#rejected', (err, res) ->
|
||||
res.should.equal 'changeed: changeinput'
|
||||
.call done
|
||||
|
||||
describe 'Cuckoo can capture captured events', ->
|
||||
it 'should capture propagated events', (done) ->
|
||||
browser
|
||||
.url testPage
|
||||
.waitForExist '#clickablediv', 5000
|
||||
.click '#clickablediv'
|
||||
.getText '#result', (err, res) ->
|
||||
res.should.equal 'clicked: clickablediv'
|
||||
.call done
|
||||
|
||||
it 'should capture unpropagated events', (done) ->
|
||||
browser
|
||||
.url testPage
|
||||
.waitForExist '#dontstopmenow', 5000
|
||||
.click '#dontstopmenow'
|
||||
.getText '#result', (err, res) ->
|
||||
res.should.equal 'clicked: dontstopmenow'
|
||||
.call done
|
||||
#it 'should capture page leave', (done) ->
|
||||
|
||||
+9
-1
@@ -1,5 +1,5 @@
|
||||
<!doctype html>
|
||||
<html class="no-js" lang="">
|
||||
<html class="no-js" lang="en-us">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="x-ua-compatible" content="ie=edge">
|
||||
@@ -12,5 +12,13 @@
|
||||
<script src="espy.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="flush"></div>
|
||||
<script>
|
||||
Espy.url = "http://localhost:8080/analytics/?token=eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJiaXQiOjIwLCJqdGkiOiJiZ1hRYkpyWGtDQSIsInN1YiI6IkdQVHE2ZTM2c1IifQ.7SllMXMCydU5kTivZlMDBHfkUQm5l742l7Y0x7Pci03x7iHKL_ggrEeiGDkfYUoThv7p1vXjqVE1ps3JY0exjw"
|
||||
Espy.flushRate = 10000
|
||||
Espy.onflush = function(record) {
|
||||
document.getElementById('flush').innerHTML = JSON.stringify(record)
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
Reference in New Issue
Block a user