@segment/analytics-browser-actions-google-analytics-4 1.0.0

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.
Files changed (64) hide show
  1. package/package.json +20 -0
  2. package/src/__tests__/addPaymentInfo.test.ts +101 -0
  3. package/src/__tests__/addToCart.test.ts +95 -0
  4. package/src/__tests__/addToWishlist.test.ts +95 -0
  5. package/src/__tests__/beginCheckout.test.ts +101 -0
  6. package/src/__tests__/customEvent.test.ts +70 -0
  7. package/src/__tests__/generateLead.test.ts +68 -0
  8. package/src/__tests__/login.test.ts +63 -0
  9. package/src/__tests__/purchase.test.ts +103 -0
  10. package/src/__tests__/refund.test.ts +103 -0
  11. package/src/__tests__/removeFromCart.test.ts +99 -0
  12. package/src/__tests__/search.test.ts +64 -0
  13. package/src/__tests__/selectItem.test.ts +96 -0
  14. package/src/__tests__/selectPromotion.test.ts +111 -0
  15. package/src/__tests__/signUp.test.ts +62 -0
  16. package/src/__tests__/viewCart.test.ts +96 -0
  17. package/src/__tests__/viewItem.test.ts +96 -0
  18. package/src/__tests__/viewItemList.test.ts +96 -0
  19. package/src/__tests__/viewPromotion.test.ts +111 -0
  20. package/src/addPaymentInfo/generated-types.ts +117 -0
  21. package/src/addPaymentInfo/index.ts +48 -0
  22. package/src/addToCart/generated-types.ts +109 -0
  23. package/src/addToCart/index.ts +36 -0
  24. package/src/addToWishlist/generated-types.ts +109 -0
  25. package/src/addToWishlist/index.ts +38 -0
  26. package/src/beginCheckout/generated-types.ts +113 -0
  27. package/src/beginCheckout/index.ts +38 -0
  28. package/src/customEvent/generated-types.ts +28 -0
  29. package/src/customEvent/index.ts +52 -0
  30. package/src/ga4-functions.ts +8 -0
  31. package/src/ga4-properties.ts +368 -0
  32. package/src/ga4-types.ts +28 -0
  33. package/src/generateLead/generated-types.ts +28 -0
  34. package/src/generateLead/index.ts +32 -0
  35. package/src/generated-types.ts +56 -0
  36. package/src/index.ts +194 -0
  37. package/src/login/generated-types.ts +24 -0
  38. package/src/login/index.ts +31 -0
  39. package/src/purchase/generated-types.ts +125 -0
  40. package/src/purchase/index.ts +54 -0
  41. package/src/refund/generated-types.ts +129 -0
  42. package/src/refund/index.ts +57 -0
  43. package/src/removeFromCart/generated-types.ts +109 -0
  44. package/src/removeFromCart/index.ts +37 -0
  45. package/src/search/generated-types.ts +24 -0
  46. package/src/search/index.ts +30 -0
  47. package/src/selectItem/generated-types.ts +109 -0
  48. package/src/selectItem/index.ts +43 -0
  49. package/src/selectPromotion/generated-types.ts +137 -0
  50. package/src/selectPromotion/index.ts +67 -0
  51. package/src/setConfigurationFields/generated-types.ts +70 -0
  52. package/src/setConfigurationFields/index.ts +143 -0
  53. package/src/signUp/generated-types.ts +24 -0
  54. package/src/signUp/index.ts +29 -0
  55. package/src/types.ts +3 -0
  56. package/src/viewCart/generated-types.ts +109 -0
  57. package/src/viewCart/index.ts +36 -0
  58. package/src/viewItem/generated-types.ts +109 -0
  59. package/src/viewItem/index.ts +37 -0
  60. package/src/viewItemList/generated-types.ts +109 -0
  61. package/src/viewItemList/index.ts +36 -0
  62. package/src/viewPromotion/generated-types.ts +137 -0
  63. package/src/viewPromotion/index.ts +67 -0
  64. package/tsconfig.json +9 -0
package/package.json ADDED
@@ -0,0 +1,20 @@
1
+ {
2
+ "name": "@segment/analytics-browser-actions-google-analytics-4",
3
+ "version": "1.0.0",
4
+ "license": "MIT",
5
+ "main": "./dist/cjs",
6
+ "module": "./dist/esm",
7
+ "scripts": {
8
+ "build": "yarn build:esm && yarn build:cjs",
9
+ "build:cjs": "tsc --module commonjs --outDir ./dist/cjs",
10
+ "build:esm": "tsc --outDir ./dist/esm"
11
+ },
12
+ "typings": "./dist/esm",
13
+ "dependencies": {
14
+ "@segment/actions-core": "^3.71.0",
15
+ "@segment/browser-destination-runtime": "^1.0.0"
16
+ },
17
+ "peerDependencies": {
18
+ "@segment/analytics-next": "*"
19
+ }
20
+ }
@@ -0,0 +1,101 @@
1
+ import { Subscription } from '@segment/browser-destination-runtime/types'
2
+ import { Analytics, Context } from '@segment/analytics-next'
3
+ import googleAnalytics4Web, { destination } from '../index'
4
+ import { GA } from '../types'
5
+
6
+ const subscriptions: Subscription[] = [
7
+ {
8
+ partnerAction: 'addPaymentInfo',
9
+ name: 'Add Payment Info',
10
+ enabled: true,
11
+ subscribe: 'type = "track"',
12
+ mapping: {
13
+ currency: {
14
+ '@path': '$.properties.currency'
15
+ },
16
+ value: {
17
+ '@path': '$.properties.value'
18
+ },
19
+ coupon: {
20
+ '@path': '$.properties.coupon'
21
+ },
22
+ items: [
23
+ {
24
+ item_name: {
25
+ '@path': `$.properties.products.0.name`
26
+ },
27
+ item_id: {
28
+ '@path': `$.properties.products.0.product_id`
29
+ },
30
+ currency: {
31
+ '@path': `$.properties.products.0.currency`
32
+ },
33
+ price: {
34
+ '@path': `$.properties.products.0.price`
35
+ },
36
+ quantity: {
37
+ '@path': `$.properties.products.0.quantity`
38
+ }
39
+ }
40
+ ]
41
+ }
42
+ }
43
+ ]
44
+
45
+ describe('GoogleAnalytics4Web.addPaymentInfo', () => {
46
+ const settings = {
47
+ measurementID: 'test123'
48
+ }
49
+
50
+ let mockGA4: GA
51
+ let addPaymentInfoEvent: any
52
+ beforeEach(async () => {
53
+ jest.restoreAllMocks()
54
+
55
+ const [trackEventPlugin] = await googleAnalytics4Web({
56
+ ...settings,
57
+ subscriptions
58
+ })
59
+ addPaymentInfoEvent = trackEventPlugin
60
+
61
+ jest.spyOn(destination, 'initialize').mockImplementation(() => {
62
+ mockGA4 = {
63
+ gtag: jest.fn()
64
+ }
65
+ return Promise.resolve(mockGA4.gtag)
66
+ })
67
+ await trackEventPlugin.load(Context.system(), {} as Analytics)
68
+ })
69
+
70
+ test('GA4 addPaymentInfo Event', async () => {
71
+ const context = new Context({
72
+ event: 'Payment Info Entered',
73
+ type: 'track',
74
+ properties: {
75
+ currency: 'USD',
76
+ value: 10,
77
+ coupon: 'SUMMER_123',
78
+ payment_method: 'Credit Card',
79
+ products: [
80
+ {
81
+ product_id: '12345',
82
+ name: 'Monopoly: 3rd Edition',
83
+ currency: 'USD'
84
+ }
85
+ ]
86
+ }
87
+ })
88
+ await addPaymentInfoEvent.track?.(context)
89
+
90
+ expect(mockGA4.gtag).toHaveBeenCalledWith(
91
+ expect.anything(),
92
+ expect.stringContaining('add_payment_info'),
93
+ expect.objectContaining({
94
+ coupon: 'SUMMER_123',
95
+ currency: 'USD',
96
+ items: [{ currency: 'USD', item_id: '12345', item_name: 'Monopoly: 3rd Edition' }],
97
+ value: 10
98
+ })
99
+ )
100
+ })
101
+ })
@@ -0,0 +1,95 @@
1
+ import { Subscription } from '@segment/browser-destination-runtime/types'
2
+ import { Analytics, Context } from '@segment/analytics-next'
3
+ import googleAnalytics4Web, { destination } from '../index'
4
+ import { GA } from '../types'
5
+
6
+ const subscriptions: Subscription[] = [
7
+ {
8
+ partnerAction: 'addToCart',
9
+ name: 'Add To Cart',
10
+ enabled: true,
11
+ subscribe: 'type = "track"',
12
+ mapping: {
13
+ currency: {
14
+ '@path': '$.properties.currency'
15
+ },
16
+ value: {
17
+ '@path': '$.properties.value'
18
+ },
19
+ items: [
20
+ {
21
+ item_name: {
22
+ '@path': `$.properties.products.0.name`
23
+ },
24
+ item_id: {
25
+ '@path': `$.properties.products.0.product_id`
26
+ },
27
+ currency: {
28
+ '@path': `$.properties.products.0.currency`
29
+ },
30
+ price: {
31
+ '@path': `$.properties.products.0.price`
32
+ },
33
+ quantity: {
34
+ '@path': `$.properties.products.0.quantity`
35
+ }
36
+ }
37
+ ]
38
+ }
39
+ }
40
+ ]
41
+
42
+ describe('GoogleAnalytics4Web.addToCart', () => {
43
+ const settings = {
44
+ measurementID: 'test123'
45
+ }
46
+
47
+ let mockGA4: GA
48
+ let addToCartEvent: any
49
+ beforeEach(async () => {
50
+ jest.restoreAllMocks()
51
+
52
+ const [trackEventPlugin] = await googleAnalytics4Web({
53
+ ...settings,
54
+ subscriptions
55
+ })
56
+ addToCartEvent = trackEventPlugin
57
+
58
+ jest.spyOn(destination, 'initialize').mockImplementation(() => {
59
+ mockGA4 = {
60
+ gtag: jest.fn()
61
+ }
62
+ return Promise.resolve(mockGA4.gtag)
63
+ })
64
+ await trackEventPlugin.load(Context.system(), {} as Analytics)
65
+ })
66
+
67
+ test('GA4 addToCart Event', async () => {
68
+ const context = new Context({
69
+ event: 'Add To Cart',
70
+ type: 'track',
71
+ properties: {
72
+ currency: 'USD',
73
+ value: 10,
74
+ products: [
75
+ {
76
+ product_id: '12345',
77
+ name: 'Monopoly: 3rd Edition',
78
+ currency: 'USD'
79
+ }
80
+ ]
81
+ }
82
+ })
83
+ await addToCartEvent.track?.(context)
84
+
85
+ expect(mockGA4.gtag).toHaveBeenCalledWith(
86
+ expect.anything(),
87
+ expect.stringContaining('add_to_cart'),
88
+ expect.objectContaining({
89
+ currency: 'USD',
90
+ items: [{ currency: 'USD', item_id: '12345', item_name: 'Monopoly: 3rd Edition' }],
91
+ value: 10
92
+ })
93
+ )
94
+ })
95
+ })
@@ -0,0 +1,95 @@
1
+ import { Subscription } from '@segment/browser-destination-runtime/types'
2
+ import { Analytics, Context } from '@segment/analytics-next'
3
+ import googleAnalytics4Web, { destination } from '../index'
4
+ import { GA } from '../types'
5
+
6
+ const subscriptions: Subscription[] = [
7
+ {
8
+ partnerAction: 'addToWishlist',
9
+ name: 'Add To Wishlist',
10
+ enabled: true,
11
+ subscribe: 'type = "track"',
12
+ mapping: {
13
+ currency: {
14
+ '@path': '$.properties.currency'
15
+ },
16
+ value: {
17
+ '@path': '$.properties.value'
18
+ },
19
+ items: [
20
+ {
21
+ item_name: {
22
+ '@path': `$.properties.products.0.name`
23
+ },
24
+ item_id: {
25
+ '@path': `$.properties.products.0.product_id`
26
+ },
27
+ currency: {
28
+ '@path': `$.properties.products.0.currency`
29
+ },
30
+ price: {
31
+ '@path': `$.properties.products.0.price`
32
+ },
33
+ quantity: {
34
+ '@path': `$.properties.products.0.quantity`
35
+ }
36
+ }
37
+ ]
38
+ }
39
+ }
40
+ ]
41
+
42
+ describe('GoogleAnalytics4Web.addToWishlist', () => {
43
+ const settings = {
44
+ measurementID: 'test123'
45
+ }
46
+
47
+ let mockGA4: GA
48
+ let addToWishlistEvent: any
49
+ beforeEach(async () => {
50
+ jest.restoreAllMocks()
51
+
52
+ const [trackEventPlugin] = await googleAnalytics4Web({
53
+ ...settings,
54
+ subscriptions
55
+ })
56
+ addToWishlistEvent = trackEventPlugin
57
+
58
+ jest.spyOn(destination, 'initialize').mockImplementation(() => {
59
+ mockGA4 = {
60
+ gtag: jest.fn()
61
+ }
62
+ return Promise.resolve(mockGA4.gtag)
63
+ })
64
+ await trackEventPlugin.load(Context.system(), {} as Analytics)
65
+ })
66
+
67
+ test('Track call without parameters', async () => {
68
+ const context = new Context({
69
+ event: 'Add To Wishlist',
70
+ type: 'track',
71
+ properties: {
72
+ currency: 'USD',
73
+ value: 10,
74
+ products: [
75
+ {
76
+ product_id: '12345',
77
+ name: 'Monopoly: 3rd Edition',
78
+ currency: 'USD'
79
+ }
80
+ ]
81
+ }
82
+ })
83
+ await addToWishlistEvent.track?.(context)
84
+
85
+ expect(mockGA4.gtag).toHaveBeenCalledWith(
86
+ expect.anything(),
87
+ expect.stringContaining('add_to_wishlist'),
88
+ expect.objectContaining({
89
+ currency: 'USD',
90
+ items: [{ currency: 'USD', item_id: '12345', item_name: 'Monopoly: 3rd Edition' }],
91
+ value: 10
92
+ })
93
+ )
94
+ })
95
+ })
@@ -0,0 +1,101 @@
1
+ import { Subscription } from '@segment/browser-destination-runtime/types'
2
+ import { Analytics, Context } from '@segment/analytics-next'
3
+ import googleAnalytics4Web, { destination } from '../index'
4
+ import { GA } from '../types'
5
+
6
+ const subscriptions: Subscription[] = [
7
+ {
8
+ partnerAction: 'beginCheckout',
9
+ name: 'Begin Checkout',
10
+ enabled: true,
11
+ subscribe: 'type = "track"',
12
+ mapping: {
13
+ currency: {
14
+ '@path': '$.properties.currency'
15
+ },
16
+ value: {
17
+ '@path': '$.properties.value'
18
+ },
19
+ coupon: {
20
+ '@path': '$.properties.coupon'
21
+ },
22
+ items: [
23
+ {
24
+ item_name: {
25
+ '@path': `$.properties.products.0.name`
26
+ },
27
+ item_id: {
28
+ '@path': `$.properties.products.0.product_id`
29
+ },
30
+ currency: {
31
+ '@path': `$.properties.products.0.currency`
32
+ },
33
+ price: {
34
+ '@path': `$.properties.products.0.price`
35
+ },
36
+ quantity: {
37
+ '@path': `$.properties.products.0.quantity`
38
+ }
39
+ }
40
+ ]
41
+ }
42
+ }
43
+ ]
44
+
45
+ describe('GoogleAnalytics4Web.beginCheckout', () => {
46
+ const settings = {
47
+ measurementID: 'test123'
48
+ }
49
+
50
+ let mockGA4: GA
51
+ let beginCheckoutEvent: any
52
+ beforeEach(async () => {
53
+ jest.restoreAllMocks()
54
+
55
+ const [trackEventPlugin] = await googleAnalytics4Web({
56
+ ...settings,
57
+ subscriptions
58
+ })
59
+ beginCheckoutEvent = trackEventPlugin
60
+
61
+ jest.spyOn(destination, 'initialize').mockImplementation(() => {
62
+ mockGA4 = {
63
+ gtag: jest.fn()
64
+ }
65
+ return Promise.resolve(mockGA4.gtag)
66
+ })
67
+ await trackEventPlugin.load(Context.system(), {} as Analytics)
68
+ })
69
+
70
+ test('GA4 beginCheckout Event', async () => {
71
+ const context = new Context({
72
+ event: 'Begin Checkout',
73
+ type: 'track',
74
+ properties: {
75
+ currency: 'USD',
76
+ value: 10,
77
+ coupon: 'SUMMER_123',
78
+ payment_method: 'Credit Card',
79
+ products: [
80
+ {
81
+ product_id: '12345',
82
+ name: 'Monopoly: 3rd Edition',
83
+ currency: 'USD'
84
+ }
85
+ ]
86
+ }
87
+ })
88
+ await beginCheckoutEvent.track?.(context)
89
+
90
+ expect(mockGA4.gtag).toHaveBeenCalledWith(
91
+ expect.anything(),
92
+ expect.stringContaining('begin_checkout'),
93
+ expect.objectContaining({
94
+ coupon: 'SUMMER_123',
95
+ currency: 'USD',
96
+ items: [{ currency: 'USD', item_id: '12345', item_name: 'Monopoly: 3rd Edition' }],
97
+ value: 10
98
+ })
99
+ )
100
+ })
101
+ })
@@ -0,0 +1,70 @@
1
+ import { Subscription } from '@segment/browser-destination-runtime/types'
2
+ import { Analytics, Context } from '@segment/analytics-next'
3
+ import googleAnalytics4Web, { destination } from '../index'
4
+ import { GA } from '../types'
5
+
6
+ const subscriptions: Subscription[] = [
7
+ {
8
+ partnerAction: 'customEvent',
9
+ name: 'Custom Event',
10
+ enabled: true,
11
+ subscribe: 'type = "track"',
12
+ mapping: {
13
+ name: {
14
+ '@path': '$.event'
15
+ },
16
+ params: {
17
+ '@path': '$.properties.params'
18
+ }
19
+ }
20
+ }
21
+ ]
22
+
23
+ describe('GoogleAnalytics4Web.customEvent', () => {
24
+ const settings = {
25
+ measurementID: 'test123'
26
+ }
27
+
28
+ let mockGA4: GA
29
+ let customEvent: any
30
+ beforeEach(async () => {
31
+ jest.restoreAllMocks()
32
+
33
+ const [trackEventPlugin] = await googleAnalytics4Web({
34
+ ...settings,
35
+ subscriptions
36
+ })
37
+ customEvent = trackEventPlugin
38
+
39
+ jest.spyOn(destination, 'initialize').mockImplementation(() => {
40
+ mockGA4 = {
41
+ gtag: jest.fn()
42
+ }
43
+ return Promise.resolve(mockGA4.gtag)
44
+ })
45
+ await trackEventPlugin.load(Context.system(), {} as Analytics)
46
+ })
47
+
48
+ test('GA4 customEvent Event', async () => {
49
+ const context = new Context({
50
+ event: 'Custom Event',
51
+ type: 'track',
52
+ properties: {
53
+ params: [
54
+ {
55
+ paramOne: 'test123',
56
+ paramTwo: 'test123',
57
+ paramThree: 123
58
+ }
59
+ ]
60
+ }
61
+ })
62
+ await customEvent.track?.(context)
63
+
64
+ expect(mockGA4.gtag).toHaveBeenCalledWith(
65
+ expect.anything(),
66
+ expect.stringContaining('Custom_Event'),
67
+ expect.objectContaining([{ paramOne: 'test123', paramThree: 123, paramTwo: 'test123' }])
68
+ )
69
+ })
70
+ })
@@ -0,0 +1,68 @@
1
+ import { Subscription } from '@segment/browser-destination-runtime/types'
2
+ import { Analytics, Context } from '@segment/analytics-next'
3
+ import googleAnalytics4Web, { destination } from '../index'
4
+ import { GA } from '../types'
5
+
6
+ const subscriptions: Subscription[] = [
7
+ {
8
+ partnerAction: 'generateLead',
9
+ name: 'Generate Leaad',
10
+ enabled: true,
11
+ subscribe: 'type = "track"',
12
+ mapping: {
13
+ currency: {
14
+ '@path': '$.properties.currency'
15
+ },
16
+ value: {
17
+ '@path': '$.properties.value'
18
+ }
19
+ }
20
+ }
21
+ ]
22
+
23
+ describe('GoogleAnalytics4Web.generateLead', () => {
24
+ const settings = {
25
+ measurementID: 'test123'
26
+ }
27
+
28
+ let mockGA4: GA
29
+ let generateLeadEvent: any
30
+ beforeEach(async () => {
31
+ jest.restoreAllMocks()
32
+
33
+ const [trackEventPlugin] = await googleAnalytics4Web({
34
+ ...settings,
35
+ subscriptions
36
+ })
37
+ generateLeadEvent = trackEventPlugin
38
+
39
+ jest.spyOn(destination, 'initialize').mockImplementation(() => {
40
+ mockGA4 = {
41
+ gtag: jest.fn()
42
+ }
43
+ return Promise.resolve(mockGA4.gtag)
44
+ })
45
+ await trackEventPlugin.load(Context.system(), {} as Analytics)
46
+ })
47
+
48
+ test('GA4 generateLead Event', async () => {
49
+ const context = new Context({
50
+ event: 'Generate Lead',
51
+ type: 'track',
52
+ properties: {
53
+ currency: 'USD',
54
+ value: 10
55
+ }
56
+ })
57
+ await generateLeadEvent.track?.(context)
58
+
59
+ expect(mockGA4.gtag).toHaveBeenCalledWith(
60
+ expect.anything(),
61
+ expect.stringContaining('generate_lead'),
62
+ expect.objectContaining({
63
+ currency: 'USD',
64
+ value: 10
65
+ })
66
+ )
67
+ })
68
+ })
@@ -0,0 +1,63 @@
1
+ import { Subscription } from '@segment/browser-destination-runtime/types'
2
+ import { Analytics, Context } from '@segment/analytics-next'
3
+ import googleAnalytics4Web, { destination } from '../index'
4
+ import { GA } from '../types'
5
+
6
+ const subscriptions: Subscription[] = [
7
+ {
8
+ partnerAction: 'login',
9
+ name: 'Login',
10
+ enabled: true,
11
+ subscribe: 'type = "track"',
12
+ mapping: {
13
+ method: {
14
+ '@path': '$.properties.method'
15
+ }
16
+ }
17
+ }
18
+ ]
19
+
20
+ describe('GoogleAnalytics4Web.login', () => {
21
+ const settings = {
22
+ measurementID: 'test123'
23
+ }
24
+
25
+ let mockGA4: GA
26
+ let loginEvent: any
27
+ beforeEach(async () => {
28
+ jest.restoreAllMocks()
29
+
30
+ const [trackEventPlugin] = await googleAnalytics4Web({
31
+ ...settings,
32
+ subscriptions
33
+ })
34
+ loginEvent = trackEventPlugin
35
+
36
+ jest.spyOn(destination, 'initialize').mockImplementation(() => {
37
+ mockGA4 = {
38
+ gtag: jest.fn()
39
+ }
40
+ return Promise.resolve(mockGA4.gtag)
41
+ })
42
+ await trackEventPlugin.load(Context.system(), {} as Analytics)
43
+ })
44
+
45
+ test('GA4 login Event', async () => {
46
+ const context = new Context({
47
+ event: 'Login',
48
+ type: 'track',
49
+ properties: {
50
+ method: 'Google'
51
+ }
52
+ })
53
+ await loginEvent.track?.(context)
54
+
55
+ expect(mockGA4.gtag).toHaveBeenCalledWith(
56
+ expect.anything(),
57
+ expect.stringContaining('login'),
58
+ expect.objectContaining({
59
+ method: 'Google'
60
+ })
61
+ )
62
+ })
63
+ })