Commit abecb7d9 authored by sandromaggi's avatar sandromaggi Committed by Commit Bot

[Autofill Assistant] Integration tests for showcast in iFrame

This adds integration tests for Showcast actions on elements in an
iFrame.

The helper has been rewritten to support selecting elements in iFrames.

Bug: b/143942385
Change-Id: Ida4045364de9bbbcfd27057d9ecb8cb5e8dc8284
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2082564
Commit-Queue: Sandro Maggi <sandromaggi@google.com>
Reviewed-by: default avatarClemens Arbesser <arbesser@google.com>
Cr-Commit-Position: refs/heads/master@{#746785}
parent 8243bb18
...@@ -551,7 +551,7 @@ public class AutofillAssistantBottomsheetTest { ...@@ -551,7 +551,7 @@ public class AutofillAssistantBottomsheetTest {
float y = GeneralLocation.TOP_CENTER.calculateCoordinates( float y = GeneralLocation.TOP_CENTER.calculateCoordinates(
mTestRule.getActivity().findViewById( mTestRule.getActivity().findViewById(
R.id.autofill_assistant_bottom_sheet_toolbar))[1]; R.id.autofill_assistant_bottom_sheet_toolbar))[1];
Rect el = getAbsoluteBoundingRect(elementId, mTestRule); Rect el = getAbsoluteBoundingRect(mTestRule, elementId);
return el.bottom > y == shouldBeCovered; return el.bottom > y == shouldBeCovered;
} catch (Exception e) { } catch (Exception e) {
throw new RuntimeException(e); throw new RuntimeException(e);
......
...@@ -181,11 +181,11 @@ public class AutofillAssistantCollectUserDataIntegrationTest { ...@@ -181,11 +181,11 @@ public class AutofillAssistantCollectUserDataIntegrationTest {
onView(withId(R.id.card_unmask_input)).perform(typeText("123")); onView(withId(R.id.card_unmask_input)).perform(typeText("123"));
onView(withId(R.id.positive_button)).perform(click()); onView(withId(R.id.positive_button)).perform(click());
waitUntilViewMatchesCondition(withText("Prompt"), isCompletelyDisplayed()); waitUntilViewMatchesCondition(withText("Prompt"), isCompletelyDisplayed());
assertThat(getElementValue("name", getWebContents()), is("John Doe")); assertThat(getElementValue(getWebContents(), "name"), is("John Doe"));
assertThat(getElementValue("card_number", getWebContents()), is("4111111111111111")); assertThat(getElementValue(getWebContents(), "card_number"), is("4111111111111111"));
assertThat(getElementValue("cv2_number", getWebContents()), is("123")); assertThat(getElementValue(getWebContents(), "cv2_number"), is("123"));
assertThat(getElementValue("exp_month", getWebContents()), is("12")); assertThat(getElementValue(getWebContents(), "exp_month"), is("12"));
assertThat(getElementValue("exp_year", getWebContents()), is("2050")); assertThat(getElementValue(getWebContents(), "exp_year"), is("2050"));
} }
/** /**
...@@ -236,8 +236,8 @@ public class AutofillAssistantCollectUserDataIntegrationTest { ...@@ -236,8 +236,8 @@ public class AutofillAssistantCollectUserDataIntegrationTest {
startAutofillAssistant(mTestRule.getActivity(), testService); startAutofillAssistant(mTestRule.getActivity(), testService);
waitUntilViewMatchesCondition(withText("Prompt"), isCompletelyDisplayed()); waitUntilViewMatchesCondition(withText("Prompt"), isCompletelyDisplayed());
String password = getElementValue("password", getWebContents()); String password = getElementValue(getWebContents(), "password");
String confirmation_password = getElementValue("password-conf", getWebContents()); String confirmation_password = getElementValue(getWebContents(), "password-conf");
assertThat(password.length(), greaterThan(0)); assertThat(password.length(), greaterThan(0));
assertThat(password, is(confirmation_password)); assertThat(password, is(confirmation_password));
} }
...@@ -307,12 +307,12 @@ public class AutofillAssistantCollectUserDataIntegrationTest { ...@@ -307,12 +307,12 @@ public class AutofillAssistantCollectUserDataIntegrationTest {
startAutofillAssistant(mTestRule.getActivity(), testService); startAutofillAssistant(mTestRule.getActivity(), testService);
waitUntilViewMatchesCondition(withText("Continue"), isDisplayed()); waitUntilViewMatchesCondition(withText("Continue"), isDisplayed());
tapElement("button", mTestRule); tapElement(mTestRule, "button");
onView(withText("Continue")).perform(click()); onView(withText("Continue")).perform(click());
waitUntilViewMatchesCondition(withText("Toggle"), isDisplayed()); waitUntilViewMatchesCondition(withText("Toggle"), isDisplayed());
// Verify that in the next step the touchable window is not present anymore. // Verify that in the next step the touchable window is not present anymore.
tapElement("button", mTestRule); tapElement(mTestRule, "button");
onView(withText("Toggle")).check(matches(isDisplayed())); onView(withText("Toggle")).check(matches(isDisplayed()));
} }
......
...@@ -103,12 +103,12 @@ public class AutofillAssistantOverlayIntegrationTest { ...@@ -103,12 +103,12 @@ public class AutofillAssistantOverlayIntegrationTest {
waitUntilViewMatchesCondition(withText("Prompt"), isCompletelyDisplayed()); waitUntilViewMatchesCondition(withText("Prompt"), isCompletelyDisplayed());
// Tapping on the element should remove it from the DOM. // Tapping on the element should remove it from the DOM.
assertThat(checkElementExists("touch_area_one", mTestRule.getWebContents()), is(true)); assertThat(checkElementExists(mTestRule.getWebContents(), "touch_area_one"), is(true));
tapElement("touch_area_one", mTestRule); tapElement(mTestRule, "touch_area_one");
assertThat(checkElementExists("touch_area_one", mTestRule.getWebContents()), is(false)); assertThat(checkElementExists(mTestRule.getWebContents(), "touch_area_one"), is(false));
// Tapping on the element should be blocked by the overlay. // Tapping on the element should be blocked by the overlay.
tapElement("touch_area_four", mTestRule); tapElement(mTestRule, "touch_area_four");
assertThat(checkElementExists("touch_area_four", mTestRule.getWebContents()), is(true)); assertThat(checkElementExists(mTestRule.getWebContents(), "touch_area_four"), is(true));
} }
/** /**
...@@ -149,15 +149,112 @@ public class AutofillAssistantOverlayIntegrationTest { ...@@ -149,15 +149,112 @@ public class AutofillAssistantOverlayIntegrationTest {
// Tapping on the element should remove it from the DOM. The element should be after a // Tapping on the element should remove it from the DOM. The element should be after a
// big element forcing the page to scroll. // big element forcing the page to scroll.
assertThat(checkElementExists("touch_area_five", mTestRule.getWebContents()), is(true)); assertThat(checkElementExists(mTestRule.getWebContents(), "touch_area_five"), is(true));
tapElement("touch_area_five", mTestRule); tapElement(mTestRule, "touch_area_five");
assertThat(checkElementExists("touch_area_five", mTestRule.getWebContents()), is(false)); assertThat(checkElementExists(mTestRule.getWebContents(), "touch_area_five"), is(false));
// Tapping on the element should be blocked by the overlay. // Tapping on the element should be blocked by the overlay.
tapElement("touch_area_six", mTestRule); tapElement(mTestRule, "touch_area_six");
assertThat(checkElementExists("touch_area_six", mTestRule.getWebContents()), is(true)); assertThat(checkElementExists(mTestRule.getWebContents(), "touch_area_six"), is(true));
} }
// TODO(b/143942385): Write a test for an element within an iFrame. /**
* Tests that clicking on an iFrame element works with a showcast.
*/
@Test
@MediumTest
public void testShowCastOnIFrameElement() throws Exception {
ElementReferenceProto element = (ElementReferenceProto) ElementReferenceProto.newBuilder()
.addSelectors("#iframe")
.addSelectors("#touch_area_1")
.build();
ArrayList<ActionProto> list = new ArrayList<>();
list.add(
(ActionProto) ActionProto.newBuilder()
.setFocusElement(FocusElementProto.newBuilder()
.setElement(element)
.setTouchableElementArea(
ElementAreaProto.newBuilder().addTouchable(
Rectangle.newBuilder().addElements(
element))))
.build());
list.add((ActionProto) ActionProto.newBuilder()
.setPrompt(PromptProto.newBuilder().setMessage("Prompt").addChoices(
PromptProto.Choice.newBuilder()))
.build());
AutofillAssistantTestScript script = new AutofillAssistantTestScript(
(SupportedScriptProto) SupportedScriptProto.newBuilder()
.setPath("autofill_assistant_target_website.html")
.setPresentation(PresentationProto.newBuilder().setAutostart(true).setChip(
ChipProto.newBuilder().setText("Done")))
.build(),
list);
runScript(script);
waitUntilViewMatchesCondition(withText("Prompt"), isCompletelyDisplayed());
// Tapping on the element should remove it from the DOM.
assertThat(
checkElementExists(mTestRule.getWebContents(), "iframe", "touch_area_1"), is(true));
tapElement(mTestRule, "iframe", "touch_area_1");
assertThat(checkElementExists(mTestRule.getWebContents(), "iframe", "touch_area_1"),
is(false));
// Tapping on the element should be blocked by the overlay.
tapElement(mTestRule, "iframe", "touch_area_2");
assertThat(
checkElementExists(mTestRule.getWebContents(), "iframe", "touch_area_2"), is(true));
}
/**
* Tests that clicking on an iFrame element works with a showcast in a scrolled iFrame.
*/
@Test
@MediumTest
public void testShowCastOnIFrameElementInScrollIFrame() throws Exception {
ElementReferenceProto element = (ElementReferenceProto) ElementReferenceProto.newBuilder()
.addSelectors("#iframe")
.addSelectors("#touch_area_3")
.build();
ArrayList<ActionProto> list = new ArrayList<>();
list.add(
(ActionProto) ActionProto.newBuilder()
.setFocusElement(FocusElementProto.newBuilder()
.setElement(element)
.setTouchableElementArea(
ElementAreaProto.newBuilder().addTouchable(
Rectangle.newBuilder().addElements(
element))))
.build());
list.add((ActionProto) ActionProto.newBuilder()
.setPrompt(PromptProto.newBuilder().setMessage("Prompt").addChoices(
PromptProto.Choice.newBuilder()))
.build());
AutofillAssistantTestScript script = new AutofillAssistantTestScript(
(SupportedScriptProto) SupportedScriptProto.newBuilder()
.setPath("autofill_assistant_target_website.html")
.setPresentation(PresentationProto.newBuilder().setAutostart(true).setChip(
ChipProto.newBuilder().setText("Done")))
.build(),
list);
runScript(script);
waitUntilViewMatchesCondition(withText("Prompt"), isCompletelyDisplayed());
// Tapping on the element should remove it from the DOM. The element should be after a
// big element forcing the page to scroll.
assertThat(
checkElementExists(mTestRule.getWebContents(), "iframe", "touch_area_3"), is(true));
tapElement(mTestRule, "iframe", "touch_area_3");
assertThat(checkElementExists(mTestRule.getWebContents(), "iframe", "touch_area_3"),
is(false));
// Tapping on the element should be blocked by the overlay.
tapElement(mTestRule, "iframe", "touch_area_4");
assertThat(
checkElementExists(mTestRule.getWebContents(), "iframe", "touch_area_4"), is(true));
}
private void runScript(AutofillAssistantTestScript script) { private void runScript(AutofillAssistantTestScript script) {
AutofillAssistantTestService testService = AutofillAssistantTestService testService =
......
...@@ -100,7 +100,7 @@ public class AutofillAssistantOverlayUiTest { ...@@ -100,7 +100,7 @@ public class AutofillAssistantOverlayUiTest {
assertScrimDisplayed(false); assertScrimDisplayed(false);
tapElement("touch_area_one"); tapElement("touch_area_one");
assertThat(checkElementExists("touch_area_one", getWebContents()), is(false)); assertThat(checkElementExists(getWebContents(), "touch_area_one"), is(false));
} }
/** Tests assumptions about the full overlay. */ /** Tests assumptions about the full overlay. */
...@@ -114,13 +114,13 @@ public class AutofillAssistantOverlayUiTest { ...@@ -114,13 +114,13 @@ public class AutofillAssistantOverlayUiTest {
() -> model.set(AssistantOverlayModel.STATE, AssistantOverlayState.FULL)); () -> model.set(AssistantOverlayModel.STATE, AssistantOverlayState.FULL));
assertScrimDisplayed(true); assertScrimDisplayed(true);
tapElement("touch_area_one"); tapElement("touch_area_one");
assertThat(checkElementExists("touch_area_one", getWebContents()), is(true)); assertThat(checkElementExists(getWebContents(), "touch_area_one"), is(true));
runOnUiThreadBlocking( runOnUiThreadBlocking(
() -> model.set(AssistantOverlayModel.STATE, AssistantOverlayState.HIDDEN)); () -> model.set(AssistantOverlayModel.STATE, AssistantOverlayState.HIDDEN));
assertScrimDisplayed(false); assertScrimDisplayed(false);
tapElement("touch_area_one"); tapElement("touch_area_one");
assertThat(checkElementExists("touch_area_one", getWebContents()), is(false)); assertThat(checkElementExists(getWebContents(), "touch_area_one"), is(false));
} }
/** Tests assumptions about the full overlay. */ /** Tests assumptions about the full overlay. */
...@@ -152,16 +152,16 @@ public class AutofillAssistantOverlayUiTest { ...@@ -152,16 +152,16 @@ public class AutofillAssistantOverlayUiTest {
() -> model.set(AssistantOverlayModel.STATE, AssistantOverlayState.PARTIAL)); () -> model.set(AssistantOverlayModel.STATE, AssistantOverlayState.PARTIAL));
assertScrimDisplayed(true); assertScrimDisplayed(true);
tapElement("touch_area_one"); tapElement("touch_area_one");
assertThat(checkElementExists("touch_area_one", getWebContents()), is(true)); assertThat(checkElementExists(getWebContents(), "touch_area_one"), is(true));
Rect rect = getBoundingRectForElement("touch_area_one", getWebContents()); Rect rect = getBoundingRectForElement(getWebContents(), "touch_area_one");
runOnUiThreadBlocking(() runOnUiThreadBlocking(()
-> model.set(AssistantOverlayModel.TOUCHABLE_AREA, -> model.set(AssistantOverlayModel.TOUCHABLE_AREA,
Collections.singletonList(new RectF(rect)))); Collections.singletonList(new RectF(rect))));
// Touchable area set, but no viewport given: equivalent to full overlay. // Touchable area set, but no viewport given: equivalent to full overlay.
tapElement("touch_area_one"); tapElement("touch_area_one");
assertThat(checkElementExists("touch_area_one", getWebContents()), is(true)); assertThat(checkElementExists(getWebContents(), "touch_area_one"), is(true));
// Set viewport. // Set viewport.
Rect viewport = getViewport(getWebContents()); Rect viewport = getViewport(getWebContents());
...@@ -170,12 +170,12 @@ public class AutofillAssistantOverlayUiTest { ...@@ -170,12 +170,12 @@ public class AutofillAssistantOverlayUiTest {
// Now the partial overlay allows tapping the highlighted touch area. // Now the partial overlay allows tapping the highlighted touch area.
tapElement("touch_area_one"); tapElement("touch_area_one");
assertThat(checkElementExists("touch_area_one", getWebContents()), is(false)); assertThat(checkElementExists(getWebContents(), "touch_area_one"), is(false));
runOnUiThreadBlocking( runOnUiThreadBlocking(
() -> model.set(AssistantOverlayModel.TOUCHABLE_AREA, Collections.emptyList())); () -> model.set(AssistantOverlayModel.TOUCHABLE_AREA, Collections.emptyList()));
tapElement("touch_area_three"); tapElement("touch_area_three");
assertThat(checkElementExists("touch_area_three", getWebContents()), is(true)); assertThat(checkElementExists(getWebContents(), "touch_area_three"), is(true));
} }
/** Scrolls a touchable area into view and then taps it. */ /** Scrolls a touchable area into view and then taps it. */
...@@ -185,7 +185,7 @@ public class AutofillAssistantOverlayUiTest { ...@@ -185,7 +185,7 @@ public class AutofillAssistantOverlayUiTest {
AssistantOverlayModel model = new AssistantOverlayModel(); AssistantOverlayModel model = new AssistantOverlayModel();
AssistantOverlayCoordinator coordinator = createCoordinator(model); AssistantOverlayCoordinator coordinator = createCoordinator(model);
Rect rect = getBoundingRectForElement("touch_area_two", getWebContents()); Rect rect = getBoundingRectForElement(getWebContents(), "touch_area_two");
Rect viewport = getViewport(getWebContents()); Rect viewport = getViewport(getWebContents());
runOnUiThreadBlocking(() -> { runOnUiThreadBlocking(() -> {
model.set(AssistantOverlayModel.STATE, AssistantOverlayState.PARTIAL); model.set(AssistantOverlayModel.STATE, AssistantOverlayState.PARTIAL);
...@@ -198,7 +198,7 @@ public class AutofillAssistantOverlayUiTest { ...@@ -198,7 +198,7 @@ public class AutofillAssistantOverlayUiTest {
runOnUiThreadBlocking( runOnUiThreadBlocking(
() -> model.set(AssistantOverlayModel.VISUAL_VIEWPORT, new RectF(newViewport))); () -> model.set(AssistantOverlayModel.VISUAL_VIEWPORT, new RectF(newViewport)));
tapElement("touch_area_two"); tapElement("touch_area_two");
assertThat(checkElementExists("touch_area_two", getWebContents()), is(false)); assertThat(checkElementExists(getWebContents(), "touch_area_two"), is(false));
} }
/** /**
...@@ -264,7 +264,7 @@ public class AutofillAssistantOverlayUiTest { ...@@ -264,7 +264,7 @@ public class AutofillAssistantOverlayUiTest {
} }
void tapElement(String elementId) throws Exception { void tapElement(String elementId) throws Exception {
AutofillAssistantUiTestUtil.tapElement(elementId, mTestRule); AutofillAssistantUiTestUtil.tapElement(mTestRule, elementId);
} }
/** /**
......
...@@ -165,8 +165,8 @@ public class AutofillAssistantPersonalDataManagerTest { ...@@ -165,8 +165,8 @@ public class AutofillAssistantPersonalDataManagerTest {
.check(matches(allOf(withText("johndoe@google.com"), isDisplayed()))); .check(matches(allOf(withText("johndoe@google.com"), isDisplayed())));
onView(withText("Continue")).perform(click()); onView(withText("Continue")).perform(click());
waitUntilViewMatchesCondition(withText("Prompt"), isCompletelyDisplayed()); waitUntilViewMatchesCondition(withText("Prompt"), isCompletelyDisplayed());
assertThat(getElementValue("profile_name", getWebContents()), is("John Doe")); assertThat(getElementValue(getWebContents(), "profile_name"), is("John Doe"));
assertThat(getElementValue("email", getWebContents()), is("johndoe@google.com")); assertThat(getElementValue(getWebContents(), "email"), is("johndoe@google.com"));
} }
/** /**
...@@ -217,8 +217,8 @@ public class AutofillAssistantPersonalDataManagerTest { ...@@ -217,8 +217,8 @@ public class AutofillAssistantPersonalDataManagerTest {
waitUntilViewMatchesCondition(withContentDescription("Continue"), isEnabled()); waitUntilViewMatchesCondition(withContentDescription("Continue"), isEnabled());
onView(withContentDescription("Continue")).perform(click()); onView(withContentDescription("Continue")).perform(click());
waitUntilViewMatchesCondition(withText("Prompt"), isCompletelyDisplayed()); waitUntilViewMatchesCondition(withText("Prompt"), isCompletelyDisplayed());
assertThat(getElementValue("profile_name", getWebContents()), is("John Doe")); assertThat(getElementValue(getWebContents(), "profile_name"), is("John Doe"));
assertThat(getElementValue("email", getWebContents()), is("johndoe@google.com")); assertThat(getElementValue(getWebContents(), "email"), is("johndoe@google.com"));
} }
/** /**
...@@ -276,8 +276,8 @@ public class AutofillAssistantPersonalDataManagerTest { ...@@ -276,8 +276,8 @@ public class AutofillAssistantPersonalDataManagerTest {
onView(withText("Continue")).perform(click()); onView(withText("Continue")).perform(click());
waitUntilViewMatchesCondition(withText("Prompt"), isCompletelyDisplayed()); waitUntilViewMatchesCondition(withText("Prompt"), isCompletelyDisplayed());
// Make sure it's not Adam West that was selected. // Make sure it's not Adam West that was selected.
assertThat(getElementValue("profile_name", getWebContents()), is("John Doe")); assertThat(getElementValue(getWebContents(), "profile_name"), is("John Doe"));
assertThat(getElementValue("email", getWebContents()), is("johndoe@google.com")); assertThat(getElementValue(getWebContents(), "email"), is("johndoe@google.com"));
} }
/** /**
...@@ -395,8 +395,8 @@ public class AutofillAssistantPersonalDataManagerTest { ...@@ -395,8 +395,8 @@ public class AutofillAssistantPersonalDataManagerTest {
onView(withText("Continue")).perform(click()); onView(withText("Continue")).perform(click());
waitUntilViewMatchesCondition(withText("Prompt"), isCompletelyDisplayed()); waitUntilViewMatchesCondition(withText("Prompt"), isCompletelyDisplayed());
// Make sure it's now Jane Doe. // Make sure it's now Jane Doe.
assertThat(getElementValue("profile_name", getWebContents()), is("Jane Doe")); assertThat(getElementValue(getWebContents(), "profile_name"), is("Jane Doe"));
assertThat(getElementValue("email", getWebContents()), is("janedoe@google.com")); assertThat(getElementValue(getWebContents(), "email"), is("janedoe@google.com"));
} }
/** /**
...@@ -477,11 +477,11 @@ public class AutofillAssistantPersonalDataManagerTest { ...@@ -477,11 +477,11 @@ public class AutofillAssistantPersonalDataManagerTest {
onView(withId(R.id.card_unmask_input)).perform(typeText("123")); onView(withId(R.id.card_unmask_input)).perform(typeText("123"));
onView(withId(R.id.positive_button)).perform(click()); onView(withId(R.id.positive_button)).perform(click());
waitUntilViewMatchesCondition(withText("Prompt"), isCompletelyDisplayed()); waitUntilViewMatchesCondition(withText("Prompt"), isCompletelyDisplayed());
assertThat(getElementValue("name", getWebContents()), is("John Doe")); assertThat(getElementValue(getWebContents(), "name"), is("John Doe"));
assertThat(getElementValue("card_number", getWebContents()), is("4111111111111111")); assertThat(getElementValue(getWebContents(), "card_number"), is("4111111111111111"));
assertThat(getElementValue("cv2_number", getWebContents()), is("123")); assertThat(getElementValue(getWebContents(), "cv2_number"), is("123"));
assertThat(getElementValue("exp_month", getWebContents()), is("01")); assertThat(getElementValue(getWebContents(), "exp_month"), is("01"));
assertThat(getElementValue("exp_year", getWebContents()), is(String.valueOf(year + 2))); assertThat(getElementValue(getWebContents(), "exp_year"), is(String.valueOf(year + 2)));
} }
/** /**
......
...@@ -65,6 +65,7 @@ import org.chromium.content_public.browser.test.util.TestThreadUtils; ...@@ -65,6 +65,7 @@ import org.chromium.content_public.browser.test.util.TestThreadUtils;
import org.chromium.content_public.browser.test.util.TestTouchUtils; import org.chromium.content_public.browser.test.util.TestTouchUtils;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.List; import java.util.List;
import jp.tomorrowkey.android.gifplayer.BaseGifImage; import jp.tomorrowkey.android.gifplayer.BaseGifImage;
...@@ -429,27 +430,28 @@ class AutofillAssistantUiTestUtil { ...@@ -429,27 +430,28 @@ class AutofillAssistantUiTestUtil {
} }
/** Performs a single tap on the center of the specified element. */ /** Performs a single tap on the center of the specified element. */
public static void tapElement(String elementId, CustomTabActivityTestRule testRule) public static void tapElement(CustomTabActivityTestRule testRule, String... elementIds)
throws Exception { throws Exception {
Rect coords = getAbsoluteBoundingRect(elementId, testRule); Rect coords = getAbsoluteBoundingRect(testRule, elementIds);
float x = coords.left + 0.5f * (coords.right - coords.left); float x = coords.left + 0.5f * (coords.right - coords.left);
float y = coords.top + 0.5f * (coords.bottom - coords.top); float y = coords.top + 0.5f * (coords.bottom - coords.top);
// Sanity check, can only click on coordinates on screen. // Sanity check, can only click on coordinates on screen.
DisplayMetrics displayMetrics = testRule.getActivity().getResources().getDisplayMetrics(); DisplayMetrics displayMetrics = testRule.getActivity().getResources().getDisplayMetrics();
if (x < 0 || x > displayMetrics.widthPixels || y < 0 || y > displayMetrics.heightPixels) { if (x < 0 || x > displayMetrics.widthPixels || y < 0 || y > displayMetrics.heightPixels) {
throw new IllegalArgumentException(elementId + " not on screen: tried to tap x=" + x throw new IllegalArgumentException(Arrays.toString(elementIds)
+ ", y=" + y + ", which is outside of display with w=" + " not on screen: tried to tap x=" + x + ", y=" + y
+ displayMetrics.widthPixels + ", h=" + displayMetrics.heightPixels); + ", which is outside of display with w=" + displayMetrics.widthPixels
+ ", h=" + displayMetrics.heightPixels);
} }
TestTouchUtils.singleClick(InstrumentationRegistry.getInstrumentation(), x, y); TestTouchUtils.singleClick(InstrumentationRegistry.getInstrumentation(), x, y);
} }
/** Computes the bounding rectangle of the specified DOM element in absolute screen space. */ /** Computes the bounding rectangle of the specified DOM element in absolute screen space. */
public static Rect getAbsoluteBoundingRect(String elementId, CustomTabActivityTestRule testRule) public static Rect getAbsoluteBoundingRect(
throws Exception { CustomTabActivityTestRule testRule, String... elementIds) throws Exception {
// Get bounding rectangle in viewport space. // Get bounding rectangle in viewport space.
Rect elementRect = getBoundingRectForElement(elementId, testRule.getWebContents()); Rect elementRect = getBoundingRectForElement(testRule.getWebContents(), elementIds);
/* /*
* Conversion from viewport space to screen space is done in two steps: * Conversion from viewport space to screen space is done in two steps:
...@@ -475,34 +477,45 @@ class AutofillAssistantUiTestUtil { ...@@ -475,34 +477,45 @@ class AutofillAssistantUiTestUtil {
* Retrieves the bounding rectangle for the specified element in the DOM tree in CSS pixel * Retrieves the bounding rectangle for the specified element in the DOM tree in CSS pixel
* coordinates. * coordinates.
*/ */
public static Rect getBoundingRectForElement(String elementId, WebContents webContents) public static Rect getBoundingRectForElement(WebContents webContents, String... elementIds)
throws Exception { throws Exception {
if (!checkElementExists(elementId, webContents)) { if (!checkElementExists(webContents, elementIds)) {
throw new IllegalArgumentException(elementId + " does not exist"); throw new IllegalArgumentException(Arrays.toString(elementIds) + " does not exist");
} }
TestCallbackHelperContainer.OnEvaluateJavaScriptResultHelper javascriptHelper = TestCallbackHelperContainer.OnEvaluateJavaScriptResultHelper javascriptHelper =
new TestCallbackHelperContainer.OnEvaluateJavaScriptResultHelper(); new TestCallbackHelperContainer.OnEvaluateJavaScriptResultHelper();
Rect rect = new Rect(0, 0, Integer.MAX_VALUE, Integer.MAX_VALUE);
for (int i = 0; i < elementIds.length; ++i) {
String offsetX = i == 0 ? "window.scrollX" : "0";
String offsetY = i == 0 ? "window.scrollY" : "0";
String elementSelector =
getElementSelectorString(Arrays.copyOfRange(elementIds, 0, i + 1));
javascriptHelper.evaluateJavaScriptForTests(webContents, javascriptHelper.evaluateJavaScriptForTests(webContents,
"(function() {" "(function() {"
+ " rect = document.getElementById('" + elementId + " rect = " + elementSelector + ".getBoundingClientRect();"
+ "').getBoundingClientRect();" + " return [" + offsetX + " + rect.left, " + offsetY + " + rect.top, "
+ " return [window.scrollX + rect.left, window.scrollY + rect.top, " + " " + offsetX + " + rect.right, " + offsetY
+ " window.scrollX + rect.right, window.scrollY + rect.bottom];" + " + rect.bottom];"
+ "})()"); + "})()");
javascriptHelper.waitUntilHasValue(); javascriptHelper.waitUntilHasValue();
JSONArray rectJson = new JSONArray(javascriptHelper.getJsonResultAndClear()); JSONArray rectJson = new JSONArray(javascriptHelper.getJsonResultAndClear());
return new Rect(
rectJson.getInt(0), rectJson.getInt(1), rectJson.getInt(2), rectJson.getInt(3)); rect = new Rect(Math.min(rect.right, rect.left + rectJson.getInt(0)),
Math.min(rect.bottom, rect.top + rectJson.getInt(1)),
Math.min(rect.right, rect.left + rectJson.getInt(2)),
Math.min(rect.bottom, rect.top + rectJson.getInt(3)));
}
return rect;
} }
/** Checks whether the specified element exists in the DOM tree. */ /** Checks whether the specified element exists in the DOM tree. */
public static boolean checkElementExists(String elementId, WebContents webContents) public static boolean checkElementExists(WebContents webContents, String... elementIds)
throws Exception { throws Exception {
TestCallbackHelperContainer.OnEvaluateJavaScriptResultHelper javascriptHelper = TestCallbackHelperContainer.OnEvaluateJavaScriptResultHelper javascriptHelper =
new TestCallbackHelperContainer.OnEvaluateJavaScriptResultHelper(); new TestCallbackHelperContainer.OnEvaluateJavaScriptResultHelper();
javascriptHelper.evaluateJavaScriptForTests(webContents, javascriptHelper.evaluateJavaScriptForTests(webContents,
"(function() {" "(function() {"
+ " return [document.getElementById('" + elementId + "') != null]; " + " return [" + getElementSelectorString(elementIds) + " != null]; "
+ "})()"); + "})()");
javascriptHelper.waitUntilHasValue(); javascriptHelper.waitUntilHasValue();
JSONArray result = new JSONArray(javascriptHelper.getJsonResultAndClear()); JSONArray result = new JSONArray(javascriptHelper.getJsonResultAndClear());
...@@ -510,14 +523,14 @@ class AutofillAssistantUiTestUtil { ...@@ -510,14 +523,14 @@ class AutofillAssistantUiTestUtil {
} }
/** Checks whether the specified element is displayed in the DOM tree. */ /** Checks whether the specified element is displayed in the DOM tree. */
public static boolean checkElementIsDisplayed(String elementId, WebContents webContents) public static boolean checkElementIsDisplayed(WebContents webContents, String... elementIds)
throws Exception { throws Exception {
TestCallbackHelperContainer.OnEvaluateJavaScriptResultHelper javascriptHelper = TestCallbackHelperContainer.OnEvaluateJavaScriptResultHelper javascriptHelper =
new TestCallbackHelperContainer.OnEvaluateJavaScriptResultHelper(); new TestCallbackHelperContainer.OnEvaluateJavaScriptResultHelper();
javascriptHelper.evaluateJavaScriptForTests(webContents, javascriptHelper.evaluateJavaScriptForTests(webContents,
"(function() {" "(function() {"
+ " return [document.getElementById('" + elementId + " return [" + getElementSelectorString(elementIds)
+ "').style.display != \"none\"]; " + ".style.display != \"none\"]; "
+ "})()"); + "})()");
javascriptHelper.waitUntilHasValue(); javascriptHelper.waitUntilHasValue();
JSONArray result = new JSONArray(javascriptHelper.getJsonResultAndClear()); JSONArray result = new JSONArray(javascriptHelper.getJsonResultAndClear());
...@@ -543,19 +556,37 @@ class AutofillAssistantUiTestUtil { ...@@ -543,19 +556,37 @@ class AutofillAssistantUiTestUtil {
/** /**
* Retrieves the value of the specified element. * Retrieves the value of the specified element.
*/ */
public static String getElementValue(String elementId, WebContents webContents) public static String getElementValue(WebContents webContents, String... elementIds)
throws Exception { throws Exception {
if (!checkElementExists(elementId, webContents)) { if (!checkElementExists(webContents, elementIds)) {
throw new IllegalArgumentException(elementId + " does not exist"); throw new IllegalArgumentException(Arrays.toString(elementIds) + " does not exist");
} }
TestCallbackHelperContainer.OnEvaluateJavaScriptResultHelper javascriptHelper = TestCallbackHelperContainer.OnEvaluateJavaScriptResultHelper javascriptHelper =
new TestCallbackHelperContainer.OnEvaluateJavaScriptResultHelper(); new TestCallbackHelperContainer.OnEvaluateJavaScriptResultHelper();
javascriptHelper.evaluateJavaScriptForTests(webContents, javascriptHelper.evaluateJavaScriptForTests(webContents,
"(function() {" "(function() {"
+ " return [document.getElementById('" + elementId + "').value]" + " return [" + getElementSelectorString(elementIds) + ".value]"
+ "})()"); + "})()");
javascriptHelper.waitUntilHasValue(); javascriptHelper.waitUntilHasValue();
JSONArray result = new JSONArray(javascriptHelper.getJsonResultAndClear()); JSONArray result = new JSONArray(javascriptHelper.getJsonResultAndClear());
return result.getString(0); return result.getString(0);
} }
private static String getElementSelectorString(String[] elementIds) {
StringBuilder builder = new StringBuilder();
builder.append("document");
for (int i = 0; i < elementIds.length; ++i) {
builder.append(".getElementById('");
builder.append(elementIds[i]);
builder.append("')");
if (i != elementIds.length - 1) {
// Get the iFrame document. This only works for local iFrames, OutOfProcess iFrames
// may respond with an error.
builder.append(".contentWindow.document");
}
}
return builder.toString();
}
} }
...@@ -1483,9 +1483,10 @@ IN_PROC_BROWSER_TEST_F(WebControllerBrowserTest, GetElementPosition) { ...@@ -1483,9 +1483,10 @@ IN_PROC_BROWSER_TEST_F(WebControllerBrowserTest, GetElementPosition) {
Selector document_element({"#full_height_section"}); Selector document_element({"#full_height_section"});
EXPECT_TRUE(GetElementPosition(document_element, &document_element_rect)); EXPECT_TRUE(GetElementPosition(document_element, &document_element_rect));
// This element must be after the full_height_section! // The iFrame must be after the #full_height_section element to check that
// the resulting rect is global.
RectF iframe_element_rect; RectF iframe_element_rect;
Selector iframe_element({"#iframe", "#touch_area"}); Selector iframe_element({"#iframe", "#touch_area_1"});
EXPECT_TRUE(GetElementPosition(iframe_element, &iframe_element_rect)); EXPECT_TRUE(GetElementPosition(iframe_element, &iframe_element_rect));
EXPECT_GT(iframe_element_rect.top, document_element_rect.bottom); EXPECT_GT(iframe_element_rect.top, document_element_rect.bottom);
......
...@@ -30,8 +30,8 @@ found in the LICENSE file. ...@@ -30,8 +30,8 @@ found in the LICENSE file.
button.parentNode.removeChild(button); button.parentNode.removeChild(button);
} }
var removeTouchArea = function() { var removeTouchArea = function(id) {
var touch_area = document.getElementById("touch_area"); var touch_area = document.getElementById(id);
touch_area.parentNode.removeChild(touch_area); touch_area.parentNode.removeChild(touch_area);
} }
...@@ -91,7 +91,20 @@ found in the LICENSE file. ...@@ -91,7 +91,20 @@ found in the LICENSE file.
</div> </div>
<div> <div>
<p id="touch_area" ontouchend="removeTouchArea()">Touchable Area</p> <p id="touch_area" ontouchend="removeTouchArea('touch_area')">
Touchable Area</p>
<br>
</div>
<div>
<p id="touch_area_1" ontouchend="removeTouchArea('touch_area_1')">
Touchable Area 1 (iFrame)</p>
<br>
</div>
<div>
<p id="touch_area_2" ontouchend="removeTouchArea('touch_area_2')">
Touchable Area 2 (iFrame)</p>
<br> <br>
</div> </div>
...@@ -108,6 +121,18 @@ found in the LICENSE file. ...@@ -108,6 +121,18 @@ found in the LICENSE file.
</div> </div>
<div id="focus">Hidden Text</div> <div id="focus">Hidden Text</div>
<div>
<p id="touch_area_3" ontouchend="removeTouchArea('touch_area_3')">
Touchable Area 3 (iFrame)</p>
<br>
</div>
<div>
<p id="touch_area_4" ontouchend="removeTouchArea('touch_area_4')">
Touchable Area 4 (iFrame)</p>
<br>
</div>
<iframe id="iframe" width="100%" height="500" src= <iframe id="iframe" width="100%" height="500" src=
"autofill_assistant_target_website_iframe_two.html"></iframe> "autofill_assistant_target_website_iframe_two.html"></iframe>
</body> </body>
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment