Skip to content

Commit 1b23e26

Browse files
authored
Merge pull request #1001 from seleniumbase/recorder-downloads
Recorder Mode updates for file downloads, classes, and form submissions
2 parents bea532f + bc74b3c commit 1b23e26

File tree

6 files changed

+49
-19
lines changed

6 files changed

+49
-19
lines changed

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
<link rel="icon" href="https://seleniumbase.io/img/logo6.png" />
77

88
<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="530" /></a></h2>
9-
<h4 align="center">Create web and mobile tests faster.</h4>
9+
<h4 align="center">Everything you need for web testing.</h4>
1010
<p align="center"><a href="https://github.com/seleniumbase/SeleniumBase/releases">
1111
<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/">
1212
<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">
@@ -16,7 +16,7 @@
1616
<p align="center"><a href="https://github.com/seleniumbase/SeleniumBase/actions">
1717
<img src="https://github.com/seleniumbase/SeleniumBase/workflows/CI%20build/badge.svg" alt="SeleniumBase GitHub Actions" /></a> <a href="https://dev.azure.com/seleniumbase/seleniumbase/_build/latest?definitionId=1&branchName=master"> <img src="https://dev.azure.com/seleniumbase/seleniumbase/_apis/build/status/seleniumbase.SeleniumBase?branchName=master" alt="SeleniumBase Azure Pipelines" /></a> <a href="https://gitter.im/seleniumbase/SeleniumBase">
1818
<img src="https://badges.gitter.im/seleniumbase/SeleniumBase.svg" alt="SeleniumBase" /></a> <a href="https://seleniumbase.io">
19-
<img src="https://img.shields.io/badge/docs-%20seleniumbase.io-22BBAA.svg" alt="SeleniumBase.io Docs" /></a></p>
19+
<img src="https://img.shields.io/badge/docs-%20📓📖📚-11BBCC.svg" alt="SeleniumBase.io Docs" title="SeleniumBase.io Docs" /></a></p>
2020

2121
<p align="center">SeleniumBase is a complete framework for browser automation and 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 cleaner, maintainable code. <br />Includes advanced features such as a <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 <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/help_docs/js_package_manager.md">JS code generators</a>.</p>
2222

help_docs/recorder_mode.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,8 @@ class RecorderTest(BaseCase):
7878

7979
<p>🔴 SeleniumBase <code>1.66.8</code> generates better selectors in Recorder Mode and improves the algorithm for converting recorded actions into SeleniumBase code.</p>
8080

81+
<p>🔴 SeleniumBase <code>1.66.9</code> allows the Recorder to record methods related to file downloads. It also updates how the Recorder handles class-parsing and form submissions.</p>
82+
8183
--------
8284

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

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__ = "1.66.8"
2+
__version__ = "1.66.9"

seleniumbase/extensions/recorder.zip

-75 Bytes
Binary file not shown.

seleniumbase/fixtures/base_case.py

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3350,9 +3350,11 @@ def __process_recorded_actions(self):
33503350
ext_actions.append("hi_li")
33513351
ext_actions.append("as_lt")
33523352
ext_actions.append("as_ti")
3353+
ext_actions.append("as_df")
3354+
ext_actions.append("do_fi")
3355+
ext_actions.append("as_at")
33533356
ext_actions.append("as_te")
33543357
ext_actions.append("as_et")
3355-
ext_actions.append("as_at")
33563358
ext_actions.append("sw_fr")
33573359
ext_actions.append("sw_dc")
33583360
ext_actions.append("s_c_f")
@@ -3539,6 +3541,22 @@ def __process_recorded_actions(self):
35393541
sb_actions.append('self.%s("%s")' % (method, action[1]))
35403542
else:
35413543
sb_actions.append("self.%s('%s')" % (method, action[1]))
3544+
elif action[0] == "as_df":
3545+
method = "assert_downloaded_file"
3546+
if '"' not in action[1]:
3547+
sb_actions.append('self.%s("%s")' % (method, action[1]))
3548+
else:
3549+
sb_actions.append("self.%s('%s')" % (method, action[1]))
3550+
elif action[0] == "do_fi":
3551+
method = "download_file"
3552+
file_url = action[1][0]
3553+
dest = action[1][1]
3554+
if not dest:
3555+
sb_actions.append('self.%s("%s")' % (
3556+
method, file_url))
3557+
else:
3558+
sb_actions.append('self.%s("%s", "%s")' % (
3559+
method, file_url, dest))
35423560
elif action[0] == "as_at":
35433561
method = "assert_attribute"
35443562
if ('"' not in action[1][0]) and action[1][2]:
@@ -4608,6 +4626,16 @@ def download_file(self, file_url, destination_folder=None):
46084626
if not os.path.exists(destination_folder):
46094627
os.makedirs(destination_folder)
46104628
page_utils._download_file_to(file_url, destination_folder)
4629+
if self.recorder_mode:
4630+
url = self.get_current_url()
4631+
if url and len(url) > 0:
4632+
if ("http:") in url or ("https:") in url or ("file:") in url:
4633+
if self.get_session_storage_item("pause_recorder") == "no":
4634+
time_stamp = self.execute_script("return Date.now();")
4635+
origin = self.get_origin()
4636+
url_dest = [file_url, destination_folder]
4637+
action = ["do_fi", url_dest, origin, time_stamp]
4638+
self.__extra_actions.append(action)
46114639

46124640
def save_file_as(self, file_url, new_file_name, destination_folder=None):
46134641
"""Similar to self.download_file(), except that you get to rename the
@@ -4776,6 +4804,15 @@ def assert_downloaded_file(self, file, timeout=None, browser=False):
47764804
% (file, self.get_downloads_folder(), timeout)
47774805
)
47784806
page_actions.timeout_exception("NoSuchFileException", message)
4807+
if self.recorder_mode:
4808+
url = self.get_current_url()
4809+
if url and len(url) > 0:
4810+
if ("http:") in url or ("https:") in url or ("file:") in url:
4811+
if self.get_session_storage_item("pause_recorder") == "no":
4812+
time_stamp = self.execute_script("return Date.now();")
4813+
origin = self.get_origin()
4814+
action = ["as_df", file, origin, time_stamp]
4815+
self.__extra_actions.append(action)
47794816
if self.demo_mode:
47804817
messenger_post = "ASSERT DOWNLOADED FILE: [%s]" % file
47814818
try:

seleniumbase/js_code/recorder_js.py

Lines changed: 6 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -155,19 +155,12 @@
155155
num_by_attr = [];
156156
child_count_by_attr = [];
157157
for (var i = 0; i < non_id_attributes.length; i++) {
158-
if (non_id_attributes[i] == 'class' && el.hasAttribute('class')) {
159-
class_name = el.getAttribute('class');
160-
if (class_name.length > 0 && !class_name.includes(' ') &&
161-
class_name.includes('-'))
162-
{
163-
selector_by_class = tag_name + '.' + class_name;
164-
all_by_class = document.querySelectorAll(selector_by_class);
165-
if (all_by_class.length == 1)
166-
return selector_by_class;
167-
}
168-
continue;
158+
selector_by_attr[i] = null;
159+
if (non_id_attributes[i] == 'class')
160+
selector_by_attr[i] = selector_by_class;
161+
else {
162+
selector_by_attr[i] = cssPathByAttribute(el, non_id_attributes[i]);
169163
}
170-
selector_by_attr[i] = cssPathByAttribute(el, non_id_attributes[i]);
171164
all_by_attr[i] = document.querySelectorAll(selector_by_attr[i]);
172165
num_by_attr[i] = all_by_attr[i].length;
173166
if (!selector_by_attr[i].includes(child_sep) &&
@@ -646,9 +639,7 @@
646639
if (ra_len > 0 && event.key.toLowerCase() === 'enter' &&
647640
document.recorded_actions[ra_len-1][0] === 'input' &&
648641
document.recorded_actions[ra_len-1][1] === selector &&
649-
!document.recorded_actions[ra_len-1][2].endsWith('\n') &&
650-
document.recorded_actions[ra_len-1][2].length > 0 &&
651-
element.value.length == 0)
642+
!document.recorded_actions[ra_len-1][2].endsWith('\n'))
652643
{
653644
s_text = document.recorded_actions[ra_len-1][2] + '\n';
654645
document.recorded_actions.pop();

0 commit comments

Comments
 (0)