From 9ba398dee959b557c2838002c35eea261a4518f9 Mon Sep 17 00:00:00 2001 From: Ian Wienand Date: Tue, 7 Sep 2021 10:47:38 +1000 Subject: [PATCH] testinfra: refactor screenshot taking Reduce the screenshots to a single utility function to avoid copying a lot of boilerplate. Change-Id: Iad1c7afa4e9ea9a4ddaca5e62751795e60bc2980 --- testinfra/test_gerrit.py | 60 +++++++++++--------------------------- testinfra/test_gitea.py | 47 ++++-------------------------- testinfra/test_grafana.py | 40 ++++--------------------- testinfra/test_paste.py | 24 ++++----------- testinfra/util.py | 61 +++++++++++++++++++++++++++++++++++++++ 5 files changed, 95 insertions(+), 137 deletions(-) diff --git a/testinfra/test_gerrit.py b/testinfra/test_gerrit.py index f57cc61637..c18a0759d1 100644 --- a/testinfra/test_gerrit.py +++ b/testinfra/test_gerrit.py @@ -12,11 +12,10 @@ # License for the specific language governing permissions and limitations # under the License. -from selenium import webdriver -from selenium.webdriver.support.ui import WebDriverWait -from selenium.common.exceptions import TimeoutException import time +from util import take_screenshots + testinfra_hosts = [ 'review02.opendev.org', ] @@ -33,46 +32,21 @@ def test_gerrit_x_project_clone(host): assert cmd.succeeded def test_gerrit_screenshot(host): - driver = webdriver.Remote( - command_executor='http://%s:4444/wd/hub' % (host.backend.get_hostname()), - desired_capabilities=webdriver.DesiredCapabilities.FIREFOX) - try: - driver.get("http://localhost:8081") - WebDriverWait(driver, 30).until(lambda driver: driver.execute_script( - 'return document.readyState') == 'complete') - # NOTE(ianw): The page doesn't really seem to be complete at - # this point, not sure what to listen for... - time.sleep(5) - driver.save_screenshot("/var/log/screenshots/gerrit-main-page.png") + # Click the gerrit results tab into view + script = ("document.querySelector('gr-app').shadowRoot" + ".querySelector('gr-app-element').shadowRoot" + ".querySelector('main')" + ".querySelector('gr-change-view').shadowRoot" + ".querySelector('paper-tab[data-name=\"change-view-tab-header-zuul-results-summary\"]')" + ".click()") - for change in (1, 2): - driver.get("http://localhost:8081/c/x/test-project/+/%s" % change) - time.sleep(5) - driver.execute_script( - "document.querySelector('gr-app').shadowRoot" - ".querySelector('gr-app-element').shadowRoot" - ".querySelector('main')" - ".querySelector('gr-change-view').shadowRoot" - ".querySelector('paper-tab[data-name=\"change-view-tab-header-zuul-results-summary\"]')" - ".click()" - ) - time.sleep(5) + shots = ( + ('http://localhost:8081', None, 'gerrit-main-page.png'), + ('http://localhost:8081/c/x/test-project/+/1', script, + 'gerrit-change-page-1.png'), + ('http://localhost:8081/c/x/test-project/+/2', script, + 'gerrit-change-page-2.png') + ) - original_size = driver.get_window_size() - required_width = driver.execute_script( - 'return document.body.parentNode.scrollWidth') - required_height = driver.execute_script( - 'return document.body.parentNode.scrollHeight') + 100 - driver.set_window_size(required_width, required_height) - - driver.find_element_by_tag_name('body'). \ - screenshot("/var/log/screenshots/gerrit-change-page-%s.png" % change) - - driver.set_window_size( - original_size['width'], original_size['height']) - - except TimeoutException as e: - raise e - finally: - driver.quit() + take_screenshots(host, shots) diff --git a/testinfra/test_gitea.py b/testinfra/test_gitea.py index 265eb17395..cd919bacf4 100644 --- a/testinfra/test_gitea.py +++ b/testinfra/test_gitea.py @@ -12,11 +12,7 @@ # License for the specific language governing permissions and limitations # under the License. -import time - -from selenium import webdriver -from selenium.webdriver.support.ui import WebDriverWait -from selenium.common.exceptions import TimeoutException +from util import take_screenshots testinfra_hosts = ['gitea99.opendev.org'] @@ -91,46 +87,13 @@ def test_project_clone(host): assert cmd.succeeded def test_gitea_screenshots(host): - driver = webdriver.Remote( - command_executor='http://%s:4444/wd/hub' % (host.backend.get_hostname()), - desired_capabilities=webdriver.DesiredCapabilities.FIREFOX) shots = ( - ('https://localhost:3081', 'gitea-main.png'), - ('https://localhost:3081/opendev/system-config', + ('https://localhost:3081', None, 'gitea-main.png'), + ('https://localhost:3081/opendev/system-config', None, 'gitea-project-system-config.png'), - ('https://localhost:3081/opendev/disk-image-builder', + ('https://localhost:3081/opendev/disk-image-builder', None, 'gitea-project-dib.png') ) - try: - for url, png in shots: - driver.get(url) - WebDriverWait(driver, 30).until( - lambda driver: driver.execute_script( - 'return document.readyState') == 'complete') - time.sleep(5) - # NOTE(ianw) This is a mash-up of things I found on - # stackoverflow and other bits googling "full size - # screenshot". You expand the viewport and take a - # shot of the element so that you don't also - # get scrollbars in the shot, with some tweaking - # because the window size. Apparently selinum 4 - # will have getFullPageScreeshotAs, so we should switch - # to that when available. - original_size = driver.get_window_size() - required_width = driver.execute_script( - 'return document.body.parentNode.scrollWidth') - required_height = driver.execute_script( - 'return document.body.parentNode.scrollHeight') + 100 - driver.set_window_size(required_width, required_height) - driver.find_element_by_tag_name('body'). \ - screenshot("/var/log/screenshots/%s" % png) - - driver.set_window_size( - original_size['width'], original_size['height']) - - except TimeoutException as e: - raise e - finally: - driver.quit() + take_screenshots(host, shots) diff --git a/testinfra/test_grafana.py b/testinfra/test_grafana.py index 044c20f5a4..4cde8c1e0f 100644 --- a/testinfra/test_grafana.py +++ b/testinfra/test_grafana.py @@ -12,11 +12,7 @@ # License for the specific language governing permissions and limitations # under the License. -from selenium import webdriver -from selenium.webdriver.support.ui import WebDriverWait -from selenium.common.exceptions import TimeoutException -import time - +from util import take_screenshots testinfra_hosts = ['grafana01.opendev.org'] @@ -41,32 +37,8 @@ def test_grafana_api_denial(host): assert '403 Forbidden' in cmd.stdout def test_grafana_screenshots(host): - driver = webdriver.Remote( - command_executor='http://%s:4444/wd/hub' % (host.backend.get_hostname()), - desired_capabilities=webdriver.DesiredCapabilities.FIREFOX) - - try: - driver.get("https://localhost") - WebDriverWait(driver, 30).until(lambda driver: driver.execute_script( - 'return document.readyState') == 'complete') - # NOTE(ianw): The page doesn't really seem to be complete at - # this point, not sure what to listen for... - time.sleep(5) - driver.save_screenshot("/var/log/screenshots/grafana-main-page.png") - - driver.get("https://localhost/dashboards") - original_size = driver.get_window_size() - required_width = driver.execute_script( - 'return document.body.parentNode.scrollWidth') - required_height = driver.execute_script( - 'return document.body.parentNode.scrollHeight') + 100 - driver.set_window_size(required_width, required_height) - driver.find_element_by_tag_name('body'). \ - screenshot("/var/log/screenshots/grafana-dashboards-page.png") - driver.set_window_size( - original_size['width'], original_size['height']) - - except TimeoutException as e: - raise e - finally: - driver.quit() + shots = ( + ('https://localhost/', None, 'grafana-main-page.png'), + ('https://localhost/dashboards', None, 'grafana-dashboards-page.png') + ) + take_screenshots(host, shots) diff --git a/testinfra/test_paste.py b/testinfra/test_paste.py index 2bebcc6e27..014a0813df 100644 --- a/testinfra/test_paste.py +++ b/testinfra/test_paste.py @@ -13,10 +13,8 @@ # under the License. import requests -from selenium import webdriver -from selenium.webdriver.support.ui import WebDriverWait -from selenium.common.exceptions import TimeoutException -import time + +from util import take_screenshots testinfra_hosts = ['paste01.opendev.org'] @@ -54,18 +52,8 @@ def test_paste_robots(host): assert 'Disallow: /' in cmd.stdout def test_paste_screenshots(host): - driver = webdriver.Remote( - command_executor='http://%s:4444/wd/hub' % (host.backend.get_hostname()), - desired_capabilities=webdriver.DesiredCapabilities.FIREFOX) + shots = ( + ('https://localhost', None, 'paste-main-page.png'), + ) - try: - driver.get("https://localhost") - WebDriverWait(driver, 30).until(lambda driver: driver.execute_script( - 'return document.readyState') == 'complete') - time.sleep(5) - driver.save_screenshot("/var/log/screenshots/paste-main-page.png") - - except TimeoutException as e: - raise e - finally: - driver.quit() + take_screenshots(host, shots) diff --git a/testinfra/util.py b/testinfra/util.py index 865861c7e1..d494d86c4e 100644 --- a/testinfra/util.py +++ b/testinfra/util.py @@ -13,6 +13,67 @@ # under the License. import socket +import time + +from selenium import webdriver +from selenium.webdriver.support.ui import WebDriverWait +from selenium.common.exceptions import TimeoutException + +def take_screenshots(host, shots): + """Take screenshots + + host: the testinfra host info of the remote host where selenium is + running + shots: a list where each element is a list consisting of + + * (str) URL to screenshot + * (str) Javascript to execute before shot, None to skip + * (str) filename.png, will be placed in /var/log/screenshots for collection + """ + driver = webdriver.Remote( + command_executor='http://%s:4444/wd/hub' % (host.backend.get_hostname()), + desired_capabilities=webdriver.DesiredCapabilities.FIREFOX) + + try: + for url, execute, png in shots: + driver.get(url) + WebDriverWait(driver, 30).until( + lambda driver: driver.execute_script( + 'return document.readyState') == 'complete') + + if execute: + time.sleep(5) + driver.execute_script(execute) + + time.sleep(5) + + # NOTE(ianw) This is a mash-up of things I found on + # stackoverflow and other bits googling "full size + # screenshot". You expand the viewport and take a + # shot of the element so that you don't also + # get scrollbars in the shot, with some tweaking + # because the window size. Apparently selinum 4 + # will have getFullPageScreeshotAs, so we should switch + # to that when available. + original_size = driver.get_window_size() + required_width = driver.execute_script( + 'return document.body.parentNode.scrollWidth') + required_height = driver.execute_script( + 'return document.body.parentNode.scrollHeight') + 100 + driver.set_window_size(required_width, required_height) + + driver.find_element_by_tag_name('body'). \ + screenshot("/var/log/screenshots/%s" % png) + + driver.set_window_size( + original_size['width'], original_size['height']) + + except TimeoutException as e: + raise e + finally: + driver.quit() + + def get_ips(value, family=None): ret = set()