Page MenuHomePhabricator

Instrument Vue.js search
Closed, ResolvedPublic8 Estimated Story Points


This task encompasses the work to implement the instrumentation requirements identified in T249366. The initial requirements suggest that only the top-most search component needs instrumentation.

Acceptance criteria

  • T250282 requirements are implemented.
  • Any long term plans are tasked.
  • Any recommendations are documented on wiki.

Options (not necessarily exclusive)

  1. Add data-event-name attributes to each component primitive and let the WikimediaEvents document onClickListener extract any data it needs. This is the approach used by the sidebar in T250282.
  2. Like 1, emit data logging events for each component and the consumer can use them or not. This would allow our schemas to be more standardized but may not have all the custom data clients want. It may also add some bloat to the library.
  3. Add top-level search form instrumentation. We can ensure that whatever lifecycles (e.g., mounted) and methods (e.g., getQuery()) are needed are exposed. The logging could live in WVUI or Vector as wanted.
  4. Something else.
    1. Vuex was also discussed as a robust solution for more complex scenarios but is out of scope for search.
    2. Logging directives, plugins, or mixins could be used to specify a logger where wanted.



QA of the instrumentation is blocked on T259798 or setting up a staging environment with WikimediaEvents support (note patchdemo does not support WikimediaEvents)

Event Timeline

There are a very large number of changes, so older changes are hidden. Show Older Changes

@MNeisler: If you do want to mark Vue.js widget-produced events in the SearchSatisfaction schema, you'd need to add such a field to its current.yaml in the modern event platform schema repository as described in wikitech:Event Platform/Schemas#Modifying schemas, not the legacy schema on meta.

Also, the extraParams field was created for exactly such situations so you could have events with extraParams: "vuejs-widget" and use that for filtering instead.

And any new instruments based on SearchSatisfaction schema

Hm. Yes you could change the SearchSatsifaction instrumentation code to use mw.eventLog.submit, but you'd have to make sure that the legacy integration logic that is currently formatting the event like EventGate wants it is run in the instrumentation code instead.

For legacy EventLogging schemas, I think it is fine to continue to run with mw.eventLog.logEvent if you prefer. Or, at least it wasn't in the migration plan to move them to mw.eventLog.submit.

@Niedzielski: okay, so unless y'all want to make a new Event Platform schema from scratch (but inspired by SearchSatisfaction, but sans the legacy event capsule stuff that the port has to have), you'll want to use mw.eventLog.logEvent()

I'm going to start by defining some terms – that this has to be done should probably be taken as a warning sign for a long comment!

We can safely ignore the SearchSatisfaction supporting code here.

Now, in order to use the SearchSatisfaction instrument with the Vue.js-based search widget, we'll need to speak the searchSuggest protocol, which is a little… complicated at times. What follows are my rough notes of what we'll have to send and when we'll have to send it:

1. User types a character in the search widget
mw.track( 'mediawiki.searchSuggest', {
  action: 'session-start'
} );
2. Autocomplete results are displayed
const query = 'Cult of Luna';
const request = makeRequest( query ); 

request.done( ( results ) => {
  mw.track( 'mediawiki.searchSuggest', {
      action: 'impression-results',
      numberOfResults: results.length,
      resultSetType: request.getResponseHeader( 'X-OpenSearch-Type' ) || 'unknown',
      searchId: request.getResponseHeader( 'X-Search-ID' ) || null,
      query: query,

      // The SearchSatisfaction schema already has a field to track where the search widget was placed.
      inputLocation: 'moved', // See T256100
  } );
} );
3. User clicks an autocomplete result
mw.track( 'mediawiki.searchSuggest', {
  action: 'click-result',
  index: /* ... */,
  numberOfResults: results.length
} );
4. User submits the search form

At this point, the protocol becomes more complicated. The submit-form action leads the SearchSatisfaction instrument to directly manipulate the DOM, adding a hidden input element that encodes the position of the result in the provenance parameter to the DOM element.

// If the user has highlighted a result with their keyboard, then this is the index of that result in
// the result set; -1 otherwise.
const resultIndex = /* ... */;

mw.track( 'mediawiki.searchSuggest', {
  action: 'submit-form',
  index: resultIndex,
  numberOfResults: results.length,
  $form: $( formElement )
} );

Note well that the same SearchSatisfaction event is logged by both the submit-form and click-result actions. The former only exists to facilitate the creation/maintenance of the hidden input. However, the value of the hidden input is easy to compute (see below) so we can deviate from the protocol here.

function getWprovFromResultIndex( index ) {

  // If the user hasn't highlighted an autocomplete result, NOOP.
  if ( index === -1 ) {
    return 'acrw1';

  return 'acrw1' + index;
5. When an autocomplete result is rendered

The searchSuggest protocol also facilitates adding a provenance parameter to the URLs of autocomplete result via the render-one action. Similar to 4, the value of this parameter is easy to compute given the index of the autocomplete result in the result set so we can add it ourselves, i.e.

const BASE_URL = '/wiki/Special:Search';

function getAutocompleteResultUrl( result, index ) {
  const url = new mw.Uri( BASE_URL );

  url.query.wprov = getWprovFromResultIndex( index );

  /* ... */

It's worth pointing out that if we do choose to ignore the protocol for 4 and 5 above, we'll still have to reconcile the Vue.js-based search widget with the protocol or vice versa if/when it's deployed.

Change 629693 had a related patch set uploaded (by Phuedx; owner: Phuedx):
[wvui@master] Add fundamentals of instrumentation for TypeaheadSearch component

^Followed up on the open patch with some feedback that can be addressed in the meantime

Change 631799 had a related patch set uploaded (by Phuedx; owner: Phuedx):
[wvui@master] [search] TypeaheadSearch emits suggestion-click and submit events

Change 629693 abandoned by Phuedx:
[wvui@master] Add instrumentation for TypeaheadSearch component

Abandoned in favour of Ic967b5e58768123f8561c455178a71d933f08228.

Change 638487 had a related patch set uploaded (by Phuedx; owner: Phuedx):
[wvui@master] [components][typeahead-search] Further tidy onInput method definition

Change 638487 merged by jenkins-bot:
[wvui@master] [components][typeahead-search] Further tidy onInput method definition

Change 640115 had a related patch set uploaded (by Phuedx; owner: Phuedx):
[mediawiki/skins/Vector@feat/search] [WIP] [search] Instrument Vue.js-based search widget

Change 643266 had a related patch set uploaded (by Phuedx; owner: Phuedx):
[wvui@master] [components][typeahead-search] Show footer when there aren't suggestions

Change 643266 merged by jenkins-bot:
[wvui@master] [components][typeahead-search] Show footer when there aren't suggestions

Change 643355 had a related patch set uploaded (by Phuedx; owner: Phuedx):
[mediawiki/skins/Vector@master] [WIP] [search] Instrument Vue.js-based search widget

Change 643355 abandoned by Phuedx:
[mediawiki/skins/Vector@master] [WIP] [search] Instrument Vue.js-based search widget


Change 643355 restored by Phuedx:
[mediawiki/skins/Vector@master] [WIP] [search] Instrument Vue.js-based search widget

Change 640115 abandoned by Phuedx:
[mediawiki/skins/Vector@feat/search] [WIP] [search] Instrument Vue.js-based search widget


Change 631799 merged by jenkins-bot:
[wvui@master] [components][typeahead-search] Emit suggestion-click and submit events

The Vector integration patch has been merged on the basis that the new search is disabled by default and will only work while is checked out. This unblocks review here and I've found an issue with the logging of click events on

There is a bug in the instrumentation inside wvui library.

Whenever clicking a search result, the event is logged with an index of -1, this is because updateSuggestions sets this.suggestionActiveIndex to -1

and onSuggestionClick calls this method here:

Change 643355 merged by jenkins-bot:
[mediawiki/skins/Vector@master] [search] Instrument Vue.js-based search widget

Change 647322 had a related patch set uploaded (by Phuedx; owner: Phuedx):
[wvui@master] [components][typeahead-search] Fix suggestion-click event data

Change 647322 merged by jenkins-bot:
[wvui@master] [components][typeahead-search] Fix suggestion-click event data

Jdlrobson reassigned this task from Edtadros to Jdrewniak.
Jdlrobson added a subscriber: Edtadros.

@Jdrewniak could you update the core patch with the latest wvui master? Once that's done I can setup a QA instance for Edward.

Change 649858 had a related patch set uploaded (by Jdrewniak; owner: Jdrewniak):
[mediawiki/extensions/WikimediaEvents@master] Update query selector for modern Vector test in searchSatisfaction

@phuedx Working off of WikimediaEvents & Vector master, we changed #app to #p-search in Vector, so I updated the following line in the patch above.

Also, I'm going to assume that the value extraParams: "{}" is OK on the initial page-load (it looks like that value is derived from more things than we are interested in).

Change 649858 merged by jenkins-bot:
[mediawiki/extensions/WikimediaEvents@master] Update query selector for modern Vector test in searchSatisfaction

phuedx claimed this task.

Being bold.