Skip to content

Commit efd282a

Browse files
authored
Merge pull request #1028 from seleniumbase/refresh-recorder-mode
Refresh Recorder Mode with "codegen" and more
2 parents 2a46f6f + 1ccb89b commit efd282a

File tree

18 files changed

+212
-126
lines changed

18 files changed

+212
-126
lines changed

README.md

Lines changed: 54 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -134,30 +134,31 @@ pip install seleniumbase
134134
* OR: "sbase [COMMAND] [PARAMETERS]"
135135
136136
COMMANDS:
137-
install [DRIVER] [OPTIONS]
138-
methods (List common Python methods)
139-
options (List common pytest options)
140-
mkdir [DIRECTORY] [OPTIONS]
141-
mkfile [FILE.py] [OPTIONS]
142-
mkpres [FILE.py] [LANG]
143-
mkchart [FILE.py] [LANG]
144-
print [FILE] [OPTIONS]
145-
translate [SB_FILE.py] [LANG] [ACTION]
146-
convert [WEBDRIVER_UNITTEST_FILE.py]
147-
extract-objects [SB_FILE.py]
148-
inject-objects [SB_FILE.py] [OPTIONS]
149-
objectify [SB_FILE.py] [OPTIONS]
150-
revert-objects [SB_FILE.py] [OPTIONS]
151-
encrypt (OR: obfuscate)
152-
decrypt (OR: unobfuscate)
153-
download server (The Selenium Grid JAR file)
154-
grid-hub [start|stop] [OPTIONS]
155-
grid-node [start|stop] --hub=[HOST/IP]
156-
* (EXAMPLE: "sbase install chromedriver latest") *
137+
install [DRIVER] [OPTIONS]
138+
methods (List common Python methods)
139+
options (List common pytest options)
140+
mkdir [DIRECTORY] [OPTIONS]
141+
mkfile [FILE.py] [OPTIONS]
142+
mkrec / codegen [FILE.py]
143+
mkpres [FILE.py] [LANG]
144+
mkchart [FILE.py] [LANG]
145+
print [FILE] [OPTIONS]
146+
translate [SB_FILE.py] [LANG] [ACTION]
147+
convert [WEBDRIVER_UNITTEST_FILE.py]
148+
extract-objects [SB_FILE.py]
149+
inject-objects [SB_FILE.py] [OPTIONS]
150+
objectify [SB_FILE.py] [OPTIONS]
151+
revert-objects [SB_FILE.py] [OPTIONS]
152+
encrypt / obfuscate
153+
decrypt / unobfuscate
154+
download server (Get Selenium Grid JAR file)
155+
grid-hub [start|stop] [OPTIONS]
156+
grid-node [start|stop] --hub=[HOST/IP]
157+
* (EXAMPLE: "sbase install chromedriver latest") *
157158
158159
Type "sbase help [COMMAND]" for specific command info.
159160
For info on all commands, type: "seleniumbase --help".
160-
* (Use "pytest" for running tests) *
161+
Use "pytest" for running tests.
161162
```
162163
163164
<h3><img src="https://seleniumbase.io/img/logo6.png" title="SeleniumBase" width="32" /> Download a webdriver:</h3>
@@ -213,26 +214,38 @@ pytest my_first_test.py --demo
213214
* Here are some common ``SeleniumBase`` methods that you might find in tests:
214215
215216
```python
216-
self.open(URL) # Navigate to the web page
217-
self.click(SELECTOR) # Click a page element
218-
self.type(SELECTOR, TEXT) # Type text (Add "\n" to text for pressing enter/return.)
219-
self.assert_element(SELECTOR) # Assert element is visible
220-
self.assert_text(TEXT) # Assert text is visible (has optional SELECTOR arg)
221-
self.assert_title(PAGE_TITLE) # Assert page title
222-
self.assert_no_404_errors() # Assert no 404 errors from files on the page
223-
self.assert_no_js_errors() # Assert no JavaScript errors on the page (Chrome-ONLY)
224-
self.execute_script(JAVASCRIPT) # Execute JavaScript code
225-
self.go_back() # Navigate to the previous URL
226-
self.get_text(SELECTOR) # Get text from a selector
227-
self.get_attribute(SELECTOR, ATTRIBUTE) # Get a specific attribute from a selector
228-
self.is_element_visible(SELECTOR) # Determine if an element is visible on the page
229-
self.is_text_visible(TEXT) # Determine if text is visible on the page (optional SELECTOR)
230-
self.hover_and_click(HOVER_SELECTOR, CLICK_SELECTOR) # Mouseover element & click another
231-
self.select_option_by_text(DROPDOWN_SELECTOR, OPTION_TEXT) # Select a dropdown option
232-
self.switch_to_frame(FRAME_NAME) # Switch webdriver control to an iframe on the page
233-
self.switch_to_default_content() # Switch webdriver control out of the current iframe
234-
self.switch_to_window(WINDOW_NUMBER) # Switch to a different window/tab
235-
self.save_screenshot(FILE_NAME) # Save a screenshot of the current page
217+
self.open(url) # Navigate the browser window to the URL.
218+
self.type(selector, text) # Update the field with the text.
219+
self.click(selector) # Click the element with the selector.
220+
self.click_link(link_text) # Click the link containing text.
221+
self.go_back() # Navigate back to the previous URL.
222+
self.select_option_by_text(dropdown_selector, option)
223+
self.hover_and_click(hover_selector, click_selector)
224+
self.drag_and_drop(drag_selector, drop_selector)
225+
self.get_text(selector) # Get the text from the element.
226+
self.get_current_url() # Get the URL of the current page.
227+
self.get_page_source() # Get the HTML of the current page.
228+
self.get_attribute(selector, attribute) # Get element attribute.
229+
self.get_title() # Get the title of the current page.
230+
self.switch_to_frame(frame) # Switch into the iframe container.
231+
self.switch_to_default_content() # Leave the iframe container.
232+
self.open_new_window() # Open a new window in the same browser.
233+
self.switch_to_window(window) # Switch to the browser window.
234+
self.switch_to_default_window() # Switch to the original window.
235+
self.get_new_driver(OPTIONS) # Open a new driver with OPTIONS.
236+
self.switch_to_driver(driver) # Switch to the browser driver.
237+
self.switch_to_default_driver() # Switch to the original driver.
238+
self.wait_for_element(selector) # Wait until element is visible.
239+
self.is_element_visible(selector) # Return element visibility.
240+
self.is_text_visible(text, selector) # Return text visibility.
241+
self.sleep(seconds) # Do nothing for the given amount of time.
242+
self.save_screenshot(name) # Save a screenshot in .png format.
243+
self.assert_element(selector) # Verify the element is visible.
244+
self.assert_text(text, selector) # Verify text in the element.
245+
self.assert_title(title) # Verify the title of the web page.
246+
self.assert_downloaded_file(file) # Verify file was downloaded.
247+
self.assert_no_404_errors() # Verify there are no broken links.
248+
self.assert_no_js_errors() # Verify there are no JS errors.
236249
```
237250
238251
🔵 For the complete list of SeleniumBase methods, see: <b><a href="https://github.com/seleniumbase/SeleniumBase/blob/master/help_docs/method_summary.md">Method Summary</a></b>
@@ -436,7 +449,6 @@ sbase mkdir ui_tests
436449
437450
```bash
438451
ui_tests/
439-
440452
├── __init__.py
441453
├── my_first_test.py
442454
├── parameterized_test.py
@@ -445,15 +457,13 @@ ui_tests/
445457
├── setup.cfg
446458
├── test_demo_site.py
447459
└── boilerplates/
448-
449460
├── __init__.py
450461
├── base_test_case.py
451462
├── boilerplate_test.py
452463
├── classic_obj_test.py
453464
├── page_objects.py
454465
├── sb_fixture_test.py
455466
└── samples/
456-
457467
├── __init__.py
458468
├── google_objects.py
459469
├── google_test.py

docs/requirements.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
regex>=2021.10.8
1+
regex>=2021.10.21
22
tqdm>=4.62.3
33
livereload==2.6.3;python_version>="3.6"
44
joblib==1.1.0;python_version>="3.6"

help_docs/recorder_mode.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,14 +70,16 @@ class RecorderTest(BaseCase):
7070

7171
<p>🔴 SeleniumBase <code>1.66.12</code> adds the ability to instantly create a new test recording by running <code>sbase mkrec FILE.py</code>. Once the browser spins up, you can open a new web page and start performing actions that will get recorded and saved to the file you specified.</p>
7272

73-
<p>🔴 SeleniumBase <code>1.66.13</code> lets you add assertions for elements and text while making a recording. To add an element assertion, press the <code>[^]-key (SHIFT+6)</code>, (the border will become purple) then click on elements that you'd like to assert. To add a text assertion, press the <code>[&]-key (SHIFT+7)</code>, (the border will become orange) then click on text elements that you'd like to assert. To go back to the regular Record Mode, press any other key. While in the special assertion modes, certain actions such as clicking on links won't have any effect. This lets you make assertions on elements without certain actions getting in the way.</p>
73+
<p>🔴 SeleniumBase <code>1.66.13</code> lets you add assertions for elements and text while making a recording. To add an element assertion, press the <code>{^}-key (SHIFT+6)</code>, (the border will become purple) then click on elements that you'd like to assert. To add a text assertion, press the <code>{&}-key (SHIFT+7)</code>, (the border will become orange) then click on text elements that you'd like to assert. To go back to the regular Record Mode, press any other key. While in the special assertion modes, certain actions such as clicking on links won't have any effect. This lets you make assertions on elements without certain actions getting in the way.</p>
7474

7575
<p>🔴 SeleniumBase <code>1.66.14</code> improves the algorithm for converting recorded assertions into SeleniumBase code. Text assertions that contain the newline character will now be handled correctly. If a text assertion has a <code>:contains</code> selector, then the text assertion will be changed to an element assertion. Asserted text from multi-line assertions will use <code>self.assert_text()</code> on the first non-empty line. Asserted text from single-line assertions will use <code>self.assert_exact_text()</code>. Element assertions will be handled with <code>self.assert_element()</code>.</p>
7676

7777
<p>🔴 SeleniumBase <code>2.0.1</code> adds the ability to preview selectors via the page title when hovering over elements. It also fixes an issue that may occur when opening up new URLs while in Recorder Mode.</p>
7878

7979
<p>🔴 SeleniumBase <code>2.0.2</code> fixes a bug with Recorder Mode that was preventing the last recorded assert on a domain from being saved unless it was followed by a non-assert recorded action on the same domain.</p>
8080

81+
<p>🔴 SeleniumBase <code>2.0.4</code> lets you go back to regular Recorder Mode from Assert Mode by pressing [ESC] once. If you press it again, it will pause the Recorder. (Previously, pressing [ESC] would pause the Recorder right away if using Assert Mode). As before, pressing the <code>{^}-key (SHIFT+6)</code> will switch the Recorder into Assert Element Mode and pressing the <code>{&}-key (SHIFT+7)</code> will switch the Recorder into Assert Text Mode. You can switch back to regular Recorder Mode from Assert Mode by pressing any key other than [SHIFT] and [BACKSPACE]. Also, <code>--codegen</code> can be used in place of <code>--recorder</code> for Recorder initialization, and <code>sbase codegen [FILE.py]</code> can be used in place of <code>sbase mkrec [FILE.py]</code>, which calls attention to the code-generation abilities of the Recorder.</p>
82+
8183
--------
8284

8385
<div>To learn more about SeleniumBase, check out the Docs Site:</div>

help_docs/verify_webdriver.md

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,36 @@
11
## Verifying that web drivers are installed
22

3-
*You can do this by checking inside a Python command prompt.*
3+
On newer versions of SeleniumBase, the driver is automatically downloaded to the ``seleniumbase/drivers`` folder, and does not need to be on the System Path when running tests.
4+
5+
Drivers can be manually downloaded with commands such as:
6+
7+
```bash
8+
sbase install chromedriver
9+
sbase install chromedriver latest
10+
sbase install geckodriver
11+
sbase install edgedriver
12+
```
13+
14+
--------
15+
16+
If you want to check that you have the correct driver installed on your System PATH (which is no longer necessary unless using the Selenium Grid), then continue reading below:
17+
18+
*This assumes you've already downloaded a driver to your **System PATH** with a command such as:*
19+
20+
```bash
21+
sbase install chromedriver --path
22+
```
23+
24+
(The above ``--path`` addition is for Linux/Mac only, which uses ``/usr/local/bin/``. The "Path" is different on Windows, and you'll need to manually copy the driver to your System Path, which is defined in the Control Panel's System Environment Variables.)
25+
26+
*You can verify that the correct drivers exist on your System Path by checking inside a Python command prompt.*
427

528
#### Verifying ChromeDriver
29+
630
```bash
731
python
832
```
33+
934
```python
1035
>>> from selenium import webdriver
1136
>>> driver = webdriver.Chrome()
@@ -15,9 +40,11 @@ python
1540
```
1641

1742
#### Verifying Geckodriver (Firefox WebDriver)
43+
1844
```bash
1945
python
2046
```
47+
2148
```python
2249
>>> from selenium import webdriver
2350
>>> driver = webdriver.Firefox()
@@ -27,9 +54,11 @@ python
2754
```
2855

2956
#### Verifying WebDriver for Safari
57+
3058
```bash
3159
python
3260
```
61+
3362
```python
3463
>>> from selenium import webdriver
3564
>>> driver = webdriver.Safari()

help_docs/webdriver_installation.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,13 @@ sbase install chromedriver 88.0.4324.96
2626
sbase install chromedriver 88
2727
```
2828

29+
* You can run the following two commands on Mac/Linux (once you've installed SeleniumBase) to automatically upgrade your Chromedriver to match your version of Chrome: (``wget`` downloads the file, and ``pytest`` runs it.)
30+
31+
```bash
32+
wget https://raw.githubusercontent.com/seleniumbase/SeleniumBase/master/examples/upgrade_chromedriver.py
33+
pytest upgrade_chromedriver.py -s
34+
```
35+
2936
If you plan on using the [Selenium Grid integration](https://github.com/seleniumbase/SeleniumBase/blob/master/seleniumbase/utilities/selenium_grid/ReadMe.md) (which allows for remote webdriver), you'll need to put the drivers on your System PATH. On macOS and Linux, ``/usr/local/bin`` is a good PATH spot. On Windows, you may need to set the System PATH under Environment Variables to include the location where you placed the driver files. As a shortcut, you could place the driver files into your Python ``Scripts/`` folder in the location where you have Python installed, which should already be on your System PATH.
3037

3138
Here's where you can go to manually install web drivers from the source:

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__ = "2.0.3"
2+
__version__ = "2.0.4"

seleniumbase/common/decorators.py

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
1-
import inspect
21
import logging
32
import math
43
import sys
5-
import threading
64
import time
75
import warnings
86
from functools import wraps
@@ -55,6 +53,8 @@ def rate_limited(max_per_second):
5553
If the limit is exceeded, the call will be held in a queue until
5654
enough time has passed.
5755
Useful when trying to avoid overloading a system with rapid calls."""
56+
import threading
57+
5858
min_interval = 1.0 / float(max_per_second)
5959

6060
def decorate(func):
@@ -88,23 +88,24 @@ def rate_limited_function(*args, **kargs):
8888
def deprecated(message=None):
8989
"""This decorator marks methods as deprecated.
9090
A warning is displayed if the method is called."""
91+
import inspect
9192

9293
def decorated_method_to_deprecate(func):
9394
if inspect.isclass(func):
9495
# Handle a deprecated class differently from a deprecated method
95-
msg = "Class {}() is DEPRECATED! *** ".format(func.__name__)
96+
msg = "Class {}() is DEPRECATED!".format(func.__name__)
9697
if message:
97-
msg += "<> %s <>" % message
98+
msg += " *** %s ***" % message
9899
warnings.simplefilter("always", DeprecationWarning) # See Warnings
99100
warnings.warn(msg, category=DeprecationWarning, stacklevel=2)
100101
warnings.simplefilter("default", DeprecationWarning) # Set Default
101102
return func
102103

103104
@wraps(func)
104105
def new_func(*args, **kwargs):
105-
msg = "Method {}() is DEPRECATED! *** ".format(func.__name__)
106+
msg = "Method {}() is DEPRECATED!".format(func.__name__)
106107
if message:
107-
msg += "<> %s <>" % message
108+
msg += " *** %s ***" % message
108109
warnings.simplefilter("always", DeprecationWarning) # See Warnings
109110
warnings.warn(msg, category=DeprecationWarning, stacklevel=2)
110111
warnings.simplefilter("default", DeprecationWarning) # Set Default

seleniumbase/console_scripts/ReadMe.md

Lines changed: 25 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -14,26 +14,26 @@ SeleniumBase console scripts help you get things done more easily, such as insta
1414

1515
```
1616
COMMANDS:
17-
install [DRIVER] [OPTIONS]
18-
methods (List common Python methods)
19-
options (List common pytest options)
20-
mkdir [DIRECTORY] [OPTIONS]
21-
mkfile [FILE.py] [OPTIONS]
22-
mkrec [FILE.py]
23-
mkpres [FILE.py] [LANG]
24-
mkchart [FILE.py] [LANG]
25-
print [FILE] [OPTIONS]
26-
translate [SB_FILE.py] [LANG] [ACTION]
27-
convert [WEBDRIVER_UNITTEST_FILE.py]
28-
extract-objects [SB_FILE.py]
29-
inject-objects [SB_FILE.py] [OPTIONS]
30-
objectify [SB_FILE.py] [OPTIONS]
31-
revert-objects [SB_FILE.py] [OPTIONS]
32-
encrypt (OR: obfuscate)
33-
decrypt (OR: unobfuscate)
34-
download server (The Selenium Grid JAR file)
35-
grid-hub [start|stop] [OPTIONS]
36-
grid-node [start|stop] --hub=[HOST/IP]
17+
install [DRIVER] [OPTIONS]
18+
methods (List common Python methods)
19+
options (List common pytest options)
20+
mkdir [DIRECTORY] [OPTIONS]
21+
mkfile [FILE.py] [OPTIONS]
22+
mkrec / codegen [FILE.py]
23+
mkpres [FILE.py] [LANG]
24+
mkchart [FILE.py] [LANG]
25+
print [FILE] [OPTIONS]
26+
translate [SB_FILE.py] [LANG] [ACTION]
27+
convert [WEBDRIVER_UNITTEST_FILE.py]
28+
extract-objects [SB_FILE.py]
29+
inject-objects [SB_FILE.py] [OPTIONS]
30+
objectify [SB_FILE.py] [OPTIONS]
31+
revert-objects [SB_FILE.py] [OPTIONS]
32+
encrypt / obfuscate
33+
decrypt / unobfuscate
34+
download server (Get Selenium Grid JAR file)
35+
grid-hub [start|stop] [OPTIONS]
36+
grid-node [start|stop] --hub=[HOST/IP]
3737
* (EXAMPLE: "sbase install chromedriver latest") *
3838
3939
Type "sbase help [COMMAND]" for specific command info.
@@ -203,7 +203,7 @@ ui_tests/
203203

204204
* Options:
205205
``-b`` / ``--basic`` (Basic boilerplate / single-line test)
206-
``-r`` / ``--recorder`` (Recorder Mode has ipdb breakpoint)
206+
``-r`` / ``--rec`` (adds ipdb breakpoint for Recorder Mode)
207207

208208
* Language Options:
209209
``--en`` / ``--English`` | ``--zh`` / ``--Chinese``
@@ -222,13 +222,15 @@ methods, which are "open", "type", "click",
222222
basic boilerplate option, only the "open" method
223223
is included.
224224

225-
<h3>mkrec</h3>
225+
<h3>mkrec / codegen</h3>
226226

227227
* Usage:
228228
``sbase mkrec [FILE.py]``
229+
``sbase codegen [FILE.py]``
229230

230-
* Example:
231+
* Examples:
231232
``sbase mkrec new_test.py``
233+
``sbase codegen new_test.py``
232234

233235
* Output:
234236
Creates a new SeleniumBase test using the Recorder.

0 commit comments

Comments
 (0)