Skip to content

Iterating Elements

David O'Donoghue edited this page Jan 28, 2026 · 3 revisions

Iterating Elements

Loop over UI elements and perform actions on each one using FindAll, FindItems, and foreach patterns.

FindAll

Find all matching elements and iterate over them:

// Find all buttons and click each one
var buttons = await FindAll<Button>(Type<Button>());
foreach (var button in buttons)
{
    await Click(button);
    await Wait(0.5f);
}

// Find all items matching a pattern
var menuItems = await FindAll<Button>(Name("MenuItem_*"));
foreach (var item in menuItems)
{
    Debug.Log($"Found: {item.name}");
}

// Find all toggles and turn them on
var toggles = await FindAll<Toggle>(Type<Toggle>());
foreach (var toggle in toggles)
{
    if (!toggle.isOn)
        await Click(toggle);
}

Component Overloads

All action methods accept components directly, enabling clean iteration:

// Click each button
foreach (var button in await FindAll<Button>(Type<Button>()))
{
    await Click(button);
}

// Double-click each item
foreach (var item in await FindAll<Selectable>(Name("Item_*")))
{
    await DoubleClick(item);
}

// Hold each element
foreach (var target in await FindAll<Button>(Text("Hold Me")))
{
    await Hold(target, 1.0f);
}

// Drag each draggable
foreach (var draggable in await FindAll<RectTransform>(Name("Draggable_*")))
{
    await Drag(draggable, new Vector2(100, 0));
}

FindItems (Container Iteration)

Find items within containers like ScrollRect, Dropdown, or LayoutGroups:

// Iterate items in a scroll view
foreach (var (container, item) in await FindItems(Name("InventoryList")))
{
    await Click(item);
    await Wait(0.2f);
}

// Iterate dropdown options
foreach (var (dropdown, option) in await FindItems(Name("SettingsDropdown")))
{
    Debug.Log($"Option: {option.name}");
}

// Iterate grid items
foreach (var (grid, cell) in await FindItems(Type<GridLayoutGroup>()))
{
    await Click(cell);
}

ClickScrollItems / ClickDropdownItems

Built-in helpers for common iteration patterns:

// Click each item in a scroll view (auto-scrolls to each)
await ClickScrollItems(Name("ItemList"));

// Click each option in a dropdown
await ClickDropdownItems(Name("OptionsDropdown"));

// With delay between clicks
await ClickScrollItems(Name("ItemList"), delayBetween: 500);
await ClickDropdownItems(Name("OptionsDropdown"), delayBetween: 300);

Filtering During Iteration

Combine FindAll with LINQ or conditions:

// Only interactable buttons
var buttons = await FindAll<Button>(Type<Button>());
foreach (var button in buttons.Where(b => b.interactable))
{
    await Click(button);
}

// Skip first N items
var items = await FindAll<Button>(Name("Item_*"));
foreach (var item in items.Skip(2))
{
    await Click(item);
}

// Take only first N items
foreach (var item in items.Take(5))
{
    await Click(item);
}

// Filter by component property
var sliders = await FindAll<Slider>(Type<Slider>());
foreach (var slider in sliders.Where(s => s.value < 0.5f))
{
    await DragSlider(slider, slider.value, 1.0f);
}

Accessing Properties During Iteration

Use reflection access on found elements:

// Read properties from each element
var labels = await FindAll<TMP_Text>(Name("Label_*"));
foreach (var label in labels)
{
    Debug.Log($"Text: {label.text}, Color: {label.color}");
}

// Use Search.Property on each
foreach (var item in await FindAll<Transform>(Name("Item_*")))
{
    var search = new Search().Name(item.name);
    var isActive = search.Property("gameObject").Property("activeSelf").BoolValue;
    Debug.Log($"{item.name} active: {isActive}");
}

Static Array Iteration

Iterate over arrays accessed via reflection:

// Iterate static array
foreach (var player in Search.Reflect("GameManager.Players"))
{
    var name = player.Property("Name").StringValue;
    var score = player.Property("Score").IntValue;
    Debug.Log($"{name}: {score}");
}

// Iterate inventory items
foreach (var item in Search.Reflect("Inventory.Instance.Items"))
{
    var itemName = item.Property("Name").StringValue;
    var quantity = item.Property("Quantity").IntValue;
    Assert.Greater(quantity, 0, $"{itemName} should have positive quantity");
}

// Nested iteration
foreach (var truck in Search.Reflect("TruckManager.AllTrucks"))
{
    foreach (var wheel in truck.Property("Wheels"))
    {
        var health = wheel.Property("Health").FloatValue;
        Debug.Log($"Wheel health: {health}");
    }
}

Counting and Validation

Validate element counts:

// Assert exact count
var items = await FindAll<Button>(Name("CartItem_*"));
Assert.AreEqual(3, items.Count, "Should have 3 cart items");

// Assert minimum count
Assert.GreaterOrEqual(items.Count, 1, "Should have at least 1 item");

// Assert all have property
foreach (var item in items)
{
    Assert.IsTrue(item.interactable, $"{item.name} should be interactable");
}

Common Patterns

Test All Menu Items

using static ODDGames.UIAutomation.ActionExecutor;

[TestFixture]
public class MenuNavigationTest
{
    [Test]
    public async Task TestAllMenuItems()
    {
        var menuButtons = await FindAll<Button>(Name("Menu_*"));

        foreach (var button in menuButtons)
        {
            await Click(button);
            await Wait(0.5f);
            await Click(Text("Back"));
        }
    }
}

Verify All Items Loaded

using static ODDGames.UIAutomation.ActionExecutor;

[TestFixture]
public class InventoryTest
{
    [Test]
    public async Task VerifyAllItemsLoaded()
    {
        await Click(Text("OpenInventory"));
        await WaitFor(Name("InventoryPanel"));

        var items = await FindAll<Button>(Name("InventorySlot_*"));
        Assert.GreaterOrEqual(items.Count, 10, "Should load at least 10 slots");

        // Verify each slot is clickable
        foreach (var slot in items.Take(5))
        {
            await Click(slot);
            await WaitFor(Name("ItemDetails"));
            await Click(Text("CloseDetails"));
        }
    }
}

Process Form Fields

// Fill all input fields
var inputs = await FindAll<TMP_InputField>(Type<TMP_InputField>());
foreach (var input in inputs)
{
    await Click(input);
    await TextInput(input, "test value");
}

// Toggle all checkboxes
var checkboxes = await FindAll<Toggle>(Type<Toggle>());
foreach (var checkbox in checkboxes)
{
    if (!checkbox.isOn)
        await Click(checkbox);
}

Related Pages

Clone this wiki locally