countly-sdk-web 25.4.3 → 25.4.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +4 -0
- package/cypress/e2e/bridged_utils.cy.js +1 -1
- package/cypress/e2e/up_order.cy.js +139 -0
- package/lib/countly.js +33 -13
- package/lib/countly.min.js +192 -191
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
/* eslint-disable cypress/no-unnecessary-waiting */
|
|
2
|
+
/* eslint-disable require-jsdoc */
|
|
3
|
+
var Countly = require("../../lib/countly");
|
|
4
|
+
var hp = require("../support/helper");
|
|
5
|
+
|
|
6
|
+
Countly.q = Countly.q || [];
|
|
7
|
+
|
|
8
|
+
function initMain() {
|
|
9
|
+
Countly.init({
|
|
10
|
+
app_key: "YOUR_APP_KEY",
|
|
11
|
+
url: "https://your.domain.count.ly",
|
|
12
|
+
test_mode_eq: true,
|
|
13
|
+
test_mode: true
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const userDetailObj = hp.userDetailObj;
|
|
18
|
+
|
|
19
|
+
// an event object to use
|
|
20
|
+
const eventObj = {
|
|
21
|
+
key: "in_app_purchase",
|
|
22
|
+
count: 3,
|
|
23
|
+
sum: 2.97,
|
|
24
|
+
dur: 300,
|
|
25
|
+
segmentation: {
|
|
26
|
+
app_version: "1.0",
|
|
27
|
+
country: "Tahiti"
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
const custUP = {
|
|
31
|
+
custom: { "name": "John Doe"}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
describe("User properties order test", () => {
|
|
35
|
+
it("User details order test", () => {
|
|
36
|
+
hp.haltAndClearStorage(() => {
|
|
37
|
+
initMain();
|
|
38
|
+
Countly.begin_session();
|
|
39
|
+
Countly.add_event(eventObj);
|
|
40
|
+
Countly.user_details(userDetailObj);
|
|
41
|
+
Countly.add_event(eventObj);
|
|
42
|
+
Countly.add_event(eventObj);
|
|
43
|
+
Countly.user_details(userDetailObj);
|
|
44
|
+
cy.fetch_local_event_queue().then((eq) => {
|
|
45
|
+
expect(eq.length).to.equal(0);
|
|
46
|
+
});
|
|
47
|
+
cy.wait(500).then(() => {
|
|
48
|
+
cy.fetch_local_request_queue(hp.appKey).then((rq) => {
|
|
49
|
+
expect(rq.length).to.equal(5);
|
|
50
|
+
cy.log(rq);
|
|
51
|
+
cy.check_session(rq[0]);
|
|
52
|
+
cy.check_event(JSON.parse(rq[1].events)[1], eventObj, undefined, false);
|
|
53
|
+
cy.check_user_details(rq[2], userDetailObj);
|
|
54
|
+
cy.check_event(JSON.parse(rq[3].events)[0], eventObj, undefined, false);
|
|
55
|
+
cy.check_event(JSON.parse(rq[3].events)[1], eventObj, undefined, false);
|
|
56
|
+
cy.check_user_details(rq[4], userDetailObj);
|
|
57
|
+
});
|
|
58
|
+
});
|
|
59
|
+
});
|
|
60
|
+
});
|
|
61
|
+
it("User details order test, async", () => {
|
|
62
|
+
hp.haltAndClearStorage(() => {
|
|
63
|
+
initMain();
|
|
64
|
+
Countly.q.push(['track_sessions']);
|
|
65
|
+
Countly.q.push(['add_event', eventObj]);
|
|
66
|
+
Countly.q.push(['user_details', userDetailObj]);
|
|
67
|
+
Countly.q.push(['add_event', eventObj]);
|
|
68
|
+
Countly.q.push(['add_event', eventObj]);
|
|
69
|
+
Countly.q.push(['user_details', userDetailObj]);
|
|
70
|
+
cy.fetch_local_event_queue().then((eq) => {
|
|
71
|
+
expect(eq.length).to.equal(0);
|
|
72
|
+
});
|
|
73
|
+
cy.wait(500).then(() => {
|
|
74
|
+
cy.fetch_local_request_queue(hp.appKey).then((rq) => {
|
|
75
|
+
expect(rq.length).to.equal(5);
|
|
76
|
+
cy.log(rq);
|
|
77
|
+
cy.check_session(rq[0]);
|
|
78
|
+
cy.check_event(JSON.parse(rq[1].events)[1], eventObj, undefined, false);
|
|
79
|
+
cy.check_user_details(rq[2], userDetailObj);
|
|
80
|
+
cy.check_event(JSON.parse(rq[3].events)[0], eventObj, undefined, false);
|
|
81
|
+
cy.check_event(JSON.parse(rq[3].events)[1], eventObj, undefined, false);
|
|
82
|
+
cy.check_user_details(rq[4], userDetailObj);
|
|
83
|
+
});
|
|
84
|
+
});
|
|
85
|
+
});
|
|
86
|
+
});
|
|
87
|
+
it("User data order test", () => {
|
|
88
|
+
hp.haltAndClearStorage(() => {
|
|
89
|
+
initMain();
|
|
90
|
+
Countly.userData.set("name", "John Doe");
|
|
91
|
+
Countly.begin_session();
|
|
92
|
+
Countly.userData.set("name", "John Doe");
|
|
93
|
+
Countly.add_event(eventObj);
|
|
94
|
+
Countly.userData.set("name", "John Doe");
|
|
95
|
+
Countly.user_details(userDetailObj);
|
|
96
|
+
cy.fetch_local_event_queue().then((eq) => {
|
|
97
|
+
expect(eq.length).to.equal(0);
|
|
98
|
+
});
|
|
99
|
+
cy.wait(500).then(() => {
|
|
100
|
+
cy.fetch_local_request_queue(hp.appKey).then((rq) => {
|
|
101
|
+
expect(rq.length).to.equal(6);
|
|
102
|
+
cy.log(rq);
|
|
103
|
+
cy.check_user_details(rq[0], custUP);
|
|
104
|
+
cy.check_session(rq[1]);
|
|
105
|
+
cy.check_user_details(rq[2], custUP);
|
|
106
|
+
cy.check_event(JSON.parse(rq[3].events)[1], eventObj, undefined, false);
|
|
107
|
+
cy.check_user_details(rq[4], custUP);
|
|
108
|
+
cy.check_user_details(rq[5], userDetailObj);
|
|
109
|
+
});
|
|
110
|
+
});
|
|
111
|
+
});
|
|
112
|
+
});
|
|
113
|
+
it("User data order test, async", () => {
|
|
114
|
+
hp.haltAndClearStorage(() => {
|
|
115
|
+
initMain();
|
|
116
|
+
Countly.q.push(['userData.set', "name", "John Doe"]);
|
|
117
|
+
Countly.q.push(['track_sessions']);
|
|
118
|
+
Countly.q.push(['userData.set', "name", "John Doe"]);
|
|
119
|
+
Countly.q.push(['add_event', eventObj]);
|
|
120
|
+
Countly.q.push(['userData.set', "name", "John Doe"]);
|
|
121
|
+
Countly.q.push(['user_details', userDetailObj]);
|
|
122
|
+
cy.fetch_local_event_queue().then((eq) => {
|
|
123
|
+
expect(eq.length).to.equal(0);
|
|
124
|
+
});
|
|
125
|
+
cy.wait(500).then(() => {
|
|
126
|
+
cy.fetch_local_request_queue(hp.appKey).then((rq) => {
|
|
127
|
+
expect(rq.length).to.equal(6);
|
|
128
|
+
cy.log(rq);
|
|
129
|
+
cy.check_user_details(rq[0], custUP);
|
|
130
|
+
cy.check_session(rq[1]);
|
|
131
|
+
cy.check_user_details(rq[2], custUP);
|
|
132
|
+
cy.check_event(JSON.parse(rq[3].events)[1], eventObj, undefined, false);
|
|
133
|
+
cy.check_user_details(rq[4], custUP);
|
|
134
|
+
cy.check_user_details(rq[5], userDetailObj);
|
|
135
|
+
});
|
|
136
|
+
});
|
|
137
|
+
});
|
|
138
|
+
});
|
|
139
|
+
});
|
package/lib/countly.js
CHANGED
|
@@ -217,7 +217,7 @@
|
|
|
217
217
|
backoffCount: "cly_hc_backoff_count",
|
|
218
218
|
consecutiveBackoffCount: "cly_hc_consecutive_backoff_count"
|
|
219
219
|
});
|
|
220
|
-
var SDK_VERSION = "25.4.
|
|
220
|
+
var SDK_VERSION = "25.4.4";
|
|
221
221
|
var SDK_NAME = "javascript_native_web";
|
|
222
222
|
|
|
223
223
|
// Using this on document.referrer would return an array with 17 elements in it. The 12th element (array[11]) would be the path we are looking for. Others would be things like password and such (use https://regex101.com/ to check more)
|
|
@@ -945,6 +945,7 @@
|
|
|
945
945
|
var _testModeTime = /*#__PURE__*/new WeakMap();
|
|
946
946
|
var _requestTimeoutDuration = /*#__PURE__*/new WeakMap();
|
|
947
947
|
var _contentFilterCallback = /*#__PURE__*/new WeakMap();
|
|
948
|
+
var _isProcessingAsyncFromUserDataSave = /*#__PURE__*/new WeakMap();
|
|
948
949
|
var _getAndSetServerConfig = /*#__PURE__*/new WeakMap();
|
|
949
950
|
var _populateServerConfig = /*#__PURE__*/new WeakMap();
|
|
950
951
|
var _initialize = /*#__PURE__*/new WeakMap();
|
|
@@ -1101,6 +1102,7 @@
|
|
|
1101
1102
|
_classPrivateFieldInitSpec(this, _testModeTime, void 0);
|
|
1102
1103
|
_classPrivateFieldInitSpec(this, _requestTimeoutDuration, void 0);
|
|
1103
1104
|
_classPrivateFieldInitSpec(this, _contentFilterCallback, void 0);
|
|
1105
|
+
_classPrivateFieldInitSpec(this, _isProcessingAsyncFromUserDataSave, void 0);
|
|
1104
1106
|
_classPrivateFieldInitSpec(this, _getAndSetServerConfig, function () {
|
|
1105
1107
|
if (_this.device_id === "[CLY]_temp_id") {
|
|
1106
1108
|
_classPrivateFieldGet2(_log, _this).call(_this, logLevelEnums.INFO, "server_config, Device ID is temporary, not fetching server config");
|
|
@@ -2059,6 +2061,7 @@
|
|
|
2059
2061
|
var req = {};
|
|
2060
2062
|
req.begin_session = 1;
|
|
2061
2063
|
req.metrics = JSON.stringify(_classPrivateFieldGet2(_getMetrics, _this).call(_this));
|
|
2064
|
+
_this.userData.save(true); // ensure user data is saved before session start
|
|
2062
2065
|
_classPrivateFieldGet2(_toRequestQueue, _this).call(_this, req);
|
|
2063
2066
|
}
|
|
2064
2067
|
_classPrivateFieldGet2(_setValueInStorage, _this).call(_this, "cly_session", getTimestamp() + _classPrivateFieldGet2(_sessionCookieTimeout, _this) * 60);
|
|
@@ -2085,6 +2088,7 @@
|
|
|
2085
2088
|
return;
|
|
2086
2089
|
}
|
|
2087
2090
|
_classPrivateFieldGet2(_log, _this).call(_this, logLevelEnums.INFO, "session_duration, Session extended: [" + sec + "]");
|
|
2091
|
+
_this.userData.save(true); // ensure user data is saved before session update
|
|
2088
2092
|
_classPrivateFieldGet2(_toRequestQueue, _this).call(_this, {
|
|
2089
2093
|
session_duration: sec
|
|
2090
2094
|
});
|
|
@@ -2107,6 +2111,7 @@
|
|
|
2107
2111
|
_classPrivateFieldGet2(_reportViewDuration, _this).call(_this);
|
|
2108
2112
|
if (!_classPrivateFieldGet2(_useSessionCookie, _this) || force) {
|
|
2109
2113
|
_classPrivateFieldGet2(_log, _this).call(_this, logLevelEnums.INFO, "end_session, Session ended");
|
|
2114
|
+
_this.userData.save(true); // ensure user data is saved before session end
|
|
2110
2115
|
_classPrivateFieldGet2(_toRequestQueue, _this).call(_this, {
|
|
2111
2116
|
end_session: 1,
|
|
2112
2117
|
session_duration: sec
|
|
@@ -2267,6 +2272,9 @@
|
|
|
2267
2272
|
_classPrivateFieldGet2(_log, _this).call(_this, logLevelEnums.ERROR, "Adding event failed. Event must have a key property");
|
|
2268
2273
|
return;
|
|
2269
2274
|
}
|
|
2275
|
+
if (!_classPrivateFieldGet2(_isProcessingAsyncFromUserDataSave, _this)) {
|
|
2276
|
+
_this.userData.save(true); // ensure cached user data is saved before adding event
|
|
2277
|
+
}
|
|
2270
2278
|
if (!event.count) {
|
|
2271
2279
|
event.count = 1;
|
|
2272
2280
|
}
|
|
@@ -2441,6 +2449,7 @@
|
|
|
2441
2449
|
user.byear = truncateSingleValue(user.byear, _classPrivateFieldGet2(_SCLimitValueSize, _this), "user_details", _classPrivateFieldGet2(_log, _this));
|
|
2442
2450
|
user.custom = truncateObject(user.custom, _classPrivateFieldGet2(_SCLimitKeyLength, _this), _classPrivateFieldGet2(_SCLimitValueSize, _this), _classPrivateFieldGet2(_SCLimitSegmentationValues, _this), "user_details", _classPrivateFieldGet2(_log, _this));
|
|
2443
2451
|
var props = ["name", "username", "email", "organization", "phone", "picture", "gender", "byear", "custom"];
|
|
2452
|
+
_this.userData.save(); // ensure user data (and events) is saved before sending user details
|
|
2444
2453
|
_classPrivateFieldGet2(_toRequestQueue, _this).call(_this, {
|
|
2445
2454
|
user_details: JSON.stringify(createNewObjectFromProperties(user, props))
|
|
2446
2455
|
});
|
|
@@ -2627,20 +2636,30 @@
|
|
|
2627
2636
|
* Save changes made to user's custom properties object and send them to server
|
|
2628
2637
|
* @memberof Countly.userData
|
|
2629
2638
|
* */
|
|
2630
|
-
save: function save() {
|
|
2631
|
-
_classPrivateFieldGet2(_log, _this).call(_this, logLevelEnums.INFO, "[userData] save, Saving changes to user's custom property");
|
|
2632
|
-
if (_this.check_consent(featureEnums.USERS)) {
|
|
2633
|
-
|
|
2634
|
-
|
|
2635
|
-
|
|
2639
|
+
save: function save(forEvents) {
|
|
2640
|
+
_classPrivateFieldGet2(_log, _this).call(_this, logLevelEnums.INFO, "[userData] save, Saving changes to user's custom property. forEvents:[" + forEvents + "]");
|
|
2641
|
+
if (!_this.check_consent(featureEnums.USERS) || Object.keys(_classPrivateFieldGet2(_customData, _this)).length === 0) {
|
|
2642
|
+
return;
|
|
2643
|
+
}
|
|
2644
|
+
if (!forEvents) {
|
|
2645
|
+
_classPrivateFieldGet2(_log, _this).call(_this, logLevelEnums.DEBUG, "[userData] save, flushing async queue and event queue before sending custom user data");
|
|
2646
|
+
_classPrivateFieldSet2(_isProcessingAsyncFromUserDataSave, _this, true);
|
|
2647
|
+
try {
|
|
2648
|
+
// process async queue before sending events
|
|
2649
|
+
_classPrivateFieldGet2(_processAsyncQueue, _this).call(_this);
|
|
2650
|
+
} finally {
|
|
2651
|
+
_classPrivateFieldSet2(_isProcessingAsyncFromUserDataSave, _this, false);
|
|
2652
|
+
}
|
|
2653
|
+
|
|
2654
|
+
// flush events to request queue
|
|
2636
2655
|
_classPrivateFieldGet2(_sendEventsForced, _this).call(_this);
|
|
2637
|
-
_classPrivateFieldGet2(_log, _this).call(_this, logLevelEnums.INFO, "user_details, flushed the event queue");
|
|
2638
|
-
_classPrivateFieldGet2(_toRequestQueue, _this).call(_this, {
|
|
2639
|
-
user_details: JSON.stringify({
|
|
2640
|
-
custom: _classPrivateFieldGet2(_customData, _this)
|
|
2641
|
-
})
|
|
2642
|
-
});
|
|
2643
2656
|
}
|
|
2657
|
+
_classPrivateFieldGet2(_log, _this).call(_this, logLevelEnums.INFO, "[userData] save, will send the following custom data to server: [" + JSON.stringify(_classPrivateFieldGet2(_customData, _this)) + "]");
|
|
2658
|
+
_classPrivateFieldGet2(_toRequestQueue, _this).call(_this, {
|
|
2659
|
+
user_details: JSON.stringify({
|
|
2660
|
+
custom: _classPrivateFieldGet2(_customData, _this)
|
|
2661
|
+
})
|
|
2662
|
+
});
|
|
2644
2663
|
_classPrivateFieldSet2(_customData, _this, {});
|
|
2645
2664
|
}
|
|
2646
2665
|
});
|
|
@@ -6516,6 +6535,7 @@
|
|
|
6516
6535
|
_classPrivateFieldSet2(_SCBackoffDuration, this, 60); // 60 seconds
|
|
6517
6536
|
_classPrivateFieldSet2(_requestTimeoutDuration, this, 30000); // 30 seconds
|
|
6518
6537
|
_classPrivateFieldSet2(_contentFilterCallback, this, null);
|
|
6538
|
+
_classPrivateFieldSet2(_isProcessingAsyncFromUserDataSave, this, false);
|
|
6519
6539
|
this.app_key = getConfig("app_key", _ob, null);
|
|
6520
6540
|
this.url = stripTrailingSlash(getConfig("url", _ob, ""));
|
|
6521
6541
|
this.serialize = getConfig("serialize", _ob, Countly.serialize);
|