Merge pull request #986 from seleniumbase/recorder-mode-updates
Make improvements to "Recorder Mode"
This commit is contained in:
commit
b5b0d9e788
12
README.md
12
README.md
|
@ -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">
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
|
@ -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"]')
|
||||
|
|
|
@ -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>
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
# seleniumbase package
|
||||
__version__ = "1.66.0"
|
||||
__version__ = "1.66.1"
|
||||
|
|
Binary file not shown.
|
@ -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)
|
||||
|
|
|
@ -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')
|
||||
|
|
4
setup.py
4
setup.py
|
@ -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"',
|
||||
|
|
Loading…
Reference in New Issue