@antelopejs/dms-marketing 0.3.3 → 0.4.1
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/README.md +18 -15
- package/dist/config.d.ts +1 -0
- package/dist/config.js +4 -0
- package/dist/config.js.map +1 -1
- package/dist/data-api/funnels.d.ts +2 -0
- package/dist/data-api/funnels.js +8 -1
- package/dist/data-api/funnels.js.map +1 -1
- package/dist/db/models/funnels.model.d.ts +2 -0
- package/dist/db/models/funnels.model.js +9 -0
- package/dist/db/models/funnels.model.js.map +1 -1
- package/dist/db/models/index.d.ts +1 -0
- package/dist/db/models/index.js +1 -0
- package/dist/db/models/index.js.map +1 -1
- package/dist/db/models/marketing_events.model.d.ts +22 -0
- package/dist/db/models/marketing_events.model.js +70 -5
- package/dist/db/models/marketing_events.model.js.map +1 -1
- package/dist/db/models/marketing_preferences.model.d.ts +25 -0
- package/dist/db/models/marketing_preferences.model.js +29 -0
- package/dist/db/models/marketing_preferences.model.js.map +1 -0
- package/dist/db/models/marketing_sessions.model.d.ts +2 -1
- package/dist/db/models/marketing_sessions.model.js +11 -1
- package/dist/db/models/marketing_sessions.model.js.map +1 -1
- package/dist/db/models/page_snapshots.model.d.ts +2 -1
- package/dist/db/models/page_snapshots.model.js +7 -7
- package/dist/db/models/page_snapshots.model.js.map +1 -1
- package/dist/db/models/website_statistics.model.d.ts +4 -1
- package/dist/db/models/website_statistics.model.js +15 -1
- package/dist/db/models/website_statistics.model.js.map +1 -1
- package/dist/db/tables/index.d.ts +1 -0
- package/dist/db/tables/index.js +1 -0
- package/dist/db/tables/index.js.map +1 -1
- package/dist/db/tables/marketing_preferences.table.d.ts +6 -0
- package/dist/db/tables/marketing_preferences.table.js +31 -0
- package/dist/db/tables/marketing_preferences.table.js.map +1 -0
- package/dist/hooks/index.js +8 -4
- package/dist/hooks/index.js.map +1 -1
- package/dist/index.js +18 -3
- package/dist/index.js.map +1 -1
- package/dist/pages/acquisition/page.d.ts +9 -0
- package/dist/pages/acquisition/page.js +181 -0
- package/dist/pages/acquisition/page.js.map +1 -0
- package/dist/pages/all.d.ts +5 -1
- package/dist/pages/all.js +5 -1
- package/dist/pages/all.js.map +1 -1
- package/dist/pages/blocks.d.ts +18 -0
- package/dist/pages/blocks.js +56 -0
- package/dist/pages/blocks.js.map +1 -0
- package/dist/pages/funnel/page.d.ts +9 -0
- package/dist/pages/funnel/page.js +36 -0
- package/dist/pages/funnel/page.js.map +1 -0
- package/dist/pages/funnel-builder/page.d.ts +9 -0
- package/dist/pages/funnel-builder/page.js +29 -0
- package/dist/pages/funnel-builder/page.js.map +1 -0
- package/dist/pages/funnels/page.d.ts +1 -1
- package/dist/pages/funnels/page.js +200 -3
- package/dist/pages/funnels/page.js.map +1 -1
- package/dist/pages/index.d.ts +1 -0
- package/dist/pages/index.js +1 -0
- package/dist/pages/index.js.map +1 -1
- package/dist/pages/{campaigns → install}/page.d.ts +3 -3
- package/dist/pages/{campaigns → install}/page.js +14 -12
- package/dist/pages/install/page.js.map +1 -0
- package/dist/pages/module.d.ts +3 -0
- package/dist/pages/module.js +30 -3
- package/dist/pages/module.js.map +1 -1
- package/dist/pages/overview/page.d.ts +1 -1
- package/dist/pages/overview/page.js +122 -3
- package/dist/pages/overview/page.js.map +1 -1
- package/dist/pages/pages/page.d.ts +1 -1
- package/dist/pages/pages/page.js +9 -4
- package/dist/pages/pages/page.js.map +1 -1
- package/dist/pages/quick-actions.d.ts +1 -0
- package/dist/pages/quick-actions.js +25 -0
- package/dist/pages/quick-actions.js.map +1 -0
- package/dist/pages/settings/form.d.ts +2 -1
- package/dist/pages/settings/form.js +62 -20
- package/dist/pages/settings/form.js.map +1 -1
- package/dist/pages/settings/page.d.ts +4 -1
- package/dist/pages/settings/page.js +50 -4
- package/dist/pages/settings/page.js.map +1 -1
- package/dist/pages/websites/page.d.ts +11 -0
- package/dist/pages/websites/page.js +62 -0
- package/dist/pages/websites/page.js.map +1 -0
- package/dist/routes/blocks.d.ts +50 -0
- package/dist/routes/blocks.js +269 -0
- package/dist/routes/blocks.js.map +1 -0
- package/dist/routes/collect.d.ts +1 -2
- package/dist/routes/collect.js +19 -12
- package/dist/routes/collect.js.map +1 -1
- package/dist/routes/context.d.ts +8 -0
- package/dist/routes/context.js +54 -0
- package/dist/routes/context.js.map +1 -0
- package/dist/routes/experiments.js +2 -1
- package/dist/routes/experiments.js.map +1 -1
- package/dist/routes/funnels.d.ts +21 -3
- package/dist/routes/funnels.js +150 -7
- package/dist/routes/funnels.js.map +1 -1
- package/dist/routes/index.d.ts +2 -0
- package/dist/routes/index.js +2 -0
- package/dist/routes/index.js.map +1 -1
- package/dist/routes/settings.d.ts +6 -1
- package/dist/routes/settings.js +65 -4
- package/dist/routes/settings.js.map +1 -1
- package/dist/routes/snapshot.d.ts +1 -1
- package/dist/routes/snapshot.js +24 -25
- package/dist/routes/snapshot.js.map +1 -1
- package/dist/routes/stats.d.ts +14 -23
- package/dist/routes/stats.js +73 -97
- package/dist/routes/stats.js.map +1 -1
- package/dist/routes/tracker.js +6 -4
- package/dist/routes/tracker.js.map +1 -1
- package/dist/routes/websites.d.ts +4 -0
- package/dist/routes/websites.js +111 -12
- package/dist/routes/websites.js.map +1 -1
- package/dist/services/acquisition-report.d.ts +62 -0
- package/dist/services/acquisition-report.js +181 -0
- package/dist/services/acquisition-report.js.map +1 -0
- package/dist/services/acquisition.d.ts +9 -3
- package/dist/services/acquisition.js +35 -5
- package/dist/services/acquisition.js.map +1 -1
- package/dist/services/catalog.d.ts +3 -0
- package/dist/services/catalog.js +17 -0
- package/dist/services/catalog.js.map +1 -0
- package/dist/services/collect.d.ts +1 -2
- package/dist/services/collect.js +49 -24
- package/dist/services/collect.js.map +1 -1
- package/dist/services/composed.d.ts +9 -0
- package/dist/services/composed.js +62 -0
- package/dist/services/composed.js.map +1 -0
- package/dist/services/context.d.ts +20 -0
- package/dist/services/context.js +76 -0
- package/dist/services/context.js.map +1 -0
- package/dist/services/dashboard.d.ts +74 -0
- package/dist/services/dashboard.js +343 -0
- package/dist/services/dashboard.js.map +1 -0
- package/dist/services/experiments/results.d.ts +12 -1
- package/dist/services/experiments/results.js +19 -2
- package/dist/services/experiments/results.js.map +1 -1
- package/dist/services/experiments/stats.d.ts +7 -1
- package/dist/services/experiments/stats.js +43 -5
- package/dist/services/experiments/stats.js.map +1 -1
- package/dist/services/funnel-report.d.ts +64 -0
- package/dist/services/funnel-report.js +280 -0
- package/dist/services/funnel-report.js.map +1 -0
- package/dist/services/funnels/compute.d.ts +2 -0
- package/dist/services/funnels/compute.js +25 -13
- package/dist/services/funnels/compute.js.map +1 -1
- package/dist/services/funnels/results.js +4 -1
- package/dist/services/funnels/results.js.map +1 -1
- package/dist/services/funnels/step-path.d.ts +4 -0
- package/dist/services/funnels/step-path.js +47 -0
- package/dist/services/funnels/step-path.js.map +1 -0
- package/dist/services/funnels-table.d.ts +31 -0
- package/dist/services/funnels-table.js +230 -0
- package/dist/services/funnels-table.js.map +1 -0
- package/dist/services/heatmap.d.ts +15 -3
- package/dist/services/heatmap.js +54 -11
- package/dist/services/heatmap.js.map +1 -1
- package/dist/services/hourly-traffic.d.ts +4 -0
- package/dist/services/hourly-traffic.js +35 -0
- package/dist/services/hourly-traffic.js.map +1 -0
- package/dist/services/origin-guard.d.ts +9 -1
- package/dist/services/origin-guard.js +46 -1
- package/dist/services/origin-guard.js.map +1 -1
- package/dist/services/period.d.ts +26 -1
- package/dist/services/period.js +99 -9
- package/dist/services/period.js.map +1 -1
- package/dist/services/prune.d.ts +6 -0
- package/dist/services/prune.js +35 -0
- package/dist/services/prune.js.map +1 -1
- package/dist/services/request-body.d.ts +1 -2
- package/dist/services/request-body.js +10 -36
- package/dist/services/request-body.js.map +1 -1
- package/dist/services/request-meta.d.ts +0 -1
- package/dist/services/request-meta.js +0 -11
- package/dist/services/request-meta.js.map +1 -1
- package/dist/services/rollups.d.ts +25 -0
- package/dist/services/rollups.js +102 -0
- package/dist/services/rollups.js.map +1 -0
- package/dist/services/sessionize.d.ts +5 -1
- package/dist/services/sessionize.js +52 -10
- package/dist/services/sessionize.js.map +1 -1
- package/dist/services/settings.d.ts +41 -2
- package/dist/services/settings.js +219 -6
- package/dist/services/settings.js.map +1 -1
- package/dist/services/snapshots.d.ts +3 -2
- package/dist/services/snapshots.js +110 -9
- package/dist/services/snapshots.js.map +1 -1
- package/dist/services/tenant-website.js +1 -0
- package/dist/services/tenant-website.js.map +1 -1
- package/dist/services/url.js +12 -4
- package/dist/services/url.js.map +1 -1
- package/dist/services/website-hosts.d.ts +15 -0
- package/dist/services/website-hosts.js +67 -0
- package/dist/services/website-hosts.js.map +1 -0
- package/dist/services/website-report.d.ts +40 -0
- package/dist/services/website-report.js +84 -0
- package/dist/services/website-report.js.map +1 -0
- package/dist/types/constants.d.ts +14 -2
- package/dist/types/constants.js +17 -6
- package/dist/types/constants.js.map +1 -1
- package/dist/types/events.d.ts +221 -68
- package/dist/types/events.js +60 -11
- package/dist/types/events.js.map +1 -1
- package/dist/types/snapshots.d.ts +6 -0
- package/dist/types/snapshots.js +2 -0
- package/dist/types/snapshots.js.map +1 -1
- package/dist/types/statistics.d.ts +2 -1
- package/dist/types/statistics.js +9 -2
- package/dist/types/statistics.js.map +1 -1
- package/dist/utils/experiment-type.js +1 -1
- package/dist/utils/experiment-type.js.map +1 -1
- package/dist/utils/funnel-steps-type.d.ts +21 -3
- package/dist/utils/funnel-steps-type.js +7 -2
- package/dist/utils/funnel-steps-type.js.map +1 -1
- package/frontend-vue/app/components/ChannelsCard.vue +265 -0
- package/frontend-vue/app/components/Context.vue +479 -0
- package/frontend-vue/app/components/ExperimentInput.vue +3 -1
- package/frontend-vue/app/components/ExperimentReport.vue +736 -0
- package/frontend-vue/app/components/FirstRun.vue +60 -0
- package/frontend-vue/app/components/FunnelBuilder.vue +1595 -0
- package/frontend-vue/app/components/FunnelFigure.vue +640 -0
- package/frontend-vue/app/components/FunnelReport.vue +532 -0
- package/frontend-vue/app/components/FunnelStepsInput.vue +3 -1
- package/frontend-vue/app/components/FunnelTemplates.vue +161 -0
- package/frontend-vue/app/components/HeatmapCanvas.vue +11 -4
- package/frontend-vue/app/components/InstallGuide.vue +753 -0
- package/frontend-vue/app/components/PagePreview.vue +889 -416
- package/frontend-vue/app/components/PagesExplorer.vue +552 -0
- package/frontend-vue/app/components/ScrollDepthOverlay.vue +48 -20
- package/frontend-vue/app/components/TopListTabs.vue +317 -0
- package/frontend-vue/app/components/TrackerSnippet.vue +50 -16
- package/frontend-vue/app/components/VariationsInput.vue +15 -5
- package/frontend-vue/app/components/WebsitesGrid.vue +799 -0
- package/frontend-vue/app/composables/useContextLink.ts +16 -0
- package/frontend-vue/app/composables/useExperiment.ts +1 -2
- package/frontend-vue/app/composables/useFunnelSteps.ts +1 -2
- package/frontend-vue/app/composables/useLatestRequest.ts +2 -4
- package/frontend-vue/app/composables/useMarketingApi.ts +298 -133
- package/frontend-vue/app/composables/useMarketingContext.ts +55 -0
- package/frontend-vue/app/composables/useMarketingRoutes.ts +80 -27
- package/frontend-vue/app/composables/useSnapshotFrame.ts +26 -4
- package/frontend-vue/app/constants.ts +22 -0
- package/frontend-vue/app/plugins/funnel-steps-data-type.client.ts +2 -1
- package/frontend-vue/app/utils/channels.ts +37 -0
- package/frontend-vue/app/utils/format.ts +132 -0
- package/frontend-vue/app/utils/funnel-draft.ts +264 -0
- package/frontend-vue/app/utils/heatmap.ts +82 -0
- package/frontend-vue/app/utils/heatmapPalette.ts +10 -0
- package/frontend-vue/app/utils/host-conflict.ts +48 -0
- package/frontend-vue/app/utils/sample-size.ts +17 -0
- package/frontend-vue/app/utils/snapshotViewportUnits.ts +15 -5
- package/frontend-vue/app/utils/snippet.ts +53 -0
- package/frontend-vue/app/utils/step-path.ts +32 -0
- package/frontend-vue/dms.frontend.ts +4 -3
- package/frontend-vue/i18n/locales/marketing-en-GB.json +1083 -316
- package/frontend-vue/i18n/locales/marketing-fr-FR.json +1087 -320
- package/frontend-vue/package.json +1 -2
- package/frontend-vue/pnpm-lock.yaml +51 -19
- package/frontend-vue/tests/drafts.test.ts +3 -3
- package/frontend-vue/tests/format.test.ts +73 -0
- package/frontend-vue/tests/funnel-draft.test.ts +194 -0
- package/frontend-vue/tests/heatmap.test.ts +32 -0
- package/frontend-vue/tests/i18n.test.ts +87 -4
- package/frontend-vue/tests/latest-request.test.ts +6 -3
- package/frontend-vue/tests/locale-typography.test.ts +115 -0
- package/frontend-vue/tests/registration.test.ts +17 -11
- package/frontend-vue/tests/routes.test.ts +67 -7
- package/frontend-vue/tests/server-parity.test.ts +77 -0
- package/frontend-vue/tests/stubs/frontend-module.ts +18 -3
- package/frontend-vue/vitest.config.ts +3 -1
- package/package.json +10 -8
- package/static/snapshot.js +46 -16
- package/static/tracker.js +139 -48
- package/dist/pages/campaigns/page.js.map +0 -1
- package/frontend-vue/app/components/CampaignsView.vue +0 -330
- package/frontend-vue/app/components/FunnelDetail.vue +0 -1026
- package/frontend-vue/app/components/FunnelsView.vue +0 -493
- package/frontend-vue/app/components/NoWebsiteState.vue +0 -18
- package/frontend-vue/app/components/OverviewView.vue +0 -493
- package/frontend-vue/app/components/PagesView.vue +0 -391
- package/frontend-vue/app/components/TextKpiCard.vue +0 -28
- package/frontend-vue/app/components/TopListTabsCard.vue +0 -162
- package/frontend-vue/app/composables/useChildId.ts +0 -13
- package/frontend-vue/app/composables/useMarketingPeriod.ts +0 -65
- package/frontend-vue/app/composables/useMarketingWebsiteForm.ts +0 -69
- package/frontend-vue/app/composables/useMarketingWebsites.ts +0 -80
- package/frontend-vue/app/utils/dmsComponent.ts +0 -18
- package/frontend-vue/tests/period.test.ts +0 -35
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
"license": "Apache-2.0",
|
|
8
8
|
"packageManager": "pnpm@10.6.5",
|
|
9
9
|
"engines": {
|
|
10
|
-
"@antelopejs/dms-frontend": ">=0.2
|
|
10
|
+
"@antelopejs/dms-frontend": ">=0.5.2 <0.6.0"
|
|
11
11
|
},
|
|
12
12
|
"scripts": {
|
|
13
13
|
"dev": "pnpm --dir ../playground frontend:dev",
|
|
@@ -24,7 +24,6 @@
|
|
|
24
24
|
"@vitejs/plugin-vue": "^6.0.0",
|
|
25
25
|
"eslint": "^9.0.0",
|
|
26
26
|
"eslint-plugin-vue": "^10.0.0",
|
|
27
|
-
"jsdom": "^26",
|
|
28
27
|
"prettier": "^3.5.3",
|
|
29
28
|
"typescript": "^5.9.3",
|
|
30
29
|
"typescript-eslint": "^8.0.0",
|
|
@@ -24,9 +24,6 @@ importers:
|
|
|
24
24
|
eslint-plugin-vue:
|
|
25
25
|
specifier: ^10.0.0
|
|
26
26
|
version: 10.11.0(@typescript-eslint/parser@8.70.0(eslint@9.39.5(jiti@2.7.0))(typescript@5.9.3))(eslint@9.39.5(jiti@2.7.0))(vue-eslint-parser@10.4.1(eslint@9.39.5(jiti@2.7.0)))
|
|
27
|
-
jsdom:
|
|
28
|
-
specifier: ^26
|
|
29
|
-
version: 26.1.0
|
|
30
27
|
prettier:
|
|
31
28
|
specifier: ^3.5.3
|
|
32
29
|
version: 3.9.7
|
|
@@ -2653,6 +2650,7 @@ snapshots:
|
|
|
2653
2650
|
'@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4)
|
|
2654
2651
|
'@csstools/css-tokenizer': 3.0.4
|
|
2655
2652
|
lru-cache: 10.4.3
|
|
2653
|
+
optional: true
|
|
2656
2654
|
|
|
2657
2655
|
'@babel/helper-string-parser@7.29.7': {}
|
|
2658
2656
|
|
|
@@ -2671,12 +2669,14 @@ snapshots:
|
|
|
2671
2669
|
dependencies:
|
|
2672
2670
|
fontkitten: 1.0.3
|
|
2673
2671
|
|
|
2674
|
-
'@csstools/color-helpers@5.1.0':
|
|
2672
|
+
'@csstools/color-helpers@5.1.0':
|
|
2673
|
+
optional: true
|
|
2675
2674
|
|
|
2676
2675
|
'@csstools/css-calc@2.1.4(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4)':
|
|
2677
2676
|
dependencies:
|
|
2678
2677
|
'@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4)
|
|
2679
2678
|
'@csstools/css-tokenizer': 3.0.4
|
|
2679
|
+
optional: true
|
|
2680
2680
|
|
|
2681
2681
|
'@csstools/css-color-parser@3.1.0(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4)':
|
|
2682
2682
|
dependencies:
|
|
@@ -2684,12 +2684,15 @@ snapshots:
|
|
|
2684
2684
|
'@csstools/css-calc': 2.1.4(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4)
|
|
2685
2685
|
'@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4)
|
|
2686
2686
|
'@csstools/css-tokenizer': 3.0.4
|
|
2687
|
+
optional: true
|
|
2687
2688
|
|
|
2688
2689
|
'@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4)':
|
|
2689
2690
|
dependencies:
|
|
2690
2691
|
'@csstools/css-tokenizer': 3.0.4
|
|
2692
|
+
optional: true
|
|
2691
2693
|
|
|
2692
|
-
'@csstools/css-tokenizer@3.0.4':
|
|
2694
|
+
'@csstools/css-tokenizer@3.0.4':
|
|
2695
|
+
optional: true
|
|
2693
2696
|
|
|
2694
2697
|
'@esbuild/aix-ppc64@0.27.7':
|
|
2695
2698
|
optional: true
|
|
@@ -3830,7 +3833,8 @@ snapshots:
|
|
|
3830
3833
|
|
|
3831
3834
|
acorn@8.18.0: {}
|
|
3832
3835
|
|
|
3833
|
-
agent-base@7.1.4:
|
|
3836
|
+
agent-base@7.1.4:
|
|
3837
|
+
optional: true
|
|
3834
3838
|
|
|
3835
3839
|
ajv@6.15.0:
|
|
3836
3840
|
dependencies:
|
|
@@ -3946,6 +3950,7 @@ snapshots:
|
|
|
3946
3950
|
dependencies:
|
|
3947
3951
|
'@asamuzakjp/css-color': 3.2.0
|
|
3948
3952
|
rrweb-cssom: 0.8.0
|
|
3953
|
+
optional: true
|
|
3949
3954
|
|
|
3950
3955
|
csstype@3.2.3: {}
|
|
3951
3956
|
|
|
@@ -3953,12 +3958,14 @@ snapshots:
|
|
|
3953
3958
|
dependencies:
|
|
3954
3959
|
whatwg-mimetype: 4.0.0
|
|
3955
3960
|
whatwg-url: 14.2.0
|
|
3961
|
+
optional: true
|
|
3956
3962
|
|
|
3957
3963
|
debug@4.4.3:
|
|
3958
3964
|
dependencies:
|
|
3959
3965
|
ms: 2.1.3
|
|
3960
3966
|
|
|
3961
|
-
decimal.js@10.6.0:
|
|
3967
|
+
decimal.js@10.6.0:
|
|
3968
|
+
optional: true
|
|
3962
3969
|
|
|
3963
3970
|
deep-is@0.1.4: {}
|
|
3964
3971
|
|
|
@@ -4012,7 +4019,8 @@ snapshots:
|
|
|
4012
4019
|
graceful-fs: 4.2.11
|
|
4013
4020
|
tapable: 2.3.3
|
|
4014
4021
|
|
|
4015
|
-
entities@6.0.1:
|
|
4022
|
+
entities@6.0.1:
|
|
4023
|
+
optional: true
|
|
4016
4024
|
|
|
4017
4025
|
entities@7.0.1: {}
|
|
4018
4026
|
|
|
@@ -4293,6 +4301,7 @@ snapshots:
|
|
|
4293
4301
|
html-encoding-sniffer@4.0.0:
|
|
4294
4302
|
dependencies:
|
|
4295
4303
|
whatwg-encoding: 3.1.1
|
|
4304
|
+
optional: true
|
|
4296
4305
|
|
|
4297
4306
|
http-proxy-agent@7.0.2:
|
|
4298
4307
|
dependencies:
|
|
@@ -4300,6 +4309,7 @@ snapshots:
|
|
|
4300
4309
|
debug: 4.4.3
|
|
4301
4310
|
transitivePeerDependencies:
|
|
4302
4311
|
- supports-color
|
|
4312
|
+
optional: true
|
|
4303
4313
|
|
|
4304
4314
|
https-proxy-agent@7.0.6:
|
|
4305
4315
|
dependencies:
|
|
@@ -4307,12 +4317,14 @@ snapshots:
|
|
|
4307
4317
|
debug: 4.4.3
|
|
4308
4318
|
transitivePeerDependencies:
|
|
4309
4319
|
- supports-color
|
|
4320
|
+
optional: true
|
|
4310
4321
|
|
|
4311
4322
|
human-signals@5.0.0: {}
|
|
4312
4323
|
|
|
4313
4324
|
iconv-lite@0.6.3:
|
|
4314
4325
|
dependencies:
|
|
4315
4326
|
safer-buffer: 2.1.2
|
|
4327
|
+
optional: true
|
|
4316
4328
|
|
|
4317
4329
|
ignore@5.3.2: {}
|
|
4318
4330
|
|
|
@@ -4335,7 +4347,8 @@ snapshots:
|
|
|
4335
4347
|
dependencies:
|
|
4336
4348
|
is-extglob: 2.1.1
|
|
4337
4349
|
|
|
4338
|
-
is-potential-custom-element-name@1.0.1:
|
|
4350
|
+
is-potential-custom-element-name@1.0.1:
|
|
4351
|
+
optional: true
|
|
4339
4352
|
|
|
4340
4353
|
is-stream@3.0.0: {}
|
|
4341
4354
|
|
|
@@ -4377,6 +4390,7 @@ snapshots:
|
|
|
4377
4390
|
- bufferutil
|
|
4378
4391
|
- supports-color
|
|
4379
4392
|
- utf-8-validate
|
|
4393
|
+
optional: true
|
|
4380
4394
|
|
|
4381
4395
|
json-buffer@3.0.1: {}
|
|
4382
4396
|
|
|
@@ -4513,7 +4527,8 @@ snapshots:
|
|
|
4513
4527
|
|
|
4514
4528
|
lodash.merge@4.6.2: {}
|
|
4515
4529
|
|
|
4516
|
-
lru-cache@10.4.3:
|
|
4530
|
+
lru-cache@10.4.3:
|
|
4531
|
+
optional: true
|
|
4517
4532
|
|
|
4518
4533
|
lru-cache@11.5.2: {}
|
|
4519
4534
|
|
|
@@ -4600,7 +4615,8 @@ snapshots:
|
|
|
4600
4615
|
dependencies:
|
|
4601
4616
|
boolbase: 1.0.0
|
|
4602
4617
|
|
|
4603
|
-
nwsapi@2.2.27:
|
|
4618
|
+
nwsapi@2.2.27:
|
|
4619
|
+
optional: true
|
|
4604
4620
|
|
|
4605
4621
|
obug@2.2.1: {}
|
|
4606
4622
|
|
|
@@ -4649,6 +4665,7 @@ snapshots:
|
|
|
4649
4665
|
parse5@7.3.0:
|
|
4650
4666
|
dependencies:
|
|
4651
4667
|
entities: 6.0.1
|
|
4668
|
+
optional: true
|
|
4652
4669
|
|
|
4653
4670
|
path-exists@4.0.0: {}
|
|
4654
4671
|
|
|
@@ -4823,13 +4840,16 @@ snapshots:
|
|
|
4823
4840
|
|
|
4824
4841
|
rope-sequence@1.3.4: {}
|
|
4825
4842
|
|
|
4826
|
-
rrweb-cssom@0.8.0:
|
|
4843
|
+
rrweb-cssom@0.8.0:
|
|
4844
|
+
optional: true
|
|
4827
4845
|
|
|
4828
|
-
safer-buffer@2.1.2:
|
|
4846
|
+
safer-buffer@2.1.2:
|
|
4847
|
+
optional: true
|
|
4829
4848
|
|
|
4830
4849
|
saxes@6.0.0:
|
|
4831
4850
|
dependencies:
|
|
4832
4851
|
xmlchars: 2.2.0
|
|
4852
|
+
optional: true
|
|
4833
4853
|
|
|
4834
4854
|
scule@1.3.0: {}
|
|
4835
4855
|
|
|
@@ -4869,7 +4889,8 @@ snapshots:
|
|
|
4869
4889
|
dependencies:
|
|
4870
4890
|
has-flag: 4.0.0
|
|
4871
4891
|
|
|
4872
|
-
symbol-tree@3.2.4:
|
|
4892
|
+
symbol-tree@3.2.4:
|
|
4893
|
+
optional: true
|
|
4873
4894
|
|
|
4874
4895
|
tailwind-merge@3.7.0: {}
|
|
4875
4896
|
|
|
@@ -4895,21 +4916,25 @@ snapshots:
|
|
|
4895
4916
|
|
|
4896
4917
|
tinyrainbow@3.1.1: {}
|
|
4897
4918
|
|
|
4898
|
-
tldts-core@6.1.86:
|
|
4919
|
+
tldts-core@6.1.86:
|
|
4920
|
+
optional: true
|
|
4899
4921
|
|
|
4900
4922
|
tldts@6.1.86:
|
|
4901
4923
|
dependencies:
|
|
4902
4924
|
tldts-core: 6.1.86
|
|
4925
|
+
optional: true
|
|
4903
4926
|
|
|
4904
4927
|
totalist@3.0.1: {}
|
|
4905
4928
|
|
|
4906
4929
|
tough-cookie@5.1.2:
|
|
4907
4930
|
dependencies:
|
|
4908
4931
|
tldts: 6.1.86
|
|
4932
|
+
optional: true
|
|
4909
4933
|
|
|
4910
4934
|
tr46@5.1.1:
|
|
4911
4935
|
dependencies:
|
|
4912
4936
|
punycode: 2.3.1
|
|
4937
|
+
optional: true
|
|
4913
4938
|
|
|
4914
4939
|
ts-api-utils@2.5.0(typescript@5.9.3):
|
|
4915
4940
|
dependencies:
|
|
@@ -5179,21 +5204,26 @@ snapshots:
|
|
|
5179
5204
|
w3c-xmlserializer@5.0.0:
|
|
5180
5205
|
dependencies:
|
|
5181
5206
|
xml-name-validator: 5.0.0
|
|
5207
|
+
optional: true
|
|
5182
5208
|
|
|
5183
|
-
webidl-conversions@7.0.0:
|
|
5209
|
+
webidl-conversions@7.0.0:
|
|
5210
|
+
optional: true
|
|
5184
5211
|
|
|
5185
5212
|
webpack-virtual-modules@0.6.2: {}
|
|
5186
5213
|
|
|
5187
5214
|
whatwg-encoding@3.1.1:
|
|
5188
5215
|
dependencies:
|
|
5189
5216
|
iconv-lite: 0.6.3
|
|
5217
|
+
optional: true
|
|
5190
5218
|
|
|
5191
|
-
whatwg-mimetype@4.0.0:
|
|
5219
|
+
whatwg-mimetype@4.0.0:
|
|
5220
|
+
optional: true
|
|
5192
5221
|
|
|
5193
5222
|
whatwg-url@14.2.0:
|
|
5194
5223
|
dependencies:
|
|
5195
5224
|
tr46: 5.1.1
|
|
5196
5225
|
webidl-conversions: 7.0.0
|
|
5226
|
+
optional: true
|
|
5197
5227
|
|
|
5198
5228
|
wheel-gestures@2.3.0: {}
|
|
5199
5229
|
|
|
@@ -5208,11 +5238,13 @@ snapshots:
|
|
|
5208
5238
|
|
|
5209
5239
|
word-wrap@1.2.5: {}
|
|
5210
5240
|
|
|
5211
|
-
ws@8.21.3:
|
|
5241
|
+
ws@8.21.3:
|
|
5242
|
+
optional: true
|
|
5212
5243
|
|
|
5213
5244
|
xml-name-validator@5.0.0: {}
|
|
5214
5245
|
|
|
5215
|
-
xmlchars@2.2.0:
|
|
5246
|
+
xmlchars@2.2.0:
|
|
5247
|
+
optional: true
|
|
5216
5248
|
|
|
5217
5249
|
y-protocols@1.0.7(yjs@13.6.32):
|
|
5218
5250
|
dependencies:
|
|
@@ -33,9 +33,9 @@ describe('parseExperimentValue', () => {
|
|
|
33
33
|
})
|
|
34
34
|
|
|
35
35
|
it('reads a value carrying no runs as a split that served no traffic', () => {
|
|
36
|
-
expect(
|
|
37
|
-
|
|
38
|
-
)
|
|
36
|
+
expect(parseExperimentValue({ key: 'cta', variations: [] })?.runs).toEqual(
|
|
37
|
+
[],
|
|
38
|
+
)
|
|
39
39
|
})
|
|
40
40
|
|
|
41
41
|
it('answers null on anything else', () => {
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest'
|
|
2
|
+
import {
|
|
3
|
+
displayName,
|
|
4
|
+
formatDuration,
|
|
5
|
+
formatSignedDelta,
|
|
6
|
+
initials,
|
|
7
|
+
percentChangeTrend,
|
|
8
|
+
} from '../app/utils/format'
|
|
9
|
+
import { sampleSizePerArm } from '../app/utils/sample-size'
|
|
10
|
+
import { normalizeFunnelStepPath } from '../app/utils/step-path'
|
|
11
|
+
import { trackerSnippet } from '../app/utils/snippet'
|
|
12
|
+
|
|
13
|
+
describe('formatting', () => {
|
|
14
|
+
it('writes durations the way analytics tools do', () => {
|
|
15
|
+
expect(formatDuration(8)).toBe('8s')
|
|
16
|
+
expect(formatDuration(168)).toBe('2m 48s')
|
|
17
|
+
expect(formatDuration(3720)).toBe('1h 2m')
|
|
18
|
+
})
|
|
19
|
+
|
|
20
|
+
it('signs deltas after rounding, so a tiny change reads as flat', () => {
|
|
21
|
+
expect(formatSignedDelta(-2.34, 'points', 'en')).toBe('−2.3 pt')
|
|
22
|
+
expect(formatSignedDelta(8, 'seconds', 'en')).toBe('+8s')
|
|
23
|
+
expect(formatSignedDelta(0.04, 'number', 'en')).toBe('±0.0')
|
|
24
|
+
})
|
|
25
|
+
|
|
26
|
+
it('reads a change in percent that rounds to 0 % as flat', () => {
|
|
27
|
+
expect(percentChangeTrend(0.3)).toBe('flat')
|
|
28
|
+
expect(percentChangeTrend(-0.49)).toBe('flat')
|
|
29
|
+
expect(percentChangeTrend(0)).toBe('flat')
|
|
30
|
+
expect(percentChangeTrend(0.5)).toBe('up')
|
|
31
|
+
expect(percentChangeTrend(-12)).toBe('down')
|
|
32
|
+
})
|
|
33
|
+
|
|
34
|
+
it('shows a pasted page step as the path the server matches', () => {
|
|
35
|
+
expect(
|
|
36
|
+
normalizeFunnelStepPath('https://shop.acme.test/Sale/Chairs/?utm=x'),
|
|
37
|
+
).toBe('/Sale/Chairs')
|
|
38
|
+
expect(normalizeFunnelStepPath('/blog/*')).toBe('/blog/*')
|
|
39
|
+
expect(normalizeFunnelStepPath('/')).toBe('/')
|
|
40
|
+
})
|
|
41
|
+
|
|
42
|
+
it('names websites by their initials', () => {
|
|
43
|
+
expect(initials('Acme shop')).toBe('AS')
|
|
44
|
+
expect(initials('docs')).toBe('DO')
|
|
45
|
+
})
|
|
46
|
+
|
|
47
|
+
it('falls back to the raw code on a malformed region', () => {
|
|
48
|
+
expect(displayName('FR', 'region', 'en')).toBe('France')
|
|
49
|
+
expect(displayName('not a code!', 'region', 'en')).toBe('not a code!')
|
|
50
|
+
})
|
|
51
|
+
})
|
|
52
|
+
|
|
53
|
+
describe('helpers', () => {
|
|
54
|
+
it('asks for more sessions on a rarer conversion', () => {
|
|
55
|
+
expect(sampleSizePerArm(0.03, 0.2)).toBeGreaterThan(
|
|
56
|
+
sampleSizePerArm(0.3, 0.2),
|
|
57
|
+
)
|
|
58
|
+
})
|
|
59
|
+
|
|
60
|
+
it('builds the tracker tag for every flavour', () => {
|
|
61
|
+
const html = trackerSnippet('html', 'https://dms.example.com/', 'site-1')
|
|
62
|
+
expect(html).toContain(
|
|
63
|
+
'src="https://dms.example.com/api/marketing/tracker.js"',
|
|
64
|
+
)
|
|
65
|
+
expect(html).toContain('data-website-id="site-1"')
|
|
66
|
+
expect(
|
|
67
|
+
trackerSnippet('gtm', 'https://dms.example.com', 'site-1'),
|
|
68
|
+
).toContain('setAttribute("data-website-id", "site-1")')
|
|
69
|
+
expect(
|
|
70
|
+
trackerSnippet('nuxt', 'https://dms.example.com', 'site-1'),
|
|
71
|
+
).toContain('"data-website-id": "site-1"')
|
|
72
|
+
})
|
|
73
|
+
})
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest'
|
|
2
|
+
import {
|
|
3
|
+
draftIssues,
|
|
4
|
+
isExperimentKey,
|
|
5
|
+
splitSampleSize,
|
|
6
|
+
templateSteps,
|
|
7
|
+
variationSnippet,
|
|
8
|
+
type FunnelDraftValues,
|
|
9
|
+
} from '../app/utils/funnel-draft'
|
|
10
|
+
import { sampleSizePerArm } from '../app/utils/sample-size'
|
|
11
|
+
|
|
12
|
+
function draft(overrides: Partial<FunnelDraftValues> = {}): FunnelDraftValues {
|
|
13
|
+
return {
|
|
14
|
+
name: 'Checkout',
|
|
15
|
+
websiteId: 'acme-shop',
|
|
16
|
+
steps: [{ kind: 'url', value: '/cart' }],
|
|
17
|
+
windowHours: 24,
|
|
18
|
+
split: false,
|
|
19
|
+
experimentKey: '',
|
|
20
|
+
variations: [
|
|
21
|
+
{ key: 'control', weight: 1 },
|
|
22
|
+
{ key: 'bold', weight: 1 },
|
|
23
|
+
],
|
|
24
|
+
...overrides,
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
describe('experiment keys', () => {
|
|
29
|
+
it('follow the server rule: a slug starting with a letter or a digit, 64 max', () => {
|
|
30
|
+
expect(isExperimentKey('hero-cta')).toBe(true)
|
|
31
|
+
expect(isExperimentKey('a_1')).toBe(true)
|
|
32
|
+
expect(isExperimentKey('-abc')).toBe(false)
|
|
33
|
+
expect(isExperimentKey('_abc')).toBe(false)
|
|
34
|
+
expect(isExperimentKey('Hero CTA')).toBe(false)
|
|
35
|
+
expect(isExperimentKey('')).toBe(false)
|
|
36
|
+
expect(isExperimentKey('a'.repeat(64))).toBe(true)
|
|
37
|
+
expect(isExperimentKey('a'.repeat(65))).toBe(false)
|
|
38
|
+
})
|
|
39
|
+
})
|
|
40
|
+
|
|
41
|
+
describe('template links', () => {
|
|
42
|
+
it('keep the valid steps and drop the rest, never throwing', () => {
|
|
43
|
+
expect(templateSteps('[{"kind":"custom"}]')).toEqual([])
|
|
44
|
+
expect(templateSteps('not json')).toEqual([])
|
|
45
|
+
expect(templateSteps('{"kind":"url","value":"/"}')).toEqual([])
|
|
46
|
+
expect(templateSteps(undefined)).toEqual([])
|
|
47
|
+
expect(
|
|
48
|
+
templateSteps(
|
|
49
|
+
JSON.stringify([
|
|
50
|
+
{ kind: 'foo', value: '/a' },
|
|
51
|
+
{ kind: 'url', value: ' /b ' },
|
|
52
|
+
{ kind: 'url', value: `/${'x'.repeat(600)}` },
|
|
53
|
+
{ kind: 'custom', value: 'signup' },
|
|
54
|
+
]),
|
|
55
|
+
),
|
|
56
|
+
).toEqual([
|
|
57
|
+
{ kind: 'url', value: '/b' },
|
|
58
|
+
{ kind: 'custom', value: 'signup' },
|
|
59
|
+
])
|
|
60
|
+
})
|
|
61
|
+
|
|
62
|
+
it('stop at the step limit', () => {
|
|
63
|
+
const many = Array.from({ length: 12 }, (_, i) => ({
|
|
64
|
+
kind: 'url',
|
|
65
|
+
value: `/p${i}`,
|
|
66
|
+
}))
|
|
67
|
+
expect(templateSteps(JSON.stringify(many))).toHaveLength(10)
|
|
68
|
+
})
|
|
69
|
+
})
|
|
70
|
+
|
|
71
|
+
describe('draft issues', () => {
|
|
72
|
+
it('are empty for a valid funnel', () => {
|
|
73
|
+
expect(draftIssues(draft(), false)).toEqual({})
|
|
74
|
+
})
|
|
75
|
+
|
|
76
|
+
it('name the field each refusal belongs to', () => {
|
|
77
|
+
const issues = draftIssues(
|
|
78
|
+
draft({
|
|
79
|
+
name: ' ',
|
|
80
|
+
websiteId: '',
|
|
81
|
+
steps: [{ kind: 'url', value: '' }],
|
|
82
|
+
windowHours: 1000,
|
|
83
|
+
}),
|
|
84
|
+
false,
|
|
85
|
+
)
|
|
86
|
+
expect(Object.keys(issues)).toEqual([
|
|
87
|
+
'name',
|
|
88
|
+
'websiteId',
|
|
89
|
+
'steps',
|
|
90
|
+
'conversionWindowHours',
|
|
91
|
+
])
|
|
92
|
+
})
|
|
93
|
+
|
|
94
|
+
it('flag the step that is too long', () => {
|
|
95
|
+
const issues = draftIssues(
|
|
96
|
+
draft({
|
|
97
|
+
steps: [
|
|
98
|
+
{ kind: 'url', value: '/a' },
|
|
99
|
+
{ kind: 'url', value: `/${'x'.repeat(500)}` },
|
|
100
|
+
],
|
|
101
|
+
}),
|
|
102
|
+
false,
|
|
103
|
+
)
|
|
104
|
+
expect(issues.steps).toMatchObject({ message: 'step_length', index: 1 })
|
|
105
|
+
})
|
|
106
|
+
|
|
107
|
+
it('refuse a window that is empty, fractional or out of bounds', () => {
|
|
108
|
+
for (const windowHours of ['', 0, 1.5, 721]) {
|
|
109
|
+
expect(draftIssues(draft({ windowHours }), false)).toHaveProperty(
|
|
110
|
+
'conversionWindowHours',
|
|
111
|
+
)
|
|
112
|
+
}
|
|
113
|
+
expect(draftIssues(draft({ windowHours: 720 }), false)).toEqual({})
|
|
114
|
+
})
|
|
115
|
+
|
|
116
|
+
it('check the split: key, arm keys, then weights', () => {
|
|
117
|
+
const split = { split: true, experimentKey: 'hero-cta' }
|
|
118
|
+
expect(draftIssues(draft(split), false)).toEqual({})
|
|
119
|
+
expect(
|
|
120
|
+
draftIssues(draft({ ...split, experimentKey: '-abc' }), false),
|
|
121
|
+
).toHaveProperty('experiment')
|
|
122
|
+
expect(
|
|
123
|
+
draftIssues(
|
|
124
|
+
draft({
|
|
125
|
+
...split,
|
|
126
|
+
variations: [
|
|
127
|
+
{ key: 'a', weight: 1 },
|
|
128
|
+
{ key: 'a', weight: 1 },
|
|
129
|
+
],
|
|
130
|
+
}),
|
|
131
|
+
false,
|
|
132
|
+
).variations,
|
|
133
|
+
).toMatchObject({ message: 'variations', index: 1 })
|
|
134
|
+
for (const weights of [
|
|
135
|
+
[0, 0],
|
|
136
|
+
[-3, 1],
|
|
137
|
+
['', 1],
|
|
138
|
+
]) {
|
|
139
|
+
expect(
|
|
140
|
+
draftIssues(
|
|
141
|
+
draft({
|
|
142
|
+
...split,
|
|
143
|
+
variations: [
|
|
144
|
+
{ key: 'control', weight: weights[0]! },
|
|
145
|
+
{ key: 'bold', weight: weights[1]! },
|
|
146
|
+
],
|
|
147
|
+
}),
|
|
148
|
+
false,
|
|
149
|
+
).variations,
|
|
150
|
+
).toMatchObject({ message: 'weights' })
|
|
151
|
+
}
|
|
152
|
+
})
|
|
153
|
+
|
|
154
|
+
it('leave a started split alone: its key and arms are frozen', () => {
|
|
155
|
+
expect(
|
|
156
|
+
draftIssues(draft({ split: true, experimentKey: '-abc' }), true),
|
|
157
|
+
).toEqual({})
|
|
158
|
+
})
|
|
159
|
+
})
|
|
160
|
+
|
|
161
|
+
describe('split sample size', () => {
|
|
162
|
+
it('is what the smallest arm needs, scaled to the whole traffic', () => {
|
|
163
|
+
const perArm = sampleSizePerArm(0.04, 0.2)
|
|
164
|
+
expect(splitSampleSize(0.04, 0.2, [1, 1])).toBeCloseTo(perArm * 2)
|
|
165
|
+
expect(splitSampleSize(0.04, 0.2, [1, 3])).toBeCloseTo(perArm * 4)
|
|
166
|
+
expect(splitSampleSize(0.04, 0.2, [1, 1, 1])).toBeCloseTo(perArm * 3)
|
|
167
|
+
})
|
|
168
|
+
|
|
169
|
+
it('ignores arms that receive no traffic, and needs two that do', () => {
|
|
170
|
+
const perArm = sampleSizePerArm(0.04, 0.2)
|
|
171
|
+
expect(splitSampleSize(0.04, 0.2, [1, 1, 0])).toBeCloseTo(perArm * 2)
|
|
172
|
+
expect(splitSampleSize(0.04, 0.2, [1, 0])).toBeNull()
|
|
173
|
+
expect(splitSampleSize(0, 0.2, [1, 1])).toBeNull()
|
|
174
|
+
})
|
|
175
|
+
})
|
|
176
|
+
|
|
177
|
+
describe('variation snippet', () => {
|
|
178
|
+
it('runs in a classic script: no top-level await', () => {
|
|
179
|
+
const code = variationSnippet('hero-cta', 'control', ['bold', 'quiet'])
|
|
180
|
+
expect(code).not.toMatch(/^\s*(const|let|var) .*= await/m)
|
|
181
|
+
expect(code).toContain('variation("hero-cta").then(')
|
|
182
|
+
expect(code).toContain('} else if (arm === "quiet") {')
|
|
183
|
+
expect(() => new Function(code)).not.toThrow()
|
|
184
|
+
})
|
|
185
|
+
|
|
186
|
+
it('writes its comments in the language it is given', () => {
|
|
187
|
+
const code = variationSnippet('hero-cta', 'control', ['bold'], {
|
|
188
|
+
show: (variation) => `afficher ${variation}`,
|
|
189
|
+
keep: (control) => `garder ${control}`,
|
|
190
|
+
})
|
|
191
|
+
expect(code).toContain('// afficher bold')
|
|
192
|
+
expect(code).toContain('// garder control')
|
|
193
|
+
})
|
|
194
|
+
})
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest'
|
|
2
|
+
import {
|
|
3
|
+
heatmapDataLabel,
|
|
4
|
+
normalizePagePath,
|
|
5
|
+
} from '../app/utils/heatmap'
|
|
6
|
+
|
|
7
|
+
/** A `t` that shows which key and which plural form were asked for. */
|
|
8
|
+
function t(key: string, named: Record<string, unknown> = {}, plural?: number) {
|
|
9
|
+
const name = key.split('.').at(-1)
|
|
10
|
+
if (name === 'and') {
|
|
11
|
+
return `${named.first} + ${named.second}`
|
|
12
|
+
}
|
|
13
|
+
return `${named.count} ${name}${plural === 1 ? '' : '[n]'}`
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
describe('heatmap helpers', () => {
|
|
17
|
+
it('reduces a typed path the way the tracker stores it', () => {
|
|
18
|
+
expect(normalizePagePath('demo/pricing')).toBe('/demo/pricing')
|
|
19
|
+
expect(normalizePagePath(' /demo/pricing?x=1#top ')).toBe('/demo/pricing')
|
|
20
|
+
expect(normalizePagePath('https://shop.example/cart')).toBe('/cart')
|
|
21
|
+
expect(normalizePagePath(' ')).toBeUndefined()
|
|
22
|
+
})
|
|
23
|
+
|
|
24
|
+
it('names what a reset deletes, snapshots only when there are some', () => {
|
|
25
|
+
expect(heatmapDataLabel({ events: 1, snapshots: 0 }, t, 'en-GB')).toBe(
|
|
26
|
+
'1 events',
|
|
27
|
+
)
|
|
28
|
+
expect(heatmapDataLabel({ events: 18, snapshots: 1 }, t, 'en-GB')).toBe(
|
|
29
|
+
'18 events[n] + 1 snapshots',
|
|
30
|
+
)
|
|
31
|
+
})
|
|
32
|
+
})
|