Commit 029257f2 authored by mnaganov's avatar mnaganov Committed by Commit bot

[Android WebView] Deflake new OnReceived*Error tests that simulate tap

It seems that the first non-empty draw sometimes is missing the link that
the test is supposed to "tap". Waiting for the pixel colour to actually
change to the link colour stabilizes tests.

BUG=456782

Review URL: https://codereview.chromium.org/1026723002

Cr-Commit-Position: refs/heads/master@{#321557}
parent cbacfd78
...@@ -4,8 +4,6 @@ ...@@ -4,8 +4,6 @@
package org.chromium.android_webview.test; package org.chromium.android_webview.test;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.os.Build; import android.os.Build;
import android.test.suitebuilder.annotation.SmallTest; import android.test.suitebuilder.annotation.SmallTest;
import android.util.Pair; import android.util.Pair;
...@@ -14,7 +12,6 @@ import org.chromium.android_webview.AwContents; ...@@ -14,7 +12,6 @@ import org.chromium.android_webview.AwContents;
import org.chromium.android_webview.AwWebResourceResponse; import org.chromium.android_webview.AwWebResourceResponse;
import org.chromium.android_webview.test.util.AwTestTouchUtils; import org.chromium.android_webview.test.util.AwTestTouchUtils;
import org.chromium.android_webview.test.util.CommonResources; import org.chromium.android_webview.test.util.CommonResources;
import org.chromium.android_webview.test.util.GraphicsTestUtils;
import org.chromium.android_webview.test.util.JSUtils; import org.chromium.android_webview.test.util.JSUtils;
import org.chromium.base.test.util.Feature; import org.chromium.base.test.util.Feature;
import org.chromium.base.test.util.MinAndroidSdkLevel; import org.chromium.base.test.util.MinAndroidSdkLevel;
...@@ -242,21 +239,8 @@ public class AwContentsClientShouldInterceptRequestTest extends AwTestBase { ...@@ -242,21 +239,8 @@ public class AwContentsClientShouldInterceptRequestTest extends AwTestBase {
assertEquals(false, assertEquals(false,
mShouldInterceptRequestHelper.getRequestsForUrl(pageWithLinkUrl).hasUserGesture); mShouldInterceptRequestHelper.getRequestsForUrl(pageWithLinkUrl).hasUserGesture);
// TODO(mkosiba): Remove this once we have a real API to wait for the page to load and waitForPixelColorAtCenterOfView(mAwContents,
// display. mTestContainerView, CommonResources.LINK_COLOR);
// http://crbug.com/364612
//
// The code here is waiting for the "link" (which is a full-screen blue div) to appear on
// screen.
pollOnUiThread(new Callable<Boolean>() {
@Override
public Boolean call() throws Exception {
Bitmap bitmap = GraphicsTestUtils.drawAwContents(mAwContents, 2, 2,
-(float) mTestContainerView.getWidth() / 2,
-(float) mTestContainerView.getHeight() / 2);
return bitmap.getPixel(0, 0) == Color.BLUE;
}
});
callCount = mShouldInterceptRequestHelper.getCallCount(); callCount = mShouldInterceptRequestHelper.getCallCount();
AwTestTouchUtils.simulateTouchCenterOfView(mTestContainerView); AwTestTouchUtils.simulateTouchCenterOfView(mTestContainerView);
mShouldInterceptRequestHelper.waitForCallback(callCount); mShouldInterceptRequestHelper.waitForCallback(callCount);
......
...@@ -6,6 +6,7 @@ package org.chromium.android_webview.test; ...@@ -6,6 +6,7 @@ package org.chromium.android_webview.test;
import android.app.Instrumentation; import android.app.Instrumentation;
import android.content.Context; import android.content.Context;
import android.graphics.Bitmap;
import android.test.ActivityInstrumentationTestCase2; import android.test.ActivityInstrumentationTestCase2;
import android.util.Log; import android.util.Log;
...@@ -16,6 +17,7 @@ import org.chromium.android_webview.AwBrowserProcess; ...@@ -16,6 +17,7 @@ import org.chromium.android_webview.AwBrowserProcess;
import org.chromium.android_webview.AwContents; import org.chromium.android_webview.AwContents;
import org.chromium.android_webview.AwContentsClient; import org.chromium.android_webview.AwContentsClient;
import org.chromium.android_webview.AwSettings; import org.chromium.android_webview.AwSettings;
import org.chromium.android_webview.test.util.GraphicsTestUtils;
import org.chromium.android_webview.test.util.JSUtils; import org.chromium.android_webview.test.util.JSUtils;
import org.chromium.base.test.util.InMemorySharedPreferences; import org.chromium.base.test.util.InMemorySharedPreferences;
import org.chromium.content.browser.test.util.CallbackHelper; import org.chromium.content.browser.test.util.CallbackHelper;
...@@ -293,6 +295,22 @@ public class AwTestBase ...@@ -293,6 +295,22 @@ public class AwTestBase
ch.waitForCallback(chCount); ch.waitForCallback(chCount);
} }
// Waits for the pixel at the center of AwContents to color up into expectedColor.
// Note that this is a stricter condition that waiting for a visual state callback,
// as visual state callback only indicates that *something* has appeared in WebView.
public void waitForPixelColorAtCenterOfView(final AwContents awContents,
final AwTestContainerView testContainerView, final int expectedColor) throws Exception {
pollOnUiThread(new Callable<Boolean>() {
@Override
public Boolean call() throws Exception {
Bitmap bitmap = GraphicsTestUtils.drawAwContents(awContents, 2, 2,
-(float) testContainerView.getWidth() / 2,
-(float) testContainerView.getHeight() / 2);
return bitmap.getPixel(0, 0) == expectedColor;
}
});
}
/** /**
* Checks the current test has |clazz| annotation. Note this swallows NoSuchMethodException * Checks the current test has |clazz| annotation. Note this swallows NoSuchMethodException
* and returns false in that case. * and returns false in that case.
......
...@@ -120,7 +120,8 @@ public class ClientOnReceivedError2Test extends AwTestBase { ...@@ -120,7 +120,8 @@ public class ClientOnReceivedError2Test extends AwTestBase {
useDefaultTestAwContentsClient(); useDefaultTestAwContentsClient();
final String pageHtml = CommonResources.makeHtmlPageWithSimpleLinkTo(BAD_HTML_URL); final String pageHtml = CommonResources.makeHtmlPageWithSimpleLinkTo(BAD_HTML_URL);
loadDataAsync(mAwContents, pageHtml, "text/html", false); loadDataAsync(mAwContents, pageHtml, "text/html", false);
waitForVisualStateCallback(mAwContents); waitForPixelColorAtCenterOfView(mAwContents,
mTestContainerView, CommonResources.LINK_COLOR);
TestAwContentsClient.OnReceivedError2Helper onReceivedError2Helper = TestAwContentsClient.OnReceivedError2Helper onReceivedError2Helper =
mContentsClient.getOnReceivedError2Helper(); mContentsClient.getOnReceivedError2Helper();
...@@ -182,7 +183,8 @@ public class ClientOnReceivedError2Test extends AwTestBase { ...@@ -182,7 +183,8 @@ public class ClientOnReceivedError2Test extends AwTestBase {
final String pageHtml = CommonResources.makeHtmlPageFrom( final String pageHtml = CommonResources.makeHtmlPageFrom(
"", "<iframe style='width:100%;height:100%;' src='" + iframeUrl + "' />"); "", "<iframe style='width:100%;height:100%;' src='" + iframeUrl + "' />");
loadDataAsync(mAwContents, pageHtml, "text/html", false); loadDataAsync(mAwContents, pageHtml, "text/html", false);
waitForVisualStateCallback(mAwContents); waitForPixelColorAtCenterOfView(mAwContents,
mTestContainerView, CommonResources.LINK_COLOR);
TestAwContentsClient.OnReceivedError2Helper onReceivedError2Helper = TestAwContentsClient.OnReceivedError2Helper onReceivedError2Helper =
mContentsClient.getOnReceivedError2Helper(); mContentsClient.getOnReceivedError2Helper();
......
...@@ -129,7 +129,8 @@ public class ClientOnReceivedHttpErrorTest extends AwTestBase { ...@@ -129,7 +129,8 @@ public class ClientOnReceivedHttpErrorTest extends AwTestBase {
CommonResources.makeHtmlPageWithSimpleLinkTo(badUrl), null); CommonResources.makeHtmlPageWithSimpleLinkTo(badUrl), null);
enableJavaScriptOnUiThread(mAwContents); enableJavaScriptOnUiThread(mAwContents);
loadUrlAsync(mAwContents, pageWithLinkUrl); loadUrlAsync(mAwContents, pageWithLinkUrl);
waitForVisualStateCallback(mAwContents); waitForPixelColorAtCenterOfView(mAwContents,
mTestContainerView, CommonResources.LINK_COLOR);
TestAwContentsClient.OnReceivedHttpErrorHelper onReceivedHttpErrorHelper = TestAwContentsClient.OnReceivedHttpErrorHelper onReceivedHttpErrorHelper =
mContentsClient.getOnReceivedHttpErrorHelper(); mContentsClient.getOnReceivedHttpErrorHelper();
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
package org.chromium.android_webview.test.util; package org.chromium.android_webview.test.util;
import android.graphics.Color;
import android.util.Pair; import android.util.Pair;
import java.util.ArrayList; import java.util.ArrayList;
...@@ -39,18 +40,18 @@ public class CommonResources { ...@@ -39,18 +40,18 @@ public class CommonResources {
// Returns the HTML code used to verify if an image has been successfully loaded. // Returns the HTML code used to verify if an image has been successfully loaded.
public static String getOnImageLoadedHtml(String imageSrc) { public static String getOnImageLoadedHtml(String imageSrc) {
return "<html>" + return "<html>"
" <head>" + + " <head>"
" <script>" + + " <script>"
" function updateTitle() {" + + " function updateTitle() {"
" document.title=document.getElementById('img').naturalHeight" + + " document.title=document.getElementById('img').naturalHeight"
" }" + + " }"
" </script>" + + " </script>"
" </head>" + + " </head>"
" <body onload='updateTitle();'>" + + " <body onload='updateTitle();'>"
" <img id='img' onload='updateTitle();' src='" + imageSrc + "'>" + + " <img id='img' onload='updateTitle();' src='" + imageSrc + "'>"
" </body>" + + " </body>"
"</html>"; + "</html>";
} }
// Default name for the favicon image. // Default name for the favicon image.
...@@ -61,37 +62,37 @@ public class CommonResources { ...@@ -61,37 +62,37 @@ public class CommonResources {
// HTML code of a static simple page with a favicon. // HTML code of a static simple page with a favicon.
public static final String FAVICON_STATIC_HTML = public static final String FAVICON_STATIC_HTML =
"<html><head><link rel=\"icon\" type=\"image/png\" href=\"" + FAVICON_FILENAME + "\">" + "<html><head><link rel=\"icon\" type=\"image/png\" href=\"" + FAVICON_FILENAME + "\">"
"</head><body>Favicon example</body></html>"; + "</head><body>Favicon example</body></html>";
// Base64 data of a 256x256 png with all pixels having colour value 0x0000ff // Base64 data of a 256x256 png with all pixels having colour value 0x0000ff
public static final String BLUE_PNG_BASE64 = public static final String BLUE_PNG_BASE64 =
"iVBORw0KGgoAAAANSUhEUgAAAQAAAAEACAIAAADTED8xAAACvUlEQVR4nO3TMQEA" + "iVBORw0KGgoAAAANSUhEUgAAAQAAAAEACAIAAADTED8xAAACvUlEQVR4nO3TMQEA"
"IAzAsIF/zyBjRxMFfXpm3kDV3Q6ATQYgzQCkGYA0A5BmANIMQJoBSDMAaQYgzQCk" + + "IAzAsIF/zyBjRxMFfXpm3kDV3Q6ATQYgzQCkGYA0A5BmANIMQJoBSDMAaQYgzQCk"
"GYA0A5BmANIMQJoBSDMAaQYgzQCkGYA0A5BmANIMQJoBSDMAaQYgzQCkGYA0A5Bm" + + "GYA0A5BmANIMQJoBSDMAaQYgzQCkGYA0A5BmANIMQJoBSDMAaQYgzQCkGYA0A5Bm"
"ANIMQJoBSDMAaQYgzQCkGYA0A5BmANIMQJoBSDMAaQYgzQCkGYA0A5BmANIMQJoB" + + "ANIMQJoBSDMAaQYgzQCkGYA0A5BmANIMQJoBSDMAaQYgzQCkGYA0A5BmANIMQJoB"
"SDMAaQYgzQCkGYA0A5BmANIMQJoBSDMAaQYgzQCkGYA0A5BmANIMQJoBSDMAaQYg" + + "SDMAaQYgzQCkGYA0A5BmANIMQJoBSDMAaQYgzQCkGYA0A5BmANIMQJoBSDMAaQYg"
"zQCkGYA0A5BmANIMQJoBSDMAaQYgzQCkGYA0A5BmANIMQJoBSDMAaQYgzQCkGYA0" + + "zQCkGYA0A5BmANIMQJoBSDMAaQYgzQCkGYA0A5BmANIMQJoBSDMAaQYgzQCkGYA0"
"A5BmANIMQJoBSDMAaQYgzQCkGYA0A5BmANIMQJoBSDMAaQYgzQCkGYA0A5BmANIM" + + "A5BmANIMQJoBSDMAaQYgzQCkGYA0A5BmANIMQJoBSDMAaQYgzQCkGYA0A5BmANIM"
"QJoBSDMAaQYgzQCkGYA0A5BmANIMQJoBSDMAaQYgzQCkGYA0A5BmANIMQJoBSDMA" + + "QJoBSDMAaQYgzQCkGYA0A5BmANIMQJoBSDMAaQYgzQCkGYA0A5BmANIMQJoBSDMA"
"aQYgzQCkGYA0A5BmANIMQJoBSDMAaQYgzQCkGYA0A5BmANIMQJoBSDMAaQYgzQCk" + + "aQYgzQCkGYA0A5BmANIMQJoBSDMAaQYgzQCkGYA0A5BmANIMQJoBSDMAaQYgzQCk"
"GYA0A5BmANIMQJoBSDMAaQYgzQCkGYA0A5BmANIMQJoBSDMAaQYgzQCkGYA0A5Bm" + + "GYA0A5BmANIMQJoBSDMAaQYgzQCkGYA0A5BmANIMQJoBSDMAaQYgzQCkGYA0A5Bm"
"ANIMQJoBSDMAaQYgzQCkGYA0A5BmANIMQJoBSDMAaQYgzQCkGYA0A5BmANIMQJoB" + + "ANIMQJoBSDMAaQYgzQCkGYA0A5BmANIMQJoBSDMAaQYgzQCkGYA0A5BmANIMQJoB"
"SDMAaQYgzQCkGYA0A5BmANIMQJoBSDMAaQYgzQCkGYA0A5BmANIMQJoBSDMAaQYg" + + "SDMAaQYgzQCkGYA0A5BmANIMQJoBSDMAaQYgzQCkGYA0A5BmANIMQJoBSDMAaQYg"
"zQCkGYA0A5BmANIMQJoBSDMAaQYgzQCkGYA0A5BmANIMQJoBSDMAaQYgzQCkGYA0" + + "zQCkGYA0A5BmANIMQJoBSDMAaQYgzQCkGYA0A5BmANIMQJoBSDMAaQYgzQCkGYA0"
"A5BmANIMQJoBSDMAaQYgzQCkGYA0A5BmANIMQJoBSDMAaQYgzQCkGYA0A5BmANIM" + + "A5BmANIMQJoBSDMAaQYgzQCkGYA0A5BmANIMQJoBSDMAaQYgzQCkGYA0A5BmANIM"
"QJoBSDMAaQYgzQCkGYA0A5BmANIMQJoBSDMAaQYgzQCkGYA0A5BmANIMQJoBSDMA" + + "QJoBSDMAaQYgzQCkGYA0A5BmANIMQJoBSDMAaQYgzQCkGYA0A5BmANIMQJoBSDMA"
"aQYgzQCkGYA0A5BmANIMQNoHVyEC/zTGc0UAAAAASUVORK5CYII="; + "aQYgzQCkGYA0A5BmANIMQNoHVyEC/zTGc0UAAAAASUVORK5CYII=";
// Base64 data of a favicon image resource. // Base64 data of a favicon image resource.
public static final String FAVICON_DATA_BASE64 = public static final String FAVICON_DATA_BASE64 =
"iVBORw0KGgoAAAANSUhEUgAAABAAAAAFCAYAAABM6GxJAAAABHNCSVQICAgIfAhkiAAAASJJREFU" + "iVBORw0KGgoAAAANSUhEUgAAABAAAAAFCAYAAABM6GxJAAAABHNCSVQICAgIfAhkiAAAASJJREFU"
"GJU9yDtLQnEYwOHfOZ40L3gZDJKgJCKaamvpGzS09wUaormh7xA0S5C0ZDTkZJsNUltkkpAUZkIX" + + "GJU9yDtLQnEYwOHfOZ40L3gZDJKgJCKaamvpGzS09wUaormh7xA0S5C0ZDTkZJsNUltkkpAUZkIX"
"L3g9FzzH/9vm9vAgoqRUGUu20JHTXFfafUdERJSIKJnOPFUTERHpqIYclY5nb2QKFumky95OlO+W" + + "L3g9FzzH/9vm9vAgoqRUGUu20JHTXFfafUdERJSIKJnOPFUTERHpqIYclY5nb2QKFumky95OlO+W"
"TSgATqOO5k3xr6ZxelXmDFDhdaqfLkPRWQglULaN/V5DPzl3iIb9xCI+Eskog/wdyhowLlb4vThE" + + "TSgATqOO5k3xr6ZxelXmDFDhdaqfLkPRWQglULaN/V5DPzl3iIb9xCI+Eskog/wdyhowLlb4vThE"
"giF8zRsurx55beg8lMfMezZW9hqz20M/Owhwe2/yUrPI5Ds8//mRehN7JYWxvIX6eWJkbLK9laL8" + + "giF8zRsurx55beg8lMfMezZW9hqz20M/Owhwe2/yUrPI5Ds8//mRehN7JYWxvIX6eWJkbLK9laL8"
"ZrKxFETzxTBNB5SOJjKV/mhCq+uSjGvE4hHc4QA9YGAEwnhWF1ePkCtOWFv0+PiasL8bR3QDr93h" + + "ZrKxFETzxTBNB5SOJjKV/mhCq+uSjGvE4hHc4QA9YGAEwnhWF1ePkCtOWFv0+PiasL8bR3QDr93h"
"HyFup9LWUksHAAAAAElFTkSuQmCC"; + "HyFup9LWUksHAAAAAElFTkSuQmCC";
// Default name for an example 'about' HTML page. // Default name for an example 'about' HTML page.
public static final String ABOUT_FILENAME = "about.html"; public static final String ABOUT_FILENAME = "about.html";
...@@ -101,38 +102,41 @@ public class CommonResources { ...@@ -101,38 +102,41 @@ public class CommonResources {
// HTML code of an 'about' example. // HTML code of an 'about' example.
public static final String ABOUT_HTML = public static final String ABOUT_HTML =
"<html>" + "<html>"
" <head>" + + " <head>"
" <title>" + ABOUT_TITLE + "</title>" + + " <title>" + ABOUT_TITLE + "</title>"
" </head>" + + " </head>"
" <body>" + + " <body>"
" This is the Google!" + + " This is the Google!"
" </body>" + + " </body>"
"</html>"; + "</html>";
public static String makeHtmlPageFrom(String headers, String body) { public static String makeHtmlPageFrom(String headers, String body) {
return "<html>" + return "<html>"
" <head>" + + " <head>"
" <style type=\"text/css\">" + + " <style type=\"text/css\">"
// Make the image take up all of the page so that we don't have to do // Make the image take up all of the page so that we don't have to do
// any fancy hit target calculations when synthesizing the touch event // any fancy hit target calculations when synthesizing the touch event
// to click it. // to click it.
" img.big { width:100%; height:100%; background-color:blue; }" + + " img.big { width:100%; height:100%; background-color:blue; }"
" .full_view { height:100%; width:100%; position:absolute; }" + + " .full_view { height:100%; width:100%; position:absolute; }"
" </style>" + + " </style>"
headers + + headers
" </head>" + + " </head>"
" <body>" + + " <body>"
body + + body
" </body>" + + " </body>"
"</html>"; + "</html>";
} }
// The color must match the background color of 'img.big' CSS class.
public static final int LINK_COLOR = Color.BLUE;
public static String makeHtmlPageWithSimpleLinkTo(String headers, String destination) { public static String makeHtmlPageWithSimpleLinkTo(String headers, String destination) {
return makeHtmlPageFrom(headers, return makeHtmlPageFrom(headers,
"<a href=\"" + destination + "\" id=\"link\">" + "<a href=\"" + destination + "\" id=\"link\">"
" <img class=\"big\" />" + + " <img class=\"big\" />"
"</a>"); + "</a>");
} }
public static String makeHtmlPageWithSimpleLinkTo(String destination) { public static String makeHtmlPageWithSimpleLinkTo(String destination) {
...@@ -141,8 +145,8 @@ public class CommonResources { ...@@ -141,8 +145,8 @@ public class CommonResources {
public static String makeHtmlPageWithSimplePostFormTo(String destination) { public static String makeHtmlPageWithSimplePostFormTo(String destination) {
return makeHtmlPageFrom("", return makeHtmlPageFrom("",
"<form action=\"" + destination + "\" method=\"post\">" + "<form action=\"" + destination + "\" method=\"post\">"
" <input type=\"submit\" value=\"post\" id=\"link\">" + + " <input type=\"submit\" value=\"post\" id=\"link\">"
"</form>"); + "</form>");
} }
} }
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