Skip to content

Commit

Permalink
Merge pull request #2533 from seleniumbase/optimizations-and-test-upd…
Browse files Browse the repository at this point in the history
…ates

Optimizations and test updates
  • Loading branch information
mdmintz authored Feb 23, 2024
2 parents b2ec928 + 18dd9f1 commit edeb2db
Show file tree
Hide file tree
Showing 17 changed files with 128 additions and 113 deletions.
8 changes: 4 additions & 4 deletions examples/presenter/multi_uc.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,16 @@

@pytest.mark.parametrize("", [[]] * 3)
def test_multi_threaded(sb):
sb.driver.uc_open_with_tab("https://nowsecure.nl/#relax")
sb.driver.uc_open_with_reconnect("https://top.gg/", 5)
sb.set_window_rect(randint(0, 755), randint(38, 403), 700, 500)
try:
sb.assert_text("OH YEAH, you passed!", "h1", timeout=4)
sb.assert_text("Discord Bots", "h1", timeout=2)
sb.post_message("Selenium wasn't detected!", duration=4)
sb._print("\n Success! Website did not detect Selenium! ")
except Exception:
sb.driver.uc_open_with_tab("https://nowsecure.nl/#relax")
sb.driver.uc_open_with_reconnect("https://top.gg/", 5)
try:
sb.assert_text("OH YEAH, you passed!", "h1", timeout=4)
sb.assert_text("Discord Bots", "h1", timeout=2)
sb.post_message("Selenium wasn't detected!", duration=4)
sb._print("\n Success! Website did not detect Selenium! ")
except Exception:
Expand Down
9 changes: 4 additions & 5 deletions examples/presenter/uc_presentation.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,17 +30,16 @@ def test_presentation(self):
self.get_new_driver(undetectable=True)
try:
self.driver.uc_open_with_reconnect(
"https://nowsecure.nl/#relax", reconnect_time=3
"https://top.gg/", reconnect_time=4
)
try:
self.assert_text("OH YEAH, you passed!", "h1", timeout=4)
self.assert_text("Discord Bots", "h1", timeout=3)
self.post_message("Selenium wasn't detected!", duration=4)
except Exception:
self.clear_all_cookies()
self.driver.uc_open_with_reconnect(
"https://nowsecure.nl/#relax", reconnect_time=3
"https://top.gg/", reconnect_time=5
)
self.assert_text("OH YEAH, you passed!", "h1", timeout=4)
self.assert_text("Discord Bots", "h1", timeout=2)
self.post_message("Selenium wasn't detected!", duration=4)
finally:
self.quit_extra_driver()
Expand Down
10 changes: 10 additions & 0 deletions examples/raw_cdp_logging.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
from rich.pretty import pprint
from seleniumbase import Driver

driver = Driver(uc=True, log_cdp=True)
try:
driver.get("https://seleniumbase.io/apps/invisible_recaptcha")
driver.sleep(3)
pprint(driver.get_log("performance"))
finally:
driver.quit()
6 changes: 3 additions & 3 deletions examples/raw_driver_context.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
"""Can run with "python". (pytest not needed)."""
"""DriverContext() example. (Runs with "python")."""
from seleniumbase import DriverContext

with DriverContext() as driver:
driver.open("seleniumbase.github.io/")
driver.open("seleniumbase.io/")
driver.highlight('img[alt="SeleniumBase"]', loops=6)

with DriverContext(browser="chrome", incognito=True) as driver:
Expand All @@ -13,7 +13,7 @@
driver.highlight("#output", loops=6)

with DriverContext() as driver:
driver.open("seleniumbase.github.io/demo_page")
driver.open("seleniumbase.io/demo_page")
driver.highlight("h2")
driver.type("#myTextInput", "Automation")
driver.click("#checkBox1")
Expand Down
22 changes: 11 additions & 11 deletions examples/raw_browser_launcher.py → examples/raw_driver_manager.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,16 @@
"""Driver() test. Runs with "python". (pytest not needed)."""
"""Driver() manager example. (Runs with "python")."""
from seleniumbase import Driver

driver = Driver()
try:
driver.open("seleniumbase.io/demo_page")
driver.highlight("h2")
driver.type("#myTextInput", "Automation")
driver.click("#checkBox1")
driver.highlight("img", loops=6)
finally:
driver.quit()

driver = Driver(browser="chrome", headless=False)
try:
driver.open("seleniumbase.io/apps/calculator")
Expand All @@ -10,13 +20,3 @@
driver.highlight("#output", loops=6)
finally:
driver.quit()

driver = Driver()
try:
driver.open("seleniumbase.github.io/demo_page")
driver.highlight("h2")
driver.type("#myTextInput", "Automation")
driver.click("#checkBox1")
driver.highlight("img", loops=6)
finally:
driver.quit()
2 changes: 1 addition & 1 deletion examples/raw_sb.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
"""Context Manager Test. Runs with "python". (pytest not needed)."""
"""SB() context manager example. (Runs with "python")."""
from seleniumbase import SB

with SB() as sb: # By default, browser="chrome" if not set.
Expand Down
19 changes: 5 additions & 14 deletions examples/raw_uc_mode.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,9 @@
from seleniumbase import SB

with SB(uc=True, test=True) as sb:
sb.driver.uc_open_with_tab("https://nowsecure.nl/#relax")
sb.sleep(1.2)
if not sb.is_text_visible("OH YEAH, you passed!", "h1"):
sb.driver.uc_open_with_reconnect("https://top.gg/", 4)
if not sb.is_text_visible("Discord Bots", "h1"):
sb.get_new_driver(undetectable=True)
sb.driver.uc_open_with_reconnect(
"https://nowsecure.nl/#relax", reconnect_time=3
)
sb.sleep(1.2)
if not sb.is_text_visible("OH YEAH, you passed!", "h1"):
if sb.is_element_visible('iframe[src*="challenge"]'):
with sb.frame_switch('iframe[src*="challenge"]'):
sb.click("span.mark")
sb.sleep(2)
sb.activate_demo_mode()
sb.assert_text("OH YEAH, you passed!", "h1", timeout=3)
sb.driver.uc_open_with_reconnect("https://top.gg/", 5)
sb.activate_demo_mode() # Highlight + show assertions
sb.assert_text("Discord Bots", "h1", timeout=3)
28 changes: 4 additions & 24 deletions examples/uc_cdp_events.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from pprint import pformat
from rich.pretty import pprint
from seleniumbase import BaseCase
BaseCase.main(__name__, __file__, "--uc", "--uc-cdp", "-s")

Expand All @@ -9,38 +9,18 @@ def add_cdp_listener(self):
# self.driver.add_cdp_listener("*", lambda data: print(pformat(data)))
self.driver.add_cdp_listener(
"Network.requestWillBeSentExtraInfo",
lambda data: print(pformat(data))
lambda data: pprint(data)
)

def verify_success(self):
self.assert_text("OH YEAH, you passed!", "h1", timeout=6.25)
self.sleep(1)

def fail_me(self):
self.fail('Selenium was detected! Try using: "pytest --uc"')

def test_display_cdp_events(self):
if not (self.undetectable and self.uc_cdp_events):
self.get_new_driver(undetectable=True, uc_cdp_events=True)
self.driver.get("https://nowsecure.nl/#relax")
try:
self.verify_success()
except Exception:
self.clear_all_cookies()
self.get_new_driver(undetectable=True, uc_cdp_events=True)
self.driver.get("https://nowsecure.nl/#relax")
try:
self.verify_success()
except Exception:
if self.is_element_visible('iframe[src*="challenge"]'):
with self.frame_switch('iframe[src*="challenge"]'):
self.click("span.mark")
else:
self.fail_me()
try:
self.verify_success()
except Exception:
self.fail_me()
self.driver.uc_open_with_tab("https://nowsecure.nl/#relax")
self.verify_success()
self.add_cdp_listener()
self.refresh()
self.sleep(1)
16 changes: 5 additions & 11 deletions examples/verify_undetected.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,20 +10,14 @@ def test_browser_is_undetected(self):
if not self.undetectable:
self.get_new_driver(undetectable=True)
self.driver.uc_open_with_reconnect(
"https://nowsecure.nl/#relax", reconnect_time=3
"https://top.gg/", reconnect_time=4
)
self.sleep(1.2)
if not self.is_text_visible("OH YEAH, you passed!", "h1"):
if not self.is_text_visible("Discord Bots", "h1"):
self.get_new_driver(undetectable=True)
self.driver.uc_open_with_reconnect(
"https://nowsecure.nl/#relax", reconnect_time=3
"https://top.gg/", reconnect_time=5
)
self.sleep(1.2)
if not self.is_text_visible("OH YEAH, you passed!", "h1"):
if self.is_element_visible('iframe[src*="challenge"]'):
with self.frame_switch('iframe[src*="challenge"]'):
self.click("span.mark")
self.sleep(2)
self.assert_text("OH YEAH, you passed!", "h1", timeout=3)
self.assert_text("Discord Bots", "h1", timeout=3)
self.set_messenger_theme(theme="air", location="top_center")
self.post_message("Selenium wasn't detected!", duration=2.8)
self._print("\n Success! Website did not detect Selenium! ")
63 changes: 39 additions & 24 deletions help_docs/syntax_formats.md
Original file line number Diff line number Diff line change
Expand Up @@ -832,17 +832,16 @@ This format provides a pure Python way of using SeleniumBase without a test runn
```python
from seleniumbase import SB

with SB() as sb: # By default, browser="chrome" if not set.
sb.open("https://seleniumbase.github.io/realworld/login")
with SB() as sb:
sb.open("seleniumbase.io/simple/login")
sb.type("#username", "demo_user")
sb.type("#password", "secret_pass")
sb.enter_mfa_code("#totpcode", "GAXG2MTEOR3DMMDG") # 6-digit
sb.assert_text("Welcome!", "h1")
sb.highlight("img#image1") # A fancier assert_element() call
sb.click('a:contains("This Page")') # Use :contains() on any tag
sb.click_link("Sign out") # Link must be "a" tag. Not "button".
sb.assert_element('a:contains("Sign in")')
sb.assert_exact_text("You have been signed out!", "#top_message")
sb.click('a:contains("Sign in")')
sb.assert_exact_text("Welcome!", "h1")
sb.assert_element("img#image1")
sb.highlight("#image1")
sb.click_link("Sign out")
sb.assert_text("signed out", "#top_message")
```

(See <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/raw_sb.py">examples/raw_sb.py</a> for the test.)
Expand Down Expand Up @@ -881,11 +880,11 @@ with SB(test=True, rtf=True, demo=True) as sb:
This pure Python format gives you a raw <code translate="no">webdriver</code> instance in a <code translate="no">with</code> block. The SeleniumBase Driver Manager will automatically make sure that your driver is compatible with your browser version. It gives you full access to customize driver options via method args or via the command-line. The driver will automatically call <code translate="no">quit()</code> after the code leaves the <code translate="no">with</code> block. Here are some examples:

```python
"""Can run with "python". (pytest not needed)."""
"""DriverContext() example. (Runs with "python")."""
from seleniumbase import DriverContext

with DriverContext() as driver:
driver.open("seleniumbase.github.io/")
driver.open("seleniumbase.io/")
driver.highlight('img[alt="SeleniumBase"]', loops=6)

with DriverContext(browser="chrome", incognito=True) as driver:
Expand All @@ -896,7 +895,7 @@ with DriverContext(browser="chrome", incognito=True) as driver:
driver.highlight("#output", loops=6)

with DriverContext() as driver:
driver.open("seleniumbase.github.io/demo_page")
driver.open("seleniumbase.io/demo_page")
driver.highlight("h2")
driver.type("#myTextInput", "Automation")
driver.click("#checkBox1")
Expand All @@ -911,9 +910,19 @@ with DriverContext() as driver:
Another way of running Selenium tests with pure ``python`` (as opposed to using ``pytest`` or ``pynose``) is by using this format, which bypasses [BaseCase](https://github.com/seleniumbase/SeleniumBase/blob/master/seleniumbase/fixtures/base_case.py) methods while still giving you a flexible driver with a manager. SeleniumBase includes helper files such as [page_actions.py](https://github.com/seleniumbase/SeleniumBase/blob/master/seleniumbase/fixtures/page_actions.py), which may help you get around some of the limitations of bypassing ``BaseCase``. Here's an example:

```python
"""Driver() test. Runs with "python". (pytest not needed)."""
"""Driver() example. (Runs with "python")."""
from seleniumbase import Driver

driver = Driver()
try:
driver.open("seleniumbase.io/demo_page")
driver.highlight("h2")
driver.type("#myTextInput", "Automation")
driver.click("#checkBox1")
driver.highlight("img", loops=6)
finally:
driver.quit()

driver = Driver(browser="chrome", headless=False)
try:
driver.open("seleniumbase.io/apps/calculator")
Expand All @@ -923,19 +932,9 @@ try:
driver.highlight("#output", loops=6)
finally:
driver.quit()

driver = Driver()
try:
driver.open("seleniumbase.github.io/demo_page")
driver.highlight("h2")
driver.type("#myTextInput", "Automation")
driver.click("#checkBox1")
driver.highlight("img", loops=6)
finally:
driver.quit()
```

(From <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/raw_browser_launcher.py">examples/raw_browser_launcher.py</a>)
(From <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/raw_driver_manager.py">examples/raw_driver_manager.py</a>)

Here's how the [selenium-wire](https://github.com/wkeeling/selenium-wire) integration may look when using the ``Driver()`` format:

Expand All @@ -951,6 +950,22 @@ finally:
driver.quit()
```

Here's another `selenium-wire` example with the `Driver()` format:

```python
from seleniumbase import Driver

def intercept_response(request, response):
print(request.headers)

driver = Driver(wire=True)
try:
driver.response_interceptor = intercept_response
driver.get("https://wikipedia.org")
finally:
driver.quit()
```

Here's an example of basic login with the ``Driver()`` format:

```python
Expand Down
6 changes: 3 additions & 3 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ charset-normalizer==3.3.2
urllib3>=1.26.18,<2;python_version<"3.10"
urllib3>=1.26.18,<2.3.0;python_version>="3.10"
requests==2.31.0
pynose==1.4.8
pynose==1.5.0
sniffio==1.3.0
h11==0.14.0
outcome==1.3.0.post0
Expand All @@ -29,7 +29,7 @@ trio==0.24.0;python_version>="3.8"
trio-websocket==0.11.1
wsproto==1.2.0
selenium==4.11.2;python_version<"3.8"
selenium==4.17.2;python_version>="3.8"
selenium==4.18.1;python_version>="3.8"
cssselect==1.2.0
sortedcontainers==2.4.0
fasteners==0.19
Expand Down Expand Up @@ -69,7 +69,7 @@ rich==13.7.0

coverage==6.2;python_version<"3.7"
coverage==7.2.7;python_version>="3.7" and python_version<"3.8"
coverage==7.4.1;python_version>="3.8"
coverage==7.4.2;python_version>="3.8"
pytest-cov==4.0.0;python_version<"3.7"
pytest-cov==4.1.0;python_version>="3.7"
flake8==5.0.4;python_version<"3.9"
Expand Down
2 changes: 1 addition & 1 deletion seleniumbase/__version__.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
# seleniumbase package
__version__ = "4.23.7"
__version__ = "4.24.0"
16 changes: 14 additions & 2 deletions seleniumbase/core/browser_launcher.py
Original file line number Diff line number Diff line change
Expand Up @@ -3833,17 +3833,29 @@ def get_local_driver(
)
return extend_driver(driver)
except Exception:
if is_using_uc(undetectable, browser_name):
raise
# Try again if Chrome didn't launch
try:
# Try again if Chrome didn't launch
service = ChromeService(service_args=["--disable-build-check"])
driver = webdriver.Chrome(
service=service, options=chrome_options
)
return extend_driver(driver)
except Exception:
pass
if headless:
if user_data_dir:
print("\nUnable to set user_data_dir while starting Chrome!\n")
raise
elif mobile_emulator:
print("\nFailed to start Chrome's mobile device emulator!\n")
raise
elif extension_zip or extension_dir:
print("\nUnable to load extension while starting Chrome!\n")
raise
elif headless or headless2 or IS_LINUX or proxy_string or use_wire:
raise
# Try running without any options (bare bones Chrome launch)
if LOCAL_CHROMEDRIVER and os.path.exists(LOCAL_CHROMEDRIVER):
try:
make_driver_executable_if_not(LOCAL_CHROMEDRIVER)
Expand Down
6 changes: 3 additions & 3 deletions seleniumbase/fixtures/base_case.py
Original file line number Diff line number Diff line change
Expand Up @@ -2162,9 +2162,9 @@ def find_visible_elements(self, selector, by="css selector", limit=0):
selector, by = self.__recalculate_selector(selector, by)
self.wait_for_ready_state_complete()
time.sleep(0.05)
v_elems = page_actions.find_visible_elements(self.driver, selector, by)
if limit and limit > 0 and len(v_elems) > limit:
v_elems = v_elems[:limit]
v_elems = page_actions.find_visible_elements(
self.driver, selector, by, limit
)
return v_elems

def click_visible_elements(
Expand Down
Loading

0 comments on commit edeb2db

Please sign in to comment.