### Get Experiment Manager Service (PHP) Source: https://context7.com/wikimedia/mediawiki-extensions-testkitchen/llms.txt Access the ExperimentManager service to work with experiments server-side. Handles user enrollment and experiment coordination. ```php use MediaWiki\MediaWikiServices; // Get the ExperimentManager service $experimentManager = MediaWikiServices::getInstance() ->getService('TestKitchen.ExperimentManager'); // Initialize with request data (typically done in hooks) $experimentManager->setRequest($request); // Update enrollment based on logged-in user $experimentManager->updateUser($user); // Update enrollment using identifier directly $experimentManager->updateIdentifier('mw-user', (string)$centralId); ``` -------------------------------- ### Get Experiment and Check Assignment (PHP) Source: https://context7.com/wikimedia/mediawiki-extensions-testkitchen/llms.txt Retrieve an experiment and work with it server-side. Similar API to the JavaScript SDK for checking group assignments. ```php use MediaWiki\MediaWikiServices; $experimentManager = MediaWikiServices::getInstance() ->getService('TestKitchen.ExperimentManager'); // Get experiment by name $experiment = $experimentManager->getExperiment('my-awesome-experiment'); // Check assigned group $group = $experiment->getAssignedGroup(); // Returns string or null // Check if user is in specific group(s) if ($experiment->isAssignedGroup('treatment')) { // Show treatment variant } // Check multiple groups if ($experiment->isAssignedGroup('treatment-a', 'treatment-b')) { // User is in one of the treatment groups } ``` -------------------------------- ### Retrieve All User Assignments Source: https://context7.com/wikimedia/mediawiki-extensions-testkitchen/llms.txt Get a map of all current experiment assignments. This is primarily intended for internal use cases like error logging. ```javascript const assignments = mw.testKitchen.getAssignments(); // Returns: { 'experiment-1': 'treatment', 'experiment-2': 'control' } // Check if user has any assignments if (Object.keys(assignments).length > 0) { console.log('User is enrolled in experiments:', assignments); } ``` -------------------------------- ### Get Instrument for Analytics Source: https://context7.com/wikimedia/mediawiki-extensions-testkitchen/llms.txt Retrieves an instrument for analytics data collection. Use this to track non-experiment analytics with configurable sampling rates. ```javascript const instrument = mw.testKitchen.getInstrument('my-analytics-instrument'); // Check if the instrument is in sample if (instrument.isInSample()) { // Send analytics event instrument.send('page_load', { load_time_ms: performance.now() }); } // Send event (no-op if out of sample) instrument.send('feature_used', { feature_name: 'dark_mode_toggle' }); // Send event immediately using sendBeacon (for page unload scenarios) instrument.sendImmediately('page_exit', { time_on_page_ms: getTimeOnPage() }); ``` -------------------------------- ### Configure Extension in LocalSettings.php Source: https://context7.com/wikimedia/mediawiki-extensions-testkitchen/llms.txt Define global configuration variables for experiment features, API endpoints, and event intake services. ```php // Enable experiment features $wgTestKitchenEnableExperiments = true; // Enable fetching configs from Test Kitchen UI (not for production) $wgTestKitchenEnableConfigsFetching = false; // Base URL for Test Kitchen UI API $wgTestKitchenInstrumentConfiguratorBaseUrl = 'https://testkitchen.example.org'; // Event intake service name (must be a key in $wgEventServices) $wgTestKitchenEventIntakeServiceName = 'eventgate-analytics'; // Event intake URLs for different experiment types $wgTestKitchenExperimentEventIntakeServiceUrl = 'https://eventgate.example.org/v1/events'; $wgTestKitchenLoggedInExperimentEventIntakeServiceUrl = 'https://eventgate.example.org/v1/events'; $wgTestKitchenInstrumentEventIntakeServiceUrl = 'https://eventgate.example.org/v1/events'; // Stream names for Test Kitchen experiments $wgTestKitchenExperimentStreamNames = [ 'product_metrics.web_base' ]; // Experiments to preserve in auth query params $wgTestKitchenAuthPreserveQueryParamsExperiments = []; // Exposure log reset epoch (seconds) for global invalidation $wgTestKitchenExposureResetEpoch = 0; ``` -------------------------------- ### Extension Configuration Source: https://context7.com/wikimedia/mediawiki-extensions-testkitchen/llms.txt Configuration settings for TestKitchen in LocalSettings.php. ```APIDOC ## LocalSettings.php Configuration ### Description Global configuration variables for enabling experiments and setting event intake service URLs. ### Configuration Variables - **$wgTestKitchenEnableExperiments** (bool) - Enable experiment features. - **$wgTestKitchenEventIntakeServiceName** (string) - The service name for event intake. - **$wgTestKitchenExperimentStreamNames** (array) - List of stream names for experiments. ``` -------------------------------- ### Configure Custom Stream and Schema Source: https://context7.com/wikimedia/mediawiki-extensions-testkitchen/llms.txt Override default stream and schema settings for experiment events using fluent method chaining. ```php $experiment = $experimentManager->getExperiment('my-awesome-experiment'); // Set custom stream (updates contextual attributes automatically) $experiment->setStream('my_custom_stream'); // Set custom schema $experiment->setSchema('/my/custom/schema/1.0.0'); // Chain methods and send $experiment ->setStream('my_custom_stream') ->setSchema('/my/custom/schema/1.0.0') ->send('custom_action', ['data' => 'value']); ``` -------------------------------- ### Retrieve Experiments by Prefix Source: https://context7.com/wikimedia/mediawiki-extensions-testkitchen/llms.txt Fetch multiple experiments matching a specific naming prefix. Useful for managing sequential or related experiments. ```javascript // User is enrolled in: // - my-awesome-experiment-1 // - my-awesome-experiment-2 // - my-other-awesome-experiment // Get all experiments starting with 'my-awesome-experiment-' const experiments = mw.testKitchen.getExperimentsByPrefix('my-awesome-experiment-'); // Returns array with my-awesome-experiment-1 and my-awesome-experiment-2 experiments.forEach((exp) => { exp.send('interaction', { action_source: 'weekly_survey' }); }); ``` -------------------------------- ### Retrieve and Check Experiment Assignments Source: https://context7.com/wikimedia/mediawiki-extensions-testkitchen/llms.txt Use getExperiment to access an experiment object. Check group assignments using isAssignedGroup or retrieve the group name directly with getAssignedGroup. ```javascript // Get an experiment and check the assigned group const experiment = mw.testKitchen.getExperiment('my-awesome-experiment'); // Check if user is in a specific group if (experiment.isAssignedGroup('treatment')) { // Show treatment variant showNewFeature(); } // Check multiple groups at once if (experiment.isAssignedGroup('treatment-a', 'treatment-b')) { // User is in one of the treatment groups } // Get the assigned group name directly const group = experiment.getAssignedGroup(); // Returns 'control', 'treatment', etc. or null ``` -------------------------------- ### JavaScript SDK Experiment Methods Source: https://context7.com/wikimedia/mediawiki-extensions-testkitchen/llms.txt Methods for retrieving experiments, checking group assignments, and managing experiment overrides. ```APIDOC ## mw.testKitchen.getExperiment(name) ### Description Retrieves an experiment object by name to check group assignments and send events. ### Parameters - **name** (string) - Required - The name of the experiment. ## mw.testKitchen.getExperimentsByPrefix(prefix) ### Description Retrieves all experiments that match a given prefix. ### Parameters - **prefix** (string) - Required - The prefix string to match experiment names. ## mw.testKitchen.overrideExperimentGroup(name, group) ### Description Manually overrides the assigned group for an experiment for testing and QA purposes. ### Parameters - **name** (string) - Required - The experiment name. - **group** (string) - Required - The group name to assign. ``` -------------------------------- ### Stub Experiments for Unit Testing (QUnit) Source: https://context7.com/wikimedia/mediawiki-extensions-testkitchen/llms.txt Stub experiments for unit testing to test experiment-dependent code without actual experiment enrollment. Requires QUnit. ```javascript // In QUnit tests QUnit.test('my feature with experiment', function(assert) { // Create fake experiments helper const tk = mw.testKitchen.useFakeExperiments(); // Stub an experiment with specific group assignment const experiment = tk.stubExperiment('my-awesome-experiment', 'treatment'); // Run code under test that calls mw.testKitchen.getExperiment() myFeature.initialize(); // Assert events were sent assert.strictEqual(experiment.eventCount, 1); assert.strictEqual(experiment.events[0].action, 'feature_init'); assert.deepEqual(experiment.events[0].interactionData, { source: 'auto' }); // Check global event count across all stubbed experiments assert.strictEqual(tk.globalEventCount, 1); // Restore original getExperiment tk.restore(); }); ``` -------------------------------- ### Define Experiment Interface Source: https://context7.com/wikimedia/mediawiki-extensions-testkitchen/llms.txt The ExperimentInterface contract for managing experiment states and event dispatching. ```php namespace MediaWiki\Extension\TestKitchen\Sdk; interface ExperimentInterface { /** * Gets the assigned group for the current user * @return string|null */ public function getAssignedGroup(): ?string; /** * Checks if assigned to one of the given groups * @param string ...$groups * @return bool */ public function isAssignedGroup(string ...$groups): bool; /** * Sends an interaction event * @param string $action * @param array $interactionData * @param array $contextualAttributes */ public function send( string $action, array $interactionData = [], array $contextualAttributes = [] ): void; /** * Sends an exposure event with deduplication */ public function sendExposure(): void; } ``` -------------------------------- ### Stub Instruments for Unit Testing (QUnit) Source: https://context7.com/wikimedia/mediawiki-extensions-testkitchen/llms.txt Stub instruments for unit testing to test instrument-dependent code without actual sampling. Requires QUnit. ```javascript // In QUnit tests QUnit.test('my analytics with instrument', function(assert) { // Create fake instruments helper const tk = mw.testKitchen.useFakeInstruments(); // Stub an instrument const instrument = tk.stubInstrument('my-analytics-instrument'); // Run code under test myAnalytics.trackPageLoad(); // Assert events were sent assert.strictEqual(instrument.eventCount, 1); assert.strictEqual(instrument.events[0].action, 'page_load'); // Stubbed instruments always return true for isInSample() assert.true(instrument.isInSample()); // Restore original getInstrument tk.restore(); }); ``` -------------------------------- ### ExperimentManager Service Source: https://context7.com/wikimedia/mediawiki-extensions-testkitchen/llms.txt Methods for interacting with experiments, sending events, and configuring event streams or schemas. ```APIDOC ## PHP ExperimentManager Service ### Description Access the ExperimentManager service to retrieve experiments and send analytics events associated with them. ### Method PHP Service Call ### Parameters - **experimentName** (string) - Required - The identifier of the experiment. - **action** (string) - Required - The action name for the event. - **interactionData** (array) - Optional - Key-value pairs of interaction data. - **contextualAttributes** (array) - Optional - List of contextual attributes to include. ### Request Example $experiment->send('form_submit', ['action_source' => 'special_page']); ### Response - **void** - This method does not return a value. ``` -------------------------------- ### Send Experiment Events in PHP Source: https://context7.com/wikimedia/mediawiki-extensions-testkitchen/llms.txt Use the ExperimentManager service to send various types of analytics events, including simple actions, interaction data, and exposure events. ```php $experimentManager = MediaWikiServices::getInstance() ->getService('TestKitchen.ExperimentManager'); $experiment = $experimentManager->getExperiment('my-awesome-experiment'); // Send simple action event $experiment->send('api_request'); // Send event with interaction data $experiment->send('form_submit', [ 'action_source' => 'special_page', 'action_context' => 'settings' ]); // Send event with additional contextual attributes $experiment->send('page_save', ['revision_id' => $revId], ['performer_is_logged_in', 'performer_edit_count_bucket'] ); // Send exposure event with automatic deduplication $experiment->sendExposure(); ``` -------------------------------- ### JavaScript SDK Event Tracking Source: https://context7.com/wikimedia/mediawiki-extensions-testkitchen/llms.txt Methods for sending analytics events and logging experiment exposure. ```APIDOC ## experiment.send(action, data, attributes) ### Description Sends analytics events associated with an experiment, including metadata. ### Parameters - **action** (string) - Required - The event action name. - **data** (object) - Optional - Interaction data. - **attributes** (array) - Optional - Additional contextual attributes. ## experiment.sendExposure() ### Description Logs an experiment exposure event with automatic deduplication to prevent duplicate events across page views and sessions. ``` -------------------------------- ### Log Experiment Exposure Source: https://context7.com/wikimedia/mediawiki-extensions-testkitchen/llms.txt Log exposure events using sendExposure. This method includes built-in deduplication to prevent redundant logging across page views. ```javascript const experiment = mw.testKitchen.getExperiment('my-awesome-experiment'); // Send exposure event when user is exposed to the experiment // Automatically deduplicated - safe to call multiple times experiment.sendExposure(); // Typical usage: call when the experimental feature is rendered if (experiment.isAssignedGroup('treatment')) { experiment.sendExposure(); renderTreatmentUI(); } ``` -------------------------------- ### InstrumentManager Service Source: https://context7.com/wikimedia/mediawiki-extensions-testkitchen/llms.txt Methods for managing analytics instruments and sending custom metrics. ```APIDOC ## PHP InstrumentManager Service ### Description Access the InstrumentManager service to perform server-side analytics instrumentation. ### Method PHP Service Call ### Parameters - **instrumentName** (string) - Required - The name of the analytics instrument. - **action** (string) - Required - The action name for the event. - **data** (array) - Optional - Data payload for the event. ### Request Example $instrument->send('api_call', ['response_time_ms' => 100]); ### Response - **void** - This method does not return a value. ``` -------------------------------- ### Manage Experiment Group Overrides Source: https://context7.com/wikimedia/mediawiki-extensions-testkitchen/llms.txt Manually set or clear experiment group assignments for testing purposes. Overridden experiments log to the console instead of sending events. ```javascript // Override experiment assignment to 'treatment' group and reload page mw.testKitchen.overrideExperimentGroup('my-awesome-experiment', 'treatment'); // Clear override for a specific experiment mw.testKitchen.clearExperimentOverride('my-awesome-experiment'); // Clear all experiment overrides mw.testKitchen.clearExperimentOverrides(); ``` -------------------------------- ### Access Instrument Manager Service Source: https://context7.com/wikimedia/mediawiki-extensions-testkitchen/llms.txt Retrieve the InstrumentManager service to send analytics events with custom schemas and interaction data. ```php use MediaWiki\MediaWikiServices; // Get the InstrumentManager service $instrumentManager = MediaWikiServices::getInstance() ->getService('TestKitchen.InstrumentManager'); // Get instrument by name $instrument = $instrumentManager->getInstrument('my-analytics-instrument'); // Send analytics event $instrument->send('api_call', [ 'endpoint' => '/api/query', 'response_time_ms' => $responseTime ]); // Set custom schema $instrument->setSchema('/analytics/custom/schema/1.0.0') ->send('custom_metric', ['value' => 42]); ``` -------------------------------- ### Send Experiment Analytics Events Source: https://context7.com/wikimedia/mediawiki-extensions-testkitchen/llms.txt Send events associated with an experiment using the send method. Metadata is automatically included in the event payload. ```javascript const experiment = mw.testKitchen.getExperiment('my-awesome-experiment'); // Send a simple action event experiment.send('button_click'); // Send event with interaction data experiment.send('form_submit', { action_source: 'signup_form', action_context: 'homepage' }); // Send event with additional contextual attributes experiment.send('page_view', { action_source: 'navigation' }, ['performer_is_logged_in', 'performer_is_bot'] ); // Listen to UI events and track them const dialog = require('my.awesome.dialog'); ['open', 'default-action', 'primary-action'].forEach((event) => { dialog.on(event, () => experiment.send(event)); }); ``` -------------------------------- ### Set Custom Schema for Events Source: https://context7.com/wikimedia/mediawiki-extensions-testkitchen/llms.txt Override the default schema ID for experiment or instrument events to send events with custom schemas. ```javascript const experiment = mw.testKitchen.getExperiment('my-awesome-experiment'); // Set custom schema for this experiment's events experiment .setSchema('/my/custom/schema/1.0.0') .send('custom_action'); const instrument = mw.testKitchen.getInstrument('my-instrument'); // Set custom schema for instrument events instrument .setSchema('/analytics/custom/instrument/1.0.0') .send('custom_metric', { value: 42 }); ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.