mobile/android/base/tests/testVkbOverlap.java

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

     1 package org.mozilla.gecko.tests;
     3 import org.mozilla.gecko.Actions;
     4 import org.mozilla.gecko.PaintedSurface;
     6 import android.net.Uri;
     8 /**
     9  * A test to ensure that when an input field is focused, it is not obscured by the VKB.
    10  * - Loads a page with an input field past the bottom of the visible area.
    11  * - scrolls down to make the input field visible at the bottom of the screen.
    12  * - taps on the input field to bring up the VKB
    13  * - verifies that the input field is still visible.
    14  */
    15 public class testVkbOverlap extends PixelTest {
    16     private static final int CURSOR_BLINK_PERIOD = 500;
    17     private static final int LESS_THAN_CURSOR_BLINK_PERIOD = CURSOR_BLINK_PERIOD - 50;
    18     private static final int PAGE_SETTLE_TIME = 5000;
    20     public void testVkbOverlap() {
    21         blockForGeckoReady();
    22         testSetup("initial-scale=1.0, user-scalable=no", false);
    23         testSetup("initial-scale=1.0", false);
    24         testSetup("", "phone".equals(mDevice.type));
    25     }
    27     private void testSetup(String viewport, boolean shouldZoom) {
    28         loadAndPaint(getAbsoluteUrl("/robocop/test_viewport.sjs?metadata=" + Uri.encode(viewport)));
    30         // scroll to the bottom of the page and let it settle
    31         Actions.RepeatedEventExpecter paintExpecter = mActions.expectPaint();
    32         MotionEventHelper meh = new MotionEventHelper(getInstrumentation(), mDriver.getGeckoLeft(), mDriver.getGeckoTop());
    33         meh.dragSync(10, 150, 10, 50);
    35         // the input field has a green background, so let's count the number of green pixels
    36         int greenPixelCount = 0;
    38         PaintedSurface painted = waitForPaint(paintExpecter);
    39         paintExpecter.unregisterListener();
    40         try {
    41             greenPixelCount = countGreenPixels(painted);
    42         } finally {
    43             painted.close();
    44         }
    46         mAsserter.ok(greenPixelCount > 0, "testInputVisible", "Found " + greenPixelCount + " green pixels after scrolling");
    48         paintExpecter = mActions.expectPaint();
    49         // the input field should be in the bottom-left corner, so tap thereabouts
    50         meh.tap(5, mDriver.getGeckoHeight() - 5);
    52         // After tapping in the input field, the page needs some time to do stuff, like draw and undraw the focus highlight
    53         // on the input field, trigger the VKB, process any resulting events generated by the system, and scroll the page. So
    54         // we give it a few seconds to do all that. We are sufficiently generous with our definition of "few seconds" to
    55         // prevent intermittent test failures.
    56         try {
    57             Thread.sleep(PAGE_SETTLE_TIME);
    58         } catch (InterruptedException ie) {
    59             ie.printStackTrace();
    60         }
    62         // now that the focus is in the text field we will repaint every 500ms as the cursor blinks, so we need to use a smaller
    63         // "no paints" threshold to consider the page painted
    64         paintExpecter.blockUntilClear(LESS_THAN_CURSOR_BLINK_PERIOD);
    65         paintExpecter.unregisterListener();
    66         painted = mDriver.getPaintedSurface();
    67         try {
    68             // if the vkb scrolled into view as expected, then the number of green pixels now visible should be about the
    69             // same as it was before, since the green pixels indicate the text input is in view. use a fudge factor of 0.9 to
    70             // account for borders and such of the text input which might still be out of view.
    71             int newCount = countGreenPixels(painted);
    73             // if zooming is allowed, the number of green pixels visible should have increased substatially
    74             if (shouldZoom) {
    75                 mAsserter.ok(newCount > greenPixelCount * 1.5, "testVkbOverlap", "Found " + newCount + " green pixels after tapping; expected " + greenPixelCount);
    76             } else {
    77                 mAsserter.ok((Math.abs(greenPixelCount - newCount) / greenPixelCount < 0.1), "testVkbOverlap", "Found " + newCount + " green pixels after tapping; expected " + greenPixelCount);
    78             }
    79         } finally {
    80             painted.close();
    81         }
    82     }
    84     private int countGreenPixels(PaintedSurface painted) {
    85         int count = 0;
    86         for (int y = painted.getHeight() - 1; y >= 0; y--) {
    87             for (int x = painted.getWidth() - 1; x >= 0; x--) {
    88                 int pixel = painted.getPixelAt(x, y);
    89                 int r = (pixel >> 16) & 0xFF;
    90                 int g = (pixel >> 8) & 0xFF;
    91                 int b = (pixel & 0xFF);
    92                 if (g > (r + 0x30) && g > (b + 0x30)) {
    93                     // there's more green in this pixel than red or blue, so count it.
    94                     // the reason this is so hacky-looking is because even though green is supposed to
    95                     // be (r,g,b) = (0x00, 0x80, 0x00), the GL readback ends up coming back quite
    96                     // different.
    97                     count++;
    98                 }
    99                 // uncomment for debugging:
   100                 // if (pixel != -1) mAsserter.dumpLog("Pixel at " + x + ", " + y + ": " + Integer.toString(pixel, 16));
   101             }
   102         }
   103         return count;
   104     }
   105 }

mercurial