Skip to content

Commit 4feb585

Browse files
authored
Merge pull request #1602 from seleniumbase/mac-m1-and-m2-compatibility
Mac M1 and M2 compatibility
2 parents 8c61274 + affe79e commit 4feb585

File tree

14 files changed

+175
-55
lines changed

14 files changed

+175
-55
lines changed

examples/boilerplates/samples/google_test.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
""" google.com example test that uses page objects """
1+
"""google.com example test that uses page objects"""
22

33
from seleniumbase import BaseCase
44
from .google_objects import HomePage, ResultsPage
@@ -7,7 +7,9 @@
77
class GoogleTests(BaseCase):
88
def test_google_dot_com(self):
99
self.open("https://google.com/ncr")
10-
self.type(HomePage.search_box, "github")
10+
self.sleep(0.1)
11+
self.save_screenshot_to_logs() # In "./latest_logs/" folder.
12+
self.type(HomePage.search_box, "github.com")
1113
self.assert_element(HomePage.search_button)
1214
self.assert_element(HomePage.feeling_lucky_button)
1315
self.click(HomePage.search_button)

examples/boilerplates/samples/test_page_objects.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ def click_search_result(self, sb, content):
1515

1616
class SeleniumBaseIOPage:
1717
def do_search_and_click(self, sb, search_term):
18+
sb.sleep(0.05)
1819
sb.type('form[name="search"] input', search_term)
1920
sb.click("li.md-search-result__item h1:contains(%s)" % search_term)
2021

examples/swag_labs_user_tests.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ def login_to_swag_labs(self, username="standard_user"):
77
"""Login to Swag Labs and verify success."""
88
url = "https://www.saucedemo.com"
99
self.open(url)
10+
self.wait_for_element("div.login_logo")
11+
self.wait_for_element("div.bot_column")
1012
if username not in self.get_text("#login_credentials"):
1113
self.fail("Invalid user for login: %s" % username)
1214
self.type("#user-name", username)

examples/test_login.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
class SwagLabsLoginTests(BaseCase):
66
def login_to_swag_labs(self):
77
self.open("https://www.saucedemo.com")
8+
self.wait_for_element("div.login_logo")
9+
self.wait_for_element("div.bot_column")
810
self.type("#user-name", "standard_user")
911
self.type("#password", "secret_sauce")
1012
self.click('input[type="submit"]')

examples/visual_testing/layout_test.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,13 @@ def test_applitools_layout_change(self):
66
self.open("https://applitools.com/helloworld?diff1")
77
self.wait_for_element('a[href="?diff1"]')
88
print('\nCreating baseline in "visual_baseline" folder.')
9+
self.sleep(0.05)
910
self.check_window(name="helloworld", baseline=True)
1011
# Click a button that changes the text of an element
1112
# (Text changes do not impact visual comparisons)
13+
self.sleep(0.05)
1214
self.click('a[href="?diff1"]')
13-
self.wait_for_ready_state_complete()
15+
self.sleep(0.05)
1416
# Verify html tags match the baseline
1517
self.check_window(name="helloworld", level=1)
1618
# Verify html tags and attribute names match the baseline

requirements.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ tomli>=1.2.3;python_version>="3.6" and python_version<"3.7"
1010
tomli>=2.0.1;python_version>="3.7"
1111
tqdm>=4.64.1
1212
wheel>=0.37.1;python_version<"3.7"
13-
wheel>=0.38.2;python_version>="3.7"
13+
wheel>=0.38.3;python_version>="3.7"
1414
attrs>=21.4.0;python_version<"3.6"
1515
attrs>=22.1.0;python_version>="3.6"
1616
PyYAML>=6.0;python_version>="3.6"

seleniumbase/__version__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
# seleniumbase package
2-
__version__ = "4.8.1"
2+
__version__ = "4.8.2"

seleniumbase/console_scripts/sb_install.py

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ def requests_get_with_retry(url):
117117
return response
118118

119119

120-
def main(override=None):
120+
def main(override=None, intel_for_uc=None):
121121
if override:
122122
if override == "chromedriver":
123123
sys.argv = ["seleniumbase", "get", "chromedriver"]
@@ -229,7 +229,10 @@ def main(override=None):
229229
else:
230230
invalid_run_command()
231231
if "darwin" in sys_plat:
232-
file_name = "chromedriver_mac64.zip"
232+
if "arm" in platform.processor().lower() and not intel_for_uc:
233+
file_name = "chromedriver_mac_arm64.zip"
234+
else:
235+
file_name = "chromedriver_mac64.zip"
233236
elif "linux" in sys_plat:
234237
file_name = "chromedriver_linux64.zip"
235238
elif "win32" in sys_plat or "win64" in sys_plat or "x64" in sys_plat:
@@ -393,7 +396,10 @@ def main(override=None):
393396
file_name = "edgedriver_win32.zip"
394397
suffix = "WINDOWS"
395398
elif "darwin" in sys_plat:
396-
file_name = "edgedriver_mac64.zip"
399+
if "arm" in platform.processor().lower():
400+
file_name = "edgedriver_mac64_m1.zip"
401+
else:
402+
file_name = "edgedriver_mac64.zip"
397403
suffix = "MACOS"
398404
elif "linux" in sys_plat:
399405
file_name = "edgedriver_linux64.zip"
@@ -631,7 +637,23 @@ def main(override=None):
631637
if os.path.exists(new_file):
632638
os.remove(new_file) # Technically the old file now
633639
print("Extracting %s from %s ..." % (contents, file_name))
634-
zip_ref.extractall(downloads_folder)
640+
if (
641+
intel_for_uc
642+
and "darwin" in sys_plat
643+
and "arm" in platform.processor().lower()
644+
):
645+
f_name = "uc_driver"
646+
new_file = os.path.join(downloads_folder, f_name)
647+
if os.path.exists(new_file):
648+
os.remove(new_file)
649+
zipinfos = zip_ref.infolist()
650+
for zipinfo in zipinfos:
651+
if zipinfo.filename == "chromedriver":
652+
zipinfo.filename = "uc_driver"
653+
zip_ref.extract(zipinfo, downloads_folder)
654+
contents = zip_ref.namelist()
655+
else:
656+
zip_ref.extractall(downloads_folder)
635657
zip_ref.close()
636658
os.remove(zip_file_path)
637659
print("%sUnzip Complete!%s\n" % (c2, cr))

seleniumbase/console_scripts/sb_mkdir.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -612,7 +612,9 @@ def main():
612612
data.append("class GoogleTests(BaseCase):")
613613
data.append(" def test_google_dot_com(self):")
614614
data.append(' self.open("https://google.com/ncr")')
615-
data.append(' self.type(HomePage.search_box, "github")')
615+
data.append(" self.sleep(0.1)")
616+
data.append(" self.save_screenshot_to_logs()")
617+
data.append(' self.type(HomePage.search_box, "github.com")')
616618
data.append(" self.assert_element(HomePage.search_button)")
617619
data.append(" self.assert_element(HomePage.feeling_lucky_button)")
618620
data.append(" self.click(HomePage.search_button)")

seleniumbase/core/browser_launcher.py

Lines changed: 56 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import fasteners
22
import logging
33
import os
4+
import platform
45
import re
56
import shutil
67
import subprocess
@@ -49,6 +50,9 @@
4950
PROXY_DIR_PATH = proxy_helper.PROXY_DIR_PATH
5051
PROXY_DIR_LOCK = proxy_helper.PROXY_DIR_LOCK
5152
PLATFORM = sys.platform
53+
IS_ARM_MAC = False
54+
if PLATFORM.endswith("darwin") and "arm" in platform.processor().lower():
55+
IS_ARM_MAC = True
5256
IS_WINDOWS = False
5357
LOCAL_CHROMEDRIVER = None
5458
LOCAL_GECKODRIVER = None
@@ -130,6 +134,25 @@ def chromedriver_on_path():
130134
return None
131135

132136

137+
def get_uc_driver_version():
138+
uc_driver_version = None
139+
if os.path.exists(LOCAL_UC_DRIVER):
140+
try:
141+
output = subprocess.check_output(
142+
"%s --version" % LOCAL_UC_DRIVER, shell=True
143+
)
144+
if IS_WINDOWS:
145+
output = output.decode("latin1")
146+
else:
147+
output = output.decode("utf-8")
148+
output = output.split(" ")[1].split(".")[0]
149+
if int(output) >= 72:
150+
uc_driver_version = output
151+
except Exception:
152+
pass
153+
return uc_driver_version
154+
155+
133156
def edgedriver_on_path():
134157
return os.path.exists(LOCAL_EDGEDRIVER)
135158

@@ -2501,13 +2524,25 @@ def get_local_driver(
25012524
except Exception:
25022525
pass
25032526
disable_build_check = False
2527+
uc_driver_version = None
2528+
if IS_ARM_MAC:
2529+
uc_driver_version = get_uc_driver_version()
25042530
if (
25052531
LOCAL_CHROMEDRIVER
25062532
and os.path.exists(LOCAL_CHROMEDRIVER)
25072533
and (
25082534
use_version == driver_version
25092535
or use_version == "latest"
25102536
)
2537+
and (
2538+
not is_using_uc(undetectable, browser_name)
2539+
or not IS_ARM_MAC
2540+
)
2541+
or (
2542+
is_using_uc(undetectable, browser_name)
2543+
and IS_ARM_MAC
2544+
and uc_driver_version == use_version
2545+
)
25112546
):
25122547
try:
25132548
make_driver_executable_if_not(LOCAL_CHROMEDRIVER)
@@ -2527,6 +2562,16 @@ def get_local_driver(
25272562
or driver_version != "72"
25282563
)
25292564
)
2565+
or (
2566+
is_using_uc(undetectable, browser_name)
2567+
and not os.path.exists(LOCAL_UC_DRIVER)
2568+
)
2569+
or (
2570+
is_using_uc(undetectable, browser_name)
2571+
and IS_ARM_MAC
2572+
and use_version != "latest"
2573+
and uc_driver_version != use_version
2574+
)
25302575
):
25312576
# chromedriver download needed in the seleniumbase/drivers dir
25322577
from seleniumbase.console_scripts import sb_install
@@ -2538,11 +2583,14 @@ def get_local_driver(
25382583
msg = "chromedriver update needed. Getting it now:"
25392584
if not path_chromedriver:
25402585
msg = "chromedriver not found. Getting it now:"
2541-
25422586
print("\nWarning: %s" % msg)
2587+
intel_for_uc = False
2588+
if IS_ARM_MAC and is_using_uc(undetectable, browser_name):
2589+
intel_for_uc = True # Use Intel's driver for UC Mode
25432590
try:
25442591
sb_install.main(
2545-
override="chromedriver %s" % use_version
2592+
override="chromedriver %s" % use_version,
2593+
intel_for_uc=intel_for_uc,
25462594
)
25472595
except Exception:
25482596
d_latest = get_latest_chromedriver_version()
@@ -2613,27 +2661,15 @@ def get_local_driver(
26132661
uc_lock = fasteners.InterProcessLock(
26142662
constants.MultiBrowser.DRIVER_FIXING_LOCK
26152663
)
2616-
with uc_lock: # No UC multithreaded tests
2617-
uc_driver_version = None
2618-
if os.path.exists(LOCAL_UC_DRIVER):
2619-
try:
2620-
output = subprocess.check_output(
2621-
"%s --version" % LOCAL_UC_DRIVER, shell=True
2622-
)
2623-
if IS_WINDOWS:
2624-
output = output.decode("latin1")
2625-
else:
2626-
output = output.decode("utf-8")
2627-
output = output.split(" ")[1].split(".")[0]
2628-
if int(output) >= 72:
2629-
uc_driver_version = output
2630-
except Exception:
2631-
pass
2664+
with uc_lock: # Avoid multithreaded issues
2665+
uc_driver_version = get_uc_driver_version()
26322666
if (
26332667
uc_driver_version != use_version
26342668
and use_version != "latest"
26352669
):
2636-
if os.path.exists(LOCAL_CHROMEDRIVER):
2670+
if IS_ARM_MAC:
2671+
pass # Already taken care of in sb_install
2672+
elif os.path.exists(LOCAL_CHROMEDRIVER):
26372673
shutil.copyfile(
26382674
LOCAL_CHROMEDRIVER, LOCAL_UC_DRIVER
26392675
)
@@ -2683,7 +2719,7 @@ def get_local_driver(
26832719
uc_lock = fasteners.InterProcessLock(
26842720
constants.MultiBrowser.DRIVER_FIXING_LOCK
26852721
)
2686-
with uc_lock:
2722+
with uc_lock: # Avoid multithreaded issues
26872723
try:
26882724
uc_path = None
26892725
if os.path.exists(LOCAL_UC_DRIVER):

0 commit comments

Comments
 (0)