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 @@
package org.chromium.android_webview.test;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.os.Build;
import android.test.suitebuilder.annotation.SmallTest;
import android.util.Pair;
......@@ -14,7 +12,6 @@ import org.chromium.android_webview.AwContents;
import org.chromium.android_webview.AwWebResourceResponse;
import org.chromium.android_webview.test.util.AwTestTouchUtils;
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.base.test.util.Feature;
import org.chromium.base.test.util.MinAndroidSdkLevel;
......@@ -242,21 +239,8 @@ public class AwContentsClientShouldInterceptRequestTest extends AwTestBase {
assertEquals(false,
mShouldInterceptRequestHelper.getRequestsForUrl(pageWithLinkUrl).hasUserGesture);
// TODO(mkosiba): Remove this once we have a real API to wait for the page to load and
// display.
// 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;
}
});
waitForPixelColorAtCenterOfView(mAwContents,
mTestContainerView, CommonResources.LINK_COLOR);
callCount = mShouldInterceptRequestHelper.getCallCount();
AwTestTouchUtils.simulateTouchCenterOfView(mTestContainerView);
mShouldInterceptRequestHelper.waitForCallback(callCount);
......
......@@ -6,6 +6,7 @@ package org.chromium.android_webview.test;
import android.app.Instrumentation;
import android.content.Context;
import android.graphics.Bitmap;
import android.test.ActivityInstrumentationTestCase2;
import android.util.Log;
......@@ -16,6 +17,7 @@ import org.chromium.android_webview.AwBrowserProcess;
import org.chromium.android_webview.AwContents;
import org.chromium.android_webview.AwContentsClient;
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.base.test.util.InMemorySharedPreferences;
import org.chromium.content.browser.test.util.CallbackHelper;
......@@ -293,6 +295,22 @@ public class AwTestBase
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
* and returns false in that case.
......
......@@ -120,7 +120,8 @@ public class ClientOnReceivedError2Test extends AwTestBase {
useDefaultTestAwContentsClient();
final String pageHtml = CommonResources.makeHtmlPageWithSimpleLinkTo(BAD_HTML_URL);
loadDataAsync(mAwContents, pageHtml, "text/html", false);
waitForVisualStateCallback(mAwContents);
waitForPixelColorAtCenterOfView(mAwContents,
mTestContainerView, CommonResources.LINK_COLOR);
TestAwContentsClient.OnReceivedError2Helper onReceivedError2Helper =
mContentsClient.getOnReceivedError2Helper();
......@@ -182,7 +183,8 @@ public class ClientOnReceivedError2Test extends AwTestBase {
final String pageHtml = CommonResources.makeHtmlPageFrom(
"", "<iframe style='width:100%;height:100%;' src='" + iframeUrl + "' />");
loadDataAsync(mAwContents, pageHtml, "text/html", false);
waitForVisualStateCallback(mAwContents);
waitForPixelColorAtCenterOfView(mAwContents,
mTestContainerView, CommonResources.LINK_COLOR);
TestAwContentsClient.OnReceivedError2Helper onReceivedError2Helper =
mContentsClient.getOnReceivedError2Helper();
......
......@@ -129,7 +129,8 @@ public class ClientOnReceivedHttpErrorTest extends AwTestBase {
CommonResources.makeHtmlPageWithSimpleLinkTo(badUrl), null);
enableJavaScriptOnUiThread(mAwContents);
loadUrlAsync(mAwContents, pageWithLinkUrl);
waitForVisualStateCallback(mAwContents);
waitForPixelColorAtCenterOfView(mAwContents,
mTestContainerView, CommonResources.LINK_COLOR);
TestAwContentsClient.OnReceivedHttpErrorHelper onReceivedHttpErrorHelper =
mContentsClient.getOnReceivedHttpErrorHelper();
......
......@@ -4,6 +4,7 @@
package org.chromium.android_webview.test.util;
import android.graphics.Color;
import android.util.Pair;
import java.util.ArrayList;
......@@ -39,18 +40,18 @@ public class CommonResources {
// Returns the HTML code used to verify if an image has been successfully loaded.
public static String getOnImageLoadedHtml(String imageSrc) {
return "<html>" +
" <head>" +
" <script>" +
" function updateTitle() {" +
" document.title=document.getElementById('img').naturalHeight" +
" }" +
" </script>" +
" </head>" +
" <body onload='updateTitle();'>" +
" <img id='img' onload='updateTitle();' src='" + imageSrc + "'>" +
" </body>" +
"</html>";
return "<html>"
+ " <head>"
+ " <script>"
+ " function updateTitle() {"
+ " document.title=document.getElementById('img').naturalHeight"
+ " }"
+ " </script>"
+ " </head>"
+ " <body onload='updateTitle();'>"
+ " <img id='img' onload='updateTitle();' src='" + imageSrc + "'>"
+ " </body>"
+ "</html>";
}
// Default name for the favicon image.
......@@ -61,37 +62,37 @@ public class CommonResources {
// HTML code of a static simple page with a favicon.
public static final String FAVICON_STATIC_HTML =
"<html><head><link rel=\"icon\" type=\"image/png\" href=\"" + FAVICON_FILENAME + "\">" +
"</head><body>Favicon example</body></html>";
"<html><head><link rel=\"icon\" type=\"image/png\" href=\"" + FAVICON_FILENAME + "\">"
+ "</head><body>Favicon example</body></html>";
// Base64 data of a 256x256 png with all pixels having colour value 0x0000ff
public static final String BLUE_PNG_BASE64 =
"iVBORw0KGgoAAAANSUhEUgAAAQAAAAEACAIAAADTED8xAAACvUlEQVR4nO3TMQEA" +
"IAzAsIF/zyBjRxMFfXpm3kDV3Q6ATQYgzQCkGYA0A5BmANIMQJoBSDMAaQYgzQCk" +
"GYA0A5BmANIMQJoBSDMAaQYgzQCkGYA0A5BmANIMQJoBSDMAaQYgzQCkGYA0A5Bm" +
"ANIMQJoBSDMAaQYgzQCkGYA0A5BmANIMQJoBSDMAaQYgzQCkGYA0A5BmANIMQJoB" +
"SDMAaQYgzQCkGYA0A5BmANIMQJoBSDMAaQYgzQCkGYA0A5BmANIMQJoBSDMAaQYg" +
"zQCkGYA0A5BmANIMQJoBSDMAaQYgzQCkGYA0A5BmANIMQJoBSDMAaQYgzQCkGYA0" +
"A5BmANIMQJoBSDMAaQYgzQCkGYA0A5BmANIMQJoBSDMAaQYgzQCkGYA0A5BmANIM" +
"QJoBSDMAaQYgzQCkGYA0A5BmANIMQJoBSDMAaQYgzQCkGYA0A5BmANIMQJoBSDMA" +
"aQYgzQCkGYA0A5BmANIMQJoBSDMAaQYgzQCkGYA0A5BmANIMQJoBSDMAaQYgzQCk" +
"GYA0A5BmANIMQJoBSDMAaQYgzQCkGYA0A5BmANIMQJoBSDMAaQYgzQCkGYA0A5Bm" +
"ANIMQJoBSDMAaQYgzQCkGYA0A5BmANIMQJoBSDMAaQYgzQCkGYA0A5BmANIMQJoB" +
"SDMAaQYgzQCkGYA0A5BmANIMQJoBSDMAaQYgzQCkGYA0A5BmANIMQJoBSDMAaQYg" +
"zQCkGYA0A5BmANIMQJoBSDMAaQYgzQCkGYA0A5BmANIMQJoBSDMAaQYgzQCkGYA0" +
"A5BmANIMQJoBSDMAaQYgzQCkGYA0A5BmANIMQJoBSDMAaQYgzQCkGYA0A5BmANIM" +
"QJoBSDMAaQYgzQCkGYA0A5BmANIMQJoBSDMAaQYgzQCkGYA0A5BmANIMQJoBSDMA" +
"aQYgzQCkGYA0A5BmANIMQNoHVyEC/zTGc0UAAAAASUVORK5CYII=";
"iVBORw0KGgoAAAANSUhEUgAAAQAAAAEACAIAAADTED8xAAACvUlEQVR4nO3TMQEA"
+ "IAzAsIF/zyBjRxMFfXpm3kDV3Q6ATQYgzQCkGYA0A5BmANIMQJoBSDMAaQYgzQCk"
+ "GYA0A5BmANIMQJoBSDMAaQYgzQCkGYA0A5BmANIMQJoBSDMAaQYgzQCkGYA0A5Bm"
+ "ANIMQJoBSDMAaQYgzQCkGYA0A5BmANIMQJoBSDMAaQYgzQCkGYA0A5BmANIMQJoB"
+ "SDMAaQYgzQCkGYA0A5BmANIMQJoBSDMAaQYgzQCkGYA0A5BmANIMQJoBSDMAaQYg"
+ "zQCkGYA0A5BmANIMQJoBSDMAaQYgzQCkGYA0A5BmANIMQJoBSDMAaQYgzQCkGYA0"
+ "A5BmANIMQJoBSDMAaQYgzQCkGYA0A5BmANIMQJoBSDMAaQYgzQCkGYA0A5BmANIM"
+ "QJoBSDMAaQYgzQCkGYA0A5BmANIMQJoBSDMAaQYgzQCkGYA0A5BmANIMQJoBSDMA"
+ "aQYgzQCkGYA0A5BmANIMQJoBSDMAaQYgzQCkGYA0A5BmANIMQJoBSDMAaQYgzQCk"
+ "GYA0A5BmANIMQJoBSDMAaQYgzQCkGYA0A5BmANIMQJoBSDMAaQYgzQCkGYA0A5Bm"
+ "ANIMQJoBSDMAaQYgzQCkGYA0A5BmANIMQJoBSDMAaQYgzQCkGYA0A5BmANIMQJoB"
+ "SDMAaQYgzQCkGYA0A5BmANIMQJoBSDMAaQYgzQCkGYA0A5BmANIMQJoBSDMAaQYg"
+ "zQCkGYA0A5BmANIMQJoBSDMAaQYgzQCkGYA0A5BmANIMQJoBSDMAaQYgzQCkGYA0"
+ "A5BmANIMQJoBSDMAaQYgzQCkGYA0A5BmANIMQJoBSDMAaQYgzQCkGYA0A5BmANIM"
+ "QJoBSDMAaQYgzQCkGYA0A5BmANIMQJoBSDMAaQYgzQCkGYA0A5BmANIMQJoBSDMA"
+ "aQYgzQCkGYA0A5BmANIMQNoHVyEC/zTGc0UAAAAASUVORK5CYII=";
// Base64 data of a favicon image resource.
public static final String FAVICON_DATA_BASE64 =
"iVBORw0KGgoAAAANSUhEUgAAABAAAAAFCAYAAABM6GxJAAAABHNCSVQICAgIfAhkiAAAASJJREFU" +
"GJU9yDtLQnEYwOHfOZ40L3gZDJKgJCKaamvpGzS09wUaormh7xA0S5C0ZDTkZJsNUltkkpAUZkIX" +
"L3g9FzzH/9vm9vAgoqRUGUu20JHTXFfafUdERJSIKJnOPFUTERHpqIYclY5nb2QKFumky95OlO+W" +
"TSgATqOO5k3xr6ZxelXmDFDhdaqfLkPRWQglULaN/V5DPzl3iIb9xCI+Eskog/wdyhowLlb4vThE" +
"giF8zRsurx55beg8lMfMezZW9hqz20M/Owhwe2/yUrPI5Ds8//mRehN7JYWxvIX6eWJkbLK9laL8" +
"ZrKxFETzxTBNB5SOJjKV/mhCq+uSjGvE4hHc4QA9YGAEwnhWF1ePkCtOWFv0+PiasL8bR3QDr93h" +
"HyFup9LWUksHAAAAAElFTkSuQmCC";
"iVBORw0KGgoAAAANSUhEUgAAABAAAAAFCAYAAABM6GxJAAAABHNCSVQICAgIfAhkiAAAASJJREFU"
+ "GJU9yDtLQnEYwOHfOZ40L3gZDJKgJCKaamvpGzS09wUaormh7xA0S5C0ZDTkZJsNUltkkpAUZkIX"
+ "L3g9FzzH/9vm9vAgoqRUGUu20JHTXFfafUdERJSIKJnOPFUTERHpqIYclY5nb2QKFumky95OlO+W"
+ "TSgATqOO5k3xr6ZxelXmDFDhdaqfLkPRWQglULaN/V5DPzl3iIb9xCI+Eskog/wdyhowLlb4vThE"
+ "giF8zRsurx55beg8lMfMezZW9hqz20M/Owhwe2/yUrPI5Ds8//mRehN7JYWxvIX6eWJkbLK9laL8"
+ "ZrKxFETzxTBNB5SOJjKV/mhCq+uSjGvE4hHc4QA9YGAEwnhWF1ePkCtOWFv0+PiasL8bR3QDr93h"
+ "HyFup9LWUksHAAAAAElFTkSuQmCC";
// Default name for an example 'about' HTML page.
public static final String ABOUT_FILENAME = "about.html";
......@@ -101,38 +102,41 @@ public class CommonResources {
// HTML code of an 'about' example.
public static final String ABOUT_HTML =
"<html>" +
" <head>" +
" <title>" + ABOUT_TITLE + "</title>" +
" </head>" +
" <body>" +
" This is the Google!" +
" </body>" +
"</html>";
"<html>"
+ " <head>"
+ " <title>" + ABOUT_TITLE + "</title>"
+ " </head>"
+ " <body>"
+ " This is the Google!"
+ " </body>"
+ "</html>";
public static String makeHtmlPageFrom(String headers, String body) {
return "<html>" +
" <head>" +
" <style type=\"text/css\">" +
return "<html>"
+ " <head>"
+ " <style type=\"text/css\">"
// 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
// to click it.
" img.big { width:100%; height:100%; background-color:blue; }" +
" .full_view { height:100%; width:100%; position:absolute; }" +
" </style>" +
headers +
" </head>" +
" <body>" +
body +
" </body>" +
"</html>";
+ " img.big { width:100%; height:100%; background-color:blue; }"
+ " .full_view { height:100%; width:100%; position:absolute; }"
+ " </style>"
+ headers
+ " </head>"
+ " <body>"
+ body
+ " </body>"
+ "</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) {
return makeHtmlPageFrom(headers,
"<a href=\"" + destination + "\" id=\"link\">" +
" <img class=\"big\" />" +
"</a>");
"<a href=\"" + destination + "\" id=\"link\">"
+ " <img class=\"big\" />"
+ "</a>");
}
public static String makeHtmlPageWithSimpleLinkTo(String destination) {
......@@ -141,8 +145,8 @@ public class CommonResources {
public static String makeHtmlPageWithSimplePostFormTo(String destination) {
return makeHtmlPageFrom("",
"<form action=\"" + destination + "\" method=\"post\">" +
" <input type=\"submit\" value=\"post\" id=\"link\">" +
"</form>");
"<form action=\"" + destination + "\" method=\"post\">"
+ " <input type=\"submit\" value=\"post\" id=\"link\">"
+ "</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