Skip to content

[ID-3594] UI Testing to **alpha support for PKCE on Windows**. #473

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
May 21, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion sample/Assets/Editor/WindowsBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

public class WindowsBuilder
{
private const string DefaultBuildPath = "Builds/Windows64/SampleApp.exe";
private static readonly string DefaultBuildPath = $"Builds/Windows64/{Application.productName}.exe";

static void Build()
{
Expand Down
17 changes: 14 additions & 3 deletions sample/Tests/test/test.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ class TestConfig:
WALLET_ADDRESS = "0x547044ea95f03651139081241c99ffedbefdc5e8"
ANDROID_PACKAGE = "com.immutable.ImmutableSample"
IOS_BUNDLE_ID = "com.immutable.Immutable-Sample-GameSDK"

class UnityTest(unittest.TestCase):

altdriver = None
Expand All @@ -23,7 +23,18 @@ def setUpClass(cls):

@classmethod
def tearDownClass(cls):
cls.altdriver.stop()
if cls.altdriver:
cls.altdriver.stop()

def get_altdriver(self):
return self.__class__.altdriver

def start_altdriver(self):
self.__class__.altdriver = AltDriver()

def stop_altdriver(self):
if self.__class__.altdriver:
self.__class__.altdriver.stop()

@pytest.mark.skip(reason="Base test should not be executed directly")
def test_0_other_functions(self):
Expand Down Expand Up @@ -266,7 +277,7 @@ def test_3_zkevm_functions(self):
transactionHash = match.group()
else:
raise SystemExit(f"Could not find transaction hash")

# Go back to authenticated scene
self.altdriver.find_object(By.NAME, "CancelButton").tap()
self.altdriver.wait_for_current_scene_to_be("AuthenticatedScene")
Expand Down
120 changes: 60 additions & 60 deletions sample/Tests/test/test_windows.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,41 +7,50 @@

class WindowsTest(UnityTest):

altdriver = None

@classmethod
def setUpClass(cls):
open_sample_app()
cls.altdriver = AltDriver()
time.sleep(5) # Give time for the app to open
super().setUpClass()

@classmethod
def tearDownClass(cls):
cls.altdriver.stop()
stop_sample_app()
super().tearDownClass()
stop_sample_app()

def test_1_device_code_login(self):
# Select use device code auth
self.altdriver.find_object(By.NAME, "DeviceCodeAuth").tap()
def restart_app_and_altdriver(self):
self.stop_altdriver()
stop_sample_app()
open_sample_app()
time.sleep(5) # Give time for the app to open
self.start_altdriver()

def select_auth_type(self, use_pkce: bool):
auth_type = "PKCE" if use_pkce else "DeviceCodeAuth"
self.get_altdriver().find_object(By.NAME, auth_type).tap()

def login(self, use_pkce: bool):
self.select_auth_type(use_pkce)

# Wait for unauthenticated screen
self.altdriver.wait_for_current_scene_to_be("UnauthenticatedScene")
self.get_altdriver().wait_for_current_scene_to_be("UnauthenticatedScene")

for attempt in range(2):
try:
# Check app state
login_button = self.altdriver.find_object(By.NAME, "LoginBtn")
login_button = self.get_altdriver().find_object(By.NAME, "LoginBtn")
print("Found login button, app is in the correct state")

# Login
print("Logging in...")
launch_browser()
bring_sample_app_to_foreground()
login_button.tap()
login()
login(use_pkce)
bring_sample_app_to_foreground()

# Wait for authenticated screen
self.altdriver.wait_for_current_scene_to_be("AuthenticatedScene")
self.get_altdriver().wait_for_current_scene_to_be("AuthenticatedScene")
stop_browser()
print("Logged in")
return
Expand All @@ -54,31 +63,38 @@ def test_1_device_code_login(self):
# Relogin (optional: only if the button is present)
print("Try reset the app and log out once...")
try:
self.altdriver.wait_for_object(By.NAME, "ReloginBtn").tap()
self.get_altdriver().wait_for_object(By.NAME, "ReloginBtn").tap()
except Exception as e:
print("ReloginBtn not found, skipping relogin step. User may already be in AuthenticatedScene.")

# Wait for authenticated screen
self.altdriver.wait_for_current_scene_to_be("AuthenticatedScene")
self.get_altdriver().wait_for_current_scene_to_be("AuthenticatedScene")
print("Re-logged in")

# Logout
print("Logging out...")
launch_browser()
bring_sample_app_to_foreground()
self.altdriver.find_object(By.NAME, "LogoutBtn").tap()
self.get_altdriver().find_object(By.NAME, "LogoutBtn").tap()
time.sleep(5)
bring_sample_app_to_foreground()

# Wait for unauthenticated screen
self.altdriver.wait_for_current_scene_to_be("UnauthenticatedScene")
self.get_altdriver().wait_for_current_scene_to_be("UnauthenticatedScene")
stop_browser()
print("Logged out and successfully reset app")

time.sleep(5)
else:
raise SystemExit(f"Failed to reset app {err}")

def test_1a_pkce_login(self):
self.login(True)

def test_1b_device_code_login(self):
self.restart_app_and_altdriver()
self.login(False)

def test_2_other_functions(self):
self.test_0_other_functions()

Expand All @@ -92,111 +108,95 @@ def test_5_zkevm_functions(self):
self.test_3_zkevm_functions()

def test_6_relogin(self):
# Close and reopen app
stop_sample_app()
open_sample_app()

# Restart AltTester
self.altdriver.stop()
self.altdriver = AltDriver()
time.sleep(5)
self.restart_app_and_altdriver()

# Select use device code auth
self.altdriver.find_object(By.NAME, "DeviceCodeAuth").tap()
self.select_auth_type(use_pkce=False)

# Relogin
print("Re-logging in...")
self.altdriver.wait_for_object(By.NAME, "ReloginBtn").tap()
self.get_altdriver().wait_for_object(By.NAME, "ReloginBtn").tap()

# Wait for authenticated screen
self.altdriver.wait_for_current_scene_to_be("AuthenticatedScene")
self.get_altdriver().wait_for_current_scene_to_be("AuthenticatedScene")
print("Re-logged in")

# Get access token
self.altdriver.find_object(By.NAME, "GetAccessTokenBtn").tap()
output = self.altdriver.find_object(By.NAME, "Output")
self.get_altdriver().find_object(By.NAME, "GetAccessTokenBtn").tap()
output = self.get_altdriver().find_object(By.NAME, "Output")
self.assertTrue(len(output.get_text()) > 50)

# Click Connect to IMX button
self.altdriver.find_object(By.NAME, "ConnectBtn").tap()
self.get_altdriver().find_object(By.NAME, "ConnectBtn").tap()
self.assertEqual("Connected to IMX", output.get_text())

self.altdriver.stop()

def test_7_reconnect_device_code_connect_imx(self):
# Close and reopen app
stop_sample_app()
open_sample_app()
self.restart_app_and_altdriver()

# Restart AltTester
self.altdriver.stop()
self.altdriver = AltDriver()
time.sleep(5)

# Select use device code auth
self.altdriver.find_object(By.NAME, "DeviceCodeAuth").tap()
use_pkce = False
self.select_auth_type(use_pkce)

# Reconnect
print("Reconnecting...")
self.altdriver.wait_for_object(By.NAME, "ReconnectBtn").tap()
self.get_altdriver().wait_for_object(By.NAME, "ReconnectBtn").tap()

# Wait for authenticated screen
self.altdriver.wait_for_current_scene_to_be("AuthenticatedScene")
self.get_altdriver().wait_for_current_scene_to_be("AuthenticatedScene")
print("Reconnected")

# Get access token
self.altdriver.find_object(By.NAME, "GetAccessTokenBtn").tap()
output = self.altdriver.find_object(By.NAME, "Output")
self.get_altdriver().find_object(By.NAME, "GetAccessTokenBtn").tap()
output = self.get_altdriver().find_object(By.NAME, "Output")
self.assertTrue(len(output.get_text()) > 50)

# Get address without having to click Connect to IMX button
self.altdriver.find_object(By.NAME, "GetAddressBtn").tap()
self.get_altdriver().find_object(By.NAME, "GetAddressBtn").tap()
self.assertEqual(TestConfig.WALLET_ADDRESS, output.get_text())

# Logout
print("Logging out...")
launch_browser()
bring_sample_app_to_foreground()
self.altdriver.find_object(By.NAME, "LogoutBtn").tap()
self.get_altdriver().find_object(By.NAME, "LogoutBtn").tap()
time.sleep(5)
bring_sample_app_to_foreground()

# Wait for authenticated screen
self.altdriver.wait_for_current_scene_to_be("UnauthenticatedScene")
self.get_altdriver().wait_for_current_scene_to_be("UnauthenticatedScene")
stop_browser()
print("Logged out")

# Connect IMX
print("Logging in and connecting to IMX...")
launch_browser()
bring_sample_app_to_foreground()
self.altdriver.wait_for_object(By.NAME, "ConnectBtn").tap()
login()
self.get_altdriver().wait_for_object(By.NAME, "ConnectBtn").tap()
login(use_pkce)
bring_sample_app_to_foreground()

# Wait for authenticated screen
self.altdriver.wait_for_current_scene_to_be("AuthenticatedScene")
self.get_altdriver().wait_for_current_scene_to_be("AuthenticatedScene")
print("Logged in and connected to IMX")
stop_browser()

# Get access token
self.altdriver.find_object(By.NAME, "GetAccessTokenBtn").tap()
output = self.altdriver.find_object(By.NAME, "Output")
self.get_altdriver().find_object(By.NAME, "GetAccessTokenBtn").tap()
output = self.get_altdriver().find_object(By.NAME, "Output")
self.assertTrue(len(output.get_text()) > 50)

# Get address without having to click Connect to IMX button
self.altdriver.find_object(By.NAME, "GetAddressBtn").tap()
self.get_altdriver().find_object(By.NAME, "GetAddressBtn").tap()
self.assertEqual(TestConfig.WALLET_ADDRESS, output.get_text())

# Logout
launch_browser()
bring_sample_app_to_foreground()
print("Logging out...")
self.altdriver.find_object(By.NAME, "LogoutBtn").tap()
self.get_altdriver().find_object(By.NAME, "LogoutBtn").tap()
time.sleep(5)
bring_sample_app_to_foreground()

# Wait for authenticated screen
self.altdriver.wait_for_current_scene_to_be("UnauthenticatedScene")
self.get_altdriver().wait_for_current_scene_to_be("UnauthenticatedScene")
stop_browser()
print("Logged out")
Loading
Loading