From 7a3635e7f4878130d4bc20aae03060d228f65e37 Mon Sep 17 00:00:00 2001 From: Jiun-Yang Hsu Date: Thu, 31 Dec 2020 14:18:01 +0800 Subject: [PATCH] Initial commit for Settings component test Test: Tested on local device Bug: 178765084 Change-Id: I3b8f36daa31b0a44e788fe4c84f94d48653ee037 --- tests/componenttests/Android.bp | 23 +++ tests/componenttests/AndroidManifest.xml | 40 +++++ tests/componenttests/AndroidTest.xml | 30 ++++ tests/componenttests/OWNERS | 3 + ...ttonPreferenceControllerComponentTest.java | 143 ++++++++++++++++++ ...turePreferenceControllerComponentTest.java | 69 +++++++++ .../android/settings/testutils/AdbUtils.java | 62 ++++++++ .../settings/testutils/CommonUtils.java | 96 ++++++++++++ .../android/settings/testutils/Constants.java | 23 +++ .../android/settings/testutils/UiUtils.java | 58 +++++++ .../wifi/WifiSettings2ActivityTest.java | 125 +++++++++++++++ tests/robotests/Android.bp | 2 +- 12 files changed, 673 insertions(+), 1 deletion(-) create mode 100644 tests/componenttests/Android.bp create mode 100644 tests/componenttests/AndroidManifest.xml create mode 100644 tests/componenttests/AndroidTest.xml create mode 100644 tests/componenttests/OWNERS create mode 100644 tests/componenttests/src/com/android/settings/fuelgauge/batterysaver/BatterySaverButtonPreferenceControllerComponentTest.java create mode 100644 tests/componenttests/src/com/android/settings/privacy/EnabledContentCapturePreferenceControllerComponentTest.java create mode 100644 tests/componenttests/src/com/android/settings/testutils/AdbUtils.java create mode 100644 tests/componenttests/src/com/android/settings/testutils/CommonUtils.java create mode 100644 tests/componenttests/src/com/android/settings/testutils/Constants.java create mode 100644 tests/componenttests/src/com/android/settings/testutils/UiUtils.java create mode 100644 tests/componenttests/src/com/android/settings/wifi/WifiSettings2ActivityTest.java diff --git a/tests/componenttests/Android.bp b/tests/componenttests/Android.bp new file mode 100644 index 00000000000..77932ef49bb --- /dev/null +++ b/tests/componenttests/Android.bp @@ -0,0 +1,23 @@ +//############################################################ +// Settings Component test target. # +//############################################################ +android_test { + name: "SettingsComponentTests", + certificate: "platform", + privileged: true, + srcs: [ + "src/**/*.java", + ], + + static_libs: [ + "truth-prebuilt", + "androidx.test.core", + "androidx.test.runner", + "androidx.test.rules", + "androidx.test.ext.junit", + ], + + test_suites: ["device-tests"], + + instrumentation_for: "Settings", +} diff --git a/tests/componenttests/AndroidManifest.xml b/tests/componenttests/AndroidManifest.xml new file mode 100644 index 00000000000..54ea3746d97 --- /dev/null +++ b/tests/componenttests/AndroidManifest.xml @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/tests/componenttests/AndroidTest.xml b/tests/componenttests/AndroidTest.xml new file mode 100644 index 00000000000..ea7ac06d43b --- /dev/null +++ b/tests/componenttests/AndroidTest.xml @@ -0,0 +1,30 @@ + + + + diff --git a/tests/componenttests/OWNERS b/tests/componenttests/OWNERS new file mode 100644 index 00000000000..51746f0560d --- /dev/null +++ b/tests/componenttests/OWNERS @@ -0,0 +1,3 @@ +# People who can approve changes for submission +jyhsu@google.com +syaoranx@google.com \ No newline at end of file diff --git a/tests/componenttests/src/com/android/settings/fuelgauge/batterysaver/BatterySaverButtonPreferenceControllerComponentTest.java b/tests/componenttests/src/com/android/settings/fuelgauge/batterysaver/BatterySaverButtonPreferenceControllerComponentTest.java new file mode 100644 index 00000000000..30fcbf58404 --- /dev/null +++ b/tests/componenttests/src/com/android/settings/fuelgauge/batterysaver/BatterySaverButtonPreferenceControllerComponentTest.java @@ -0,0 +1,143 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.settings.fuelgauge.batterysaver; + +import static com.google.common.truth.Truth.assertThat; +import static com.google.common.truth.Truth.assert_; + +import android.app.Instrumentation; +import android.content.Context; +import android.content.Intent; +import android.os.PowerManager; +import android.provider.Settings; +import android.util.Log; +import android.widget.Button; + +import androidx.test.core.app.ActivityScenario; +import androidx.test.ext.junit.rules.ActivityScenarioRule; +import androidx.test.ext.junit.runners.AndroidJUnit4; +import androidx.test.filters.SmallTest; +import androidx.test.platform.app.InstrumentationRegistry; + +import com.android.settings.R; +import com.android.settings.Settings.BatterySaverSettingsActivity; +import com.android.settings.testutils.AdbUtils; +import com.android.settings.testutils.UiUtils; + +import org.junit.After; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; + +@RunWith(AndroidJUnit4.class) +@SmallTest +public class BatterySaverButtonPreferenceControllerComponentTest { + private static final String TAG = + BatterySaverButtonPreferenceControllerComponentTest.class.getSimpleName(); + private Instrumentation mInstrumentation = InstrumentationRegistry.getInstrumentation(); + private PowerManager mManager = + (PowerManager) mInstrumentation.getTargetContext().getSystemService( + Context.POWER_SERVICE); + + @Rule + public ActivityScenarioRule rule = new ActivityScenarioRule<>( + new Intent( + Settings.ACTION_BATTERY_SAVER_SETTINGS).setFlags( + Intent.FLAG_ACTIVITY_NEW_TASK)); + + @Before + public void setUp() throws Exception { + mInstrumentation.getUiAutomation().executeShellCommand("dumpsys battery unplug"); + mInstrumentation.getUiAutomation().executeShellCommand("settings get global low_power 0"); + } + + @Test + public void test_check_battery_saver_button() throws Exception { + ActivityScenario scenario = rule.getScenario(); + scenario.onActivity(activity -> { + final Button button = activity.findViewById(R.id.state_on_button); + UiUtils.waitUntilCondition(3000, () -> button.isEnabled()); + button.callOnClick(); + checkPowerSaverMode(true); + + Button offButton = activity.findViewById(R.id.state_off_button); + offButton.callOnClick(); + checkPowerSaverMode(false); + }); + + //Ideally, we should be able to also create BatteryTipPreferenceController and verify that + //it is showing battery saver on. Unfortunately, that part of code is tightly coupled with + //UI, and it's not possible to retrieve that string without reaching very deep into the + //codes and become very tightly coupled with any future changes. That is not what component + //tests should do, so either we'll need to do this through UI with another ActivityScenario, + //or the code needs to be refactored to be less coupled with UI. + } + + @Test + public void test_battery_saver_button_changes_when_framework_setting_change() throws Exception { + ActivityScenario scenario = rule.getScenario(); + scenario.onActivity(activity -> { + Button buttonOn = activity.findViewById(R.id.state_on_button); + Button buttonOff = activity.findViewById(R.id.state_off_button); + assertThat(buttonOn.isVisibleToUser()).isEqualTo(true); + assertThat(buttonOff.isVisibleToUser()).isEqualTo(false); + }); + + mManager.setPowerSaveModeEnabled(true); + scenario.recreate(); + scenario.onActivity(activity -> { + Button buttonOn = activity.findViewById(R.id.state_on_button); + Button buttonOff = activity.findViewById(R.id.state_off_button); + assertThat(buttonOn.isVisibleToUser()).isEqualTo(false); + assertThat(buttonOff.isVisibleToUser()).isEqualTo(true); + }); + + mManager.setPowerSaveModeEnabled(false); + scenario.recreate(); + scenario.onActivity(activity -> { + Button buttonOn = activity.findViewById(R.id.state_on_button); + Button buttonOff = activity.findViewById(R.id.state_off_button); + assertThat(buttonOn.isVisibleToUser()).isEqualTo(true); + assertThat(buttonOff.isVisibleToUser()).isEqualTo(false); + }); + } + + @After + public void tearDown() { + mInstrumentation.getUiAutomation().executeShellCommand("settings get global low_power 0"); + mInstrumentation.getUiAutomation().executeShellCommand("dumpsys battery reset"); + } + + private void checkPowerSaverMode(boolean enabled) { + //Check through adb. Note that this needs to be done first, or a wait and poll needs to be + //done to the manager.isPowerSaveMode(), because calling isPowerSaveMode immediately after + //setting it does not return true. It takes a while for isPowerSaveMode() to return the + //up-to-date value. + try { + assertThat( + AdbUtils.checkStringInAdbCommandOutput(TAG, "settings get global low_power", + null, enabled ? "1" : "0", 1000)).isTrue(); + } catch (Exception e) { + Log.e(TAG, e.getMessage()); + assert_().fail(); + } + + //Check through manager + assertThat(mManager.isPowerSaveMode() == enabled).isTrue(); + } +} diff --git a/tests/componenttests/src/com/android/settings/privacy/EnabledContentCapturePreferenceControllerComponentTest.java b/tests/componenttests/src/com/android/settings/privacy/EnabledContentCapturePreferenceControllerComponentTest.java new file mode 100644 index 00000000000..aba6f8fa445 --- /dev/null +++ b/tests/componenttests/src/com/android/settings/privacy/EnabledContentCapturePreferenceControllerComponentTest.java @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.settings.privacy; + +import static com.google.common.truth.Truth.assertThat; + +import android.app.Instrumentation; + +import androidx.test.core.app.ApplicationProvider; +import androidx.test.ext.junit.runners.AndroidJUnit4; +import androidx.test.filters.SmallTest; +import androidx.test.platform.app.InstrumentationRegistry; + +import com.android.settings.testutils.AdbUtils; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; + +@RunWith(AndroidJUnit4.class) +@SmallTest +public class EnabledContentCapturePreferenceControllerComponentTest { + private Instrumentation mInstrumentation; + private static final String TAG = + EnabledContentCapturePreferenceControllerComponentTest.class.getSimpleName(); + + @Before + public void setUp() { + if (null == mInstrumentation) { + mInstrumentation = InstrumentationRegistry.getInstrumentation(); + } + } + + @Test + public void test_uncheck_content_capture() throws Exception { + content_capture_checkbox_test_helper(false); + } + + @Test + public void test_check_content_capture() throws Exception { + content_capture_checkbox_test_helper(true); + } + + private void content_capture_checkbox_test_helper(boolean check) throws Exception { + EnableContentCapturePreferenceController enableContentCapturePreferenceController = + new EnableContentCapturePreferenceController( + ApplicationProvider.getApplicationContext(), + "Test_key"); + enableContentCapturePreferenceController.setChecked(check); + + //Check through adb command + assertThat(AdbUtils.checkStringInAdbCommandOutput(TAG, "dumpsys content_capture", + "Users disabled by Settings: ", check ? "{}" : "{0=true}", 1000)).isTrue(); + } +} diff --git a/tests/componenttests/src/com/android/settings/testutils/AdbUtils.java b/tests/componenttests/src/com/android/settings/testutils/AdbUtils.java new file mode 100644 index 00000000000..08eb47a4a64 --- /dev/null +++ b/tests/componenttests/src/com/android/settings/testutils/AdbUtils.java @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.settings.testutils; + +import android.os.ParcelFileDescriptor; +import android.text.TextUtils; +import android.util.Log; + +import androidx.test.platform.app.InstrumentationRegistry; + +import java.io.BufferedReader; +import java.io.InputStreamReader; +import java.nio.charset.StandardCharsets; +import java.util.Optional; + +public class AdbUtils { + public static boolean checkStringInAdbCommandOutput(String logTag, String command, + String prefix, String target, int timeoutInMillis) throws Exception { + long start = System.nanoTime(); + //Sometimes the change do no reflect in adn output immediately, so need a wait and poll here + while (System.nanoTime() - start < (timeoutInMillis * 1000000)) { + try (ParcelFileDescriptor.AutoCloseInputStream in = + new ParcelFileDescriptor.AutoCloseInputStream( + InstrumentationRegistry.getInstrumentation() + .getUiAutomation() + .executeShellCommand(command))) { + try (BufferedReader br = + new BufferedReader( + new InputStreamReader(in, StandardCharsets.UTF_8))) { + Optional resultOptional = br.lines().filter(line -> { + Log.d(logTag, line); + return TextUtils.isEmpty(prefix) || line.contains(prefix); + }).findFirst(); + String result = resultOptional.get(); + if (result.contains(target)) { + return true; + } else { + Thread.sleep(100); + } + } + } catch (Exception e) { + throw e; + } + } + + return false; + } +} diff --git a/tests/componenttests/src/com/android/settings/testutils/CommonUtils.java b/tests/componenttests/src/com/android/settings/testutils/CommonUtils.java new file mode 100644 index 00000000000..cbfe245f3b7 --- /dev/null +++ b/tests/componenttests/src/com/android/settings/testutils/CommonUtils.java @@ -0,0 +1,96 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.settings.testutils; + +import android.app.Activity; +import android.graphics.Bitmap; +import android.os.Environment; +import android.util.Log; +import android.view.View; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileOutputStream; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.net.HttpURLConnection; +import java.net.URL; + +import javax.net.ssl.HttpsURLConnection; + +public class CommonUtils { + private static final String TAG = CommonUtils.class.getSimpleName(); + + public static void takeScreenshot(Activity activity) { + long now = System.currentTimeMillis(); + + try { + // image naming and path to include sd card appending name you choose for file + String mPath = + Environment.getExternalStorageDirectory().toString() + "/" + now + ".jpg"; + Log.d(TAG, "screenshot path is " + mPath); + + // create bitmap screen capture + View v1 = activity.getWindow().getDecorView().getRootView(); + v1.setDrawingCacheEnabled(true); + Bitmap bitmap = Bitmap.createBitmap(v1.getDrawingCache()); + v1.setDrawingCacheEnabled(false); + + File imageFile = new File(mPath); + + FileOutputStream outputStream = new FileOutputStream(imageFile); + int quality = 100; + bitmap.compress(Bitmap.CompressFormat.JPEG, quality, outputStream); + outputStream.flush(); + outputStream.close(); + } catch (Throwable e) { + // Several error may come out with file handling or DOM + e.printStackTrace(); + } + } + + public static boolean connectToURL(URL url) { + HttpURLConnection connection = null; + try { + connection = (HttpsURLConnection) url.openConnection(); + connection.setRequestMethod("GET"); + connection.setConnectTimeout(8000); + connection.setReadTimeout(8000); + connection.connect(); + if (HttpURLConnection.HTTP_OK == connection.getResponseCode()) { + InputStream in = connection.getInputStream(); + BufferedReader reader = new BufferedReader(new InputStreamReader(in)); + StringBuilder response = new StringBuilder(); + String line; + while (null != (line = reader.readLine())) { + response.append(line); + } + return true; + } + } catch (Exception e) { + Log.d(TAG, e.getMessage()); + return false; + } finally { + if (null != connection) { + connection.disconnect(); + } + } + + return false; + } + +} diff --git a/tests/componenttests/src/com/android/settings/testutils/Constants.java b/tests/componenttests/src/com/android/settings/testutils/Constants.java new file mode 100644 index 00000000000..5e32f871835 --- /dev/null +++ b/tests/componenttests/src/com/android/settings/testutils/Constants.java @@ -0,0 +1,23 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.settings.testutils; + +public class Constants { + public static final long ACTIVITY_LAUNCH_WAIT_TIMEOUT = 5000; + public static final long VIEW_APPEAR_WAIT_MEDIUM_TIMEOUT = 5000; + public static final long WIFI_CONNECT_WAIT_TIMEOUT = 15000; +} diff --git a/tests/componenttests/src/com/android/settings/testutils/UiUtils.java b/tests/componenttests/src/com/android/settings/testutils/UiUtils.java new file mode 100644 index 00000000000..a482add9dd7 --- /dev/null +++ b/tests/componenttests/src/com/android/settings/testutils/UiUtils.java @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.settings.testutils; + +import android.app.Activity; + +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.runner.lifecycle.ActivityLifecycleMonitorRegistry; +import androidx.test.runner.lifecycle.Stage; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.function.Supplier; + +public class UiUtils { + + public static void waitUntilCondition(long timeoutInMillis, Supplier condition) { + long start = System.nanoTime(); + while (System.nanoTime() - start < (timeoutInMillis * 1000000)) { + try { + //Eat NPE from condition because there's a concurrency issue that when calling + //findViewById when the view hierarchy is still rendering, it sometimes encounter + //null views that may exist few milliseconds before, and causes a NPE. + if (condition.get()) { + return; + } + } catch (NullPointerException e) { + e.printStackTrace(); + } + } + } + + public static boolean waitForActivitiesInStage(long timeoutInMillis, Stage stage) { + final Collection activities = new ArrayList<>(); + waitUntilCondition(Constants.ACTIVITY_LAUNCH_WAIT_TIMEOUT, () -> { + InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> activities.addAll( + ActivityLifecycleMonitorRegistry.getInstance().getActivitiesInStage( + Stage.RESUMED))); + return activities.size() > 0; + }); + + return activities.size() > 0; + } +} diff --git a/tests/componenttests/src/com/android/settings/wifi/WifiSettings2ActivityTest.java b/tests/componenttests/src/com/android/settings/wifi/WifiSettings2ActivityTest.java new file mode 100644 index 00000000000..aa6b25244e3 --- /dev/null +++ b/tests/componenttests/src/com/android/settings/wifi/WifiSettings2ActivityTest.java @@ -0,0 +1,125 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.settings.wifi; + +import static com.google.common.truth.Truth.assertThat; + +import android.app.Instrumentation; +import android.content.Context; +import android.content.Intent; +import android.net.ConnectivityManager; +import android.provider.Settings; +import android.util.Log; +import android.view.View; +import android.widget.Button; + +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentActivity; +import androidx.test.ext.junit.runners.AndroidJUnit4; +import androidx.test.filters.MediumTest; +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.runner.lifecycle.ActivityLifecycleMonitorRegistry; +import androidx.test.runner.lifecycle.Stage; + +import com.android.settings.R; +import com.android.settings.Settings.NetworkProviderSettingsActivity; +import com.android.settings.fuelgauge.batterysaver.BatterySaverButtonPreferenceControllerComponentTest; +import com.android.settings.network.NetworkProviderSettings; +import com.android.settings.testutils.CommonUtils; +import com.android.settings.testutils.Constants; +import com.android.settings.testutils.UiUtils; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import java.net.URL; +import java.util.List; + +@RunWith(AndroidJUnit4.class) +@MediumTest +/* +This test is just for demonstration purpose. For component tests, this approach is not recommended. +The reason why it is written this way is because the current Settings app wifi codes have tight +coupling with UI, so it's not easy to drive from API without binding the test deeply with the code. + */ +public class WifiSettings2ActivityTest { + private static final String TAG = + BatterySaverButtonPreferenceControllerComponentTest.class.getSimpleName(); + private final Instrumentation mInstrumentation = InstrumentationRegistry.getInstrumentation(); + + @Test + public void test_connect_to_wifi() throws Exception { + //For some reason the ActivityScenario gets null activity here + mInstrumentation.getTargetContext().startActivity( + new Intent(Settings.ACTION_WIFI_SETTINGS).setFlags(Intent.FLAG_ACTIVITY_NEW_TASK)); + UiUtils.waitForActivitiesInStage(Constants.ACTIVITY_LAUNCH_WAIT_TIMEOUT, Stage.RESUMED); + + final NetworkProviderSettings[] settings = new NetworkProviderSettings[1]; + mInstrumentation.runOnMainSync(() -> { + NetworkProviderSettingsActivity activity = (NetworkProviderSettingsActivity) + ActivityLifecycleMonitorRegistry.getInstance().getActivitiesInStage( + Stage.RESUMED).iterator().next(); + settings[0] = + (NetworkProviderSettings) activity.getSupportFragmentManager().getFragments() + .get(0); + }); + + //For some reason this view does not appear immediately after the fragment is resumed. + View root = settings[0].getView(); + UiUtils.waitUntilCondition(Constants.VIEW_APPEAR_WAIT_MEDIUM_TIMEOUT, + () -> root.findViewById(R.id.settings_button) != null); + View view = root.findViewById(R.id.settings_button); + view.callOnClick(); + + UiUtils.waitForActivitiesInStage(Constants.ACTIVITY_LAUNCH_WAIT_TIMEOUT, Stage.RESUMED); + Button[] button = new Button[1]; + mInstrumentation.runOnMainSync(() -> { + FragmentActivity activity = + (FragmentActivity) ActivityLifecycleMonitorRegistry.getInstance() + .getActivitiesInStage(Stage.RESUMED).iterator().next(); + List fragments = activity.getSupportFragmentManager().getFragments(); + Log.d(TAG, "fragment class is " + fragments.get(0).getClass()); + button[0] = fragments.get(0).getView().findViewById(R.id.button3); + }); + + //HttpURLConnection needs to run outside of main thread, so running it in the test thread + final URL url = new URL("https://www.google.net/"); + + //Make sure the connectivity is available before disconnecting from wifi + assertThat(CommonUtils.connectToURL(url)).isTrue(); + + //Disconnect from wifi + button[0].callOnClick(); + + //Make sure the Internet connectivity is gone + assertThat(CommonUtils.connectToURL(url)).isFalse(); + + //Connect to wifi + button[0].callOnClick(); + ConnectivityManager manager = + (ConnectivityManager) mInstrumentation.getTargetContext().getSystemService( + Context.CONNECTIVITY_SERVICE); + + //For some reason I can't find a way to tell the time that the internet connectivity is + //actually available with the new, non-deprecated ways, so I still need to use this. + UiUtils.waitUntilCondition(Constants.WIFI_CONNECT_WAIT_TIMEOUT, + () -> manager.getActiveNetworkInfo().isConnected()); + + //Make sure the connectivity is back again + assertThat(CommonUtils.connectToURL(url)).isTrue(); + } +} diff --git a/tests/robotests/Android.bp b/tests/robotests/Android.bp index c8c6c3840d1..f6ad049ef3d 100644 --- a/tests/robotests/Android.bp +++ b/tests/robotests/Android.bp @@ -1,4 +1,4 @@ -//############################################################ + //############################################################ // Build SettingsRoboTestStub.apk which includes test-only resources.# //############################################################