Skip to content

Commit c70e8b2

Browse files
authored
Merge pull request #1976 from seleniumbase/add-dark-mode-option
Add Dark Mode option, and more
2 parents 5f64da2 + 6180b92 commit c70e8b2

24 files changed

+221
-54
lines changed

README.md

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@
5757

5858
--------
5959

60-
<p align="left"><a href="https://github.com/seleniumbase/SeleniumBase/"><img src="https://seleniumbase.github.io/cdn/img/sb_logo_p3.png" alt="SeleniumBase" title="SeleniumBase" width="232" /></a></p>
60+
<p align="left"><a href="https://github.com/seleniumbase/SeleniumBase/"><img src="https://seleniumbase.github.io/cdn/img/super_logo_sb2.png" alt="SeleniumBase" title="SeleniumBase" width="232" /></a></p>
6161

6262
<blockquote>
6363
<p dir="auto"><strong>Explore the README:</strong></p>
@@ -439,6 +439,7 @@ self.sleep(seconds) # Do nothing for the given amount of time.
439439
self.save_screenshot(name) # Save a screenshot in .png format.
440440
self.assert_element(selector) # Verify the element is visible.
441441
self.assert_text(text, selector) # Verify text in the element.
442+
self.assert_exact_text(text, selector) # Verify text is exact.
442443
self.assert_title(title) # Verify the title of the web page.
443444
self.assert_downloaded_file(file) # Verify file was downloaded.
444445
self.assert_no_404_errors() # Verify there are no broken links.
@@ -485,10 +486,10 @@ behave calculator.feature -D rs -D dashboard
485486
486487
With a SeleniumBase [pytest.ini](https://github.com/seleniumbase/SeleniumBase/blob/master/examples/pytest.ini) file present, you can modify default discovery settings. The Python class name can be anything because ``seleniumbase.BaseCase`` inherits ``unittest.TestCase`` to trigger autodiscovery.
487488
488-
<p>✅ You can do a pre-flight check to see which tests would get discovered by <code translate="no">pytest</code> before the real flight:</p>
489+
<p>✅ You can do a pre-flight check to see which tests would get discovered by <code translate="no">pytest</code> before the actual run:</p>
489490
490491
```bash
491-
pytest --collect-only -q
492+
pytest --co -q
492493
```
493494
494495
<p>✅ You can be more specific when calling <code translate="no">pytest</code> or <code translate="no">pynose</code> on a file:</p>
@@ -567,7 +568,8 @@ pytest test_coffee_cart.py --trace
567568
-q # Quiet mode. Print fewer details in the console output when running tests.
568569
-x # Stop running the tests after the first failure is reached.
569570
--html=report.html # Creates a detailed pytest-html report after tests finish.
570-
--collect-only | --co # Show what tests would get run. (Without running them)
571+
--co | --collect-only # Show what tests would get run. (Without running them)
572+
--co -q # (Both options together!) - Do a dry run with full test names shown.
571573
-n=NUM # Multithread the tests using that many threads. (Speed up test runs!)
572574
-s # See print statements. (Should be on by default with pytest.ini present.)
573575
--junit-xml=report.xml # Creates a junit-xml report after tests finish.
@@ -656,6 +658,7 @@ pytest test_coffee_cart.py --trace
656658
--swiftshader # (Use Chrome's "--use-gl=swiftshader" feature.)
657659
--incognito # (Enable Chrome's Incognito mode.)
658660
--guest # (Enable Chrome's Guest mode.)
661+
--dark # (Enable Chrome's Dark mode.)
659662
--devtools # (Open Chrome's DevTools when the browser opens.)
660663
--rs | --reuse-session # (Reuse browser session for all tests.)
661664
--rcs | --reuse-class-session # (Reuse session for tests in class.)
@@ -1157,22 +1160,39 @@ self.switch_to_window(1) # This switches to the new tab (0 is the first one)
11571160
11581161
<h3>🔵 How to handle iframes:</h3>
11591162
1160-
🔵 <b>ProTip™:</b> iframes follow the same principle as new windows: You must first switch to the iframe if you want to perform actions in there:
1163+
🔵 <b>iframes</b> follow the same principle as new windows: You must first switch to the iframe if you want to perform actions in there:
11611164
11621165
```python
11631166
self.switch_to_frame("iframe")
11641167
# ... Now perform actions inside the iframe
11651168
self.switch_to_parent_frame() # Exit the current iframe
11661169
```
11671170
1168-
To exit from multiple iframes, use ``self.switch_to_default_content()``. If inside a single iframe, this has the same effect as ``self.switch_to_parent_frame()``.
1171+
To exit from multiple iframes, use ``self.switch_to_default_content()``. (If inside a single iframe, this has the same effect as ``self.switch_to_parent_frame()``.)
1172+
1173+
```python
1174+
self.switch_to_frame('iframe[name="frame1"]')
1175+
self.switch_to_frame('iframe[name="frame2"]')
1176+
# ... Now perform actions inside the inner iframe
1177+
self.switch_to_default_content() # Back to the main page
1178+
```
11691179
11701180
🔵 You can also use a context manager to act inside iframes:
11711181
11721182
```python
11731183
with self.frame_switch("iframe"):
11741184
# ... Now perform actions while inside the code block
1175-
# You have left the iframe!
1185+
# You have left the iframe
1186+
```
1187+
1188+
This also works with nested iframes:
1189+
1190+
```python
1191+
with self.frame_switch('iframe[name="frame1"]'):
1192+
with self.frame_switch('iframe[name="frame2"]'):
1193+
# ... Now perform actions while inside the code block
1194+
# You are now back inside the first iframe
1195+
# You have left all the iframes
11761196
```
11771197
11781198
<h3>🔵 How to execute custom jQuery scripts:</h3>

examples/hack_the_planet.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -179,8 +179,8 @@ def test_all_your_base_are_belong_to_us(self):
179179
self.highlight("#ctitle", loops=7, scroll=False)
180180

181181
self.open("https://www.nintendo.com/whatsnew/")
182-
self.set_text_content("#main h2", aybabtu)
183-
self.highlight("#main h2", loops=10, scroll=False)
182+
self.set_text_content("main section h1", aybabtu)
183+
self.highlight("main section h1", loops=10, scroll=False)
184184

185185
if not self.headless:
186186
self.open("https://support.gog.com/hc/en-us?product=gog")

examples/iframe_tests.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
class FrameTests(BaseCase):
77
def test_iframe_basics(self):
88
self.open("https://seleniumbase.io/w3schools/iframes.html")
9+
self.assert_title("iframe Testing")
910
self.click("button#runbtn")
1011
self.switch_to_frame("iframeResult") # Enter the iframe
1112
self.assert_text("HTML Iframes", "h2")
@@ -22,6 +23,7 @@ def test_iframe_basics(self):
2223

2324
def test_iframes_with_context_manager(self):
2425
self.open("https://seleniumbase.io/w3schools/iframes.html")
26+
self.assert_title("iframe Testing")
2527
self.click("button#runbtn")
2628
with self.frame_switch("iframeResult"):
2729
self.assert_text("HTML Iframes", "h2")
@@ -36,6 +38,7 @@ def test_iframes_with_context_manager(self):
3638

3739
def test_set_content_to_frame(self):
3840
self.open("https://seleniumbase.io/w3schools/iframes.html")
41+
self.assert_title("iframe Testing")
3942
self.click("button#runbtn")
4043
self.set_content_to_frame("iframeResult")
4144
self.highlight('iframe[title="Iframe Example"]')

examples/raw_parameter_script.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@
5252
sb.user_agent = None
5353
sb.incognito = False
5454
sb.guest_mode = False
55+
sb.dark_mode = False
5556
sb.devtools = False
5657
sb.mobile_emulator = False
5758
sb.device_metrics = None

examples/uc_cdp_events.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
if __name__ == "__main__":
55
from pytest import main
6-
main([__file__, "--uc", "--uc-cdp", "-s"])
6+
main([__file__, "--uc", "--uc-cdp", "--incognito", "-s"])
77

88

99
class CDPTests(BaseCase):
@@ -23,8 +23,10 @@ def fail_me(self):
2323
self.fail('Selenium was detected! Try using: "pytest --uc"')
2424

2525
def test_display_cdp_events(self):
26-
if not (self.undetectable and self.uc_cdp_events):
27-
self.get_new_driver(undetectable=True, uc_cdp_events=True)
26+
if not (self.undetectable and self.uc_cdp_events and self.incognito):
27+
self.get_new_driver(
28+
undetectable=True, uc_cdp_events=True, incognito=True
29+
)
2830
self.open("https://nowsecure.nl/#relax")
2931
try:
3032
self.verify_success()

help_docs/ReadMe.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@
6969
<div><a href="https://seleniumbase.io/examples/tour_examples/ReadMe/"><b>Tour Examples</b></a></div>
7070
<div><a href="https://seleniumbase.io/examples/presenter/ReadMe/"><b>Presentation Maker</b></a></div>
7171
<div><a href="https://seleniumbase.io/examples/chart_maker/ReadMe/"><b>Chart Maker</b></a></div>
72+
<div><a href="https://seleniumbase.io/help_docs/handling_iframes/"><b>Handling iframes</b></a></div>
7273
<div><a href="https://seleniumbase.io/help_docs/mysql_installation/"><b>MySQL Installation Overview</b></a></div>
7374
<div><a href="https://seleniumbase.io/seleniumbase/utilities/selenium_grid/ReadMe/"><b>Using the Selenium Grid</b></a></div>
7475
<div><a href="https://seleniumbase.io/help_docs/desired_capabilities/"><b>Browser Desired Capabilities</b></a></div>
@@ -135,7 +136,8 @@
135136
<div><a href="https://seleniumbase.dev/examples/tour_examples/"><b>Tour Examples</b></a></div>
136137
<div><a href="https://seleniumbase.dev/examples/presenter/"><b>Presentation Maker</b></a></div>
137138
<div><a href="https://seleniumbase.dev/examples/chart_maker/ReadMe/"><b>Chart Maker</b></a></div>
138-
<div><a href="https://seleniumbase.dev/help_docs/mysql_installation"><b>MySQL Installation Overview</b></a></div>
139+
<div><a href="https://seleniumbase.dev/help_docs/mysql_installation"><b>Handling iframes</b></a></div>
140+
<div><a href="https://seleniumbase.dev/help_docs/handling_iframes"><b>MySQL Installation Overview</b></a></div>
139141
<div><a href="https://seleniumbase.dev/seleniumbase/utilities/selenium_grid/"><b>Using the Selenium Grid</b></a></div>
140142
<div><a href="https://seleniumbase.dev/help_docs/desired_capabilities"><b>Browser Desired Capabilities</b></a></div>
141143
<div><a href="https://seleniumbase.dev/help_docs/using_safari_driver"><b>Safari Driver Detailed Info</b></a></div>

help_docs/customizing_test_runs.md

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
pytest my_first_test.py
1212

1313
# Run a test in Firefox
14-
pytest test_swag_labs.py --browser=firefox
14+
pytest test_swag_labs.py --firefox
1515

1616
# Run a test in Demo Mode (highlight assertions)
1717
pytest test_demo_site.py --demo
@@ -22,11 +22,11 @@ pytest test_demo_site.py --headless
2222
# Run tests multi-threaded using [n] threads
2323
pytest test_suite.py -n4
2424

25-
# Reuse the browser session for all tests ("--rs")
26-
pytest test_suite.py --reuse-session
25+
# Reuse the browser session for all tests ("--reuse-session")
26+
pytest test_suite.py --rs
2727

2828
# Reuse the browser session, but erase cookies between tests
29-
pytest test_suite.py --reuse-session --crumbs
29+
pytest test_suite.py --rs --crumbs
3030

3131
# Create a real-time dashboard for test results
3232
pytest test_suite.py --dashboard
@@ -91,7 +91,8 @@ pytest my_first_test.py --settings-file=custom_settings.py
9191
-q # Quiet mode. Print fewer details in the console output when running tests.
9292
-x # Stop running the tests after the first failure is reached.
9393
--html=report.html # Creates a detailed pytest-html report after tests finish.
94-
--collect-only | --co # Show what tests would get run. (Without running them)
94+
--co | --collect-only # Show what tests would get run. (Without running them)
95+
--co -q # (Both options together!) - Do a dry run with full test names shown.
9596
-n=NUM # Multithread the tests using that many threads. (Speed up test runs!)
9697
-s # See print statements. (Should be on by default with pytest.ini present.)
9798
--junit-xml=report.xml # Creates a junit-xml report after tests finish.
@@ -179,6 +180,7 @@ pytest my_first_test.py --settings-file=custom_settings.py
179180
--swiftshader # (Use Chrome's "--use-gl=swiftshader" feature.)
180181
--incognito # (Enable Chrome's Incognito mode.)
181182
--guest # (Enable Chrome's Guest mode.)
183+
--dark # (Enable Chrome's Dark mode.)
182184
--devtools # (Open Chrome's DevTools when the browser opens.)
183185
--rs | --reuse-session # (Reuse browser session for all tests.)
184186
--rcs | --reuse-class-session # (Reuse session for tests in class.)

help_docs/handling_iframes.md

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
<!-- SeleniumBase Docs -->
2+
3+
## [<img src="https://seleniumbase.github.io/img/logo6.png" title="SeleniumBase" width="32">](https://github.com/seleniumbase/SeleniumBase/) How to handle iframes
4+
5+
🖼️ <b>iframes</b> follow the same principle as new windows: You must first switch to the iframe if you want to perform actions in there:
6+
7+
```python
8+
self.switch_to_frame("iframe")
9+
# ... Now perform actions inside the iframe
10+
self.switch_to_parent_frame() # Exit the current iframe
11+
```
12+
13+
To exit from multiple iframes, use ``self.switch_to_default_content()``. (If inside a single iframe, this has the same effect as ``self.switch_to_parent_frame()``.)
14+
15+
```python
16+
self.switch_to_frame('iframe[name="frame1"]')
17+
self.switch_to_frame('iframe[name="frame2"]')
18+
# ... Now perform actions inside the inner iframe
19+
self.switch_to_default_content() # Back to the main page
20+
```
21+
22+
🖼️ You can also use a context manager to act inside iframes:
23+
24+
```python
25+
with self.frame_switch("iframe"):
26+
# ... Now perform actions while inside the code block
27+
# You have left the iframe
28+
```
29+
30+
This also works with nested iframes:
31+
32+
```python
33+
with self.frame_switch('iframe[name="frame1"]'):
34+
with self.frame_switch('iframe[name="frame2"]'):
35+
# ... Now perform actions while inside the code block
36+
# You are now back inside the first iframe
37+
# You have left all the iframes
38+
```
39+
40+
🖼️ In special cases, you may want to set the page to the content of an iframe:
41+
42+
```python
43+
self.set_content_to_frame("iframe")
44+
```
45+
46+
To back out of one call of that, use:
47+
48+
```python
49+
self.set_content_to_parent()
50+
```
51+
52+
To back out of all nested calls of that, use:
53+
54+
```python
55+
self.set_content_to_default()
56+
```
57+
58+
🖼️ See [examples/iframe_tests.py](https://github.com/seleniumbase/SeleniumBase/blob/master/examples/iframe_tests.py) for tests that use all available iframe commands.
59+
60+
--------
61+
62+
<p align="center"><div align="center"><a href="https://seleniumbase.io">
63+
<img src="https://img.shields.io/badge/docs-%20seleniumbase.io-11BBDD.svg" alt="SeleniumBase.io Docs" /></a> <a href="https://github.com/seleniumbase/SeleniumBase"><img src="https://img.shields.io/badge/✅%20💛%20View%20Code-on%20GitHub%20🌎%20🚀-02A79E.svg" alt="SeleniumBase.io Docs" /></a></div></p>

help_docs/webdriver_installation.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ sbase get chromedriver 114
2323
sbase get chromedriver 114.0.5735.90
2424
sbase get chromedriver latest
2525
sbase get chromedriver latest-1
26-
sbase get edgedriver 114.0.1823.82
26+
sbase get edgedriver 115.0.1901.183
2727
```
2828

2929
(NOTE: ``sbase`` is a shortcut for ``seleniumbase``)

mkdocs.yml

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -153,17 +153,18 @@ nav:
153153
- 🔘 W3Schools radio buttons: https://seleniumbase.io/w3schools/radio_buttons
154154
- Additional Help Docs:
155155
- 📑 Table of Contents: help_docs/ReadMe.md
156+
- 🖼️ How to handle iframes: help_docs/handling_iframes.md
156157
- 🔐 Decorators / Security: seleniumbase/common/ReadMe.md
157-
- 🐳 Docker Start Guide: integrations/docker/ReadMe.md
158158
- 🗂️ Case Plans (examples): examples/case_summary.md
159159
- 🧭 Using Safari Driver: help_docs/using_safari_driver.md
160+
- 🐳 Docker Start Guide: integrations/docker/ReadMe.md
160161
- 👤 Shadow DOM Support: help_docs/shadow_dom.md
161162
- 👥 macOS Hidden Files: help_docs/hidden_files_info.md
162163
- 🗄️ MySQL Instructions: help_docs/mysql_installation.md
163164
- 📃 Desired Capabilities: help_docs/desired_capabilities.md
164165
- 📜 Useful grep commands: help_docs/useful_grep_commands.md
165-
- ⚙️ WebDriver Installation: help_docs/webdriver_installation.md
166-
- ✔️ Verifying WebDriver: help_docs/verify_webdriver.md
166+
- ⚙️ Downloading drivers: help_docs/webdriver_installation.md
167+
- ✔️ Verifying drivers: help_docs/verify_webdriver.md
167168
- Behave-BDD Integration:
168169
- 🐝 Behave-BDD ReadMe: examples/behave_bdd/ReadMe.md
169170
- 🐝 Behave-BDD GUI App: help_docs/behave_gui.md

0 commit comments

Comments
 (0)