---
schema_version: "1"
id: f8d8f00ac646a2ff7a5bfde3cae78b51f32324fa8a2b24c16d3e5bad848ab152
title: Working with slots
collection: developer
version: current
locale: en-us
portal_url: https://docs.salesforce.com/developer/current/en-us/lwc/utam/guide/slots.md
canonical_url: https://developer.salesforce.com/docs/platform/utam/guide/slots.html
source_site: developer.salesforce.com
content_type: documentation
content_hash: 63c43cd04cb49f5bdde2f46777c16eb1a2a77edbd2e0c3762ff152809a4b2ea7
products:
  - UI Test Automation Model
  - lwc
---
# Working with slots

A slot is a placeholder inside a web component that you can fill with your own markup, which lets you create separate DOM trees and present them together. See [MDN: slots documentation](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/slot).

## Slot in a Web Component

Let's look at an example of how to use slots in a page object. Here's a modal with account fields. We're using the Salesforce application as an example, but we could use any application that has an account object with certain fields.

![Inspected slot](https://developer.salesforce.com/docs/media/utam/slots_screenshot.jpg)

As you can see from the screenshot, the `<records-record-layout-item>` component has an element `<slot name="inputField"></slot>` that can contain other components like input, lookup, or picklist depending on the account field type.

For the field that we selected for inspection, the content of the slot is a `<records-record-layout-lookup slot="inputField">...</records-record-layout-lookup>` element that has other nested HTML elements.

## Slot in a UTAM page object

To test the content of the `<records-record-layout-item>` component, our page object needs an `"inputFieldContainer"` [container element](/docs/platform/utam/references/utam-grammar/page-object-elements.html) because the item can contain any component inside the slot depending on the setup:

```json
{
  "elements": [
    {
      "type": "container",
      "name": "inputFieldContainer",
      "public": true,
      "selector": {
        "css": "[slot='inputField']"
      }
    }
  ]
}
```

The first thing to notice is that the **content of the slot isn't inside the shadow root, only the slot itself is**.
If a web developer puts something inside a `<slot>`, it becomes the fallback or “default” content. The browser shows it if there’s no corresponding filler in light DOM. Even though our component has a shadow root, the container element isn't crossing the shadow boundary and isn't inside the `"shadow"` element.

## Locating slot and slot content

If a page object element points to a slot itself (for example with `"slot[name='inputField']"`), its internal elements can only be found using [assignedNodes()](https://developer.mozilla.org/en-US/docs/Web/API/HTMLSlotElement/assignedNodes), which isn't supported in UI automation tools. All we can do with such an element is to call basic actions, such as checking its presence or getting its attributes and text.

To point to another component inside the slot, the selector of our container element (`"inputFieldContainer"`) **should point to the content of the slot, not to the slot itself**: `"[slot='inputField']"`.

## Locating content of default slots

To make a UI component more generic, a developer can sometimes add a default slot (a slot without a name).

```html
<div class="slots">
  <slot name="inputField"></slot>
  <!-- default slot after named slot -->
  <slot></slot>
</div>
```

At run time, the content of the slot can be anything, so the page object can handle it in one of the following ways:

### 1. If the slot is the first element of its parent, use the default container

If you try to access the content of the first slot inside its parent, use the default selector (do not add a `"selector"` property to the JSON).

For example for the given HTML:

```html
<template>
  <!-- first slot is default slot -->
  <slot></slot>
</template>
```

The following container element can access the content.

```json
{
  "elements": [
    {
      "type": "container",
      "name": "firstSlotContent",
      "public": true
      // default selector is ":scope > *:first-child"
    }
  ]
}
```

### 2. Add a custom element of the hardcoded type (not recommended)

This approach is not a good option because you would have to add a method for every possible element. However, it might be a better option than hardcoding a selector in every test.

```json
{
  "elements": [
    {
      "type": "my/component",
      "name": "myComponentInsideSlot",
      "public": true,
      "selector": {
        "css": "my-component"
      }
    }
  ]
}
```

### 3. Locate with hardcoded CSS parameter passed at run time (not recommended)

A parameter can expose a hardcoded selector to the test; for example: `field.getRuntimeContent(MyComponent, "my-component")`. This approach violates encapsulation, but sometimes it's the only option.

Because we do not know CSS selector to locate content, it has to be added as a parameter.

```json
{
  "elements": [
    {
      "type": "container",
      "name": "runtimeContent",
      "public": true,
      "selector": {
        "css": "%s",
        "args": {
          "name": "hardcodedSelector",
          "type": "string"
        }
      }
    }
  ]
}
```

This parameter exposes a hardcoded selector to a UI test (for our example test code would be: `field.getRuntimeContent(MyComponent, "my-component")`.
This approach violates encapsulation, but can be the only available option for a page object author.

## Using a slot in a UI test

For our example, the UI test uses `field`, which is an instance of our page object with a slot:

- Java

  ```java
  RecordLayoutLookup lookup = field.getInputFieldContainer(RecordLayoutLookup.class);
  lookup.doSomething();
  ```

- JavaScript

  ```js
  const lookup = await field.getInputFieldContainer(RecordLayoutLookup);
  await lookup.doSomething();
  ```

The test invokes the container method with the type of the content to be loaded (`"RecordLayoutLookup"`) and then interacts with the returned content.

## Summary

- A slot inside a web component translates into a container element inside the UTAM page object
- A container's selector should always point to the slot content, never to the slot itself
- A container element is outside the shadow root of its immediate parent
