Add search widget treatment A/B test

If the VectorSearchTreatmentABTest config variable is truthy and the
user is loged in, then pick the Core treatment (defined in the
mediawiki.searchSuggest RL module) or Vector's Vue.js-based treatment of
the search widget based on their user ID. If not, then fall back to
picking the treatment based on VectorUseWvuiSearch.

Supporting changes:

* Update initSearchLoader() in skins.vector.js/searchLoader.js to check
  whether the body.skin-vector-search-vue exists

* Remove wgVectorUseWvuiSearch from the skins.vector.js RL module's config

* Update the performance-related metrics collection to check which
  module is being loaded rather that use the above

Bug: T261647
Change-Id: Idc978392f5db14f0ae2b06ade0175fe534f4ae70
This commit is contained in:
Sam Smith 2021-01-18 19:52:15 +00:00
parent 62376398d6
commit 746315bb5b
4 changed files with 33 additions and 7 deletions

View file

@ -153,6 +153,18 @@ final class Constants {
*/
public const SEARCH_BOX_INPUT_LOCATION_DEFAULT = 'header-navigation';
/**
* Defines whether or not the Core/Vue.js Search Widget A/B test is running. See
* https://phabricator.wikimedia.org/T261647 for additional detail about the test.
*
* Note well that if the associated config value is falsy, then we fall back to choosing the
* search widget treatment based on the `VectorUseCoreSearch` config variable (see
* `resources/skins.vector.js/searchLoader.js`).
*
* @var string
*/
public const CONFIG_SEARCH_TREATMENT_AB_TEST = 'VectorSearchTreatmentABTest';
/**
* This class is for namespacing constants only. Forbid construction.
* @throws FatalError

View file

@ -37,7 +37,6 @@ class Hooks {
) {
return [
'wgVectorSearchHost' => $config->get( 'VectorSearchHost' ),
'wgVectorUseWvuiSearch' => $config->get( 'VectorUseWvuiSearch' ),
];
}
@ -279,12 +278,20 @@ class Hooks {
return;
}
// Determine the search widget treatment to send to the user
$config = $sk->getConfig();
$user = $sk->getUser();
$shouldUseWvuiSearch = $config->get( 'VectorUseWvuiSearch' );
if ( $config->get( 'VectorUseWvuiSearch' ) ) {
if ( $config->get( 'VectorSearchTreatmentABTest' ) && $user->isRegistered() ) {
$shouldUseWvuiSearch = $user->getID() % 2 === 0;
}
if ( $shouldUseWvuiSearch ) {
$bodyAttrs['class'] .= ' skin-vector-search-vue';
}
// Should we disable the max-width styling?
if ( $sk->getTitle() && self::shouldDisableMaxWidth(
$config->get( 'VectorMaxWidthOptions' ),
$sk->getTitle(),

View file

@ -13,8 +13,7 @@ var /** @type {VectorResourceLoaderVirtualConfig} */
config = require( /** @type {string} */ ( './config.json' ) ),
// T251544: Collect search performance metrics to compare Vue search with
// mediawiki.searchSuggest performance.
SHOULD_TEST_SEARCH = !!(
config.wgVectorUseWvuiSearch &&
CAN_TEST_SEARCH = !!(
window.performance &&
performance.mark &&
performance.measure &&
@ -38,6 +37,7 @@ var /** @type {VectorResourceLoaderVirtualConfig} */
* @param {function(): void} afterLoadFn function to execute after search module loads.
*/
function loadSearchModule( element, moduleName, afterLoadFn ) {
var SHOULD_TEST_SEARCH = CAN_TEST_SEARCH && moduleName === 'skins.vector.search';
function requestSearchModule() {
if ( SHOULD_TEST_SEARCH ) {
@ -116,7 +116,7 @@ function setLoadingIndicatorListeners( element, attach, eventCallback ) {
* Marks when the lazy load has completed.
*/
function markLoadEnd() {
if ( SHOULD_TEST_SEARCH && performance.getEntriesByName( LOAD_START_MARK ).length ) {
if ( performance.getEntriesByName( LOAD_START_MARK ).length ) {
performance.mark( LOAD_END_MARK );
performance.measure( LOAD_MEASURE, LOAD_START_MARK, LOAD_END_MARK );
}
@ -130,7 +130,8 @@ function markLoadEnd() {
*/
function initSearchLoader( document ) {
var searchForm = document.getElementById( SEARCH_FORM_ID ),
searchInput = document.getElementById( SEARCH_INPUT_ID );
searchInput = document.getElementById( SEARCH_INPUT_ID ),
shouldUseCoreSearch;
// Allow developers to defined $wgVectorSearchHost in LocalSettings to target different APIs
if ( config.wgVectorSearchHost ) {
@ -141,6 +142,8 @@ function initSearchLoader( document ) {
return;
}
shouldUseCoreSearch = !document.body.classList.contains( 'skin-vector-search-vue' );
/**
* 1. If $wgVectorUseWvuiSearch is false,
* or we are in a browser that doesn't support fetch
@ -149,7 +152,7 @@ function initSearchLoader( document ) {
* 2. If we're using a different search module, enable the loading indicator
* before the search module loads.
**/
if ( !config.wgVectorUseWvuiSearch || !window.fetch ) {
if ( shouldUseCoreSearch || !window.fetch ) {
loadSearchModule( searchInput, 'mediawiki.searchSuggest', function () {} );
} else {
// Remove tooltips while Vue search is still loading

View file

@ -223,6 +223,10 @@
"VectorUseWvuiSearch": {
"value": false
},
"VectorSearchTreatmentABTest": {
"value": false,
"description": "@var boolean Enables or disables the search treatment A/B test. See https://phabricator.wikimedia.org/T261647 and associated tasks for additional detail."
},
"VectorWvuiSearchOptions": {
"value": {
"showThumbnail": true,