// Copyright 2019 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.chrome.test.pagecontroller.utils;
import static org.junit.Assert.assertEquals;
import static org.mockito.ArgumentMatchers.argThat;
import static org.mockito.Mockito.when;
import static org.chromium.chrome.test.pagecontroller.utils.TestUtils.assertLocatorResults;
import static org.chromium.chrome.test.pagecontroller.utils.TestUtils.matchesByDepth;
import static org.chromium.chrome.test.pagecontroller.utils.TestUtils.matchesByField;
import android.content.res.Resources;
import androidx.test.uiautomator.UiDevice;
import androidx.test.uiautomator.UiObject2;
import org.junit.After;
import org.junit.Before;
import org.junit.FixMethodOrder;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.MethodSorters;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.annotation.Config;
import org.chromium.base.test.BaseRobolectricTestRunner;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.regex.Pattern;
/** Tests for Ui2Locators. */
@RunWith(BaseRobolectricTestRunner.class)
@Config(manifest = Config.NONE)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class Ui2LocatorsTest {
@Mock UiDevice mDevice;
@Mock Resources mResources;
List<UiObject2> mRootAsList;
List<UiObject2> mChild0And1;
List<UiObject2> mChild1AsList;
List<UiObject2> mGrandchildren;
List<UiObject2> mGrandchild1AsList;
@Mock UiObject2 mRoot;
@Mock UiObject2 mChild0;
@Mock UiObject2 mChild1;
@Mock UiObject2 mGrandchild0;
@Mock UiObject2 mGrandchild1;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
mRootAsList = Collections.singletonList(mRoot);
mChild0And1 = new ArrayList<>();
mChild0And1.add(mChild0);
mChild0And1.add(mChild1);
mChild1AsList = Collections.singletonList(mChild1);
mGrandchildren = new ArrayList<>();
mGrandchildren.add(mGrandchild0);
mGrandchildren.add(mGrandchild1);
mGrandchild1AsList = Collections.singletonList(mGrandchild1);
when(mDevice.findObjects(argThat(matchesByDepth(0)))).thenReturn(mRootAsList);
when(mDevice.findObject(argThat(matchesByDepth(2)))).thenReturn(mGrandchild0);
when(mDevice.findObjects(argThat(matchesByDepth(2)))).thenReturn(mGrandchildren);
when(mRoot.findObject(argThat(matchesByDepth(2)))).thenReturn(mGrandchild0);
when(mRoot.findObjects(argThat(matchesByDepth(2)))).thenReturn(mGrandchildren);
when(mRoot.getChildren()).thenReturn(mChild0And1);
when(mChild0.getChildren()).thenReturn(mGrandchildren);
when(mChild1.getChildren()).thenReturn(Collections.emptyList());
}
@After
public void tearDown() {
Ui2Locators.setResources(null);
}
@Test
public void withChildIndex() {
Pattern p = Pattern.compile("name");
stubMocksWithPattern(p, "mRes");
IUi2Locator locator = Ui2Locators.withChildIndex(0, 1);
assertEquals(mChild1, locator.locateOne(mDevice));
assertEquals(mChild1AsList, locator.locateAll(mDevice));
assertEquals(mGrandchild1, locator.locateOne(mRoot));
assertEquals(mGrandchild1AsList, locator.locateAll(mRoot));
}
@Test
public void withChildDepth() {
IUi2Locator locator = Ui2Locators.withChildDepth(2);
assertLocatorResults(mDevice, mRoot, locator, mGrandchild0, mGrandchildren);
}
@Test
public void withResIdRegex() {
Pattern p = Pattern.compile("^.*:id/a.*b$");
stubMocksWithPattern(p, "mRes");
IUi2Locator locator = Ui2Locators.withResIdRegex("a.*b");
assertDefaultResults(locator);
}
@Test
public void withAnyResId() {
Pattern p = Pattern.compile("^.*:id/(a|b)$");
stubMocksWithPattern(p, "mRes");
IUi2Locator locator = Ui2Locators.withAnyResId("a", "b");
assertDefaultResults(locator);
}
@Test
public void withAnyResEntry() {
stubMocksWithResEntry(123, "someEntry");
IUi2Locator locator = Ui2Locators.withAnyResEntry(123);
assertDefaultResults(locator);
}
@Test
public void withResName() {
Pattern p = Pattern.compile(Pattern.quote("name"));
stubMocksWithPattern(p, "mRes");
IUi2Locator locator = Ui2Locators.withResName("name");
assertDefaultResults(locator);
}
@Test
public void withResNameRegex() {
Pattern p = Pattern.compile(".*name");
stubMocksWithPattern(p, "mRes");
IUi2Locator locator = Ui2Locators.withResNameRegex(".*name");
assertDefaultResults(locator);
}
@Test
public void withContentDesc() {
Pattern p = Pattern.compile(Pattern.quote("desc"));
stubMocksWithPattern(p, "mDesc");
IUi2Locator locator = Ui2Locators.withContentDesc("desc");
assertDefaultResults(locator);
}
@Test
public void withContentDescString() {
stubMocksWithDescString(123, "someDesc");
IUi2Locator locator = Ui2Locators.withContentDescString(123);
assertDefaultResults(locator);
}
@Test
public void withText() {
Pattern p = Pattern.compile(Pattern.quote("text"));
stubMocksWithPattern(p, "mText");
IUi2Locator locator = Ui2Locators.withText("text");
assertDefaultResults(locator);
}
@Test
public void withTextRegex() {
Pattern p = Pattern.compile(".*text");
stubMocksWithPattern(p, "mText");
IUi2Locator locator = Ui2Locators.withTextRegex(".*text");
assertDefaultResults(locator);
}
@Test
public void withTextContaining() {
Pattern p = Pattern.compile("^.*" + Pattern.quote("text") + ".*$");
stubMocksWithPattern(p, "mText");
IUi2Locator locator = Ui2Locators.withTextContaining("text");
assertDefaultResults(locator);
}
@Test
public void withTextString() {
stubMocksWithTextString(123, "someString");
IUi2Locator locator = Ui2Locators.withTextString(123);
assertDefaultResults(locator);
}
@Test
public void withClassRegex() {
Pattern p = Pattern.compile(".*class");
stubMocksWithPattern(p, "mClazz");
IUi2Locator locator = Ui2Locators.withClassRegex(".*class");
assertDefaultResults(locator);
}
@Test
public void withPath() {
Pattern p = Pattern.compile(".*class");
stubMocksWithPattern(p, "mClazz");
IUi2Locator locator0 = Ui2Locators.withClassRegex(".*class");
IUi2Locator locator1 = Ui2Locators.withChildIndex(1);
IUi2Locator locator = Ui2Locators.withPath(locator0, locator1);
assertLocatorResults(mDevice, mRoot, locator, mGrandchild1, mGrandchild1AsList);
}
@Test
public void withPackageName() {
Pattern p = Pattern.compile(Pattern.quote("package"));
stubMocksWithPattern(p, "mPkg");
IUi2Locator locator = Ui2Locators.withPackageName("package");
assertDefaultResults(locator);
}
private void stubMocksWithPattern(Pattern p, String fieldName) {
when(mDevice.findObjects(argThat(matchesByField(p, fieldName)))).thenReturn(mChild0And1);
when(mRoot.findObjects(argThat(matchesByField(p, fieldName)))).thenReturn(mChild0And1);
when(mDevice.findObject(argThat(matchesByField(p, fieldName)))).thenReturn(mChild0);
when(mRoot.findObject(argThat(matchesByField(p, fieldName)))).thenReturn(mChild0);
}
private void stubMocksWithResEntry(int stringId, String stringValue) {
when(mResources.getResourceEntryName(stringId)).thenReturn(stringValue);
Ui2Locators.setResources(mResources);
Pattern p = Pattern.compile("^.*:id/(" + stringValue + ")$");
stubMocksWithPattern(p, "mRes");
}
private void stubMocksWithDescString(int stringId, String stringValue) {
when(mResources.getString(stringId)).thenReturn(stringValue);
Ui2Locators.setResources(mResources);
Pattern p = Pattern.compile(Pattern.quote(stringValue));
stubMocksWithPattern(p, "mDesc");
}
private void stubMocksWithTextString(int stringId, String stringValue) {
when(mResources.getString(stringId)).thenReturn(stringValue);
Ui2Locators.setResources(mResources);
Pattern p = Pattern.compile(Pattern.quote(stringValue));
stubMocksWithPattern(p, "mText");
}
private void assertDefaultResults(IUi2Locator locator) {
assertLocatorResults(mDevice, mRoot, locator, mChild0, mChild0And1);
}
}