1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
|
{
"type": "object",
"required": ["telemetryId", "searchPageRegexp", "queryParamName"],
"properties": {
"telemetryId": {
"type": "string",
"title": "Telemetry Id",
"description": "The telemetry identifier for the provider.",
"pattern": "^[a-z0-9-._]*$"
},
"searchPageRegexp": {
"type": "string",
"title": "Search Page Regular Expression",
"description": "A regular expression which matches the search page of the provider."
},
"queryParamName": {
"type": "string",
"title": "Search Query Parameter Name",
"description": "The name of the query parameter for the user's search string. This is deprecated, in preference to queryParamNames, but still defined for older clients (pre Firefox 121)."
},
"queryParamNames": {
"type": "array",
"title": "Search Query Parameter Names",
"description": "An array of query parameters that may be used for the user's search string.",
"items": {
"type": "string"
}
},
"codeParamName": {
"type": "string",
"title": "Partner Code Parameter Name",
"description": "The name of the query parameter for the partner code."
},
"taggedCodes": {
"type": "array",
"title": "Partner Codes",
"description": "An array of partner codes to match against the parameters in the url. Matching these codes will report the SERP as tagged.",
"items": {
"type": "string",
"pattern": "^[a-zA-Z0-9-._]*$"
}
},
"expectedOrganicCodes": {
"type": "array",
"title": "Expected Organic Codes",
"description": "An array of partner codes to match against the parameters in the url. Matching these codes will report the SERP as organic:none which means the user has done a search through the search engine's website rather than through SAP.",
"items": {
"type": "string",
"pattern": "^[a-zA-Z0-9-._]*$"
}
},
"organicCodes": {
"type": "array",
"title": "Organic Codes",
"description": "An array of partner codes to match against the parameters in the url. Matching these codes will report the SERP as organic:<partner code>, which means the search was performed organically rather than through a SAP.",
"items": {
"type": "string",
"pattern": "^[a-zA-Z0-9-._]*$"
}
},
"followOnParamNames": {
"type": "array",
"title": "Follow-on Search Parameter Names",
"description": "An array of query parameter names that are used when a follow-on search occurs.",
"items": {
"type": "string",
"pattern": "^[a-z0-9-._]*$"
}
},
"followOnCookies": {
"type": "array",
"title": "Follow-on Cookies",
"description": "An array of cookie details that are used to identify follow-on searches.",
"items": {
"type": "object",
"properties": {
"extraCodeParamName": {
"type": "string",
"description": "The query parameter name in the URL that indicates this might be a follow-on search.",
"pattern": "^[a-z0-9-._]*$"
},
"extraCodePrefixes": {
"type": "array",
"description": "Possible values for the query parameter in the URL that indicates this might be a follow-on search.",
"items": {
"type": "string",
"pattern": "^[a-zA-Z0-9-._]*$"
}
},
"host": {
"type": "string",
"description": "The hostname on which the cookie is stored.",
"pattern": "^[a-z0-9-._]*$"
},
"name": {
"type": "string",
"description": "The name of the cookie to check.",
"pattern": "^[a-zA-Z0-9-._]*$"
},
"codeParamName": {
"type": "string",
"description": "The name of parameter within the cookie.",
"pattern": "^[a-zA-Z0-9-._]*$"
}
}
}
},
"extraAdServersRegexps": {
"type": "array",
"title": "Extra Ad Server Regular Expressions",
"description": "An array of regular expressions that match URLs of potential ad servers.",
"items": {
"type": "string"
}
},
"adServerAttributes": {
"type": "array",
"title": "Ad Server Attributes",
"description": "An array of strings that potentially match data-attribute keys of anchors.",
"items": {
"type": "string"
}
},
"components": {
"type": "array",
"title": "Components",
"description": "An array of components that could be on the SERP.",
"items": {
"required": ["type"],
"type": "object",
"properties": {
"type": {
"enum": [
"ad_carousel",
"ad_image_row",
"ad_link",
"ad_sitelink",
"ad_sidebar",
"incontent_searchbox",
"refined_search_buttons",
"shopping_tab"
],
"description": "The type of component the anchor or DOM element should belong to."
},
"included": {
"type": "object",
"description": "Conditions that should be fulfilled.",
"properties": {
"parent": {
"title": "Parent",
"description": "The DOM element that should only contain elements applicable to a single component type.",
"type": "object",
"properties": {
"selector": {
"description": "If topDown is true for this component, then this will be the value used in querySelectorAll(). Otherwise, it will be the value to in closest() from the context of an anchor.",
"type": "string"
}
},
"required": ["selector"]
},
"children": {
"type": "array",
"title": "Children",
"description": "Child DOM elements of the parent. Optional.",
"items": {
"type": "object",
"properties": {
"selector": {
"type": "string",
"description": "The selector to use querySelectorAll from the context of the parent."
},
"type": {
"enum": [
"ad_carousel",
"ad_image_row",
"ad_link",
"ad_sitelink",
"ad_sidebar",
"incontent_searchbox",
"refined_search_buttons",
"shopping_tab"
],
"description": "The component type to use if this child is present."
},
"countChildren": {
"type": "boolean",
"description": "Whether we should count all instances of the child element instead of anchor links found inside of the parent. Defaults to false."
}
},
"required": ["selector"]
}
},
"related": {
"type": "object",
"properties": {
"selector": {
"type": "string",
"description": "The selector to use querySelectorAll from the context of the parent. Any elements specified will have their click events registered and categorized as expanded unless explicitly overwritten in SearchSERPTelemetryChild."
}
},
"required": ["selector"]
}
},
"required": ["parent"]
},
"excluded": {
"type": "object",
"description": "Conditions that should not be included.",
"properties": {
"parent": {
"type": "object",
"properties": {
"selector": {
"type": "string",
"description": "The root DOM element that shouldn't be a parent from the context of the anchor being inspected."
}
},
"required": ["selector"]
}
}
},
"default": {
"type": "boolean",
"description": "Whether this component should be the fallback option if a link was included in both ad-related regular expressions as well as regular expressions matching non-ad elements but couldn't be categorized. Defaults to false."
},
"topDown": {
"type": "boolean",
"description": "Whether the component should be found first by using document.querySelectorAll on the parent selector definition. Defaults to false."
},
"dependentRequired": {
"topDown": ["included"]
}
}
}
},
"nonAdsLinkRegexps": {
"type": "array",
"title": "Non-ads link matching regular expressions",
"description": "An array containing known patterns that match non-ad links from a search provider.",
"items": {
"type": "string",
"description": "The matching regular expression."
}
},
"shoppingTab": {
"type": "object",
"title": "Shopping Tab",
"properties": {
"selector": {
"type": "string",
"description": "The elements on the page to inspect for the shopping tab. Should be anchor elements."
},
"regexp": {
"type": "string",
"description": "The regular expression to match against a possible shopping tab. Must be provided if using this feature."
},
"inspectRegexpInSERP": {
"type": "boolean",
"description": "Whether the regexp should be used against hrefs the selector matches against."
}
},
"required": ["selector", "regexp"]
},
"domainExtraction": {
"type": "object",
"title": "Domain Extraction",
"description": "An array of methods for extracting domains from a SERP result.",
"properties": {
"ads": {
"type": "array",
"description": "An array of methods for extracting domains from ads.",
"items": {
"$ref": "/schemas/extraction"
}
},
"nonAds": {
"type": "array",
"description": "An array of methods for extracting domains from non-ads.",
"items": {
"$ref": "/schemas/extraction"
}
}
}
}
},
"$defs": {
"extraction": {
"$id": "/schemas/extraction",
"anyOf": [
{
"type": "object",
"properties": {
"selectors": {
"type": "string",
"description": "The query to inspect all elements on the SERP."
},
"method": {
"enum": ["data-attribute"],
"description": "The extraction method used for the query."
},
"options": {
"type": "object",
"properties": {
"dataAttributeKey": {
"type": "string",
"description": "The data attribute key that will be looked up in order to retrieve its data attribute value."
}
},
"required": ["dataAttributeKey"]
}
},
"required": ["selectors", "method", "options"]
},
{
"type": "object",
"properties": {
"selectors": {
"type": "string",
"description": "The query to use to inspect all elements on the SERP."
},
"method": {
"enum": ["href"],
"description": "The extraction method to use for the query."
},
"options": {
"type": "object",
"properties": {
"queryParamKey": {
"type": "string",
"description": "The query parameter key to inspect in the href."
}
},
"required": ["queryParamKey"]
}
},
"required": ["selectors", "method"]
}
]
}
}
}
|