1// Copyright 2012 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5package org.chromium.android_webview.test.util;
6
7import android.test.InstrumentationTestCase;
8
9import junit.framework.Assert;
10
11import static org.chromium.base.test.util.ScalableTimeout.scaleTimeout;
12
13import org.chromium.android_webview.AwContents;
14import org.chromium.content.browser.test.util.Criteria;
15import org.chromium.content.browser.test.util.CriteriaHelper;
16import org.chromium.content.browser.test.util.TestCallbackHelperContainer.OnEvaluateJavaScriptResultHelper;
17
18/**
19 * Collection of functions for JavaScript-based interactions with a page.
20 */
21public class JSUtils {
22    private static final long WAIT_TIMEOUT_MS = scaleTimeout(2000);
23    private static final int CHECK_INTERVAL = 100;
24
25    public static void clickOnLinkUsingJs(
26            final InstrumentationTestCase testCase,
27            final AwContents awContents,
28            final OnEvaluateJavaScriptResultHelper onEvaluateJavaScriptResultHelper,
29            final String linkId) throws Exception {
30
31        Assert.assertTrue(CriteriaHelper.pollForCriteria(new Criteria() {
32            @Override
33            public boolean isSatisfied() {
34                try {
35                    String linkIsNotNull = executeJavaScriptAndWaitForResult(testCase, awContents,
36                        onEvaluateJavaScriptResultHelper,
37                        "document.getElementById('" + linkId + "') != null");
38                    return linkIsNotNull.equals("true");
39                } catch (Throwable t) {
40                    t.printStackTrace();
41                    Assert.fail("Failed to check if DOM is loaded: " + t.toString());
42                    return false;
43                }
44            }
45        }, WAIT_TIMEOUT_MS, CHECK_INTERVAL));
46
47        testCase.getInstrumentation().runOnMainSync(new Runnable() {
48            @Override
49            public void run() {
50                awContents.getContentViewCore().evaluateJavaScript(
51                    "var evObj = document.createEvent('Events'); " +
52                    "evObj.initEvent('click', true, false); " +
53                    "document.getElementById('" + linkId + "').dispatchEvent(evObj);" +
54                    "console.log('element with id [" + linkId + "] clicked');",
55                    null);
56            }
57        });
58    }
59
60    public static String executeJavaScriptAndWaitForResult(
61            InstrumentationTestCase testCase,
62            final AwContents awContents,
63            final OnEvaluateJavaScriptResultHelper onEvaluateJavaScriptResultHelper,
64            final String code) throws Exception {
65        testCase.getInstrumentation().runOnMainSync(new Runnable() {
66            @Override
67            public void run() {
68                onEvaluateJavaScriptResultHelper.evaluateJavaScript(
69                        awContents.getContentViewCore(), code);
70            }
71        });
72        onEvaluateJavaScriptResultHelper.waitUntilHasValue();
73        Assert.assertTrue("Failed to retrieve JavaScript evaluation results.",
74                onEvaluateJavaScriptResultHelper.hasValue());
75        return onEvaluateJavaScriptResultHelper.getJsonResultAndClear();
76    }
77}
78