Skip to content

Commit 5a5727b

Browse files
committed
chore: run tests
1 parent 8349182 commit 5a5727b

11 files changed

+834
-7
lines changed

.github/workflows/ui-tests.yml

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -51,18 +51,17 @@ jobs:
5151
- uses: actions/download-artifact@v4
5252
with:
5353
name: Build-StandaloneOSX
54-
- name: Open application
55-
run: |
56-
ls -la
57-
chmod -R 755 SampleApp.app
58-
open SampleApp.app
5954
- uses: actions/setup-python@v4
6055
with:
6156
python-version: "3.10"
6257
- name: Install dependencies
6358
run: pip install -r "sample/Tests/requirements.txt"
6459
- name: Run UI tests
60+
env:
61+
UNITY_APP_PATH: SampleApp.app
62+
UNITY_APP_NAME: SampleApp
6563
run: |
66-
osascript -e 'tell application "SampleApp" to activate'
67-
pytest -s -v sample/Tests/test.py
64+
chmod -R 755 SampleApp.app
65+
chmod +x sample/Tests/test_mac.sh
66+
./sample/Tests/test_mac.sh
6867

sample/Tests/src/device_code_login.py

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
from selenium import webdriver
2+
from selenium.webdriver.chrome.service import Service
3+
from selenium.webdriver.chrome.options import Options
4+
from selenium.webdriver.common.by import By
5+
from selenium.webdriver.support.ui import WebDriverWait
6+
from selenium.webdriver.support import expected_conditions as EC
7+
from selenium.webdriver.common.keys import Keys
8+
import time
9+
from gmail_fetch_otp import fetch_gmail_code
10+
11+
12+
13+
# brew install chromedriver
14+
15+
def main():
16+
print("Connect to Chrome")
17+
# Set up Chrome options to connect to the existing Chrome instance
18+
chrome_options = Options()
19+
chrome_options.add_argument('--remote-debugging-port=9222')
20+
# Connect to the existing Chrome instance
21+
driver = webdriver.Chrome(options=chrome_options)
22+
23+
print("Open a window on Chrome")
24+
# Get the original window handle
25+
original_window = driver.current_window_handle
26+
27+
print("Waiting for new window...")
28+
WebDriverWait(driver, 30).until(EC.number_of_windows_to_be(2))
29+
30+
# Get all window handles
31+
all_windows = driver.window_handles
32+
33+
print("Find the new window")
34+
new_window = [window for window in all_windows if window != driver.current_window_handle][0]
35+
36+
print("Switch to the new window")
37+
driver.switch_to.window(new_window)
38+
39+
wait = WebDriverWait(driver, 60)
40+
41+
print("Wait for email input...")
42+
email_field = wait.until(EC.presence_of_element_located((By.ID, ':r1:')))
43+
print("Enter email")
44+
email_field.send_keys(EMAIL)
45+
email_field.send_keys(Keys.RETURN)
46+
47+
# Wait for the OTP to arrive and page to load
48+
print("Wait for OTP...")
49+
time.sleep(10)
50+
51+
print("Get OTP from Gmail...")
52+
code = fetch_gmail_code()
53+
if code:
54+
print(f"Successfully fetched OTP: {code}")
55+
else:
56+
print("Failed to fetch OTP from Gmail")
57+
driver.quit()
58+
59+
print("Find OTP input...")
60+
otp_field = wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, 'input[data-testid="passwordless_passcode__TextInput--0__input"]')))
61+
print("Enter OTP")
62+
otp_field.send_keys(code)
63+
64+
print("Wait for success page...")
65+
success = wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, 'h1[data-testid="device_success_title"]')))
66+
print("Connected to Passport!")
67+
68+
driver.quit()
69+
70+
if __name__ == "__main__":
71+
main()
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
from selenium import webdriver
2+
from selenium.webdriver.chrome.service import Service
3+
from selenium.webdriver.chrome.options import Options
4+
from selenium.webdriver.common.by import By
5+
from selenium.webdriver.support.ui import WebDriverWait
6+
from selenium.webdriver.support import expected_conditions as EC
7+
from selenium.webdriver.common.keys import Keys
8+
import time
9+
from gmail_fetch_otp import fetch_gmail_code
10+
11+
12+
13+
# Add chrome.exe to environment variable
14+
# Download chrome driver and add to environment variable
15+
16+
def main():
17+
print("Connect to Chrome")
18+
# Set up Chrome options to connect to the existing Chrome instance
19+
chrome_options = Options()
20+
chrome_options.add_experimental_option("debuggerAddress", "localhost:9222")
21+
# Connect to the existing Chrome instance
22+
driver = webdriver.Chrome(options=chrome_options)
23+
24+
print("Waiting for new window...")
25+
WebDriverWait(driver, 60).until(EC.number_of_windows_to_be(2))
26+
27+
# Get all window handles
28+
all_windows = driver.window_handles
29+
30+
print("Find the new window")
31+
new_window = [window for window in all_windows if window != driver.current_window_handle][0]
32+
33+
print("Switch to the new window")
34+
driver.switch_to.window(new_window)
35+
36+
wait = WebDriverWait(driver, 60)
37+
38+
print("Wait for email input...")
39+
email_field = wait.until(EC.presence_of_element_located((By.ID, ':r1:')))
40+
print("Enter email")
41+
email_field.send_keys(EMAIL)
42+
email_field.send_keys(Keys.RETURN)
43+
44+
# Wait for the OTP to arrive and page to load
45+
print("Wait for OTP...")
46+
time.sleep(10)
47+
48+
print("Get OTP from Gmail...")
49+
code = fetch_gmail_code()
50+
if code:
51+
print(f"Successfully fetched OTP: {code}")
52+
else:
53+
print("Failed to fetch OTP from Gmail")
54+
driver.quit()
55+
56+
print("Find OTP input...")
57+
otp_field = wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, 'input[data-testid="passwordless_passcode__TextInput--0__input"]')))
58+
print("Enter OTP")
59+
otp_field.send_keys(code)
60+
61+
print("Wait for success page...")
62+
success = wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, 'h1[data-testid="device_success_title"]')))
63+
print("Connected to Passport!")
64+
65+
driver.quit()
66+
67+
if __name__ == "__main__":
68+
main()
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
2+
from selenium import webdriver
3+
from selenium.webdriver.chrome.service import Service
4+
from selenium.webdriver.chrome.options import Options
5+
from selenium.webdriver.common.by import By
6+
from selenium.webdriver.support.ui import WebDriverWait
7+
from selenium.webdriver.support import expected_conditions as EC
8+
from selenium.webdriver.common.keys import Keys
9+
10+
def main():
11+
print("Connect to Chrome")
12+
# Set up Chrome options to connect to the existing Chrome instance
13+
chrome_options = Options()
14+
chrome_options.add_argument('--remote-debugging-port=9222')
15+
# Connect to the existing Chrome instance
16+
driver = webdriver.Chrome(options=chrome_options)
17+
18+
print("Open a window on Chrome")
19+
# Get the original window handle
20+
original_window = driver.current_window_handle
21+
22+
print("Waiting for new window...")
23+
WebDriverWait(driver, 60).until(EC.number_of_windows_to_be(2))
24+
25+
# Get all window handles
26+
all_windows = driver.window_handles
27+
28+
print("Find the new window")
29+
new_window = [window for window in all_windows if window != driver.current_window_handle][0]
30+
31+
print("Switch to the new window")
32+
driver.switch_to.window(new_window)
33+
34+
driver.quit()
35+
36+
if __name__ == "__main__":
37+
main()
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
2+
from selenium import webdriver
3+
from selenium.webdriver.chrome.service import Service
4+
from selenium.webdriver.chrome.options import Options
5+
from selenium.webdriver.common.by import By
6+
from selenium.webdriver.support.ui import WebDriverWait
7+
from selenium.webdriver.support import expected_conditions as EC
8+
from selenium.webdriver.common.keys import Keys
9+
10+
def main():
11+
print("Connect to Chrome")
12+
# Set up Chrome options to connect to the existing Chrome instance
13+
chrome_options = Options()
14+
chrome_options.add_experimental_option("debuggerAddress", "localhost:9222")
15+
# Connect to the existing Chrome instance
16+
driver = webdriver.Chrome(options=chrome_options)
17+
18+
print("Waiting for new window...")
19+
WebDriverWait(driver, 60).until(EC.number_of_windows_to_be(2))
20+
21+
# Get all window handles
22+
all_windows = driver.window_handles
23+
24+
print("Find the new window")
25+
new_window = [window for window in all_windows if window != driver.current_window_handle][0]
26+
27+
print("Switch to the new window")
28+
driver.switch_to.window(new_window)
29+
30+
driver.quit()
31+
32+
if __name__ == "__main__":
33+
main()

sample/Tests/src/gmail_fetch_otp.py

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
import os.path
2+
import re
3+
import base64
4+
from google.auth.transport.requests import Request
5+
from google.oauth2.credentials import Credentials
6+
from google_auth_oauthlib.flow import InstalledAppFlow
7+
from googleapiclient.discovery import build
8+
from googleapiclient.errors import HttpError
9+
10+
SCOPES = ["https://www.googleapis.com/auth/gmail.readonly"]
11+
12+
def fetch_gmail_code():
13+
"""Fetches the latest email from '[email protected]' and returns a 6-digit code."""
14+
15+
creds = None
16+
# The file token.json stores the user's access and refresh tokens, and is
17+
# created automatically when the authorization flow completes for the first
18+
# time.
19+
if os.path.exists("token.json"):
20+
creds = Credentials.from_authorized_user_file("token.json", SCOPES)
21+
# If there are no (valid) credentials available, let the user log in.
22+
if not creds or not creds.valid:
23+
if creds and creds.expired and creds.refresh_token:
24+
creds.refresh(Request())
25+
else:
26+
flow = InstalledAppFlow.from_client_secrets_file(
27+
"credentials.json", SCOPES
28+
)
29+
creds = flow.run_local_server(port=0)
30+
# Save the credentials for the next run
31+
with open("token.json", "w") as token:
32+
token.write(creds.to_json())
33+
34+
try:
35+
# Call the Gmail API
36+
service = build("gmail", "v1", credentials=creds)
37+
38+
# Fetch the latest email from '[email protected]'
39+
results = service.users().messages().list(userId="me", q="from:[email protected]", maxResults=1).execute()
40+
messages = results.get("messages", [])
41+
42+
if not messages:
43+
print("No messages found.")
44+
return None
45+
46+
# Get the ID of the latest message
47+
latest_message_id = messages[0]["id"]
48+
49+
# Retrieve the full message details
50+
message = service.users().messages().get(userId="me", id=latest_message_id).execute()
51+
52+
# Extract the 6-digit code from the email content
53+
msg_payload = message["payload"]
54+
if "parts" in msg_payload:
55+
for part in msg_payload["parts"]:
56+
if part["mimeType"] == "text/plain":
57+
email_body = part["body"]["data"]
58+
email_body_decoded = base64.urlsafe_b64decode(email_body).decode("utf-8")
59+
code_match = re.search(r"\b\d{6}\b", email_body_decoded)
60+
if code_match:
61+
six_digit_code = code_match.group(0)
62+
return six_digit_code
63+
else:
64+
print("No parts found in the email.")
65+
return None
66+
67+
except HttpError as error:
68+
print(f"An error occurred: {error}")
69+
return None

0 commit comments

Comments
 (0)