diff --git a/api-docs/docs/browser-tracker/markdown/browser-tracker.md b/api-docs/docs/browser-tracker/markdown/browser-tracker.md
index df73342ea..d9a8029bd 100644
--- a/api-docs/docs/browser-tracker/markdown/browser-tracker.md
+++ b/api-docs/docs/browser-tracker/markdown/browser-tracker.md
@@ -23,8 +23,7 @@
| [enableAnonymousTracking(configuration, trackers)](./browser-tracker.enableanonymoustracking.md) | Enables anonymous tracking (ie. tracker initialized without anonymousTracking) |
| [flushBuffer(configuration, trackers)](./browser-tracker.flushbuffer.md) | Send all events in the outQueue Only need to use this when sending events with a bufferSize of at least 2 |
| [newSession(trackers)](./browser-tracker.newsession.md) | Expires current session and starts a new session. |
-| [newTracker(trackerId, endpoint)](./browser-tracker.newtracker.md) | Initialise a new tracker |
-| [newTracker(trackerId, endpoint, configuration)](./browser-tracker.newtracker_1.md) | Initialise a new tracker |
+| [newTracker(trackerId, endpoint, configuration)](./browser-tracker.newtracker.md) | Initialise a new tracker |
| [preservePageViewId(trackers)](./browser-tracker.preservepageviewid.md) | Stop regenerating pageViewId (available from web_page context) |
| [removeGlobalContexts(contexts, trackers)](./browser-tracker.removeglobalcontexts.md) | All provided contexts will no longer be sent with every event |
| [setBufferSize(newBufferSize, trackers)](./browser-tracker.setbuffersize.md) | Set the buffer size Can be useful if you want to stop batching requests to ensure events start sending closer to event creation |
diff --git a/api-docs/docs/browser-tracker/markdown/browser-tracker.newtracker.md b/api-docs/docs/browser-tracker/markdown/browser-tracker.newtracker.md
index 446ff6375..23d477b89 100644
--- a/api-docs/docs/browser-tracker/markdown/browser-tracker.newtracker.md
+++ b/api-docs/docs/browser-tracker/markdown/browser-tracker.newtracker.md
@@ -9,7 +9,7 @@ Initialise a new tracker
Signature:
```typescript
-declare function newTracker(trackerId: string, endpoint: string): BrowserTracker;
+declare function newTracker(trackerId: string, endpoint: string, configuration?: TrackerConfiguration): BrowserTracker | null | undefined;
```
## Parameters
@@ -18,8 +18,9 @@ declare function newTracker(trackerId: string, endpoint: string): BrowserTracker
| --- | --- | --- |
| trackerId | string | The tracker id - also known as tracker namespace |
| endpoint | string | Collector endpoint in the form collector.mysite.com |
+| configuration | TrackerConfiguration | The initialisation options of the tracker |
Returns:
-BrowserTracker
+BrowserTracker \| null \| undefined
diff --git a/api-docs/docs/browser-tracker/markdown/browser-tracker.newtracker_1.md b/api-docs/docs/browser-tracker/markdown/browser-tracker.newtracker_1.md
deleted file mode 100644
index ac03fc02a..000000000
--- a/api-docs/docs/browser-tracker/markdown/browser-tracker.newtracker_1.md
+++ /dev/null
@@ -1,26 +0,0 @@
-
-
-[Home](./index.md) > [@snowplow/browser-tracker](./browser-tracker.md) > [newTracker](./browser-tracker.newtracker_1.md)
-
-## newTracker() function
-
-Initialise a new tracker
-
-Signature:
-
-```typescript
-declare function newTracker(trackerId: string, endpoint: string, configuration: TrackerConfiguration): BrowserTracker;
-```
-
-## Parameters
-
-| Parameter | Type | Description |
-| --- | --- | --- |
-| trackerId | string | The tracker id - also known as tracker namespace |
-| endpoint | string | Collector endpoint in the form collector.mysite.com |
-| configuration | TrackerConfiguration | The initialisation options of the tracker |
-
-Returns:
-
-BrowserTracker
-
diff --git a/api-docs/docs/node-tracker/markdown/node-tracker.coreplugin.filter.md b/api-docs/docs/node-tracker/markdown/node-tracker.coreplugin.filter.md
new file mode 100644
index 000000000..c5d39c6d2
--- /dev/null
+++ b/api-docs/docs/node-tracker/markdown/node-tracker.coreplugin.filter.md
@@ -0,0 +1,13 @@
+
+
+[Home](./index.md) > [@snowplow/node-tracker](./node-tracker.md) > [CorePlugin](./node-tracker.coreplugin.md) > [filter](./node-tracker.coreplugin.filter.md)
+
+## CorePlugin.filter property
+
+Called before the payload is sent to the callback to decide whether to send the payload or skip it
+
+Signature:
+
+```typescript
+filter?: (payload: Payload) => boolean;
+```
diff --git a/api-docs/docs/node-tracker/markdown/node-tracker.coreplugin.md b/api-docs/docs/node-tracker/markdown/node-tracker.coreplugin.md
index 2106026ce..fd32c8130 100644
--- a/api-docs/docs/node-tracker/markdown/node-tracker.coreplugin.md
+++ b/api-docs/docs/node-tracker/markdown/node-tracker.coreplugin.md
@@ -20,5 +20,6 @@ interface CorePlugin
| [afterTrack?](./node-tracker.coreplugin.aftertrack.md) | (payload: Payload) => void | (Optional) Called just after the trackerCore callback fires |
| [beforeTrack?](./node-tracker.coreplugin.beforetrack.md) | (payloadBuilder: PayloadBuilder) => void | (Optional) Called just before the trackerCore callback fires |
| [contexts?](./node-tracker.coreplugin.contexts.md) | () => SelfDescribingJson\[\] | (Optional) Called when constructing the context for each event Useful for adding additional context to events |
+| [filter?](./node-tracker.coreplugin.filter.md) | (payload: Payload) => boolean | (Optional) Called before the payload is sent to the callback to decide whether to send the payload or skip it |
| [logger?](./node-tracker.coreplugin.logger.md) | (logger: Logger) => void | (Optional) Passed a logger instance which can be used to send log information to the active logger |
diff --git a/api-docs/docs/node-tracker/node-tracker.api.md b/api-docs/docs/node-tracker/node-tracker.api.md
index 610668e54..de73dcc6c 100644
--- a/api-docs/docs/node-tracker/node-tracker.api.md
+++ b/api-docs/docs/node-tracker/node-tracker.api.md
@@ -179,6 +179,7 @@ export interface CorePlugin {
afterTrack?: (payload: Payload) => void;
beforeTrack?: (payloadBuilder: PayloadBuilder) => void;
contexts?: () => SelfDescribingJson[];
+ filter?: (payload: Payload) => boolean;
// Warning: (ae-forgotten-export) The symbol "Logger" needs to be exported by the entry point index.module.d.ts
logger?: (logger: Logger) => void;
}
diff --git a/common/changes/@snowplow/browser-tracker-core/issue-plugin_filter_2024-07-09-11-54.json b/common/changes/@snowplow/browser-tracker-core/issue-plugin_filter_2024-07-09-11-54.json
new file mode 100644
index 000000000..927053c15
--- /dev/null
+++ b/common/changes/@snowplow/browser-tracker-core/issue-plugin_filter_2024-07-09-11-54.json
@@ -0,0 +1,10 @@
+{
+ "changes": [
+ {
+ "packageName": "@snowplow/browser-tracker-core",
+ "comment": "Add a filter function to plugins to filter out events so that they are not tracked (#1326)",
+ "type": "none"
+ }
+ ],
+ "packageName": "@snowplow/browser-tracker-core"
+}
\ No newline at end of file
diff --git a/common/changes/@snowplow/browser-tracker/issue-plugin_filter_2024-07-09-11-54.json b/common/changes/@snowplow/browser-tracker/issue-plugin_filter_2024-07-09-11-54.json
new file mode 100644
index 000000000..035e343b1
--- /dev/null
+++ b/common/changes/@snowplow/browser-tracker/issue-plugin_filter_2024-07-09-11-54.json
@@ -0,0 +1,10 @@
+{
+ "changes": [
+ {
+ "packageName": "@snowplow/browser-tracker",
+ "comment": "Add a filter function to plugins to filter out events so that they are not tracked (#1326)",
+ "type": "none"
+ }
+ ],
+ "packageName": "@snowplow/browser-tracker"
+}
\ No newline at end of file
diff --git a/common/changes/@snowplow/javascript-tracker/issue-plugin_filter_2024-07-09-11-54.json b/common/changes/@snowplow/javascript-tracker/issue-plugin_filter_2024-07-09-11-54.json
new file mode 100644
index 000000000..3ef2242ed
--- /dev/null
+++ b/common/changes/@snowplow/javascript-tracker/issue-plugin_filter_2024-07-09-11-54.json
@@ -0,0 +1,10 @@
+{
+ "changes": [
+ {
+ "packageName": "@snowplow/javascript-tracker",
+ "comment": "Add a filter function to plugins to filter out events so that they are not tracked (#1326)",
+ "type": "none"
+ }
+ ],
+ "packageName": "@snowplow/javascript-tracker"
+}
\ No newline at end of file
diff --git a/common/changes/@snowplow/node-tracker/issue-plugin_filter_2024-07-09-11-54.json b/common/changes/@snowplow/node-tracker/issue-plugin_filter_2024-07-09-11-54.json
new file mode 100644
index 000000000..53f8e7c04
--- /dev/null
+++ b/common/changes/@snowplow/node-tracker/issue-plugin_filter_2024-07-09-11-54.json
@@ -0,0 +1,10 @@
+{
+ "changes": [
+ {
+ "packageName": "@snowplow/node-tracker",
+ "comment": "Add a filter function to plugins to filter out events so that they are not tracked (#1326)",
+ "type": "none"
+ }
+ ],
+ "packageName": "@snowplow/node-tracker"
+}
\ No newline at end of file
diff --git a/common/changes/@snowplow/tracker-core/issue-plugin_filter_2024-07-09-11-54.json b/common/changes/@snowplow/tracker-core/issue-plugin_filter_2024-07-09-11-54.json
new file mode 100644
index 000000000..28b4a64ac
--- /dev/null
+++ b/common/changes/@snowplow/tracker-core/issue-plugin_filter_2024-07-09-11-54.json
@@ -0,0 +1,10 @@
+{
+ "changes": [
+ {
+ "packageName": "@snowplow/tracker-core",
+ "comment": "Add a filter function to plugins to filter out events so that they are not tracked (#1326)",
+ "type": "none"
+ }
+ ],
+ "packageName": "@snowplow/tracker-core"
+}
\ No newline at end of file
diff --git a/libraries/tracker-core/src/core.ts b/libraries/tracker-core/src/core.ts
index 1cb617117..41c7d4a54 100644
--- a/libraries/tracker-core/src/core.ts
+++ b/libraries/tracker-core/src/core.ts
@@ -138,7 +138,7 @@ export interface TrackerCore {
* @param pb - Payload
* @param context - Custom contexts relating to the event
* @param timestamp - Timestamp of the event
- * @returns Payload after the callback is applied
+ * @returns Payload after the callback is applied or undefined if the event is skipped
*/
track: (
/** A PayloadBuilder created by one of the `buildX` functions */
@@ -147,7 +147,7 @@ export interface TrackerCore {
context?: Array | null,
/** Timestamp override */
timestamp?: Timestamp | null
- ) => Payload;
+ ) => Payload | undefined;
/**
* Set a persistent key-value pair to be added to every payload
@@ -376,13 +376,13 @@ export function trackerCore(configuration: CoreConfiguration = {}): TrackerCore
* @param pb - Payload
* @param context - Custom contexts relating to the event
* @param timestamp - Timestamp of the event
- * @returns Payload after the callback is applied
+ * @returns Payload after the callback is applied or undefined if the event is skipped
*/
function track(
pb: PayloadBuilder,
context?: Array | null,
timestamp?: Timestamp | null
- ): Payload {
+ ): Payload | undefined {
pb.withJsonProcessor(payloadJsonProcessor(encodeBase64));
pb.add('eid', uuid());
pb.addDict(payloadPairs);
@@ -404,6 +404,19 @@ export function trackerCore(configuration: CoreConfiguration = {}): TrackerCore
}
});
+ // Call the filter on plugins to determine if the event should be tracked
+ const skip = corePlugins.find((plugin) => {
+ try {
+ return plugin.filter && plugin.filter(pb.build()) === false;
+ } catch (ex) {
+ LOG.error('Plugin filter', ex);
+ return false;
+ }
+ });
+ if (skip) {
+ return undefined;
+ }
+
if (typeof callback === 'function') {
callback(pb);
}
diff --git a/libraries/tracker-core/src/plugins.ts b/libraries/tracker-core/src/plugins.ts
index e0f195c57..4d1f6c2d9 100644
--- a/libraries/tracker-core/src/plugins.ts
+++ b/libraries/tracker-core/src/plugins.ts
@@ -44,7 +44,7 @@ export interface CorePlugin {
*/
activateCorePlugin?: (core: TrackerCore) => void;
/**
- * Called just before the trackerCore callback fires
+ * Called before the `filter` method is called and before the trackerCore callback fires (if the filter passes)
* @param payloadBuilder - The payloadBuilder which will be sent to the callback, can be modified
*/
beforeTrack?: (payloadBuilder: PayloadBuilder) => void;
@@ -53,6 +53,12 @@ export interface CorePlugin {
* @param payload - The final built payload
*/
afterTrack?: (payload: Payload) => void;
+ /**
+ * Called before the payload is sent to the callback to decide whether to send the payload or skip it
+ * @param payload - The final event payload, can't be modified.
+ * @returns True if the payload should be sent, false if it should be skipped
+ */
+ filter?: (payload: Payload) => boolean;
/**
* Called when constructing the context for each event
* Useful for adding additional context to events
diff --git a/libraries/tracker-core/test/core.ts b/libraries/tracker-core/test/core.ts
index b238514d6..aac62a570 100644
--- a/libraries/tracker-core/test/core.ts
+++ b/libraries/tracker-core/test/core.ts
@@ -80,7 +80,7 @@ test('tracker.track API should return the eid attribute', (t) => {
page: pageTitle,
refr: referrer,
};
- const eventPayload = tracker.track(buildPageView({ pageUrl, pageTitle, referrer }));
+ const eventPayload = tracker.track(buildPageView({ pageUrl, pageTitle, referrer }))!;
t.truthy(eventPayload.eid);
t.regex(eventPayload.eid as string, UUID_REGEX);
compare(eventPayload, expected, t);
@@ -96,7 +96,7 @@ test('should track a page view', (t) => {
page: pageTitle,
refr: referrer,
};
- compare(tracker.track(buildPageView({ pageUrl, pageTitle, referrer })), expected, t);
+ compare(tracker.track(buildPageView({ pageUrl, pageTitle, referrer }))!, expected, t);
});
test('should track a page ping', (t) => {
const pageUrl = 'http://www.example.com';
@@ -115,7 +115,7 @@ test('should track a page ping', (t) => {
compare(
tracker.track(
buildPagePing({ pageUrl, pageTitle, referrer, minXOffset: 1, maxXOffset: 2, minYOffset: 3, maxYOffset: 4 })
- ),
+ )!,
expected,
t
);
@@ -130,7 +130,7 @@ test('should track a structured event', (t) => {
se_va: '1',
};
compare(
- tracker.track(buildStructEvent({ category: 'cat', action: 'act', label: 'lab', property: 'prop', value: 1 })),
+ tracker.track(buildStructEvent({ category: 'cat', action: 'act', label: 'lab', property: 'prop', value: 1 }))!,
expected,
t
);
@@ -170,7 +170,7 @@ test('should track an ecommerce transaction event', (t) => {
country,
currency,
})
- ),
+ )!,
expected,
t
);
@@ -194,7 +194,7 @@ test('should track an ecommerce transaction item event', (t) => {
ti_cu: currency,
};
compare(
- tracker.track(buildEcommerceTransactionItem({ orderId, sku, name, category, price, quantity, currency })),
+ tracker.track(buildEcommerceTransactionItem({ orderId, sku, name, category, price, quantity, currency }))!,
expected,
t
);
@@ -213,7 +213,7 @@ test('should track a self-describing event', (t) => {
data: inputJson,
}),
};
- compare(tracker.track(buildSelfDescribingEvent({ event: inputJson })), expected, t);
+ compare(tracker.track(buildSelfDescribingEvent({ event: inputJson }))!, expected, t);
});
test('should track a link click', (t) => {
const targetUrl = 'http://www.example.com';
@@ -239,7 +239,7 @@ test('should track a link click', (t) => {
}),
};
compare(
- tracker.track(buildLinkClick({ targetUrl, elementId, elementClasses, elementTarget, elementContent })),
+ tracker.track(buildLinkClick({ targetUrl, elementId, elementClasses, elementTarget, elementContent }))!,
expected,
t
);
@@ -261,7 +261,7 @@ test('should track a screen view', (t) => {
data: inputJson,
}),
};
- compare(tracker.track(buildScreenView({ name, id })), expected, t);
+ compare(tracker.track(buildScreenView({ name, id }))!, expected, t);
});
test('should track an ad impression', (t) => {
const impressionId = 'a0e8f8780ab3';
@@ -295,7 +295,7 @@ test('should track an ad impression', (t) => {
compare(
tracker.track(
buildAdImpression({ impressionId, costModel, cost, targetUrl, bannerId, zoneId, advertiserId, campaignId })
- ),
+ )!,
expected,
t
);
@@ -334,7 +334,7 @@ test('should track an ad click', (t) => {
compare(
tracker.track(
buildAdClick({ targetUrl, clickId, costModel, cost, bannerId, zoneId, impressionId, advertiserId, campaignId })
- ),
+ )!,
expected,
t
);
@@ -383,7 +383,7 @@ test('should track an ad conversion', (t) => {
advertiserId,
campaignId,
})
- ),
+ )!,
expected,
t
);
@@ -407,7 +407,7 @@ test('should track a social interaction', (t) => {
data: inputJson,
}),
};
- compare(tracker.track(buildSocialInteraction({ action, network, target })), expected, t);
+ compare(tracker.track(buildSocialInteraction({ action, network, target }))!, expected, t);
});
test('should track an add-to-cart event', (t) => {
const sku = '4q345';
@@ -434,7 +434,7 @@ test('should track an add-to-cart event', (t) => {
data: inputJson,
}),
};
- compare(tracker.track(buildAddToCart({ sku, name, category, unitPrice, quantity, currency })), expected, t);
+ compare(tracker.track(buildAddToCart({ sku, name, category, unitPrice, quantity, currency }))!, expected, t);
});
test('should track a remove-from-cart event', (t) => {
const sku = '4q345';
@@ -461,7 +461,7 @@ test('should track a remove-from-cart event', (t) => {
data: inputJson,
}),
};
- compare(tracker.track(buildRemoveFromCart({ sku, name, category, unitPrice, quantity, currency })), expected, t);
+ compare(tracker.track(buildRemoveFromCart({ sku, name, category, unitPrice, quantity, currency }))!, expected, t);
});
test('should track a form focus event', (t) => {
const formId = 'parent';
@@ -491,7 +491,7 @@ test('should track a form focus event', (t) => {
compare(
tracker.track(
buildFormFocusOrChange({ schema: 'focus_form', formId, elementId, nodeName, type, elementClasses, value })
- ),
+ )!,
expected,
t
);
@@ -524,7 +524,7 @@ test('should track a form change event', (t) => {
compare(
tracker.track(
buildFormFocusOrChange({ schema: 'change_form', formId, elementId, nodeName, type, elementClasses, value })
- ),
+ )!,
expected,
t
);
@@ -555,7 +555,7 @@ test('should track a form submission event', (t) => {
data: inputJson,
}),
};
- compare(tracker.track(buildFormSubmission({ formId, formClasses, elements })), expected, t);
+ compare(tracker.track(buildFormSubmission({ formId, formClasses, elements }))!, expected, t);
});
test('should track a site seach event', (t) => {
const terms = ['javascript', 'development'];
@@ -581,7 +581,7 @@ test('should track a site seach event', (t) => {
data: inputJson,
}),
};
- compare(tracker.track(buildSiteSearch({ terms, filters, totalResults, pageResults })), expected, t);
+ compare(tracker.track(buildSiteSearch({ terms, filters, totalResults, pageResults }))!, expected, t);
});
test('should track a consent withdrawn event', (t) => {
const all = false;
@@ -619,7 +619,7 @@ test('should track a consent withdrawn event', (t) => {
}),
};
const consentEvent = buildConsentWithdrawn({ all, id, version, name, description });
- compare(tracker.track(consentEvent.event, consentEvent.context, timestamp), expected, t);
+ compare(tracker.track(consentEvent.event, consentEvent.context, timestamp)!, expected, t);
});
test('should track a consent granted event', (t) => {
const id = '1234';
@@ -657,7 +657,7 @@ test('should track a consent granted event', (t) => {
}),
};
const consentEvent = buildConsentGranted({ id, version, name, description, expiry });
- compare(tracker.track(consentEvent.event, consentEvent.context, timestamp), expected, t);
+ compare(tracker.track(consentEvent.event, consentEvent.context, timestamp)!, expected, t);
});
test('should track a page view with custom context', (t) => {
const pageUrl = 'http://www.example.com';
@@ -682,7 +682,7 @@ test('should track a page view with custom context', (t) => {
data: inputContext,
}),
};
- compare(tracker.track(buildPageView({ pageUrl, pageTitle, referrer }), inputContext), expected, t);
+ compare(tracker.track(buildPageView({ pageUrl, pageTitle, referrer }), inputContext)!, expected, t);
});
test('should track a page view with a timestamp', (t) => {
const timestamp = 1000000000000;
@@ -691,7 +691,7 @@ test('should track a page view with a timestamp', (t) => {
buildPageView({ pageUrl: 'http://www.example.com', pageTitle: 'title', referrer: 'ref' }),
[],
timestamp
- )['dtm'],
+ )!['dtm'],
'1000000000000'
);
});
@@ -710,7 +710,7 @@ test('should add individual name-value pairs to the payload', (t) => {
};
tracker.addPayloadPair('tna', 'sp');
tracker.addPayloadPair('tv', 'js-2.0.0');
- compare(tracker.track(buildPageView({ pageUrl, pageTitle, referrer })), expected, t);
+ compare(tracker.track(buildPageView({ pageUrl, pageTitle, referrer }))!, expected, t);
});
test('should add a dictionary of name-value pairs to the payload', (t) => {
const tracker = trackerCore({ base64: false });
@@ -731,7 +731,7 @@ test('should add a dictionary of name-value pairs to the payload', (t) => {
tna: 'sp',
aid: 'sp325',
});
- compare(tracker.track(buildPageView({ pageUrl, pageTitle, referrer })), expected, t);
+ compare(tracker.track(buildPageView({ pageUrl, pageTitle, referrer }))!, expected, t);
});
test('should reset payload name-value pairs', (t) => {
const tracker = trackerCore({ base64: false });
@@ -747,7 +747,7 @@ test('should reset payload name-value pairs', (t) => {
};
tracker.addPayloadPair('tna', 'mistake');
tracker.resetPayloadPairs({ tna: 'sp' });
- compare(tracker.track(buildPageView({ pageUrl, pageTitle, referrer })), expected, t);
+ compare(tracker.track(buildPageView({ pageUrl, pageTitle, referrer }))!, expected, t);
});
test('should execute a callback', (t) => {
const tracker = trackerCore({
@@ -802,7 +802,7 @@ test('should use setter methods', (t) => {
ua: 'SnowplowJavascript/0.0.1',
refr: referrer,
};
- compare(tracker.track(buildPageView({ pageUrl, pageTitle, referrer })), expected, t);
+ compare(tracker.track(buildPageView({ pageUrl, pageTitle, referrer }))!, expected, t);
});
test('should set true timestamp', (t) => {
@@ -812,7 +812,7 @@ test('should set true timestamp', (t) => {
const result = tracker.track(buildPageView({ pageUrl, pageTitle, referrer }), undefined, {
type: 'ttm',
value: 1477403862,
- });
+ })!;
t.true('ttm' in result);
t.is(result['ttm'], '1477403862');
t.false('dtm' in result);
@@ -828,7 +828,7 @@ test('should set device timestamp as ADT', (t) => {
const result = tracker.track(buildSelfDescribingEvent({ event: inputJson }), [inputJson], {
type: 'dtm',
value: 1477403869,
- });
+ })!;
t.true('dtm' in result);
t.is(result['dtm'], '1477403869');
t.false('ttm' in result);
@@ -932,3 +932,105 @@ test('should run plugin before and after track callbacks on each track event', (
t.is(beforeCount, fs.length);
t.is(afterCount, fs.length);
});
+
+test('should skip events in case the plugin filter function returns false', (t) => {
+ let countTracked = 0;
+ const tracker = trackerCore({
+ base64: false,
+ corePlugins: [
+ {
+ filter: (payload) => {
+ return payload.e !== 'pv';
+ },
+ },
+ {
+ filter: (payload) => {
+ return payload.e !== 'pp';
+ },
+ },
+ {
+ afterTrack: () => {
+ countTracked += 1;
+ },
+ },
+ ],
+ });
+
+ t.falsy(
+ tracker.track(
+ buildPageView({
+ pageUrl: 'http://www.example.com',
+ pageTitle: 'title page',
+ referrer: 'https://www.google.com',
+ })
+ )
+ );
+
+ t.falsy(
+ tracker.track(
+ buildPagePing({
+ pageUrl: 'http://www.example.com',
+ pageTitle: 'title page',
+ referrer: 'https://www.google.com',
+ maxXOffset: 1,
+ maxYOffset: 1,
+ minXOffset: 1,
+ minYOffset: 1,
+ })
+ )
+ );
+
+ t.truthy(
+ tracker.track(
+ buildAddToCart({
+ category: 'cat',
+ name: 'name',
+ quantity: 1,
+ sku: 'sku',
+ unitPrice: 1,
+ })
+ )
+ );
+
+ t.assert(countTracked === 1);
+});
+
+test('filter is passed full payload including dynamic context', (t) => {
+ let countTracked = 0;
+ const tracker = trackerCore({
+ base64: false,
+ corePlugins: [
+ {
+ contexts: () => {
+ return [
+ {
+ schema: 'iglu:com.acme/user/jsonschema/1-0-0',
+ data: {
+ userType: 'tester',
+ userName: 'Jon',
+ },
+ },
+ ]
+ },
+ filter: (payload) => {
+ return (payload.co as string).includes('com.acme');
+ },
+ afterTrack: () => {
+ countTracked += 1;
+ },
+ },
+ ],
+ });
+
+ t.truthy(
+ tracker.track(
+ buildPageView({
+ pageUrl: 'http://www.example.com',
+ pageTitle: 'title page',
+ referrer: 'https://www.google.com',
+ })
+ )
+ );
+
+ t.assert(countTracked === 1);
+});
diff --git a/trackers/node-tracker/test/tracker.ts b/trackers/node-tracker/test/tracker.ts
index a0636f4e3..c0fb90f37 100644
--- a/trackers/node-tracker/test/tracker.ts
+++ b/trackers/node-tracker/test/tracker.ts
@@ -110,7 +110,7 @@ for (const method of testMethods) {
const eventPayload = track.track(
buildPageView({ pageUrl: 'http://www.example.com', pageTitle: 'example page', referrer: 'http://google.com' }),
context
- );
+ )!;
t.truthy(eventPayload.eid);
t.regex(eventPayload.eid as string, UUID_REGEX);
});