countly-sdk-web 22.6.3 → 22.6.5
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/.eslintignore +0 -1
- package/.github/dependabot.yml +36 -36
- package/CHANGELOG.md +8 -0
- package/README.md +9 -9
- package/countly-sdk-web-22.06.5.tgz +0 -0
- package/cypress/integration/events.js +146 -1
- package/cypress/integration/internal_limits.js +1 -1
- package/cypress/integration/sessions.js +39 -1
- package/cypress/integration/user_details.js +430 -1
- package/cypress/support/commands.js +5 -3
- package/examples/Angular/src/app/app.component.html +1 -1
- package/examples/example_async.html +1 -1
- package/examples/example_gdpr.html +1 -1
- package/examples/example_helpers.html +1 -1
- package/examples/example_multiple_instances.html +1 -1
- package/examples/example_rating_widgets.html +1 -1
- package/examples/example_remote_config.html +1 -1
- package/examples/example_sync.html +1 -1
- package/examples/examples_feedback_widgets.html +1 -1
- package/examples/react/src/Components/Contact.js +1 -1
- package/examples/symbolication/package.json +1 -1
- package/examples/symbolication/static/index.html +1 -1
- package/jsdoc_conf.json +1 -1
- package/lib/countly.js +66 -6
- package/lib/countly.min.js +115 -113
- package/package.json +4 -4
- package/bower.json +0 -29
- package/countly-sdk-web-22.06.3.tgz +0 -0
package/.eslintignore
CHANGED
package/.github/dependabot.yml
CHANGED
|
@@ -1,38 +1,38 @@
|
|
|
1
1
|
version: 2
|
|
2
2
|
updates:
|
|
3
|
-
- package-ecosystem: npm
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
- package-ecosystem: npm
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
- package-ecosystem: npm
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
3
|
+
- package-ecosystem: npm
|
|
4
|
+
directory: "/"
|
|
5
|
+
schedule:
|
|
6
|
+
interval: monthly
|
|
7
|
+
open-pull-requests-limit: 10
|
|
8
|
+
reviewers:
|
|
9
|
+
- turtledreams
|
|
10
|
+
assignees:
|
|
11
|
+
- turtledreams
|
|
12
|
+
labels:
|
|
13
|
+
- dependencies
|
|
14
|
+
versioning-strategy: increase-if-necessary
|
|
15
|
+
- package-ecosystem: npm
|
|
16
|
+
directory: "/examples/symbolication/"
|
|
17
|
+
schedule:
|
|
18
|
+
interval: monthly
|
|
19
|
+
open-pull-requests-limit: 10
|
|
20
|
+
reviewers:
|
|
21
|
+
- turtledreams
|
|
22
|
+
assignees:
|
|
23
|
+
- turtledreams
|
|
24
|
+
labels:
|
|
25
|
+
- dependencies
|
|
26
|
+
versioning-strategy: increase-if-necessary
|
|
27
|
+
- package-ecosystem: npm
|
|
28
|
+
directory: "/examples/react/"
|
|
29
|
+
schedule:
|
|
30
|
+
interval: monthly
|
|
31
|
+
open-pull-requests-limit: 10
|
|
32
|
+
reviewers:
|
|
33
|
+
- turtledreams
|
|
34
|
+
assignees:
|
|
35
|
+
- turtledreams
|
|
36
|
+
labels:
|
|
37
|
+
- dependencies
|
|
38
|
+
versioning-strategy: increase-if-necessary
|
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
## 22.06.5
|
|
2
|
+
- SDK now adds userAgent string to each request to prevent proxy related issues
|
|
3
|
+
- Added a method to cancel timed events manually
|
|
4
|
+
- Fixed a race condition bug where a recorded event would have the wrong user properties in the drill database on the server. Now event queue is emptied (formed into a request) before recording any user profile changes
|
|
5
|
+
|
|
6
|
+
## 22.06.4
|
|
7
|
+
- Fixed an issue with remote configs not working without a parameter
|
|
8
|
+
|
|
1
9
|
## 22.06.3
|
|
2
10
|
- Fixed an issue that arose when sending crashes through a gateway. User agent information is now sent as part of the request.
|
|
3
11
|
|
package/README.md
CHANGED
|
@@ -4,11 +4,11 @@
|
|
|
4
4
|
|
|
5
5
|
# Countly Web SDK
|
|
6
6
|
|
|
7
|
-
This repository contains the Countly Web SDK, which can be integrated into websites and web applications. The Countly Web SDK is intended to be used with [Countly Community Edition](https://github.com/Countly/countly-server) or [Countly Enterprise Edition](https://
|
|
7
|
+
This repository contains the Countly Web SDK, which can be integrated into websites and web applications. The Countly Web SDK is intended to be used with [Countly Community Edition](https://github.com/Countly/countly-server) or [Countly Enterprise Edition](https://countly.com/product).
|
|
8
8
|
|
|
9
9
|
## What is Countly?
|
|
10
|
-
[Countly](https://
|
|
11
|
-
and [desktop](https://
|
|
10
|
+
[Countly](https://countly.com) is a product analytics solution and innovation enabler that helps teams track product performance and customer journey and behavior across [mobile](https://countly.com/mobile-analytics), [web](https://countly.com/web-analytics),
|
|
11
|
+
and [desktop](https://countly.com/desktop-analytics) applications. [Ensuring privacy by design](https://countly.com/privacy-by-design), Countly allows you to innovate and enhance your products to provide personalized and customized customer experiences, and meet key business and revenue goals.
|
|
12
12
|
|
|
13
13
|
Track, measure, and take action - all without leaving Countly.
|
|
14
14
|
|
|
@@ -41,21 +41,21 @@ This SDK supports the following features:
|
|
|
41
41
|
Security is very important to us. If you discover any issue regarding security, please disclose the information responsibly by sending an email to security@count.ly and **not by creating a GitHub issue**.
|
|
42
42
|
|
|
43
43
|
## Badges
|
|
44
|
-
If you like Countly, [why not use one of our badges](https://
|
|
44
|
+
If you like Countly, [why not use one of our badges](https://countly.com/brand-guidelines) and give a link back to us so others know about this wonderful platform?
|
|
45
45
|
|
|
46
|
-
<a href="https://
|
|
46
|
+
<a href="https://countly.com/f/badge" rel="nofollow"><img style="width:145px;height:60px" src="https://countly.com/badges/dark.svg?v2" alt="Countly - Product Analytics" /></a>
|
|
47
47
|
|
|
48
48
|
```JS
|
|
49
|
-
<a href="https://
|
|
49
|
+
<a href="https://countly.com/f/badge" rel="nofollow"><img style="width:145px;height:60px" src="https://countly.com/badges/dark.svg" alt="Countly - Product Analytics" /></a>
|
|
50
50
|
```
|
|
51
51
|
|
|
52
|
-
<a href="https://
|
|
52
|
+
<a href="https://countly.com/f/badge" rel="nofollow"><img style="width:145px;height:60px" src="https://countly.com/badges/light.svg?v2" alt="Countly - Product Analytics" /></a>
|
|
53
53
|
|
|
54
54
|
```JS
|
|
55
|
-
<a href="https://
|
|
55
|
+
<a href="https://countly.com/f/badge" rel="nofollow"><img style="width:145px;height:60px" src="https://countly.com/badges/light.svg" alt="Countly - Product Analytics" /></a>
|
|
56
56
|
```
|
|
57
57
|
|
|
58
58
|
## How can I help you with your efforts?
|
|
59
59
|
Glad you asked! We need ideas, feedback and constructive comments. All your suggestions will be taken care of with utmost importance. For feature requests and engaging with the community, join [our Slack Community](https://slack.count.ly) or [Community Forum](https://support.count.ly/hc/en-us/community/topics).
|
|
60
60
|
|
|
61
|
-
We are on [Twitter](
|
|
61
|
+
We are on [Twitter](https://twitter.com/gocountly), [Facebook](https://www.facebook.com/Countly) and [LinkedIn](https://www.linkedin.com/company/countly) if you would like to keep up with Countly related updates.
|
|
Binary file
|
|
@@ -34,6 +34,18 @@ const timedEventObj = {
|
|
|
34
34
|
}
|
|
35
35
|
};
|
|
36
36
|
|
|
37
|
+
const longStringName = "LongStringNameLongStringNameLongStringNameLongStringNameLongStringNameLongStringNameLongStringNameLongStringName";
|
|
38
|
+
|
|
39
|
+
// a timed event object with long string key
|
|
40
|
+
const timedEventObjLong = {
|
|
41
|
+
key: longStringName,
|
|
42
|
+
count: 1,
|
|
43
|
+
segmentation: {
|
|
44
|
+
app_version: "1.0",
|
|
45
|
+
country: "Tahiti"
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
|
|
37
49
|
describe("Events tests ", () => {
|
|
38
50
|
it("Checks if adding events works", () => {
|
|
39
51
|
hp.haltAndClearStorage(() => {
|
|
@@ -52,7 +64,106 @@ describe("Events tests ", () => {
|
|
|
52
64
|
Countly.start_event("timed");
|
|
53
65
|
// wait for a while
|
|
54
66
|
cy.wait(3000).then(() => {
|
|
55
|
-
|
|
67
|
+
cy.fetch_local_event_queue().then((eq) => {
|
|
68
|
+
// there should be nothing in the queue
|
|
69
|
+
expect(eq.length).to.equal(0);
|
|
70
|
+
});
|
|
71
|
+
cy.wait(1000).then(() => {
|
|
72
|
+
// end the event and check duration
|
|
73
|
+
Countly.end_event(timedEventObj);
|
|
74
|
+
cy.fetch_local_event_queue().then((eq) => {
|
|
75
|
+
expect(eq.length).to.equal(1);
|
|
76
|
+
// we waited 3000 milliseconds so duration must be 3 to 4
|
|
77
|
+
cy.check_event(eq[0], timedEventObj, 4);
|
|
78
|
+
});
|
|
79
|
+
});
|
|
80
|
+
});
|
|
81
|
+
});
|
|
82
|
+
});
|
|
83
|
+
it("Checks if timed events works with long string", () => {
|
|
84
|
+
hp.haltAndClearStorage(() => {
|
|
85
|
+
initMain();
|
|
86
|
+
// start the timer
|
|
87
|
+
Countly.start_event(longStringName);
|
|
88
|
+
// wait for a while
|
|
89
|
+
cy.wait(3000).then(() => {
|
|
90
|
+
cy.fetch_local_event_queue().then((eq) => {
|
|
91
|
+
// there should be nothing in the queue
|
|
92
|
+
expect(eq.length).to.equal(0);
|
|
93
|
+
});
|
|
94
|
+
cy.wait(1000).then(() => {
|
|
95
|
+
// end the event and check duration
|
|
96
|
+
Countly.end_event(timedEventObjLong);
|
|
97
|
+
cy.fetch_local_event_queue().then((eq) => {
|
|
98
|
+
expect(eq.length).to.equal(1);
|
|
99
|
+
// we waited 3000 milliseconds so duration must be 3 to 4
|
|
100
|
+
cy.check_event(eq[0], timedEventObjLong, 4);
|
|
101
|
+
});
|
|
102
|
+
});
|
|
103
|
+
});
|
|
104
|
+
});
|
|
105
|
+
});
|
|
106
|
+
it("Checks if canceling timed events works", () => {
|
|
107
|
+
hp.haltAndClearStorage(() => {
|
|
108
|
+
initMain();
|
|
109
|
+
// start the timer
|
|
110
|
+
Countly.start_event("timed");
|
|
111
|
+
// wait for a while
|
|
112
|
+
cy.wait(1000).then(() => {
|
|
113
|
+
const didCancel = Countly.cancel_event("timed");
|
|
114
|
+
expect(didCancel).to.be.true;
|
|
115
|
+
Countly.end_event(timedEventObj);
|
|
116
|
+
cy.fetch_local_event_queue().then((eq) => {
|
|
117
|
+
// queue should be empty and end_event should not create an event
|
|
118
|
+
expect(eq.length).to.equal(0);
|
|
119
|
+
});
|
|
120
|
+
});
|
|
121
|
+
});
|
|
122
|
+
});
|
|
123
|
+
it("Checks if canceling timed events works with long string key", () => {
|
|
124
|
+
hp.haltAndClearStorage(() => {
|
|
125
|
+
initMain();
|
|
126
|
+
// start the timer
|
|
127
|
+
Countly.start_event(longStringName);
|
|
128
|
+
// wait for a while
|
|
129
|
+
cy.wait(1000).then(() => {
|
|
130
|
+
const didCancel = Countly.cancel_event(longStringName);
|
|
131
|
+
expect(didCancel).to.be.true;
|
|
132
|
+
Countly.end_event(timedEventObjLong);
|
|
133
|
+
cy.fetch_local_event_queue().then((eq) => {
|
|
134
|
+
// queue should be empty and end_event should not create an event
|
|
135
|
+
expect(eq.length).to.equal(0);
|
|
136
|
+
});
|
|
137
|
+
});
|
|
138
|
+
});
|
|
139
|
+
});
|
|
140
|
+
it("Checks if canceling timed events with wrong key does nothing", () => {
|
|
141
|
+
hp.haltAndClearStorage(() => {
|
|
142
|
+
initMain();
|
|
143
|
+
// start the timer
|
|
144
|
+
Countly.start_event("timed");
|
|
145
|
+
// wait for a while
|
|
146
|
+
cy.wait(3000).then(() => {
|
|
147
|
+
const didCancel = Countly.cancel_event("false_key");
|
|
148
|
+
expect(didCancel).to.be.false; // did not cancel as the key was wrong
|
|
149
|
+
Countly.end_event(timedEventObj);
|
|
150
|
+
cy.fetch_local_event_queue().then((eq) => {
|
|
151
|
+
expect(eq.length).to.equal(1);
|
|
152
|
+
// we waited 3000 milliseconds so duration must be 3 to 4
|
|
153
|
+
cy.check_event(eq[0], timedEventObj, 3);
|
|
154
|
+
});
|
|
155
|
+
});
|
|
156
|
+
});
|
|
157
|
+
});
|
|
158
|
+
it("Checks if canceling timed events with empty key does nothing", () => {
|
|
159
|
+
hp.haltAndClearStorage(() => {
|
|
160
|
+
initMain();
|
|
161
|
+
// start the timer
|
|
162
|
+
Countly.start_event("timed");
|
|
163
|
+
// wait for a while
|
|
164
|
+
cy.wait(3000).then(() => {
|
|
165
|
+
const didCancel = Countly.cancel_event();
|
|
166
|
+
expect(didCancel).to.be.false; // did not cancel as the key was wrong
|
|
56
167
|
Countly.end_event(timedEventObj);
|
|
57
168
|
cy.fetch_local_event_queue().then((eq) => {
|
|
58
169
|
expect(eq.length).to.equal(1);
|
|
@@ -62,4 +173,38 @@ describe("Events tests ", () => {
|
|
|
62
173
|
});
|
|
63
174
|
});
|
|
64
175
|
});
|
|
176
|
+
it("Checks if canceling non existent timed events with false key does nothing", () => {
|
|
177
|
+
hp.haltAndClearStorage(() => {
|
|
178
|
+
initMain();
|
|
179
|
+
// start the timer
|
|
180
|
+
Countly.start_event();
|
|
181
|
+
// wait for a while
|
|
182
|
+
cy.wait(3000).then(() => {
|
|
183
|
+
const didCancel = Countly.cancel_event("false_key");
|
|
184
|
+
expect(didCancel).to.be.false; // did not cancel as the key was wrong
|
|
185
|
+
Countly.end_event();
|
|
186
|
+
cy.fetch_local_event_queue().then((eq) => {
|
|
187
|
+
expect(eq.length).to.equal(0);
|
|
188
|
+
});
|
|
189
|
+
});
|
|
190
|
+
});
|
|
191
|
+
});
|
|
192
|
+
it("Checks if canceling timed events with wrong key does nothing with Long string key", () => {
|
|
193
|
+
hp.haltAndClearStorage(() => {
|
|
194
|
+
initMain();
|
|
195
|
+
// start the timer
|
|
196
|
+
Countly.start_event(longStringName);
|
|
197
|
+
// wait for a while
|
|
198
|
+
cy.wait(3000).then(() => {
|
|
199
|
+
const didCancel = Countly.cancel_event("false_key");
|
|
200
|
+
expect(didCancel).to.be.false; // did not cancel as the key was wrong
|
|
201
|
+
Countly.end_event(timedEventObjLong);
|
|
202
|
+
cy.fetch_local_event_queue().then((eq) => {
|
|
203
|
+
expect(eq.length).to.equal(1);
|
|
204
|
+
// we waited 3000 milliseconds so duration must be 3 to 4
|
|
205
|
+
cy.check_event(eq[0], timedEventObjLong, 3);
|
|
206
|
+
});
|
|
207
|
+
});
|
|
208
|
+
});
|
|
209
|
+
});
|
|
65
210
|
});
|
|
@@ -147,7 +147,7 @@ describe("Internal limit tests ", () => {
|
|
|
147
147
|
Countly.userData.save();
|
|
148
148
|
cy.fetch_local_request_queue().then((rq) => {
|
|
149
149
|
expect(rq.length).to.equal(1);
|
|
150
|
-
cy.
|
|
150
|
+
cy.check_custom_properties_limit(rq[0], customProperties, limits);
|
|
151
151
|
});
|
|
152
152
|
});
|
|
153
153
|
});
|
|
@@ -20,7 +20,12 @@ function initMain() {
|
|
|
20
20
|
test_mode: true
|
|
21
21
|
});
|
|
22
22
|
}
|
|
23
|
-
const dummyQueue = [
|
|
23
|
+
const dummyQueue = [
|
|
24
|
+
{ begin_session: 1, metrics: "{\"_app_version\":\"0.0\",\"_ua\":\"Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:96.0) Gecko/20100101 Firefox/96.0\",\"_resolution\":\"1568x882\",\"_density\":1.2244897959183674,\"_locale\":\"en-US\"}", app_key: "YOUR_APP_KEY", device_id: "55669b9b-f9d7-4ed5-bc77-ec5ebb65ddd8", sdk_name: "javascript_native_web", sdk_version: "21.11.0", timestamp: 1644909864950, hour: 10, dow: 2 },
|
|
25
|
+
{ events: "[{\"key\":\"[CLY]_orientation\",\"count\":1,\"segmentation\":{\"mode\":\"portrait\"},\"timestamp\":1644909864949,\"hour\":10,\"dow\":2}]", app_key: "YOUR_APP_KEY", device_id: "55669b9b-f9d7-4ed5-bc77-ec5ebb65ddd8", sdk_name: "javascript_native_web", sdk_version: "21.11.0", timestamp: 1644909864958, hour: 10, dow: 2 },
|
|
26
|
+
{ session_duration: 4, metrics: "{\"_ua\":\"hey\"}", app_key: "YOUR_APP_KEY", device_id: "55669b9b-f9d7-4ed5-bc77-ec5ebb65ddd8", sdk_name: "javascript_native_web", sdk_version: "21.11.0", timestamp: 1644909868015, hour: 10, dow: 2 },
|
|
27
|
+
{ end_session: 1, session_duration: 10, metrics: "{\"_ua\":\"hey\"}", app_key: "YOUR_APP_KEY", device_id: "55669b9b-f9d7-4ed5-bc77-ec5ebb65ddd8", sdk_name: "javascript_native_web", sdk_version: "21.11.0", timestamp: 1644909869459, hour: 10, dow: 2 }
|
|
28
|
+
];
|
|
24
29
|
|
|
25
30
|
describe("Session tests ", () => {
|
|
26
31
|
it("Checks if session start, extension and ending works with a dummy queue", () => {
|
|
@@ -194,3 +199,36 @@ describe("Browser session tests, manual 2, no cookie", () => {
|
|
|
194
199
|
});
|
|
195
200
|
});
|
|
196
201
|
});
|
|
202
|
+
describe("Check request related functions", () => {
|
|
203
|
+
it("Check if prepareRequest forms a proper request object", () => {
|
|
204
|
+
hp.haltAndClearStorage(() => {
|
|
205
|
+
// initialize countly
|
|
206
|
+
initMain();
|
|
207
|
+
let reqObject = {};
|
|
208
|
+
Countly._internals.prepareRequest(reqObject);
|
|
209
|
+
cy.check_commons(reqObject);
|
|
210
|
+
cy.check_request_commons(reqObject);
|
|
211
|
+
});
|
|
212
|
+
});
|
|
213
|
+
it("Check if prepareRequest forms a proper request object from a bad one ", () => {
|
|
214
|
+
hp.haltAndClearStorage(() => {
|
|
215
|
+
// initialize countly
|
|
216
|
+
initMain();
|
|
217
|
+
let reqObject = { app_key: null, device_id: null };
|
|
218
|
+
Countly._internals.prepareRequest(reqObject);
|
|
219
|
+
cy.check_commons(reqObject);
|
|
220
|
+
cy.check_request_commons(reqObject);
|
|
221
|
+
});
|
|
222
|
+
});
|
|
223
|
+
it("Check if prepareRequest forms a proper request object and not erase an extra value ", () => {
|
|
224
|
+
hp.haltAndClearStorage(() => {
|
|
225
|
+
// initialize countly
|
|
226
|
+
initMain();
|
|
227
|
+
let reqObject = { extraKey: "value" };
|
|
228
|
+
Countly._internals.prepareRequest(reqObject);
|
|
229
|
+
expect(reqObject.extraKey).to.equal("value");
|
|
230
|
+
cy.check_commons(reqObject);
|
|
231
|
+
cy.check_request_commons(reqObject);
|
|
232
|
+
});
|
|
233
|
+
});
|
|
234
|
+
});
|