Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

A/B Test logic for Article Search Bar #5181

Merged
merged 11 commits into from
Feb 6, 2025
Prev Previous commit
Next Next commit
Log experiment assignment upon launch
tonisevener committed Jan 30, 2025
commit ec6bd9b164f1a102f7988a53d0f5f50e2f1f99e6
2 changes: 1 addition & 1 deletion WMF Framework/Event Platform/EventPlatformClient.swift
Original file line number Diff line number Diff line change
@@ -151,7 +151,7 @@ import WMFData
case talkPages = "/analytics/mobile_apps/ios_talk_page_interaction/2.1.0"
case readingLists = "/analytics/mobile_apps/ios_reading_lists/2.2.0"
case userHistory = "/analytics/mobile_apps/ios_user_history/2.0.0"
case search = "/analytics/mobile_apps/ios_search/2.2.0"
case search = "/analytics/mobile_apps/ios_search/2.3.1"
case sessions = "/analytics/mobile_apps/app_session/1.1.0"
case settings = "/analytics/mobile_apps/ios_setting_action/1.1.0"
case login = "/analytics/mobile_apps/ios_login_action/1.1.0"
Original file line number Diff line number Diff line change
@@ -26,7 +26,7 @@ public final class WMFNavigationExperimentsDataController {
self.experimentsDataController = WMFExperimentsDataController(store: experimentStore)
}

public func assignArticleSearchBarExperiment(project: WMFProject) throws {
public func assignArticleSearchBarExperiment(project: WMFProject) throws -> ArticleSearchBarExperimentAssignment {

guard project.qualifiesForNavigationV2Experiment() else {
throw CustomError.invalidProject
@@ -40,7 +40,16 @@ public final class WMFNavigationExperimentsDataController {
throw CustomError.alreadyAssignedBucket
}

try experimentsDataController.determineBucketForExperiment(.articleSearchBar, withPercentage: articleSearchBarExperimentPercentage)
let bucketValue = try experimentsDataController.determineBucketForExperiment(.articleSearchBar, withPercentage: articleSearchBarExperimentPercentage)

switch bucketValue {
case .articleSearchBarTest:
return ArticleSearchBarExperimentAssignment.test
case .articleSearchBarControl:
return ArticleSearchBarExperimentAssignment.control
default:
throw CustomError.unexpectedAssignment
}
}

public func articleSearchBarExperimentAssignment() throws -> ArticleSearchBarExperimentAssignment {
17 changes: 15 additions & 2 deletions Wikipedia/Code/SearchFunnel.swift
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import WMFData

@objc public final class SearchFunnel: NSObject {
@objc static let shared = SearchFunnel()

@@ -18,11 +20,13 @@
case click
case cancel
case langSwitch = "langswitch"
case launch
}

public struct Event: EventInterface {
public static let schema: EventPlatformClient.Schema = .search
let action: Action
let actionData: [String: String]?
let source: String
let position: Int?
let search_type: String?
@@ -38,9 +42,9 @@
return lang
}

func logEvent(action: Action, source: String, position: Int? = nil, searchType: WMFSearchType? = nil, numberOfResults: Int? = nil, timeToDisplay: Int? = nil, wikiId: String?) {
func logEvent(action: Action, actionData: [String: String]? = nil, source: String, position: Int? = nil, searchType: WMFSearchType? = nil, numberOfResults: Int? = nil, timeToDisplay: Int? = nil, wikiId: String?) {
guard let searchSessionToken else { return }
let event = Event(action: action, source: source, position: position, search_type: searchType?.rawValue, number_of_results: numberOfResults, time_to_display_results: timeToDisplay, session_token: searchSessionToken, wiki_id: wikiId)
let event = Event(action: action, actionData: actionData, source: source, position: position, search_type: searchType?.rawValue, number_of_results: numberOfResults, time_to_display_results: timeToDisplay, session_token: searchSessionToken, wiki_id: wikiId)
EventPlatformClient.shared.submit(stream: .search, event: event)
}

@@ -72,6 +76,15 @@
func logShowSearchError(with type: WMFSearchType, elapsedTime: Double, source: String) {
logEvent(action: .error, source: source, searchType: type, timeToDisplay: Int(elapsedTime * 1000), wikiId: searchLanguage)
}

func logDidAssignArticleSearchExperiment(assignment: WMFNavigationExperimentsDataController.ArticleSearchBarExperimentAssignment) {
let group: String
switch assignment {
case .control: group = "a"
case .test: group = "b"
}
logEvent(action: .launch, actionData: ["group": group], source: "unknown", wikiId: nil)
}

}

4 changes: 2 additions & 2 deletions Wikipedia/Code/WMFAppViewController+Extensions.swift
Original file line number Diff line number Diff line change
@@ -105,11 +105,11 @@ extension WMFAppViewController {
}

do {
try dataController.assignArticleSearchBarExperiment(project: project)
let assignment = try dataController.assignArticleSearchBarExperiment(project: project)
SearchFunnel.shared.logDidAssignArticleSearchExperiment(assignment: assignment)
} catch {
DDLogWarn("Error assigning article search experiment: \(error)")
}

}

}