Merge pull request #1028 from seleniumbase/refresh-recorder-mode

Refresh Recorder Mode with "codegen" and more
This commit is contained in:
Michael Mintz 2021-10-20 22:48:32 -04:00 committed by GitHub
commit efd282a860
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 212 additions and 126 deletions

View File

@ -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

View File

@ -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"

View File

@ -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>

View File

@ -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()

View File

@ -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:

View File

@ -1,2 +1,2 @@
# seleniumbase package
__version__ = "2.0.3"
__version__ = "2.0.4"

View File

@ -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

View File

@ -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.

View File

@ -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()

View File

@ -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"

View File

@ -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"

View File

@ -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.

View File

@ -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)
############

View File

@ -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.

View File

@ -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'))

View File

@ -660,6 +660,7 @@ def pytest_addoption(parser):
"--recorder",
"--record",
"--rec",
"--codegen",
action="store_true",
dest="recorder_mode",
default=False,

View File

@ -421,6 +421,7 @@ class SeleniumBrowser(Plugin):
"--recorder",
"--record",
"--rec",
"--codegen",
action="store_true",
dest="recorder_mode",
default=False,