Skip to content

Commit bfccaf1

Browse files
authored
Merge pull request #1460 from searchspring/ac-cached-render-event
fix: prevent autocomplete render event for cached responses, increate…
2 parents 9e6ddf6 + af580ab commit bfccaf1

3 files changed

Lines changed: 58 additions & 4 deletions

File tree

packages/snap-controller/src/Autocomplete/AutocompleteController.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -853,7 +853,8 @@ export class AutocompleteController extends AbstractController {
853853
this.events[responseId] = this.events[responseId] || { product: {}, banner: {} };
854854

855855
const previousResponseId = this.store.results[0]?.responseId;
856-
if (previousResponseId && previousResponseId === responseId) {
856+
const repeatedSearch = previousResponseId && previousResponseId === responseId;
857+
if (repeatedSearch) {
857858
const impressedResultIds = Object.keys(this.events[responseId].product || {}).filter(
858859
(resultId) => this.events[responseId].product?.[resultId]?.impression
859860
);
@@ -893,8 +894,10 @@ export class AutocompleteController extends AbstractController {
893894
// update the store
894895
this.store.update(response);
895896

896-
const data: RenderSchemaData = { responseId };
897-
this.config.beacon?.enabled && this.tracker.events.autocomplete.render({ data, siteId: this.config.globals?.siteId });
897+
if (!repeatedSearch) {
898+
const data: RenderSchemaData = { responseId };
899+
this.config.beacon?.enabled && this.tracker.events.autocomplete.render({ data, siteId: this.config.globals?.siteId });
900+
}
898901

899902
const afterStoreProfile = this.profiler.create({ type: 'event', name: 'afterStore', context: params }).start();
900903

packages/snap-controller/src/utils/isClickWithinProductLink.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import type { Product } from '@searchspring/snap-store-mobx';
22

3-
export const CLICK_DUPLICATION_TIMEOUT = 300;
3+
export const CLICK_DUPLICATION_TIMEOUT = 1000;
44
export const CLICK_THROUGH_CLOSEST_MAX_LEVELS = 12;
55

66
export const isClickWithinProductLink = (e: MouseEvent, result: Product): boolean => {

packages/snap-preact-demo/tests/cypress/e2e/tracking/track.cy.js

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,57 @@ describe('Tracking Beacon 2.0', () => {
196196
});
197197
});
198198

199+
it('does not send autocomplete render or impression events for repeated searches', () => {
200+
let renderCounter = 0;
201+
let impressionCounter = 0;
202+
let initialResponseId;
203+
cy.intercept('POST', /beacon.searchspring.io\/beacon\/v2\/.*\/autocomplete\/render/, (req) => {
204+
renderCounter++;
205+
req.reply({ success: true });
206+
}).as('beacon2/autocomplete/render-initial');
207+
cy.intercept('POST', /beacon.searchspring.io\/beacon\/v2\/.*\/autocomplete\/impression/, (req) => {
208+
impressionCounter++;
209+
req.reply({ success: true });
210+
}).as('beacon2/autocomplete/impression-initial');
211+
212+
cy.visit('https://localhost:2222');
213+
cy.get('input[name="q"]').type('glas');
214+
215+
cy.wait(`@beacon2/autocomplete/render-initial`).then(({ request }) => {
216+
const { data } = JSON.parse(request.body);
217+
initialResponseId = data.responseId;
218+
expect(initialResponseId).to.be.a('string').and.to.not.be.empty;
219+
expect(renderCounter).to.equal(1);
220+
221+
// re-register intercepts to keep counting
222+
cy.intercept('POST', /beacon.searchspring.io\/beacon\/v2\/.*\/autocomplete\/render/, (req) => {
223+
renderCounter++;
224+
req.reply({ success: true });
225+
});
226+
});
227+
cy.wait(`@beacon2/autocomplete/impression-initial`).then(({ request }) => {
228+
const { data } = JSON.parse(request.body);
229+
expect(data.responseId).to.equal(initialResponseId);
230+
expect(impressionCounter).to.equal(1);
231+
232+
cy.intercept('POST', /beacon.searchspring.io\/beacon\/v2\/.*\/autocomplete\/impression/, (req) => {
233+
impressionCounter++;
234+
req.reply({ success: true });
235+
});
236+
237+
// append 's' to make 'glass' - should return cached response (same responseId)
238+
cy.get('input[name="q"]').type('s');
239+
cy.wait(2000).then(() => {
240+
// verify the store still has the same responseId (cached response)
241+
cy.snapController('autocomplete').then(({ store }) => {
242+
expect(store.results.find((result) => result.type === 'product').responseId).to.equal(initialResponseId);
243+
});
244+
expect(renderCounter).to.equal(1);
245+
expect(impressionCounter).to.equal(1);
246+
});
247+
});
248+
});
249+
199250
it('tracked autocomplete impression only once per unique search query', () => {
200251
let counter = 0;
201252
cy.intercept('POST', /beacon.searchspring.io\/beacon\/v2\/.*\/autocomplete\/impression/, (req) => {

0 commit comments

Comments
 (0)