Merge pull request #994 from seleniumbase/recorder-mode-algorithms
Updates to Recorder Mode and the Page Objects generator
This commit is contained in:
commit
e27163faac
12
README.md
12
README.md
|
@ -5,8 +5,8 @@
|
|||
<meta property="og:image" content="https://seleniumbase.io/cdn/img/mac_sb_logo_5.png" />
|
||||
<link rel="icon" href="https://seleniumbase.io/img/logo6.png" />
|
||||
|
||||
<h2 align="center"><a href="https://github.com/seleniumbase/SeleniumBase/"><img src="https://seleniumbase.io/cdn/img/sb_logo_10t.png" alt="SeleniumBase" title="SeleniumBase" width="248" /></a></h2>
|
||||
<h4 align="center">Fast and reliable testing for web apps.</h4>
|
||||
<h2 align="center"><a href="https://github.com/seleniumbase/SeleniumBase/"><img src="https://seleniumbase.io/cdn/img/sb_banner_t.png" alt="SeleniumBase" title="SeleniumBase" width="590" /></a></h2>
|
||||
<h4 align="center">Create web & mobile tests 10x faster.</h4>
|
||||
<p align="center"><a href="https://github.com/seleniumbase/SeleniumBase/releases">
|
||||
<img src="https://img.shields.io/github/v/release/seleniumbase/SeleniumBase.svg?color=2277EE" alt="Latest Release on GitHub" /></a> <a href="https://pypi.org/project/seleniumbase/">
|
||||
<img src="https://img.shields.io/pypi/v/seleniumbase.svg?color=00a0e0" alt="Latest Release on PyPI" /></a> <a href="https://pepy.tech/project/seleniumbase">
|
||||
|
@ -18,7 +18,7 @@
|
|||
<img src="https://badges.gitter.im/seleniumbase/SeleniumBase.svg" alt="SeleniumBase" /></a> <a href="https://seleniumbase.io">
|
||||
<img src="https://img.shields.io/badge/docs-%20seleniumbase.io-22BBAA.svg" alt="SeleniumBase.io Docs" /></a></p>
|
||||
|
||||
<p align="center">SeleniumBase is a complete framework for web automation and end-to-end testing with <a href="https://docs.pytest.org/en/latest/index.html">pytest</a>.<br />The API simplifies <a href="https://www.selenium.dev/documentation/">Selenium</a>'s out-of-the-box API, leading to tests with more maintainable code. <br />SeleniumBase includes advanced features such as a realtime <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/example_logs/ReadMe.md">Dashboard</a>, a <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/help_docs/recorder_mode.md">Recorder</a>, and more.</p>
|
||||
<p align="center">SeleniumBase is a complete framework for web automation & end-to-end testing with <a href="https://docs.pytest.org/en/latest/index.html">pytest</a>.<br />The API simplifies <a href="https://www.selenium.dev/documentation/">Selenium</a>'s out-of-the-box API, which leads to more maintainable test code. <br />SeleniumBase includes advanced features such as a realtime <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/example_logs/ReadMe.md">Dashboard</a>, a <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/help_docs/recorder_mode.md">Recorder</a>, & more.</p>
|
||||
|
||||
<p align="center">
|
||||
<a href="#python_installation">🚀 Start</a> |
|
||||
|
@ -65,7 +65,7 @@
|
|||
pytest my_first_test.py --demo
|
||||
```
|
||||
|
||||
<p align="left"><a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/my_first_test.py"><img src="https://seleniumbase.io/cdn/gif/my_first_test_4.gif" alt="SeleniumBase Demo Mode" title="SeleniumBase Demo Mode" /></a></p>
|
||||
<p align="left"><a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/my_first_test.py"><img src="https://seleniumbase.io/cdn/gif/my_first_test_2.gif" width="480" alt="SeleniumBase Demo Mode" title="SeleniumBase Demo Mode" /></a></p>
|
||||
|
||||
```python
|
||||
from seleniumbase import BaseCase
|
||||
|
@ -190,7 +190,7 @@ pytest test_demo_site.py
|
|||
|
||||
> (Chrome is the default browser if not specified with ``--browser=BROWSER``. On Linux, ``--headless`` is the default behavior. You can also run in headless mode on any OS. If your Linux machine has a GUI and you want to see the web browser as tests run, add ``--headed`` or ``--gui``.)
|
||||
|
||||
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/test_demo_site.py"><img src="https://seleniumbase.io/cdn/gif/demo_page_1.gif" title="SeleniumBase Demo Page" width="450" /></a><br />
|
||||
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/test_demo_site.py"><img src="https://seleniumbase.io/cdn/gif/demo_page_2.gif" title="SeleniumBase Demo Page" width="450" /></a><br />
|
||||
|
||||
🔵 <b>Here are more examples that you can run:</b>
|
||||
|
||||
|
@ -206,7 +206,7 @@ pytest test_swag_labs.py
|
|||
pytest my_first_test.py --demo
|
||||
```
|
||||
|
||||
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/my_first_test.py"><img src="https://seleniumbase.io/cdn/gif/my_first_test_4.gif" alt="SeleniumBase Demo Mode" title="SeleniumBase Demo Mode" /></a>
|
||||
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/my_first_test.py"><img src="https://seleniumbase.io/cdn/gif/my_first_test_2.gif" alt="SeleniumBase Demo Mode" title="SeleniumBase Demo Mode" /></a>
|
||||
|
||||
* By default, **[CSS Selectors](https://www.w3schools.com/cssref/css_selectors.asp)** are used for finding page elements.
|
||||
* If you're new to CSS Selectors, games like [CSS Diner](http://flukeout.github.io/) can help you learn.
|
||||
|
|
|
@ -18,7 +18,7 @@ importlib-metadata==4.8.1;python_version>="3.6"
|
|||
bleach==4.1.0
|
||||
lunr==0.6.0;python_version>="3.6"
|
||||
nltk==3.6.4;python_version>="3.6"
|
||||
watchdog==2.1.5;python_version>="3.6"
|
||||
watchdog==2.1.6;python_version>="3.6"
|
||||
mkdocs==1.2.2;python_version>="3.6"
|
||||
mkdocs-material==7.3.0;python_version>="3.6"
|
||||
mkdocs-exclude-search==0.5.2;python_version>="3.6"
|
||||
|
|
|
@ -34,7 +34,7 @@ Run an example test in Demo Mode: (highlight assertions)
|
|||
pytest my_first_test.py --demo
|
||||
```
|
||||
|
||||
<img src="https://seleniumbase.io/cdn/gif/my_first_test_4.gif" title="SeleniumBase Demo Mode" /><br />
|
||||
<img src="https://seleniumbase.io/cdn/gif/my_first_test_2.gif" title="SeleniumBase Demo Mode" /><br />
|
||||
|
||||
Run a different example in Demo Mode:
|
||||
|
||||
|
@ -42,7 +42,7 @@ Run a different example in Demo Mode:
|
|||
pytest test_swag_labs.py --demo
|
||||
```
|
||||
|
||||
<img src="https://seleniumbase.io/cdn/gif/swag_demo_2.gif" /><br />
|
||||
<img src="https://seleniumbase.io/cdn/gif/swag_demo_3.gif" /><br />
|
||||
|
||||
Run an example test in Headless Mode: (invisible browser)
|
||||
|
||||
|
@ -70,7 +70,7 @@ Run a test on the Demo Site to try many SeleniumBase methods:
|
|||
pytest test_demo_site.py
|
||||
```
|
||||
|
||||
<img src="https://seleniumbase.io/cdn/gif/demo_page_1.gif" title="SeleniumBase Demo Page" /><br />
|
||||
<img src="https://seleniumbase.io/cdn/gif/demo_page_2.gif" title="SeleniumBase Demo Page" /><br />
|
||||
|
||||
Run tests multi-threaded using [n] threads:
|
||||
|
||||
|
@ -160,6 +160,12 @@ For more advanced run commands, such as using a proxy server, see [../help_docs/
|
|||
|
||||
--------
|
||||
|
||||
If you just need to perform some quick website verification on various devices, you can use the <a href="https://seleniumbase.io/devices/">SeleniumBase Device Farm</a>. Just plug in a website URL, and it will display how the website looks on four different devices:
|
||||
|
||||
<a href="https://seleniumbase.io/devices/"><img src="https://seleniumbase.io/cdn/img/github_demo.png" width="540" title="SeleniumBase Mobile Mode" /></a><br />
|
||||
|
||||
--------
|
||||
|
||||
To make things easier, here's a simple GUI program that allows you to run a few example tests by pressing a button:
|
||||
|
||||
```bash
|
||||
|
|
|
@ -12,12 +12,18 @@
|
|||
pytest TEST_NAME.py --recorder -s
|
||||
```
|
||||
|
||||
🔴 To add your own actions inside the test, you'll need to create a breakpoint somewhere inside of it:
|
||||
🔴 To add your own actions inside the test, you'll need to create a breakpoint inside your test to activate Debug Mode:
|
||||
|
||||
```python
|
||||
import ipdb; ipdb.set_trace()
|
||||
```
|
||||
|
||||
🔴 You can also activate Debug Mode at the start of your test by adding ``--trace`` as a ``pytest`` command-line option:
|
||||
|
||||
```bash
|
||||
pytest TEST_NAME.py --trace -s
|
||||
```
|
||||
|
||||
🔴 Once you've reached the breakpoint, you can take control of the browser and add in any actions that you want recorded. When you are finished recording, type "``c``" on the command-line and press ``[Enter]`` to let the test continue from the breakpoint. After the test completes, a file called ``TEST_NAME_rec.py`` will be automatically created in the ``./recordings`` folder, which will include the actions performed by the test, and the manual actions that you added in. Below is a command-line notification:
|
||||
|
||||
```bash
|
||||
|
@ -64,6 +70,8 @@ class RecorderTest(BaseCase):
|
|||
|
||||
<p>🔴 SeleniumBase <code>1.66.5</code> improves the algorithm for converting recorded actions into SeleniumBase code.</p>
|
||||
|
||||
<p>🔴 SeleniumBase <code>1.66.6</code> adds more selector options and improves the algorithm for converting recorded actions into SeleniumBase code.</p>
|
||||
|
||||
--------
|
||||
|
||||
<div>To learn more about SeleniumBase, check out the Docs Site:</div>
|
||||
|
|
|
@ -5,7 +5,7 @@ packaging>=21.0;python_version>="3.6"
|
|||
typing-extensions>=3.10.0.2
|
||||
setuptools>=44.1.1;python_version<"3.5"
|
||||
setuptools>=50.3.2;python_version>="3.5" and python_version<"3.6"
|
||||
setuptools>=58.1.0;python_version>="3.6"
|
||||
setuptools>=58.2.0;python_version>="3.6"
|
||||
setuptools-scm==5.0.2;python_version<"3.6"
|
||||
setuptools-scm>=6.3.2;python_version>="3.6"
|
||||
tomli>=1.2.1;python_version>="3.6"
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
# seleniumbase package
|
||||
__version__ = "1.66.5"
|
||||
__version__ = "1.66.6"
|
||||
|
|
|
@ -604,6 +604,218 @@ def process_test_file(
|
|||
seleniumbase_lines.append(command)
|
||||
continue
|
||||
|
||||
# Handle self.check_if_unchecked(SELECTOR)
|
||||
if not object_dict:
|
||||
data = re.match(
|
||||
r"""^(\s*)self\.check_if_unchecked"""
|
||||
r"""\((r?['"][\S\s]+['"])\)([\S\s]*)"""
|
||||
r"""$""",
|
||||
line,
|
||||
)
|
||||
else:
|
||||
data = re.match(
|
||||
r"""^(\s*)self\.check_if_unchecked"""
|
||||
r"""\(([\S]+)\)([\S\s]*)"""
|
||||
r"""$""",
|
||||
line,
|
||||
)
|
||||
if data:
|
||||
whitespace = data.group(1)
|
||||
selector = "%s" % data.group(2)
|
||||
selector = remove_extra_slashes(selector)
|
||||
page_selectors.append(selector)
|
||||
comments = data.group(3)
|
||||
command = """%sself.check_if_unchecked(%s)%s""" % (
|
||||
whitespace,
|
||||
selector,
|
||||
comments,
|
||||
)
|
||||
if selector_dict:
|
||||
if add_comments:
|
||||
comments = " # %s" % selector
|
||||
selector = optimize_selector(selector)
|
||||
if selector in selector_dict.keys():
|
||||
selector_object = selector_dict[selector]
|
||||
changed.append(selector_object.split(".")[0])
|
||||
command = """%sself.check_if_unchecked(%s)%s""" % (
|
||||
whitespace,
|
||||
selector_object,
|
||||
comments,
|
||||
)
|
||||
if object_dict:
|
||||
if not add_comments:
|
||||
comments = ""
|
||||
object_name = selector
|
||||
if object_name in object_dict.keys():
|
||||
selector_object = object_dict[object_name]
|
||||
changed.append(object_name.split(".")[0])
|
||||
command = """%sself.check_if_unchecked(%s)%s""" % (
|
||||
whitespace,
|
||||
selector_object,
|
||||
comments,
|
||||
)
|
||||
seleniumbase_lines.append(command)
|
||||
continue
|
||||
|
||||
# Handle self.uncheck_if_checked(SELECTOR)
|
||||
if not object_dict:
|
||||
data = re.match(
|
||||
r"""^(\s*)self\.uncheck_if_checked"""
|
||||
r"""\((r?['"][\S\s]+['"])\)([\S\s]*)"""
|
||||
r"""$""",
|
||||
line,
|
||||
)
|
||||
else:
|
||||
data = re.match(
|
||||
r"""^(\s*)self\.uncheck_if_checked"""
|
||||
r"""\(([\S]+)\)([\S\s]*)"""
|
||||
r"""$""",
|
||||
line,
|
||||
)
|
||||
if data:
|
||||
whitespace = data.group(1)
|
||||
selector = "%s" % data.group(2)
|
||||
selector = remove_extra_slashes(selector)
|
||||
page_selectors.append(selector)
|
||||
comments = data.group(3)
|
||||
command = """%sself.uncheck_if_checked(%s)%s""" % (
|
||||
whitespace,
|
||||
selector,
|
||||
comments,
|
||||
)
|
||||
if selector_dict:
|
||||
if add_comments:
|
||||
comments = " # %s" % selector
|
||||
selector = optimize_selector(selector)
|
||||
if selector in selector_dict.keys():
|
||||
selector_object = selector_dict[selector]
|
||||
changed.append(selector_object.split(".")[0])
|
||||
command = """%sself.uncheck_if_checked(%s)%s""" % (
|
||||
whitespace,
|
||||
selector_object,
|
||||
comments,
|
||||
)
|
||||
if object_dict:
|
||||
if not add_comments:
|
||||
comments = ""
|
||||
object_name = selector
|
||||
if object_name in object_dict.keys():
|
||||
selector_object = object_dict[object_name]
|
||||
changed.append(object_name.split(".")[0])
|
||||
command = """%sself.uncheck_if_checked(%s)%s""" % (
|
||||
whitespace,
|
||||
selector_object,
|
||||
comments,
|
||||
)
|
||||
seleniumbase_lines.append(command)
|
||||
continue
|
||||
|
||||
# Handle self.select_if_unselected(SELECTOR)
|
||||
if not object_dict:
|
||||
data = re.match(
|
||||
r"""^(\s*)self\.select_if_unselected"""
|
||||
r"""\((r?['"][\S\s]+['"])\)([\S\s]*)"""
|
||||
r"""$""",
|
||||
line,
|
||||
)
|
||||
else:
|
||||
data = re.match(
|
||||
r"""^(\s*)self\.select_if_unselected"""
|
||||
r"""\(([\S]+)\)([\S\s]*)"""
|
||||
r"""$""",
|
||||
line,
|
||||
)
|
||||
if data:
|
||||
whitespace = data.group(1)
|
||||
selector = "%s" % data.group(2)
|
||||
selector = remove_extra_slashes(selector)
|
||||
page_selectors.append(selector)
|
||||
comments = data.group(3)
|
||||
command = """%sself.select_if_unselected(%s)%s""" % (
|
||||
whitespace,
|
||||
selector,
|
||||
comments,
|
||||
)
|
||||
if selector_dict:
|
||||
if add_comments:
|
||||
comments = " # %s" % selector
|
||||
selector = optimize_selector(selector)
|
||||
if selector in selector_dict.keys():
|
||||
selector_object = selector_dict[selector]
|
||||
changed.append(selector_object.split(".")[0])
|
||||
command = """%sself.select_if_unselected(%s)%s""" % (
|
||||
whitespace,
|
||||
selector_object,
|
||||
comments,
|
||||
)
|
||||
if object_dict:
|
||||
if not add_comments:
|
||||
comments = ""
|
||||
object_name = selector
|
||||
if object_name in object_dict.keys():
|
||||
selector_object = object_dict[object_name]
|
||||
changed.append(object_name.split(".")[0])
|
||||
command = """%sself.select_if_unselected(%s)%s""" % (
|
||||
whitespace,
|
||||
selector_object,
|
||||
comments,
|
||||
)
|
||||
seleniumbase_lines.append(command)
|
||||
continue
|
||||
|
||||
# Handle self.unselect_if_selected(SELECTOR)
|
||||
if not object_dict:
|
||||
data = re.match(
|
||||
r"""^(\s*)self\.unselect_if_selected"""
|
||||
r"""\((r?['"][\S\s]+['"])\)([\S\s]*)"""
|
||||
r"""$""",
|
||||
line,
|
||||
)
|
||||
else:
|
||||
data = re.match(
|
||||
r"""^(\s*)self\.unselect_if_selected"""
|
||||
r"""\(([\S]+)\)([\S\s]*)"""
|
||||
r"""$""",
|
||||
line,
|
||||
)
|
||||
if data:
|
||||
whitespace = data.group(1)
|
||||
selector = "%s" % data.group(2)
|
||||
selector = remove_extra_slashes(selector)
|
||||
page_selectors.append(selector)
|
||||
comments = data.group(3)
|
||||
command = """%sself.unselect_if_selected(%s)%s""" % (
|
||||
whitespace,
|
||||
selector,
|
||||
comments,
|
||||
)
|
||||
if selector_dict:
|
||||
if add_comments:
|
||||
comments = " # %s" % selector
|
||||
selector = optimize_selector(selector)
|
||||
if selector in selector_dict.keys():
|
||||
selector_object = selector_dict[selector]
|
||||
changed.append(selector_object.split(".")[0])
|
||||
command = """%sself.unselect_if_selected(%s)%s""" % (
|
||||
whitespace,
|
||||
selector_object,
|
||||
comments,
|
||||
)
|
||||
if object_dict:
|
||||
if not add_comments:
|
||||
comments = ""
|
||||
object_name = selector
|
||||
if object_name in object_dict.keys():
|
||||
selector_object = object_dict[object_name]
|
||||
changed.append(object_name.split(".")[0])
|
||||
command = """%sself.unselect_if_selected(%s)%s""" % (
|
||||
whitespace,
|
||||
selector_object,
|
||||
comments,
|
||||
)
|
||||
seleniumbase_lines.append(command)
|
||||
continue
|
||||
|
||||
# Handle self.switch_to_frame(SELECTOR)
|
||||
if not object_dict:
|
||||
data = re.match(
|
||||
|
@ -1435,6 +1647,75 @@ def process_test_file(
|
|||
seleniumbase_lines.append(command)
|
||||
continue
|
||||
|
||||
# Handle self.drag_and_drop(SELECTOR, SELECTOR)
|
||||
if not object_dict:
|
||||
data = re.match(
|
||||
r"""^(\s*)self\.drag_and_drop"""
|
||||
r"""\((r?['"][\S\s]+['"]),\s?([\S\s]+)\)([\S\s]*)"""
|
||||
r"""$""",
|
||||
line,
|
||||
)
|
||||
else:
|
||||
data = re.match(
|
||||
r"""^(\s*)self\.drag_and_drop"""
|
||||
r"""\(([\S]+),\s?([\S]+)\)([\S\s]*)"""
|
||||
r"""$""",
|
||||
line,
|
||||
)
|
||||
if data:
|
||||
whitespace = data.group(1)
|
||||
selector1 = "%s" % data.group(2)
|
||||
selector1 = remove_extra_slashes(selector1)
|
||||
page_selectors.append(selector1)
|
||||
selector2 = "%s" % data.group(3)
|
||||
selector2 = remove_extra_slashes(selector2)
|
||||
page_selectors.append(selector2)
|
||||
comments = data.group(4)
|
||||
command = """%sself.drag_and_drop(%s, %s)%s""" % (
|
||||
whitespace,
|
||||
selector1,
|
||||
selector2,
|
||||
comments,
|
||||
)
|
||||
if selector_dict:
|
||||
if add_comments:
|
||||
comments = " # %s" % selector
|
||||
selector1 = optimize_selector(selector1)
|
||||
selector2 = optimize_selector(selector2)
|
||||
if selector1 in selector_dict.keys() and (
|
||||
selector2 in selector_dict.keys()
|
||||
):
|
||||
selector_object1 = selector_dict[selector1]
|
||||
selector_object2 = selector_dict[selector2]
|
||||
changed.append(selector_object1.split(".")[0])
|
||||
changed.append(selector_object2.split(".")[0])
|
||||
command = """%sself.drag_and_drop(%s, %s)%s""" % (
|
||||
whitespace,
|
||||
selector_object1,
|
||||
selector_object2,
|
||||
comments,
|
||||
)
|
||||
if object_dict:
|
||||
if not add_comments:
|
||||
comments = ""
|
||||
object_name1 = selector1
|
||||
object_name2 = selector2
|
||||
if object_name1 in object_dict.keys() and (
|
||||
object_name2 in object_dict.keys()
|
||||
):
|
||||
selector_object1 = object_dict[object_name1]
|
||||
selector_object2 = object_dict[object_name2]
|
||||
changed.append(object_name1.split(".")[0])
|
||||
changed.append(object_name2.split(".")[0])
|
||||
command = """%sself.drag_and_drop(%s, %s)%s""" % (
|
||||
whitespace,
|
||||
selector_object1,
|
||||
selector_object2,
|
||||
comments,
|
||||
)
|
||||
seleniumbase_lines.append(command)
|
||||
continue
|
||||
|
||||
# Handle self.hover_and_click(SELECTOR, SELECTOR)
|
||||
if not object_dict:
|
||||
data = re.match(
|
||||
|
|
Binary file not shown.
|
@ -1827,6 +1827,16 @@ class BaseCase(unittest.TestCase):
|
|||
self.scroll_to(hover_selector, by=hover_by)
|
||||
pre_action_url = self.driver.current_url
|
||||
pre_window_count = len(self.driver.window_handles)
|
||||
if self.recorder_mode:
|
||||
url = self.get_current_url()
|
||||
if url and len(url) > 0:
|
||||
if ("http:") in url or ("https:") in url or ("file:") in url:
|
||||
if self.get_session_storage_item("pause_recorder") == "no":
|
||||
time_stamp = self.execute_script("return Date.now();")
|
||||
origin = self.get_origin()
|
||||
the_selectors = [hover_selector, click_selector]
|
||||
action = ["ho_cl", the_selectors, origin, time_stamp]
|
||||
self.__extra_actions.append(action)
|
||||
outdated_driver = False
|
||||
element = None
|
||||
try:
|
||||
|
@ -3276,6 +3286,17 @@ class BaseCase(unittest.TestCase):
|
|||
origin = origin[0:-1]
|
||||
if origin not in origins:
|
||||
origins.append(origin)
|
||||
for n in range(len(srt_actions)):
|
||||
if (
|
||||
srt_actions[n][0] == "click"
|
||||
and n > 0
|
||||
and srt_actions[n-1][0] == "ho_cl"
|
||||
and srt_actions[n-1][2] in origins
|
||||
):
|
||||
srt_actions[n-1][0] = "_skip"
|
||||
srt_actions[n][0] = "h_clk"
|
||||
srt_actions[n][1] = srt_actions[n-1][1][0]
|
||||
srt_actions[n][2] = srt_actions[n-1][1][1]
|
||||
ext_actions = []
|
||||
ext_actions.append("js_cl")
|
||||
ext_actions.append("as_el")
|
||||
|
|
|
@ -101,6 +101,8 @@ var getBestSelector = function(el) {
|
|||
non_id_attributes.push('data-test-id');
|
||||
non_id_attributes.push('data-test-selector');
|
||||
non_id_attributes.push('data-nav');
|
||||
non_id_attributes.push('data-sb');
|
||||
non_id_attributes.push('data-cy');
|
||||
non_id_attributes.push('data-action');
|
||||
non_id_attributes.push('data-target');
|
||||
non_id_attributes.push('alt');
|
||||
|
@ -114,6 +116,7 @@ var getBestSelector = function(el) {
|
|||
non_id_attributes.push('value');
|
||||
non_id_attributes.push('ng-model');
|
||||
non_id_attributes.push('ng-if');
|
||||
non_id_attributes.push('src');
|
||||
selector_by_attr = [];
|
||||
all_by_attr = [];
|
||||
num_by_attr = [];
|
||||
|
@ -149,9 +152,13 @@ var getBestSelector = function(el) {
|
|||
contains_tags.push('h2');
|
||||
contains_tags.push('h3');
|
||||
contains_tags.push('h4');
|
||||
contains_tags.push('li');
|
||||
contains_tags.push('td');
|
||||
contains_tags.push('code');
|
||||
contains_tags.push('mark');
|
||||
contains_tags.push('label');
|
||||
contains_tags.push('button');
|
||||
contains_tags.push('legend');
|
||||
contains_tags.push('strong');
|
||||
all_by_tag = [];
|
||||
inner_text = el.innerText.trim();
|
||||
|
|
2
setup.py
2
setup.py
|
@ -121,7 +121,7 @@ setup(
|
|||
"typing-extensions>=3.10.0.2",
|
||||
'setuptools>=44.1.1;python_version<"3.5"',
|
||||
'setuptools>=50.3.2;python_version>="3.5" and python_version<"3.6"',
|
||||
'setuptools>=58.1.0;python_version>="3.6"',
|
||||
'setuptools>=58.2.0;python_version>="3.6"',
|
||||
'setuptools-scm==5.0.2;python_version<"3.6"',
|
||||
'setuptools-scm>=6.3.2;python_version>="3.6"',
|
||||
'tomli>=1.2.1;python_version>="3.6"',
|
||||
|
|
Loading…
Reference in New Issue