diff options
| author | David Göransson <david.goransson@mullvad.net> | 2025-05-09 15:06:07 +0200 |
|---|---|---|
| committer | David Göransson <david.goransson@mullvad.net> | 2025-05-09 15:59:28 +0200 |
| commit | 7d818e399b4bf63cb51deddf5c798adcb2a8cf11 (patch) | |
| tree | 711bc5380b36dbc7d656eee7e7f36bdbff58debd | |
| parent | 3c8fc9ef9cffb93dac3d2ebcac49af144e5f8225 (diff) | |
| download | mullvadvpn-7d818e399b4bf63cb51deddf5c798adcb2a8cf11.tar.xz mullvadvpn-7d818e399b4bf63cb51deddf5c798adcb2a8cf11.zip | |
Fix flaky device management test
The device mangement test would fail because it expect the device to be
removed however it was in a loading state while API request was being
made. This commit allows it to be visible intiailly (loading) and then
expects it to be removed.
3 files changed, 39 insertions, 14 deletions
diff --git a/android/test/common/src/main/kotlin/net/mullvad/mullvadvpn/test/common/extension/UiAutomatorExtensions.kt b/android/test/common/src/main/kotlin/net/mullvad/mullvadvpn/test/common/extension/UiAutomatorExtensions.kt index cb186463cd..aa993025f5 100644 --- a/android/test/common/src/main/kotlin/net/mullvad/mullvadvpn/test/common/extension/UiAutomatorExtensions.kt +++ b/android/test/common/src/main/kotlin/net/mullvad/mullvadvpn/test/common/extension/UiAutomatorExtensions.kt @@ -9,6 +9,7 @@ import androidx.test.uiautomator.UiObject2 import androidx.test.uiautomator.UiObject2Condition import androidx.test.uiautomator.Until import co.touchlab.kermit.Logger +import java.lang.Thread.sleep import java.util.regex.Pattern import net.mullvad.mullvadvpn.test.common.constant.DEFAULT_TIMEOUT import net.mullvad.mullvadvpn.test.common.constant.LONG_TIMEOUT @@ -40,6 +41,22 @@ fun UiDevice.findObjectWithTimeout( return foundObject } +fun UiDevice.expectObjectToDisappearWithTimeout( + selector: BySelector, + timeout: Long = DEFAULT_TIMEOUT, +) { + val sleepInterval = 100L + val startTime = System.currentTimeMillis() + + while (null != findObject(selector)) { + val elapsedTime = System.currentTimeMillis() - startTime + if (elapsedTime > timeout) { + error("Object is still visible after timeout") + } + sleep(sleepInterval) + } +} + fun UiDevice.clickObjectAwaitCondition( selector: BySelector, condition: UiObject2Condition<Boolean>, diff --git a/android/test/common/src/main/kotlin/net/mullvad/mullvadvpn/test/common/page/AccountPage.kt b/android/test/common/src/main/kotlin/net/mullvad/mullvadvpn/test/common/page/AccountPage.kt index db4a963648..67183b68f6 100644 --- a/android/test/common/src/main/kotlin/net/mullvad/mullvadvpn/test/common/page/AccountPage.kt +++ b/android/test/common/src/main/kotlin/net/mullvad/mullvadvpn/test/common/page/AccountPage.kt @@ -1,6 +1,7 @@ package net.mullvad.mullvadvpn.test.common.page import androidx.test.uiautomator.By +import net.mullvad.mullvadvpn.lib.ui.tag.MANAGE_DEVICES_BUTTON_TEST_TAG import net.mullvad.mullvadvpn.test.common.extension.findObjectWithTimeout class AccountPage internal constructor() : Page() { @@ -10,6 +11,10 @@ class AccountPage internal constructor() : Page() { uiDevice.findObjectWithTimeout(By.text("Account")) } + fun clickManageDevices() { + uiDevice.findObject(By.res(MANAGE_DEVICES_BUTTON_TEST_TAG)).click() + } + fun clickLogOut() { uiDevice.findObjectWithTimeout(logOutSelector).click() } diff --git a/android/test/mockapi/src/main/kotlin/net/mullvad/mullvadvpn/test/mockapi/ManageDevicesMockApiTest.kt b/android/test/mockapi/src/main/kotlin/net/mullvad/mullvadvpn/test/mockapi/ManageDevicesMockApiTest.kt index 6b2248a6b0..1b087ec0fe 100644 --- a/android/test/mockapi/src/main/kotlin/net/mullvad/mullvadvpn/test/mockapi/ManageDevicesMockApiTest.kt +++ b/android/test/mockapi/src/main/kotlin/net/mullvad/mullvadvpn/test/mockapi/ManageDevicesMockApiTest.kt @@ -2,11 +2,14 @@ package net.mullvad.mullvadvpn.test.mockapi import androidx.test.uiautomator.By import java.time.ZonedDateTime -import net.mullvad.mullvadvpn.lib.ui.tag.MANAGE_DEVICES_BUTTON_TEST_TAG import net.mullvad.mullvadvpn.test.common.extension.clickAgreeOnPrivacyDisclaimer import net.mullvad.mullvadvpn.test.common.extension.clickAllowOnNotificationPermissionPromptIfApiLevel33AndAbove import net.mullvad.mullvadvpn.test.common.extension.dismissChangelogDialogIfShown import net.mullvad.mullvadvpn.test.common.extension.findObjectWithTimeout +import net.mullvad.mullvadvpn.test.common.page.AccountPage +import net.mullvad.mullvadvpn.test.common.page.ConnectPage +import net.mullvad.mullvadvpn.test.common.page.DeviceManagementPage +import net.mullvad.mullvadvpn.test.common.page.on import net.mullvad.mullvadvpn.test.mockapi.constant.ALMOST_FULL_DEVICE_LIST import net.mullvad.mullvadvpn.test.mockapi.constant.DUMMY_DEVICE_NAME_1 import net.mullvad.mullvadvpn.test.mockapi.constant.DUMMY_ID_1 @@ -33,22 +36,22 @@ class ManageDevicesMockApiTest : MockApiTest() { app.attemptLogin(validAccountNumber) device.waitForIdle() device.dismissChangelogDialogIfShown() - app.ensureLoggedIn() - app.clickAccountCog() - device.findObject(By.res(MANAGE_DEVICES_BUTTON_TEST_TAG)).click() - // Assert - current device is shown but not clickable - val current = device.findObjectWithTimeout(By.text("Current device")).parent - assertNull(current.findObject(By.clickable(true))) + on<ConnectPage> { clickAccount() } - // Act - remove another device in the list - val secondDevice = device.findObjectWithTimeout(By.text("Yellow Hat")).parent - secondDevice.findObject(By.clickable(true)).click() - app.clickActionButtonByText("Remove") + on<AccountPage> { clickManageDevices() } - device.waitForIdle() + on<DeviceManagementPage> { + // Assert - current device is shown but not clickable + val current = uiDevice.findObjectWithTimeout(By.text("Current device")).parent + assertNull(current.findObject(By.clickable(true))) + + removeDevice("Yellow Hat") - // Assert - the other device is no longer shown - assertNull(device.findObject(By.text("Yellow Hat"))) + // Confirm removal of device + app.clickActionButtonByText("Remove") + + expectDeviceToBeRemoved("Yellow Hat") + } } } |
