Merge pull request #1028 from seleniumbase/refresh-recorder-mode
Refresh Recorder Mode with "codegen" and more
This commit is contained in:
commit
efd282a860
98
README.md
98
README.md
|
@ -134,30 +134,31 @@ pip install seleniumbase
|
|||
* OR: "sbase [COMMAND] [PARAMETERS]"
|
||||
|
||||
COMMANDS:
|
||||
install [DRIVER] [OPTIONS]
|
||||
methods (List common Python methods)
|
||||
options (List common pytest options)
|
||||
mkdir [DIRECTORY] [OPTIONS]
|
||||
mkfile [FILE.py] [OPTIONS]
|
||||
mkpres [FILE.py] [LANG]
|
||||
mkchart [FILE.py] [LANG]
|
||||
print [FILE] [OPTIONS]
|
||||
translate [SB_FILE.py] [LANG] [ACTION]
|
||||
convert [WEBDRIVER_UNITTEST_FILE.py]
|
||||
extract-objects [SB_FILE.py]
|
||||
inject-objects [SB_FILE.py] [OPTIONS]
|
||||
objectify [SB_FILE.py] [OPTIONS]
|
||||
revert-objects [SB_FILE.py] [OPTIONS]
|
||||
encrypt (OR: obfuscate)
|
||||
decrypt (OR: unobfuscate)
|
||||
download server (The Selenium Grid JAR file)
|
||||
grid-hub [start|stop] [OPTIONS]
|
||||
grid-node [start|stop] --hub=[HOST/IP]
|
||||
* (EXAMPLE: "sbase install chromedriver latest") *
|
||||
install [DRIVER] [OPTIONS]
|
||||
methods (List common Python methods)
|
||||
options (List common pytest options)
|
||||
mkdir [DIRECTORY] [OPTIONS]
|
||||
mkfile [FILE.py] [OPTIONS]
|
||||
mkrec / codegen [FILE.py]
|
||||
mkpres [FILE.py] [LANG]
|
||||
mkchart [FILE.py] [LANG]
|
||||
print [FILE] [OPTIONS]
|
||||
translate [SB_FILE.py] [LANG] [ACTION]
|
||||
convert [WEBDRIVER_UNITTEST_FILE.py]
|
||||
extract-objects [SB_FILE.py]
|
||||
inject-objects [SB_FILE.py] [OPTIONS]
|
||||
objectify [SB_FILE.py] [OPTIONS]
|
||||
revert-objects [SB_FILE.py] [OPTIONS]
|
||||
encrypt / obfuscate
|
||||
decrypt / unobfuscate
|
||||
download server (Get Selenium Grid JAR file)
|
||||
grid-hub [start|stop] [OPTIONS]
|
||||
grid-node [start|stop] --hub=[HOST/IP]
|
||||
* (EXAMPLE: "sbase install chromedriver latest") *
|
||||
|
||||
Type "sbase help [COMMAND]" for specific command info.
|
||||
For info on all commands, type: "seleniumbase --help".
|
||||
* (Use "pytest" for running tests) *
|
||||
Use "pytest" for running tests.
|
||||
```
|
||||
|
||||
<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
|
|||
* Here are some common ``SeleniumBase`` methods that you might find in tests:
|
||||
|
||||
```python
|
||||
self.open(URL) # Navigate to the web page
|
||||
self.click(SELECTOR) # Click a page element
|
||||
self.type(SELECTOR, TEXT) # Type text (Add "\n" to text for pressing enter/return.)
|
||||
self.assert_element(SELECTOR) # Assert element is visible
|
||||
self.assert_text(TEXT) # Assert text is visible (has optional SELECTOR arg)
|
||||
self.assert_title(PAGE_TITLE) # Assert page title
|
||||
self.assert_no_404_errors() # Assert no 404 errors from files on the page
|
||||
self.assert_no_js_errors() # Assert no JavaScript errors on the page (Chrome-ONLY)
|
||||
self.execute_script(JAVASCRIPT) # Execute JavaScript code
|
||||
self.go_back() # Navigate to the previous URL
|
||||
self.get_text(SELECTOR) # Get text from a selector
|
||||
self.get_attribute(SELECTOR, ATTRIBUTE) # Get a specific attribute from a selector
|
||||
self.is_element_visible(SELECTOR) # Determine if an element is visible on the page
|
||||
self.is_text_visible(TEXT) # Determine if text is visible on the page (optional SELECTOR)
|
||||
self.hover_and_click(HOVER_SELECTOR, CLICK_SELECTOR) # Mouseover element & click another
|
||||
self.select_option_by_text(DROPDOWN_SELECTOR, OPTION_TEXT) # Select a dropdown option
|
||||
self.switch_to_frame(FRAME_NAME) # Switch webdriver control to an iframe on the page
|
||||
self.switch_to_default_content() # Switch webdriver control out of the current iframe
|
||||
self.switch_to_window(WINDOW_NUMBER) # Switch to a different window/tab
|
||||
self.save_screenshot(FILE_NAME) # Save a screenshot of the current page
|
||||
self.open(url) # Navigate the browser window to the URL.
|
||||
self.type(selector, text) # Update the field with the text.
|
||||
self.click(selector) # Click the element with the selector.
|
||||
self.click_link(link_text) # Click the link containing text.
|
||||
self.go_back() # Navigate back to the previous URL.
|
||||
self.select_option_by_text(dropdown_selector, option)
|
||||
self.hover_and_click(hover_selector, click_selector)
|
||||
self.drag_and_drop(drag_selector, drop_selector)
|
||||
self.get_text(selector) # Get the text from the element.
|
||||
self.get_current_url() # Get the URL of the current page.
|
||||
self.get_page_source() # Get the HTML of the current page.
|
||||
self.get_attribute(selector, attribute) # Get element attribute.
|
||||
self.get_title() # Get the title of the current page.
|
||||
self.switch_to_frame(frame) # Switch into the iframe container.
|
||||
self.switch_to_default_content() # Leave the iframe container.
|
||||
self.open_new_window() # Open a new window in the same browser.
|
||||
self.switch_to_window(window) # Switch to the browser window.
|
||||
self.switch_to_default_window() # Switch to the original window.
|
||||
self.get_new_driver(OPTIONS) # Open a new driver with OPTIONS.
|
||||
self.switch_to_driver(driver) # Switch to the browser driver.
|
||||
self.switch_to_default_driver() # Switch to the original driver.
|
||||
self.wait_for_element(selector) # Wait until element is visible.
|
||||
self.is_element_visible(selector) # Return element visibility.
|
||||
self.is_text_visible(text, selector) # Return text visibility.
|
||||
self.sleep(seconds) # Do nothing for the given amount of time.
|
||||
self.save_screenshot(name) # Save a screenshot in .png format.
|
||||
self.assert_element(selector) # Verify the element is visible.
|
||||
self.assert_text(text, selector) # Verify text in the element.
|
||||
self.assert_title(title) # Verify the title of the web page.
|
||||
self.assert_downloaded_file(file) # Verify file was downloaded.
|
||||
self.assert_no_404_errors() # Verify there are no broken links.
|
||||
self.assert_no_js_errors() # Verify there are no JS errors.
|
||||
```
|
||||
|
||||
🔵 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
|
|||
|
||||
```bash
|
||||
ui_tests/
|
||||
│
|
||||
├── __init__.py
|
||||
├── my_first_test.py
|
||||
├── parameterized_test.py
|
||||
|
@ -445,7 +457,6 @@ ui_tests/
|
|||
├── setup.cfg
|
||||
├── test_demo_site.py
|
||||
└── boilerplates/
|
||||
│
|
||||
├── __init__.py
|
||||
├── base_test_case.py
|
||||
├── boilerplate_test.py
|
||||
|
@ -453,7 +464,6 @@ ui_tests/
|
|||
├── page_objects.py
|
||||
├── sb_fixture_test.py
|
||||
└── samples/
|
||||
│
|
||||
├── __init__.py
|
||||
├── google_objects.py
|
||||
├── google_test.py
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
regex>=2021.10.8
|
||||
regex>=2021.10.21
|
||||
tqdm>=4.62.3
|
||||
livereload==2.6.3;python_version>="3.6"
|
||||
joblib==1.1.0;python_version>="3.6"
|
||||
|
|
|
@ -70,7 +70,7 @@ class RecorderTest(BaseCase):
|
|||
|
||||
<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>
|
||||
|
||||
<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>
|
||||
<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>
|
||||
|
||||
<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>
|
||||
|
||||
|
@ -78,6 +78,8 @@ class RecorderTest(BaseCase):
|
|||
|
||||
<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>
|
||||
|
||||
<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>
|
||||
|
||||
--------
|
||||
|
||||
<div>To learn more about SeleniumBase, check out the Docs Site:</div>
|
||||
|
|
|
@ -1,11 +1,36 @@
|
|||
## Verifying that web drivers are installed
|
||||
|
||||
*You can do this by checking inside a Python command prompt.*
|
||||
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.
|
||||
|
||||
Drivers can be manually downloaded with commands such as:
|
||||
|
||||
```bash
|
||||
sbase install chromedriver
|
||||
sbase install chromedriver latest
|
||||
sbase install geckodriver
|
||||
sbase install edgedriver
|
||||
```
|
||||
|
||||
--------
|
||||
|
||||
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:
|
||||
|
||||
*This assumes you've already downloaded a driver to your **System PATH** with a command such as:*
|
||||
|
||||
```bash
|
||||
sbase install chromedriver --path
|
||||
```
|
||||
|
||||
(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.)
|
||||
|
||||
*You can verify that the correct drivers exist on your System Path by checking inside a Python command prompt.*
|
||||
|
||||
#### Verifying ChromeDriver
|
||||
|
||||
```bash
|
||||
python
|
||||
```
|
||||
|
||||
```python
|
||||
>>> from selenium import webdriver
|
||||
>>> driver = webdriver.Chrome()
|
||||
|
@ -15,9 +40,11 @@ python
|
|||
```
|
||||
|
||||
#### Verifying Geckodriver (Firefox WebDriver)
|
||||
|
||||
```bash
|
||||
python
|
||||
```
|
||||
|
||||
```python
|
||||
>>> from selenium import webdriver
|
||||
>>> driver = webdriver.Firefox()
|
||||
|
@ -27,9 +54,11 @@ python
|
|||
```
|
||||
|
||||
#### Verifying WebDriver for Safari
|
||||
|
||||
```bash
|
||||
python
|
||||
```
|
||||
|
||||
```python
|
||||
>>> from selenium import webdriver
|
||||
>>> driver = webdriver.Safari()
|
||||
|
|
|
@ -26,6 +26,13 @@ sbase install chromedriver 88.0.4324.96
|
|||
sbase install chromedriver 88
|
||||
```
|
||||
|
||||
* 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.)
|
||||
|
||||
```bash
|
||||
wget https://raw.githubusercontent.com/seleniumbase/SeleniumBase/master/examples/upgrade_chromedriver.py
|
||||
pytest upgrade_chromedriver.py -s
|
||||
```
|
||||
|
||||
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.
|
||||
|
||||
Here's where you can go to manually install web drivers from the source:
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
# seleniumbase package
|
||||
__version__ = "2.0.3"
|
||||
__version__ = "2.0.4"
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
import inspect
|
||||
import logging
|
||||
import math
|
||||
import sys
|
||||
import threading
|
||||
import time
|
||||
import warnings
|
||||
from functools import wraps
|
||||
|
@ -55,6 +53,8 @@ def rate_limited(max_per_second):
|
|||
If the limit is exceeded, the call will be held in a queue until
|
||||
enough time has passed.
|
||||
Useful when trying to avoid overloading a system with rapid calls."""
|
||||
import threading
|
||||
|
||||
min_interval = 1.0 / float(max_per_second)
|
||||
|
||||
def decorate(func):
|
||||
|
@ -88,13 +88,14 @@ def rate_limited(max_per_second):
|
|||
def deprecated(message=None):
|
||||
"""This decorator marks methods as deprecated.
|
||||
A warning is displayed if the method is called."""
|
||||
import inspect
|
||||
|
||||
def decorated_method_to_deprecate(func):
|
||||
if inspect.isclass(func):
|
||||
# Handle a deprecated class differently from a deprecated method
|
||||
msg = "Class {}() is DEPRECATED! *** ".format(func.__name__)
|
||||
msg = "Class {}() is DEPRECATED!".format(func.__name__)
|
||||
if message:
|
||||
msg += "<> %s <>" % message
|
||||
msg += " *** %s ***" % message
|
||||
warnings.simplefilter("always", DeprecationWarning) # See Warnings
|
||||
warnings.warn(msg, category=DeprecationWarning, stacklevel=2)
|
||||
warnings.simplefilter("default", DeprecationWarning) # Set Default
|
||||
|
@ -102,9 +103,9 @@ def deprecated(message=None):
|
|||
|
||||
@wraps(func)
|
||||
def new_func(*args, **kwargs):
|
||||
msg = "Method {}() is DEPRECATED! *** ".format(func.__name__)
|
||||
msg = "Method {}() is DEPRECATED!".format(func.__name__)
|
||||
if message:
|
||||
msg += "<> %s <>" % message
|
||||
msg += " *** %s ***" % message
|
||||
warnings.simplefilter("always", DeprecationWarning) # See Warnings
|
||||
warnings.warn(msg, category=DeprecationWarning, stacklevel=2)
|
||||
warnings.simplefilter("default", DeprecationWarning) # Set Default
|
||||
|
|
|
@ -14,26 +14,26 @@ SeleniumBase console scripts help you get things done more easily, such as insta
|
|||
|
||||
```
|
||||
COMMANDS:
|
||||
install [DRIVER] [OPTIONS]
|
||||
methods (List common Python methods)
|
||||
options (List common pytest options)
|
||||
mkdir [DIRECTORY] [OPTIONS]
|
||||
mkfile [FILE.py] [OPTIONS]
|
||||
mkrec [FILE.py]
|
||||
mkpres [FILE.py] [LANG]
|
||||
mkchart [FILE.py] [LANG]
|
||||
print [FILE] [OPTIONS]
|
||||
translate [SB_FILE.py] [LANG] [ACTION]
|
||||
convert [WEBDRIVER_UNITTEST_FILE.py]
|
||||
extract-objects [SB_FILE.py]
|
||||
inject-objects [SB_FILE.py] [OPTIONS]
|
||||
objectify [SB_FILE.py] [OPTIONS]
|
||||
revert-objects [SB_FILE.py] [OPTIONS]
|
||||
encrypt (OR: obfuscate)
|
||||
decrypt (OR: unobfuscate)
|
||||
download server (The Selenium Grid JAR file)
|
||||
grid-hub [start|stop] [OPTIONS]
|
||||
grid-node [start|stop] --hub=[HOST/IP]
|
||||
install [DRIVER] [OPTIONS]
|
||||
methods (List common Python methods)
|
||||
options (List common pytest options)
|
||||
mkdir [DIRECTORY] [OPTIONS]
|
||||
mkfile [FILE.py] [OPTIONS]
|
||||
mkrec / codegen [FILE.py]
|
||||
mkpres [FILE.py] [LANG]
|
||||
mkchart [FILE.py] [LANG]
|
||||
print [FILE] [OPTIONS]
|
||||
translate [SB_FILE.py] [LANG] [ACTION]
|
||||
convert [WEBDRIVER_UNITTEST_FILE.py]
|
||||
extract-objects [SB_FILE.py]
|
||||
inject-objects [SB_FILE.py] [OPTIONS]
|
||||
objectify [SB_FILE.py] [OPTIONS]
|
||||
revert-objects [SB_FILE.py] [OPTIONS]
|
||||
encrypt / obfuscate
|
||||
decrypt / unobfuscate
|
||||
download server (Get Selenium Grid JAR file)
|
||||
grid-hub [start|stop] [OPTIONS]
|
||||
grid-node [start|stop] --hub=[HOST/IP]
|
||||
* (EXAMPLE: "sbase install chromedriver latest") *
|
||||
|
||||
Type "sbase help [COMMAND]" for specific command info.
|
||||
|
@ -203,7 +203,7 @@ ui_tests/
|
|||
|
||||
* Options:
|
||||
``-b`` / ``--basic`` (Basic boilerplate / single-line test)
|
||||
``-r`` / ``--recorder`` (Recorder Mode has ipdb breakpoint)
|
||||
``-r`` / ``--rec`` (adds ipdb breakpoint for Recorder Mode)
|
||||
|
||||
* Language Options:
|
||||
``--en`` / ``--English`` | ``--zh`` / ``--Chinese``
|
||||
|
@ -222,13 +222,15 @@ methods, which are "open", "type", "click",
|
|||
basic boilerplate option, only the "open" method
|
||||
is included.
|
||||
|
||||
<h3>mkrec</h3>
|
||||
<h3>mkrec / codegen</h3>
|
||||
|
||||
* Usage:
|
||||
``sbase mkrec [FILE.py]``
|
||||
``sbase codegen [FILE.py]``
|
||||
|
||||
* Example:
|
||||
* Examples:
|
||||
``sbase mkrec new_test.py``
|
||||
``sbase codegen new_test.py``
|
||||
|
||||
* Output:
|
||||
Creates a new SeleniumBase test using the Recorder.
|
||||
|
|
|
@ -11,7 +11,7 @@ sbase methods
|
|||
sbase options
|
||||
sbase mkdir ui_tests
|
||||
sbase mkfile new_test.py
|
||||
sbase mkrec new_test.py
|
||||
sbase mkrec new_test.py # Same as "sbase codegen new_test.py"
|
||||
sbase mkpres new_presentation.py
|
||||
sbase mkchart new_chart.py
|
||||
sbase convert webdriver_unittest_file.py
|
||||
|
@ -70,26 +70,26 @@ def show_basic_usage():
|
|||
sc += ' * OR: "sbase [COMMAND] [PARAMETERS]"\n'
|
||||
sc += "\n"
|
||||
sc += "COMMANDS:\n"
|
||||
sc += " install [DRIVER] [OPTIONS]\n"
|
||||
sc += " methods (List common Python methods)\n"
|
||||
sc += " options (List common pytest options)\n"
|
||||
sc += " mkdir [DIRECTORY] [OPTIONS]\n"
|
||||
sc += " mkfile [FILE.py] [OPTIONS]\n"
|
||||
sc += " mkrec [FILE.py]\n"
|
||||
sc += " mkpres [FILE.py] [LANG]\n"
|
||||
sc += " mkchart [FILE.py] [LANG]\n"
|
||||
sc += " print [FILE] [OPTIONS]\n"
|
||||
sc += " translate [SB_FILE.py] [LANG] [ACTION]\n"
|
||||
sc += " convert [WEBDRIVER_UNITTEST_FILE.py]\n"
|
||||
sc += " extract-objects [SB_FILE.py]\n"
|
||||
sc += " inject-objects [SB_FILE.py] [OPTIONS]\n"
|
||||
sc += " objectify [SB_FILE.py] [OPTIONS]\n"
|
||||
sc += " revert-objects [SB_FILE.py] [OPTIONS]\n"
|
||||
sc += " encrypt (OR: obfuscate)\n"
|
||||
sc += " decrypt (OR: unobfuscate)\n"
|
||||
sc += " download server (The Selenium Grid JAR file)\n"
|
||||
sc += " grid-hub [start|stop] [OPTIONS]\n"
|
||||
sc += " grid-node [start|stop] --hub=[HOST/IP]\n"
|
||||
sc += " install [DRIVER] [OPTIONS]\n"
|
||||
sc += " methods (List common Python methods)\n"
|
||||
sc += " options (List common pytest options)\n"
|
||||
sc += " mkdir [DIRECTORY] [OPTIONS]\n"
|
||||
sc += " mkfile [FILE.py] [OPTIONS]\n"
|
||||
sc += " mkrec / codegen [FILE.py]\n"
|
||||
sc += " mkpres [FILE.py] [LANG]\n"
|
||||
sc += " mkchart [FILE.py] [LANG]\n"
|
||||
sc += " print [FILE] [OPTIONS]\n"
|
||||
sc += " translate [SB_FILE.py] [LANG] [ACTION]\n"
|
||||
sc += " convert [WEBDRIVER_UNITTEST_FILE.py]\n"
|
||||
sc += " extract-objects [SB_FILE.py]\n"
|
||||
sc += " inject-objects [SB_FILE.py] [OPTIONS]\n"
|
||||
sc += " objectify [SB_FILE.py] [OPTIONS]\n"
|
||||
sc += " revert-objects [SB_FILE.py] [OPTIONS]\n"
|
||||
sc += " encrypt / obfuscate\n"
|
||||
sc += " decrypt / unobfuscate\n"
|
||||
sc += " download server (Get Selenium Grid JAR file)\n"
|
||||
sc += " grid-hub [start|stop] [OPTIONS]\n"
|
||||
sc += " grid-node [start|stop] --hub=[HOST/IP]\n"
|
||||
sc += ' * (EXAMPLE: "sbase install chromedriver latest") *\n'
|
||||
sc += ""
|
||||
if "linux" not in sys.platform:
|
||||
|
@ -176,7 +176,7 @@ def show_mkfile_usage():
|
|||
print(" sbase mkfile new_test.py")
|
||||
print(" Options:")
|
||||
print(" -b / --basic (Basic boilerplate / single-line test)")
|
||||
print(" -r / --recorder (Recorder Mode has ipdb breakpoint)")
|
||||
print(" -r / --rec (adds ipdb breakpoint for Recorder Mode)")
|
||||
print(" Language Options:")
|
||||
print(" --en / --English | --zh / --Chinese")
|
||||
print(" --nl / --Dutch | --fr / --French")
|
||||
|
@ -213,6 +213,24 @@ def show_mkrec_usage():
|
|||
print("")
|
||||
|
||||
|
||||
def show_codegen_usage():
|
||||
c2 = colorama.Fore.BLUE + colorama.Back.LIGHTGREEN_EX
|
||||
c3 = colorama.Fore.BLUE + colorama.Back.LIGHTYELLOW_EX
|
||||
cr = colorama.Style.RESET_ALL
|
||||
sc = " " + c2 + "** " + c3 + "codegen" + c2 + " **" + cr
|
||||
print(sc)
|
||||
print("")
|
||||
print(" Usage:")
|
||||
print(" seleniumbase codegen [FILE.py]")
|
||||
print(" OR: sbase codegen [FILE.py]")
|
||||
print(" Example:")
|
||||
print(" sbase codegen new_test.py")
|
||||
print(" Output:")
|
||||
print(" Creates a new SeleniumBase test using the Recorder.")
|
||||
print(" If the filename already exists, an error is raised.")
|
||||
print("")
|
||||
|
||||
|
||||
def show_mkpres_usage():
|
||||
c2 = colorama.Fore.BLUE + colorama.Back.LIGHTGREEN_EX
|
||||
c3 = colorama.Fore.BLUE + colorama.Back.LIGHTYELLOW_EX
|
||||
|
@ -701,6 +719,7 @@ def show_detailed_help():
|
|||
show_mkdir_usage()
|
||||
show_mkfile_usage()
|
||||
show_mkrec_usage()
|
||||
show_codegen_usage()
|
||||
show_mkpres_usage()
|
||||
show_mkchart_usage()
|
||||
show_convert_usage()
|
||||
|
@ -765,6 +784,14 @@ def main():
|
|||
else:
|
||||
show_basic_usage()
|
||||
show_mkrec_usage()
|
||||
elif command == "codegen":
|
||||
if len(command_args) >= 1:
|
||||
from seleniumbase.console_scripts import sb_mkrec
|
||||
|
||||
sb_mkrec.main()
|
||||
else:
|
||||
show_basic_usage()
|
||||
show_codegen_usage()
|
||||
elif command == "mkpres":
|
||||
if len(command_args) >= 1:
|
||||
from seleniumbase.console_scripts import sb_mkpres
|
||||
|
@ -920,6 +947,10 @@ def main():
|
|||
print("")
|
||||
show_mkrec_usage()
|
||||
return
|
||||
elif command_args[0] == "codegen":
|
||||
print("")
|
||||
show_codegen_usage()
|
||||
return
|
||||
elif command_args[0] == "mkpres":
|
||||
print("")
|
||||
show_mkpres_usage()
|
||||
|
|
|
@ -11,7 +11,7 @@ Example:
|
|||
|
||||
Options:
|
||||
-b / --basic (Basic boilerplate / single-line test)
|
||||
-r / --recorder (Recorder Mode has ipdb breakpoint)
|
||||
-r / --rec (adds ipdb breakpoint for Recorder Mode)
|
||||
|
||||
Language Options:
|
||||
--en / --English | --zh / --Chinese
|
||||
|
@ -46,7 +46,7 @@ def invalid_run_command(msg=None):
|
|||
exp += " sbase mkfile new_test.py\n"
|
||||
exp += " Options:\n"
|
||||
exp += " -b / --basic (Basic boilerplate / single-line test)\n"
|
||||
exp += " -r / --recorder (Recorder Mode has ipdb breakpoint)\n"
|
||||
exp += " -r / --rec (adds ipdb breakpoint for Recorder Mode)\n"
|
||||
exp += " Language Options:\n"
|
||||
exp += " --en / --English | --zh / --Chinese\n"
|
||||
exp += " --nl / --Dutch | --fr / --French\n"
|
||||
|
|
|
@ -3,11 +3,14 @@
|
|||
Creates a new SeleniumBase test file using the Recorder.
|
||||
|
||||
Usage:
|
||||
seleniumbase mkrec [FILE.py]
|
||||
or sbase mkrec [FILE.py]
|
||||
seleniumbase mkrec [FILE.py]
|
||||
sbase mkrec [FILE.py]
|
||||
seleniumbase codegen [FILE.py]
|
||||
sbase codegen [FILE.py]
|
||||
|
||||
Example:
|
||||
Examples:
|
||||
sbase mkrec new_test.py
|
||||
sbase codegen new_test.py
|
||||
|
||||
Output:
|
||||
Creates a new SeleniumBase test using the Recorder.
|
||||
|
@ -22,12 +25,15 @@ import sys
|
|||
|
||||
|
||||
def invalid_run_command(msg=None):
|
||||
exp = " ** mkrec **\n\n"
|
||||
exp = " ** mkrec / codegen **\n\n"
|
||||
exp += " Usage:\n"
|
||||
exp += " seleniumbase mkrec [FILE.py]\n"
|
||||
exp += " OR sbase mkrec [FILE.py]\n"
|
||||
exp += " Example:\n"
|
||||
exp += " sbase mkrec [FILE.py]\n"
|
||||
exp += " seleniumbase codegen [FILE.py]\n"
|
||||
exp += " sbase codegen [FILE.py]\n"
|
||||
exp += " Examples:\n"
|
||||
exp += " sbase mkrec new_test.py\n"
|
||||
exp += " sbase codegen new_test.py\n"
|
||||
exp += " Output:\n"
|
||||
exp += " Creates a new SeleniumBase test using the Recorder.\n"
|
||||
exp += " If the filename already exists, an error is raised.\n"
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
import os
|
||||
import threading
|
||||
import zipfile
|
||||
from seleniumbase.fixtures import constants
|
||||
|
||||
|
@ -65,6 +64,8 @@ def create_proxy_zip(proxy_string, proxy_user, proxy_pass):
|
|||
""""minimum_chrome_version":"22.0.0"\n"""
|
||||
"""}"""
|
||||
)
|
||||
import threading
|
||||
|
||||
lock = threading.RLock() # Support multi-threaded test runs with Pytest
|
||||
with lock:
|
||||
abs_path = os.path.abspath(".")
|
||||
|
|
Binary file not shown.
|
@ -10095,12 +10095,9 @@ class BaseCase(unittest.TestCase):
|
|||
|
||||
from seleniumbase.common import decorators
|
||||
|
||||
# Deprecated Methods (Replace these if they're still in your code!)
|
||||
@decorators.deprecated(
|
||||
"jq_format() is deprecated. Use re.escape() instead!"
|
||||
)
|
||||
@decorators.deprecated("You should use re.escape() instead.")
|
||||
def jq_format(self, code):
|
||||
# DEPRECATED - re.escape() already performs the intended action!
|
||||
# DEPRECATED - re.escape() already performs the intended action.
|
||||
return js_utils._jq_format(code)
|
||||
|
||||
############
|
||||
|
|
|
@ -8,7 +8,6 @@ import time
|
|||
from selenium.common.exceptions import NoSuchElementException
|
||||
from selenium.common.exceptions import WebDriverException
|
||||
from seleniumbase import config as sb_config
|
||||
from seleniumbase.common import decorators
|
||||
from seleniumbase.config import settings
|
||||
from seleniumbase.fixtures import constants
|
||||
from seleniumbase.fixtures import shared_utils
|
||||
|
@ -976,7 +975,6 @@ def clear_out_console_logs(driver):
|
|||
pass
|
||||
|
||||
|
||||
@decorators.deprecated("Use re.escape() instead, which does what you want!")
|
||||
def _jq_format(code):
|
||||
"""
|
||||
DEPRECATED - Use re.escape() instead, which performs the intended action.
|
||||
|
|
|
@ -606,7 +606,7 @@ document.body.addEventListener('mouseup', function (event) {
|
|||
else if (ra_len > 0 &&
|
||||
document.recorded_actions[ra_len-1][0] === 'mo_dn')
|
||||
{
|
||||
// Probably an accidental drag & drop.
|
||||
// Maybe an accidental drag & drop.
|
||||
document.recorded_actions.pop();
|
||||
}
|
||||
json_rec_act = JSON.stringify(document.recorded_actions);
|
||||
|
@ -642,14 +642,15 @@ document.body.addEventListener('keydown', function (event) {
|
|||
});
|
||||
document.body.addEventListener('keyup', function (event) {
|
||||
reset_if_recorder_undefined();
|
||||
// Controls for Pausing & Resuming.
|
||||
// Controls to Pause & Resume.
|
||||
pause_rec = sessionStorage.getItem('pause_recorder');
|
||||
if (event.key.toLowerCase() === 'escape' && pause_rec === 'no')
|
||||
rec_mode = sessionStorage.getItem('recorder_mode');
|
||||
l_key = event.key.toLowerCase();
|
||||
if (l_key === 'escape' && pause_rec === 'no' && rec_mode === '1')
|
||||
{
|
||||
sessionStorage.setItem('pause_recorder', 'yes');
|
||||
pause_rec = 'yes';
|
||||
sessionStorage.setItem('recorder_mode', '1');
|
||||
console.log('The SeleniumBase Recorder has paused.');
|
||||
console.log('SeleniumBase Recorder paused');
|
||||
no_border = 'none';
|
||||
document.querySelector('body').style.border = no_border;
|
||||
document.title = sessionStorage.getItem('recorder_title');
|
||||
|
@ -658,15 +659,14 @@ document.body.addEventListener('keyup', function (event) {
|
|||
{
|
||||
sessionStorage.setItem('pause_recorder', 'no');
|
||||
pause_rec = 'no';
|
||||
sessionStorage.setItem('recorder_mode', '1');
|
||||
console.log('The SeleniumBase Recorder has resumed.');
|
||||
console.log('SeleniumBase Recorder resumed');
|
||||
red_border = 'thick solid #EE3344';
|
||||
document.querySelector('body').style.border = red_border;
|
||||
}
|
||||
else if (event.key === '^' && pause_rec === 'no')
|
||||
{
|
||||
sessionStorage.setItem('recorder_mode', '2');
|
||||
purple_border = 'thick solid #BF40BF';
|
||||
purple_border = 'thick solid #EF5BE9';
|
||||
document.querySelector('body').style.border = purple_border;
|
||||
}
|
||||
else if (event.key === '&' && pause_rec === 'no')
|
||||
|
@ -675,13 +675,13 @@ document.body.addEventListener('keyup', function (event) {
|
|||
orange_border = 'thick solid #F28C28';
|
||||
document.querySelector('body').style.border = orange_border;
|
||||
}
|
||||
else if (pause_rec === 'no' && event.key.toLowerCase() !== 'shift')
|
||||
else if (pause_rec === 'no' && l_key !== 'shift' && l_key !== 'backspace')
|
||||
{
|
||||
sessionStorage.setItem('recorder_mode', '1');
|
||||
red_border = 'thick solid #EE3344';
|
||||
document.querySelector('body').style.border = red_border;
|
||||
}
|
||||
// After checking for pause/resume controls.
|
||||
// After controls for switching modes.
|
||||
if (sessionStorage.getItem('pause_recorder') === 'yes') return;
|
||||
const d_now = Date.now();
|
||||
const element = event.target;
|
||||
|
@ -692,7 +692,7 @@ document.body.addEventListener('keyup', function (event) {
|
|||
element.tagName.toLowerCase() === 'textarea')
|
||||
{
|
||||
ra_len = document.recorded_actions.length;
|
||||
if (ra_len > 0 && event.key.toLowerCase() === 'enter' &&
|
||||
if (ra_len > 0 && l_key === 'enter' &&
|
||||
document.recorded_actions[ra_len-1][0] === 'input' &&
|
||||
document.recorded_actions[ra_len-1][1] === selector &&
|
||||
!document.recorded_actions[ra_len-1][2].endsWith('\n'))
|
||||
|
|
|
@ -660,6 +660,7 @@ def pytest_addoption(parser):
|
|||
"--recorder",
|
||||
"--record",
|
||||
"--rec",
|
||||
"--codegen",
|
||||
action="store_true",
|
||||
dest="recorder_mode",
|
||||
default=False,
|
||||
|
|
|
@ -421,6 +421,7 @@ class SeleniumBrowser(Plugin):
|
|||
"--recorder",
|
||||
"--record",
|
||||
"--rec",
|
||||
"--codegen",
|
||||
action="store_true",
|
||||
dest="recorder_mode",
|
||||
default=False,
|
||||
|
|
Loading…
Reference in New Issue