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