# `Cerberus.Locator`
[🔗](https://github.com/ftes/cerberus/blob/v0.1.7/lib/cerberus/locator.ex#L1)

Normalize user input into a canonical locator AST.

The AST supports:
- leaf locators (`:text`, `:label`, `:css`, `:testid`, ...)
- composition (`:scope`, `:and`, `:or`, `:not`)
- descendant/state filters via `filter/2` (`:has`, `:has_not`, and `:visible`)
- closest-scope input via `:from`
- regex text values for text-like locators and role names (without `:exact`)

# `composite_kind`

```elixir
@type composite_kind() :: :scope | :and | :or | :not
```

# `composite_value`

```elixir
@type composite_value() :: [t()]
```

# `leaf_kind`

```elixir
@type leaf_kind() :: :text | :label | :placeholder | :title | :alt | :testid | :css
```

# `locator_kind`

```elixir
@type locator_kind() :: leaf_kind() | role_kind() | composite_kind()
```

# `normalize_result`

```elixir
@type normalize_result() :: {:ok, t()} | {:error, Exception.t()}
```

# `resolved_role_kind`

```elixir
@type resolved_role_kind() :: :text | :label | :link | :button | :alt
```

# `role_kind`

```elixir
@type role_kind() :: :role
```

# `t`

```elixir
@type t() :: %Cerberus.Locator{
  kind: locator_kind(),
  opts: keyword(),
  value: String.t() | Regex.t() | composite_value()
}
```

# `closest`

```elixir
@spec closest(t(), Cerberus.Options.closest_opts()) :: t()
```

# `compose_and`

```elixir
@spec compose_and(t(), t()) :: t()
```

# `compose_not`

```elixir
@spec compose_not(t()) :: t()
```

# `compose_or`

```elixir
@spec compose_or(t(), t()) :: t()
```

# `compose_scope`

```elixir
@spec compose_scope(t(), t()) :: t()
```

# `contains_has_filter?`

```elixir
@spec contains_has_filter?(t()) :: boolean()
```

# `contains_kind?`

```elixir
@spec contains_kind?(t(), locator_kind()) :: boolean()
```

# `filter`

```elixir
@spec filter(
  t(),
  keyword()
) :: t()
```

# `leaf`

```elixir
@spec leaf(leaf_kind(), String.t() | Regex.t(), Cerberus.Options.locator_leaf_opts()) ::
  t()
```

# `normalize`

```elixir
@spec normalize(t()) :: normalize_result()
```

Normalizes locators and returns `{:ok, locator}` or `{:error, reason}`.

# `normalize!`

```elixir
@spec normalize!(t()) :: t()
```

Normalizes locators and raises `Cerberus.InvalidLocatorError` on invalid input.

# `put_from`

```elixir
@spec put_from(t(), t()) :: t()
```

# `resolve_role_kind`

```elixir
@spec resolve_role_kind(String.t() | atom()) :: {:ok, resolved_role_kind()} | :error
```

# `resolve_role_kind!`

```elixir
@spec resolve_role_kind!(String.t() | atom(), term()) :: resolved_role_kind()
```

# `resolved_kind`

```elixir
@spec resolved_kind(t()) :: locator_kind() | resolved_role_kind()
```

# `role`

```elixir
@spec role(String.t() | atom(), Cerberus.Options.role_locator_opts()) :: t()
```

# `sigil`

```elixir
@spec sigil(
  String.t(),
  charlist()
) :: t()
```

# `text_sigil`

```elixir
@spec text_sigil(String.t()) :: t()
```

---

*Consult [api-reference.md](api-reference.md) for complete listing*
