github.com/web-platform-tests/wpt.fyi@v0.0.0-20240530210107-70cf978996f1/api/query/README.md (about) 1 # wpt.fyi Search queries 2 3 wpt.fyi supports a structured search syntax, allowing the user to filter specific results. 4 5 ## wpt.fyi search syntax 6 7 As outlined below, the `/api/search` endpoint takes a structured query object. wpt.fyi's 8 UI contains a search-box that converts a search syntax into the required structured query. 9 Listed below are the "atoms" that can be used in a search. 10 11 ### Root queries 12 13 By default, a search query will be implicitly treated as an `exists` query (a disjunction 14 across each of the runs separately). However, there are several other root query types that 15 can be invoked by wrapping the query(s), including explicitly wrapping with `exists`. 16 17 If multiple root queries are used, they are implicitly combined with `AND`, i.e. each query 18 must separately be true. e.g. 19 20 count>1(status:!pass) none(status:missing) 21 22 Requires that more than one non-pass result is present, and none of the results are missing. 23 You can also explicitly combine the root queries with `and`, e.g. 24 25 count<3(status:pass) and none(status:missing) 26 27 Alternatively, root queries can be combined using `or`, e.g. 28 29 none(status:pass) or all(status:pass) 30 31 Note that the `and` conjunction takes precedence over the `or` conjunction. 32 33 #### Exists 34 35 As stated above, exists is the implicit default. 36 37 exists([query1] [query2]) 38 39 Combines the filters such that there exists some result in the row that satisfies each query. 40 41 #### All and None 42 43 all([query1] [query2]) 44 45 Combines filters such that they must all apply to all runs. 46 47 none([query1] [query2]) 48 49 Combines filters such that they must not _all_ apply to _any_ single run. 50 51 #### Sequential 52 53 seq([query1] [query2] [...]) 54 55 Combines filters such that they must apply to runs sequentially. This is mainly 56 useful when there are multiple runs with the same product, e.g. to find a regression 57 58 seq(status:pass status:fail) 59 60 #### Count 61 62 count:[number]([query1] [query2]) 63 64 Requires that the number of results matching the given query/queries is precisely 65 the given count. For example, this search atom can be used to find cases where 66 exactly one result is a failure: 67 68 count:1(status:fail) 69 70 Note that there are some special keywords for count:1, count:2, and count:3 71 (`one`, `two` and `three` respectively). For example, to find results where 72 Safari is the only one missing a result: 73 74 three(status:!missing) safari:missing 75 76 ##### Count inequality 77 78 count[inequality][number]([query1]) 79 80 Requires that the number of results matching the given query satisfies the given 81 inequality comparator. 82 83 count=1(status:PASS) 84 count>1(status:PASS) 85 count<3(status:!FAIL) 86 count<=1(status:FAIL) 87 count>=1(status:MISSING) 88 89 > NOTE: The colon after the `count` is optional for inequalities. Queries like 90 > `count:>1(status:missing)`, with a syntax similar to GitHub's search, will work. 91 92 ### Query atoms 93 94 Within a root query, there are several search atoms that can be used to 95 filter the results (according to the root query). 96 97 #### Path 98 99 path:[path] 100 101 Filters results to a specific path prefix. For example, this search atom can be 102 used to list only results for the `/dom/` directory: 103 104 path:/dom/ 105 106 Note that without the trailing `/`, the `/domparsing/` and `/domxpath` 107 directories would also be included. 108 109 #### Status 110 111 Filters to results with a specific status (or, _not_ a specific status). 112 113 Valid statuses are: 114 115 - `unknown` (a.k.a. `missing`) 116 - `pass` 117 - `ok` 118 - `error` 119 - `timeout` 120 - `notrun` 121 - `fail` 122 - `crash` 123 - `skip` 124 - `assert` 125 126 > NOTE: `ok` is the status of the test harness setup. Individual subtests will have 127 > a status of `pass` - it may be necessary to search for both. 128 129 There are a couple of different ways to filter by status. 130 131 ##### Status for any product 132 133 status:[status] 134 135 or, negation, 136 137 status:![status] 138 139 140 ##### Status for a specific product 141 142 [product]:[status] 143 144 Where `[product]` is a product specification (e.g. `safari`, `chrome-69`). 145 146 #### Meta qualities 147 148 Filters the results to values which possess/exhibit a given quality. 149 150 is:[quality] 151 152 ##### `is:different` 153 154 Filters to rows where there is more than one resulting status for a test 155 across the runs. 156 157 ##### `is:tentative` 158 159 Filters to tests that are marked as tentative (currently based on [file 160 name](https://web-platform-tests.org/writing-tests/file-names.html)). 161 162 ##### `is:optional` 163 164 Filters to tests that are marked as optional (currently based on [file 165 name](https://web-platform-tests.org/writing-tests/file-names.html)). 166 167 **Note**: At this time, the `may` and `should` [metadata 168 flags](https://web-platform-tests.org/writing-tests/css-metadata.html#requirement-flags) 169 are not supported. 170 171 #### And-conjuction 172 173 [query1] and [query2] [and ...] 174 175 Combines filters, such that they must all apply, e.g. 176 177 chrome:pass and firefox:!pass 178 179 #### Or-conjuction 180 181 [query1] or [query2] [or ...] 182 183 Combines filters, such that any must apply, e.g. 184 185 chrome:pass or chrome:ok 186 187 > NOTE: Or-conjuction takes less precedence than `and`. Precedence can be modified 188 > using parens, e.g. `chrome:pass and (firefox:!pass or safari:!pass)` 189 190 ## /api/search 191 192 The `/api/search` endpoint takes an HTTP `POST` method, where the body is of the format 193 194 { 195 "run_ids": [123, 456, ...], 196 "query": { 197 [Structured query] 198 } 199 } 200 201 ### Structured query objects 202 203 Structured query objects are produced by the syntax parser on wpt.fyi. 204 205 The easiest way to build the query you need is to use the syntax above, and inspect 206 the outgoing HTTP `POST` body. 207 208 #### exists 209 210 `exists` query objects perform a disjunction of all of the runs, in order to ensure 211 that each of its queries is satisfied _by the same run_. This matters for the case 212 that there are multiple runs with the same product. 213 214 {"exists": [query1, query2, ...]} 215 216 #### all 217 218 `all` query objects perform a conjunction of all of the runs, in order to ensure 219 that each of its queries is satisfied by all of the runs. 220 221 {"all": [query1, query2, ...]} 222 223 #### none 224 225 `none` query objects perform a disjunction of all of the runs, in order to ensure 226 that no single run satisfies all of its queries. `none` queries are a simplification for 227 `{"not": {"exists": [...] }}` queries. 228 229 {"none": [query1, query2, ...]} 230 231 #### sequential 232 233 `sequential` query objects perform an ordered disjunction of all of the runs. 234 Like exists, the queries must be satisfied by the same run, but in addition, the order 235 of the queries must be satisfied by the runs, in order. 236 237 {"sequential": [query1, query2, ...]} 238 239 #### count 240 241 `count` query objects perform a count across all the runs, returning rows which have 242 a count of exactly the given number. 243 244 { 245 "count": 2, 246 "where": { 247 // query object 248 } 249 } 250 251 #### moreThan and lessThan 252 253 `moreThan` and `lessThan` are similar to count, but perform an inequality instead of 254 equality (exact count). 255 256 { 257 "moreThan": 2, 258 "where": { 259 // query object 260 } 261 } 262 263 #### and 264 265 {"and": [query1, query2, ...]} 266 267 #### or 268 269 {"or": [query1, query2, ...]} 270 271 #### path 272 273 Takes a string of the path prefix to match. 274 275 {"path": "/dom/"} 276 277 #### status 278 279 Takes a string of the status to match. 280 281 {"status": "ok"} 282 283 #### status not 284 285 A not-clause for the given status. 286 287 {"status": {"not": "fail"} } 288 289 #### product status 290 291 Same as satuts, but with a specific product-spec. 292 293 { 294 "product": "chrome-69", 295 "status": "ok", 296 } 297 298 #### link 299 300 `link` query atoms perform a search for tests that have some matching link metadata. 301 302 {"link": pattern} 303 304 E.g. 305 306 Search untriaged issues - 307 308 chrome:fail and !link:bugs.chromium.org 309 310 Search triaged issues - 311 312 chrome:pass and link:bugs.chromium.org 313 314 #### triaged 315 316 `triaged` query atoms perform a search for tests of a specific browser that have link metadata. 317 318 {"triaged": [browsername]} 319 320 Where [browsername] is a browser specification (e.g. safari, chrome). 321 322 E.g. 323 324 Search untriaged Chrome failures - 325 326 chrome:fail and none(triaged:chrome) 327 328 Search triaged Chrome tests - 329 330 chrome:pass and triaged:chrome 331 332 #### label 333 334 `label` query atoms perform a search for tests that have a matching metadata label, 335 regardless of browsers. 336 337 {"label": label} 338 339 Where label is a string and case-insensitive. 340 341 E.g. 342 343 Search triaged tests with a label interop-2022: 344 345 label:interop-2022 346 347 #### is 348 349 `is` query atoms perform a search for tests that possess some meta quality. 350 351 {"is": "different"} 352 353 354 355 See [Meta qualities](#meta-qualities) above for more information on other 356 meta qualities than `"different"`. 357 358 #### feature 359 360 `feature` query atoms perform a search for tests that have a matching 361 feature label, regardless of browsers. 362 363 {"feature": [web-feature-name]} 364 365 Where web-feature-name is a string, case-insensitive and matches the filename base 366 for any of the .yml files in the 367 [feature-group-definitions](https://github.com/web-platform-dx/web-features/tree/main/feature-group-definitions) directory. 368 369 E.g. 370 371 Search the [nesting](https://github.com/web-platform-dx/web-features/blob/main/feature-group-definitions/nesting.yml) feature: 372 373 feature:nesting