Merge pull request #986 from seleniumbase/recorder-mode-updates

Make improvements to "Recorder Mode"
This commit is contained in:
Michael Mintz 2021-09-21 14:11:22 -04:00 committed by GitHub
commit b5b0d9e788
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 105 additions and 17 deletions

View File

@ -27,23 +27,23 @@
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/seleniumbase/console_scripts/ReadMe.md">🧙‍♂️ Scripts</a> |
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/help_docs/customizing_test_runs.md">🖥️ CLI</a> |
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/help_docs/mobile_testing.md">📱 Mobile</a> |
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/help_docs/js_package_manager.md">🕹️ JSManager</a>
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/visual_testing/ReadMe.md">🖼️ VisualTest</a>
<br />
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/help_docs/method_summary.md">📚 API</a> |
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/example_logs/ReadMe.md">📊 Reports</a> |
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/help_docs/recorder_mode.md">🔴 Recorder</a> |
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/help_docs/syntax_formats.md">🔠 Syntaxes</a> |
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/help_docs/recorder_mode.md">🔴 Recorder</a> |
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/seleniumbase/utilities/selenium_grid/ReadMe.md">🌐 Grid</a> |
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/help_docs/locale_codes.md">🗾 Locale</a> |
<a href="https://github.com/seleniumbase/SeleniumBase/tree/master/examples/boilerplates">♻️ Boilerplate</a>
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/help_docs/js_package_manager.md">🕹️ JSManager</a>
<br />
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/integrations/github/workflows/ReadMe.md">🤖 CI</a> |
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/presenter/ReadMe.md">🎞️ Present</a> |
<a href="https://github.com/seleniumbase/SeleniumBase/tree/master/examples/boilerplates">♻️ Boilerplate</a> |
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/help_docs/translations.md">🌏 Translate</a> |
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/dialog_boxes/ReadMe.md">🛂 DialogBox</a> |
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/tour_examples/ReadMe.md">🗺️ Tours</a> |
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/tour_examples/ReadMe.md">🗺️ Tour</a> |
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/chart_maker/ReadMe.md">📶 Charts</a> |
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/visual_testing/ReadMe.md">🖼️ VisualTest</a>
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/dialog_boxes/ReadMe.md">🛂 DialogBox</a>
</p>
<p align="left">

View File

@ -1,5 +1,5 @@
regex>=2021.8.27
tqdm>=4.62.2
tqdm>=4.62.3
livereload==2.6.3;python_version>="3.6"
joblib==1.0.1;python_version>="3.6"
Markdown==3.3.4;python_version>="3.6"
@ -20,8 +20,8 @@ lunr==0.6.0;python_version>="3.6"
nltk==3.6.3;python_version>="3.6"
watchdog==2.1.5;python_version>="3.6"
mkdocs==1.2.2;python_version>="3.6"
mkdocs-material==7.1.3;python_version>="3.6"
mkdocs-material==7.2.8;python_version>="3.6"
mkdocs-exclude-search==0.5.2;python_version>="3.6"
mkdocs-simple-hooks==0.1.3
mkdocs-material-extensions==1.0.3;python_version>="3.6"
mkdocs-minify-plugin==0.4.0
mkdocs-minify-plugin==0.4.1

25
examples/test_iframes.py Normal file
View File

@ -0,0 +1,25 @@
from seleniumbase import BaseCase
class FrameTests(BaseCase):
def test_iframe_basics(self):
self.open(
"https://www.w3schools.com/html/tryit.asp"
"?filename=tryhtml_iframe_height_width_css"
)
self.ad_block() # Reduce noise during automation
self.switch_to_frame("iframeResult") # Enter the iFrame
self.assert_text("HTML Iframes", "h2")
self.switch_to_frame('[title*="Iframe"]') # Enter iFrame inside iFrame
self.assert_text("This page is displayed in an iframe", "h1")
self.switch_to_default_content() # Exit all iFrames
self.switch_to_frame("iframeResult") # Go back inside 1st iFrame
self.highlight('iframe[title="Iframe Example"]')
def test_set_content_to_frame(self):
self.open(
"https://www.w3schools.com/html/tryit.asp"
"?filename=tryhtml_iframe_height_width_css"
)
self.set_content_to_frame("iframeResult")
self.highlight('iframe[title="Iframe Example"]', loops=8)

View File

@ -10,8 +10,7 @@ class FileUploadButtonTests(BaseCase):
"https://www.w3schools.com/jsref/tryit.asp"
"?filename=tryjsref_fileupload_get"
)
self.ad_block()
self.switch_to_frame("iframeResult")
self.set_content_to_frame("iframeResult")
zoom_in = 'input[type="file"]{zoom: 1.6;-moz-transform: scale(1.6);}'
self.add_css_style(zoom_in)
self.highlight('input[type="file"]')

View File

@ -32,7 +32,7 @@
<a href="https://seleniumbase.io/help_docs/recorder_mode.md">🔴 Recorder</a> |
<a href="https://github.com/seleniumbase/SeleniumBase/tree/master/integrations/node_js">🏃 NodeRunner</a>
<br />
<a href="https://seleniumbase.io/examples/presenter/ReadMe/">📰 Presenter</a> |
<a href="https://seleniumbase.io/examples/presenter/ReadMe/">🎞️ Presenter</a> |
<a href="https://seleniumbase.io/examples/chart_maker/ReadMe/">📶 ChartMaker</a>
</p>

View File

@ -197,6 +197,8 @@ self.switch_to_frame(frame, timeout=None)
self.switch_to_default_content()
self.set_content_to_frame(frame, timeout=None)
self.open_new_window(switch_to=True)
self.switch_to_window(window, timeout=None)
@ -303,6 +305,8 @@ self.remove_elements(selector, by=By.CSS_SELECTOR)
self.ad_block()
# Duplicates: self.block_ads()
self.show_file_choosers()
self.get_domain_url(url)
self.get_beautiful_soup(source=None)

View File

@ -1,4 +1,4 @@
[<img src="https://seleniumbase.io/cdn/img/super_logo_sb.png" title="SeleniumBase" width="296">](https://github.com/seleniumbase/SeleniumBase/blob/master/README.md)
[<img src="https://seleniumbase.io/cdn/img/sb_logo_10t.png" title="SeleniumBase" width="260">](https://github.com/seleniumbase/SeleniumBase/blob/master/README.md)
<h2><img src="https://seleniumbase.io/img/logo6.png" title="SeleniumBase" width="32" /> Recorder Mode</h2>
@ -47,6 +47,8 @@ class RecorderTest(BaseCase):
<p>🔴 The launch of Recorder Mode has brought a new SeleniumBase method along with it: <code>self.open_if_not_url(URL)</code>. This method will open the URL given if the browser is not currently on that page. This is used as a method in recorded scripts when SeleniumBase detects that a click action has already brought the test to the given page. This method not only prevents an extra page load if not needed, but it also lets people know the current page of the browser at that point in the test.</p>
<p>🔴 SeleniumBase <code>1.66.1</code> adds the ability to record changes to <i>"Choose File"</i> <code>input</code> fields. It also adds the <code>self.set_content_to_frame(frame)</code> method, which lets you record actions inside of iframes on pages. Sometimes the <i>"Choose File"</i> input field is hidden on some sites, so <code>self.show_file_choosers()</code> was also added to get around this edge case.
--------
<div>To learn more about SeleniumBase, check out the Docs Site:</div>

View File

@ -58,7 +58,7 @@ pytest-rerunfailures==9.1.1;python_version>="3.5" and python_version<"3.6"
pytest-rerunfailures==10.2;python_version>="3.6"
pytest-xdist==1.34.0;python_version<"3.5"
pytest-xdist==2.2.1;python_version>="3.5" and python_version<"3.6"
pytest-xdist==2.3.0;python_version>="3.6"
pytest-xdist==2.4.0;python_version>="3.6"
parameterized==0.8.1
sbvirtualdisplay==1.0.0
soupsieve==1.9.6;python_version<"3.5"

View File

@ -1,2 +1,2 @@
# seleniumbase package
__version__ = "1.66.0"
__version__ = "1.66.1"

Binary file not shown.

View File

@ -2248,6 +2248,13 @@ class BaseCase(unittest.TestCase):
self.__check_scope()
self.driver.switch_to.default_content()
def set_content_to_frame(self, frame, timeout=None):
"""Replaces the page html with an iframe's html from that page."""
self.switch_to_frame(frame, timeout=timeout)
iframe_html = self.get_page_source()
self.switch_to_default_content()
self.set_content(iframe_html)
def open_new_window(self, switch_to=True):
""" Opens a new browser tab/window and switches to it by default. """
self.__check_scope()
@ -2955,6 +2962,20 @@ class BaseCase(unittest.TestCase):
elif '"' in action[1] and '"' in action[2]:
sb_actions.append("self.set_value('%s', '%s')" % (
action[1], action[2]))
elif action[0] == "cho_f":
action[2] = action[2].replace("\\", "\\\\")
if '"' not in action[1] and '"' not in action[2]:
sb_actions.append('self.choose_file("%s", "%s")' % (
action[1], action[2]))
elif '"' not in action[1] and '"' in action[2]:
sb_actions.append('self.choose_file("%s", \'%s\')' % (
action[1], action[2]))
elif '"' in action[1] and '"' not in action[2]:
sb_actions.append('self.choose_file(\'%s\', "%s")' % (
action[1], action[2]))
elif '"' in action[1] and '"' in action[2]:
sb_actions.append("self.choose_file('%s', '%s')" % (
action[1], action[2]))
elif action[0] == "c_box":
cb_method = "check_if_unchecked"
if action[2] == "no":
@ -3477,6 +3498,29 @@ class BaseCase(unittest.TestCase):
except Exception:
pass # Don't fail test if ad_blocking fails
def show_file_choosers(self):
"""Display hidden file-chooser input fields on sites if present."""
css_selector = 'input[type="file"]'
try:
self.show_elements(css_selector)
except Exception:
pass
css_selector = re.escape(css_selector) # Add "\\" to special chars
css_selector = self.__escape_quotes_if_needed(css_selector)
script = (
"""var $elements = document.querySelectorAll('%s');
var index = 0, length = $elements.length;
for(; index < length; index++){
the_class = $elements[index].getAttribute('class');
new_class = the_class.replaceAll('hidden', 'visible');
$elements[index].setAttribute('class', new_class);}"""
% css_selector
)
try:
self.execute_script(script)
except Exception:
pass
def get_domain_url(self, url):
self.__check_scope()
return page_utils.get_domain_url(url)

View File

@ -97,6 +97,9 @@ var getBestSelector = function(el) {
non_id_attributes.push('data-test');
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-action');
non_id_attributes.push('data-target');
non_id_attributes.push('alt');
non_id_attributes.push('title');
non_id_attributes.push('heading');
@ -315,6 +318,17 @@ document.body.addEventListener('change', function (event) {
value = element.value;
document.recorded_actions.push(['set_v', selector, value, d_now]);
}
else if (tag_name === 'input' && element.type === 'file')
{
if (ra_len > 0 &&
document.recorded_actions[ra_len-1][1] === selector)
{
document.recorded_actions.pop();
ra_len = document.recorded_actions.length;
}
value = element.value;
document.recorded_actions.push(['cho_f', selector, value, d_now]);
}
else if (ra_len > 0 &&
document.recorded_actions[ra_len-1][1] === selector &&
tag_name === 'input' && element.type === 'checkbox')

View File

@ -50,7 +50,7 @@ if sys.argv[-1] == "publish":
print("\n*** Installing twine: *** (Required for PyPI uploads)\n")
os.system("python -m pip install --upgrade 'twine>=1.15.0'")
print("\n*** Installing tqdm: *** (Required for PyPI uploads)\n")
os.system("python -m pip install --upgrade 'tqdm>=4.62.2'")
os.system("python -m pip install --upgrade 'tqdm>=4.62.3'")
print("\n*** Publishing The Release to PyPI: ***\n")
os.system("python -m twine upload dist/*") # Requires ~/.pypirc Keys
print("\n*** The Release was PUBLISHED SUCCESSFULLY to PyPI! :) ***\n")
@ -174,7 +174,7 @@ setup(
'pytest-rerunfailures==10.2;python_version>="3.6"',
'pytest-xdist==1.34.0;python_version<"3.5"',
'pytest-xdist==2.2.1;python_version>="3.5" and python_version<"3.6"',
'pytest-xdist==2.3.0;python_version>="3.6"',
'pytest-xdist==2.4.0;python_version>="3.6"',
"parameterized==0.8.1",
"sbvirtualdisplay==1.0.0",
'soupsieve==1.9.6;python_version<"3.5"',