Skip to content

Commit 6958e9b

Browse files
authored
Merge pull request #418 from seleniumbase/add-html-inspector
Add the inspect_html() method
2 parents c5d2c04 + de686dc commit 6958e9b

File tree

10 files changed

+105
-5
lines changed

10 files changed

+105
-5
lines changed

.travis.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ script:
3535
- "nosetests examples/boilerplates/boilerplate_test.py --browser=chrome --headless"
3636
- "pytest examples/my_first_test.py --browser=firefox -s --headless --with-db_reporting"
3737
- "pytest examples/my_first_test.py --browser=chrome -s --headless --with-db_reporting --demo_mode --demo_sleep=0.2"
38+
- "pytest examples/test_inspect_html.py --browser=chrome -s --headless --with-db_reporting"
3839
- "pytest examples/tour_examples/google_tour.py -s --headless --with-db_reporting"
3940
- "sudo mysql --password=test -e 'select test_address,browser,state,start_time,runtime from test_db.test_run_data'"
4041
#after_script:

azure-pipelines.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,9 @@ jobs:
5454
- script: pytest examples/my_first_test.py --browser=chrome --headless -v -s --junit-xml=junit/test-results.xml
5555
displayName: 'Run pytest my_first_test.py --browser=chrome --headless'
5656

57+
- script: pytest examples/test_inspect_html.py --browser=chrome --headless -v -s --junit-xml=junit/test-results.xml
58+
displayName: 'Run pytest test_inspect_html.py --browser=chrome --headless'
59+
5760
- script: pytest examples/my_first_test.py --browser=firefox --headless -v -s --junit-xml=junit/test-results.xml
5861
displayName: 'Run pytest my_first_test.py --browser=firefox --headless'
5962

examples/test_inspect_html.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
"""
2+
Uses the SeleniumBase implementation of HTML-Inspector to inspect the HTML.
3+
See https://github.com/philipwalton/html-inspector for more details.
4+
"""
5+
6+
from seleniumbase import BaseCase
7+
8+
9+
class MyTestClass(BaseCase):
10+
11+
def test_html_inspector(self):
12+
self.open("https://xkcd.com/1144/")
13+
self.inspect_html()

help_docs/method_summary.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,8 @@ self.assert_title(title)
243243

244244
self.assert_no_js_errors()
245245

246+
self.inspect_html()
247+
246248
self.get_google_auth_password(totp_key=None)
247249

248250
self.convert_xpath_to_css(xpath)

requirements.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ pytest-forked>=1.1.3
1919
pytest-html==1.22.0
2020
pytest-metadata>=1.8.0
2121
pytest-ordering>=0.6
22-
pytest-rerunfailures>=7.0
22+
pytest-rerunfailures>=8.0
2323
pytest-timeout>=1.3.3
2424
pytest-xdist>=1.30.0
2525
parameterized>=0.7.0
@@ -28,7 +28,7 @@ atomicwrites>=1.3.0
2828
portalocker>=1.5.2
2929
cryptography>=2.8
3030
asn1crypto>=1.2.0
31-
pyopenssl>=19.0.0
31+
pyopenssl>=19.1.0
3232
colorama>=0.4.1
3333
pymysql>=0.9.3
3434
pyotp>=2.3.0

seleniumbase/fixtures/base_case.py

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2022,6 +2022,49 @@ def assert_no_js_errors(self):
20222022
messenger_post = ("ASSERT NO JS ERRORS")
20232023
self.__highlight_with_assert_success(messenger_post, "html")
20242024

2025+
def __activate_html_inspector(self):
2026+
js_utils.activate_html_inspector(self.driver)
2027+
2028+
def inspect_html(self):
2029+
""" Inspects the Page HTML with HTML-Inspector.
2030+
(https://github.com/philipwalton/html-inspector)
2031+
(https://cdnjs.com/libraries/html-inspector)
2032+
Prints the results and also returns them. """
2033+
self.__activate_html_inspector()
2034+
script = ("""HTMLInspector.inspect();""")
2035+
self.execute_script(script)
2036+
time.sleep(0.1)
2037+
browser_logs = []
2038+
try:
2039+
browser_logs = self.driver.get_log('browser')
2040+
except (ValueError, WebDriverException):
2041+
# If unable to get browser logs, skip the assert and return.
2042+
return("(Unable to Inspect HTML! -> Only works on Chrome!)")
2043+
messenger_library = "//cdnjs.cloudflare.com/ajax/libs/messenger"
2044+
url = self.get_current_url()
2045+
header = '\n* HTML Inspection Results: %s' % url
2046+
results = [header]
2047+
row_count = 0
2048+
for entry in browser_logs:
2049+
message = entry['message']
2050+
if "0:6053 " in message:
2051+
message = message.split("0:6053")[1]
2052+
message = message.replace("\\u003C", "<")
2053+
if message.startswith(' "') and message.count('"') == 2:
2054+
message = message.split('"')[1]
2055+
message = "X - " + message
2056+
if messenger_library not in message:
2057+
if message not in results:
2058+
results.append(message)
2059+
row_count += 1
2060+
if row_count > 0:
2061+
results.append('* (See the Console output for details!)')
2062+
else:
2063+
results.append('* (No issues detected!)')
2064+
results = '\n'.join(results)
2065+
print(results)
2066+
return(results)
2067+
20252068
def get_google_auth_password(self, totp_key=None):
20262069
""" Returns a time-based one-time password based on the
20272070
Google Authenticator password algorithm. Works with Authy.

seleniumbase/fixtures/constants.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,12 @@ class Backbone:
6666
"backbone.js/%s/backbone-min.js" % VER)
6767

6868

69+
class HtmlInspector:
70+
VER = "0.8.2"
71+
MIN_JS = ("//cdnjs.cloudflare.com/ajax/libs/"
72+
"html-inspector/%s/html-inspector.min.js" % VER)
73+
74+
6975
class BootstrapTour:
7076
VER = "0.11.0"
7177
MIN_CSS = ("//cdnjs.cloudflare.com/ajax/libs/"

seleniumbase/fixtures/js_utils.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,14 @@ def wait_for_angularjs(driver, timeout=settings.LARGE_TIMEOUT, **kwargs):
7575
time.sleep(0.05)
7676

7777

78+
def is_html_inspector_activated(driver):
79+
try:
80+
driver.execute_script("HTMLInspector") # Fails if not defined
81+
return True
82+
except Exception:
83+
return False
84+
85+
7886
def is_jquery_activated(driver):
7987
try:
8088
driver.execute_script("jQuery('html')") # Fails if jq is not defined
@@ -386,6 +394,28 @@ def activate_jquery_confirm(driver):
386394
time.sleep(0.1)
387395

388396

397+
def activate_html_inspector(driver):
398+
jquery_js = constants.JQuery.MIN_JS
399+
html_inspector_js = constants.HtmlInspector.MIN_JS
400+
401+
if is_html_inspector_activated(driver):
402+
return
403+
if not is_jquery_activated(driver):
404+
add_js_link(driver, jquery_js)
405+
wait_for_jquery_active(driver, timeout=0.6)
406+
add_js_link(driver, html_inspector_js)
407+
408+
for x in range(7):
409+
# HTML-Inspector needs a small amount of time to load & activate.
410+
try:
411+
driver.execute_script("HTMLInspector")
412+
wait_for_ready_state_complete(driver)
413+
wait_for_angularjs(driver)
414+
return
415+
except Exception:
416+
time.sleep(0.1)
417+
418+
389419
def activate_messenger(driver):
390420
jquery_js = constants.JQuery.MIN_JS
391421
messenger_css = constants.Messenger.MIN_CSS

seleniumbase/resources/html_inspector/html-inspector.min.js

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

setup.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@
4545

4646
setup(
4747
name='seleniumbase',
48-
version='1.32.24',
48+
version='1.33.0',
4949
description='Fast, Easy, and Reliable Browser Automation & Testing.',
5050
long_description=long_description,
5151
long_description_content_type='text/markdown',
@@ -102,7 +102,7 @@
102102
'pytest-html==1.22.0', # Keep at 1.22.0 unless tested on Windows
103103
'pytest-metadata>=1.8.0',
104104
'pytest-ordering>=0.6',
105-
'pytest-rerunfailures>=7.0',
105+
'pytest-rerunfailures>=8.0',
106106
'pytest-timeout>=1.3.3',
107107
'pytest-xdist>=1.30.0',
108108
'parameterized>=0.7.0',
@@ -111,7 +111,7 @@
111111
'portalocker>=1.5.2',
112112
'cryptography>=2.8',
113113
'asn1crypto>=1.2.0',
114-
'pyopenssl>=19.0.0',
114+
'pyopenssl>=19.1.0',
115115
'colorama>=0.4.1',
116116
'pymysql>=0.9.3',
117117
'pyotp>=2.3.0',

0 commit comments

Comments
 (0)