├── .gitignore ├── README.md ├── config.py ├── conftest.py ├── page ├── __init__.py └── baidu_page.py ├── pytest.ini ├── requirements.txt ├── run_tests.py ├── test_dir ├── __init__.py ├── data │ └── data_file.json ├── test_baidu.py └── test_parametrize.py └── test_report └── 2020_07_19_23_01_06 ├── image └── test_bd_search.py_test_search.png ├── junit-xml.xml └── report.html /.gitignore: -------------------------------------------------------------------------------- 1 | *.pyc 2 | *.log 3 | __pycache__ 4 | .idea 5 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # pyautoTest Web UI 自动化项目 2 | 3 | ### 特点 4 | 5 | * 全局配置浏览器启动/关闭。 6 | * 测试用例运行失败自动截图。 7 | * 测试用例运行失败可以重跑。 8 | * 测试数据参数化。 9 | 10 | ### 安装 11 | 12 | ```shell 13 | $ pip install -r requirements.txt 14 | ``` 15 | 16 | 注:安装```requirements.txt```指定依赖库的版本,这是经过测试的,有时候新的版本可会有错。 17 | 18 | ### 配置 19 | 20 | 在 `config.py` 文件配置 21 | 22 | ```python 23 | class RunConfig: 24 | """ 25 | 运行测试配置 26 | """ 27 | # 配置浏览器驱动类型。 28 | driver_type = "chrome" 29 | 30 | # 失败重跑次数 31 | rerun = "3" 32 | 33 | # 当达到最大失败数,停止执行 34 | max_fail = "5" 35 | 36 | # 运行测试用例的目录或文件 37 | cases_path = "./test_dir/" 38 | ``` 39 | 40 | ### 运行 41 | 42 | **不支持在编辑器(pycharm/ VS code ...)中运行,请在 cmd(windows)/终端(Linux)下执行。** 43 | 44 | ```shell 45 | $ python run_tests.py (回归模式,生成HTML报告) 46 | $ python run_tests.py -m debug (调试模式) 47 | ``` 48 | -------------------------------------------------------------------------------- /config.py: -------------------------------------------------------------------------------- 1 | import os 2 | PRO_PATH = os.path.dirname(os.path.abspath(__file__)) 3 | 4 | 5 | class RunConfig: 6 | """ 7 | 运行测试配置 8 | """ 9 | # 运行测试用例的目录或文件 10 | cases_path = os.path.join(PRO_PATH, "test_dir", "test_baidu.py") 11 | 12 | # 配置浏览器驱动类型(chrome/firefox/chrome-headless/firefox-headless)。 13 | driver_type = "chrome" 14 | 15 | # 失败重跑次数 16 | rerun = "1" 17 | 18 | # 当达到最大失败数,停止执行 19 | max_fail = "5" 20 | 21 | # 浏览器驱动(不需要修改) 22 | driver = None 23 | 24 | # 报告路径(不需要修改) 25 | NEW_REPORT = None 26 | -------------------------------------------------------------------------------- /conftest.py: -------------------------------------------------------------------------------- 1 | import os 2 | import pytest 3 | from selenium import webdriver 4 | from selenium.webdriver import Remote 5 | from selenium.webdriver.chrome.options import Options as CH_Options 6 | from selenium.webdriver.firefox.options import Options as FF_Options 7 | from config import RunConfig 8 | 9 | # 项目目录配置 10 | BASE_DIR = os.path.dirname(os.path.abspath(__file__)) 11 | REPORT_DIR = BASE_DIR + "/test_report/" 12 | 13 | 14 | # 设置用例描述表头 15 | def pytest_html_results_table_header(cells): 16 | cells.insert(2, '
{line}
" 79 | body += "" 80 | 81 | # 完整的 HTML 文档 82 | desc_doc = f"{head}{body}" 83 | 84 | return desc_doc 85 | 86 | 87 | def capture_screenshots(case_name): 88 | """ 89 | 配置用例失败截图路径 90 | :param case_name: 用例名 91 | :return: 92 | """ 93 | global driver 94 | file_name = case_name.split("/")[-1] 95 | if RunConfig.NEW_REPORT is None: 96 | raise NameError('没有初始化测试报告目录') 97 | else: 98 | image_dir = os.path.join(RunConfig.NEW_REPORT, "image", file_name) 99 | RunConfig.driver.save_screenshot(image_dir) 100 | 101 | 102 | # 启动浏览器 103 | @pytest.fixture(scope='session', autouse=True) 104 | def browser(): 105 | """ 106 | 全局定义浏览器驱动 107 | :return: 108 | """ 109 | global driver 110 | 111 | if RunConfig.driver_type == "chrome": 112 | # 本地chrome浏览器 113 | driver = webdriver.Chrome() 114 | driver.maximize_window() 115 | 116 | elif RunConfig.driver_type == "firefox": 117 | # 本地firefox浏览器 118 | driver = webdriver.Firefox() 119 | driver.maximize_window() 120 | 121 | elif RunConfig.driver_type == "chrome-headless": 122 | # chrome headless模式 123 | chrome_options = CH_Options() 124 | chrome_options.add_argument("--headless=new") 125 | chrome_options.add_argument('--disable-gpu') 126 | driver = webdriver.Chrome(options=chrome_options) 127 | 128 | elif RunConfig.driver_type == "firefox-headless": 129 | # firefox headless模式 130 | firefox_options = FF_Options() 131 | firefox_options.headless = True 132 | driver = webdriver.Firefox(options=firefox_options) 133 | 134 | elif RunConfig.driver_type == "grid": 135 | # 通过远程节点运行 136 | chrome_options = CH_Options() 137 | driver = Remote(command_executor='http://localhost:4444/wd/hub', options=chrome_options) 138 | 139 | else: 140 | raise NameError("driver驱动类型定义错误!") 141 | 142 | RunConfig.driver = driver 143 | 144 | yield driver 145 | 146 | driver.quit() 147 | 148 | return driver 149 | 150 | 151 | if __name__ == "__main__": 152 | capture_screenshots("test_dir/test_baidu_search.test_search_python.png") 153 | -------------------------------------------------------------------------------- /page/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/defnngj/pyautoTest/e4d4a52665d63f42f6941c53a413e8f14ddbf174/page/__init__.py -------------------------------------------------------------------------------- /page/baidu_page.py: -------------------------------------------------------------------------------- 1 | from poium import Page, Element 2 | 3 | 4 | class BaiduPage(Page): 5 | search_input = Element(id_="kw", describe="搜索框") 6 | search_button = Element(id_="su", describe="搜索按钮") 7 | settings = Element(css="#s-usersetting-top", describe="设置") 8 | search_setting = Element(css="#s-user-setting-menu > div > a.setpref", describe="搜索设置") 9 | save_setting = Element(link_text="保存设置", describe="保存设置") 10 | -------------------------------------------------------------------------------- /pytest.ini: -------------------------------------------------------------------------------- 1 | [pytest] 2 | base_url = https://www.baidu.com -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | pytest==8.3.2 2 | pytest-html==4.1.1 3 | pytest-rerunfailures==9.1.1 4 | pytest-base-url==1.4.2 5 | click==7.1.2 6 | poium==1.5.2 -------------------------------------------------------------------------------- /run_tests.py: -------------------------------------------------------------------------------- 1 | # coding=utf-8 2 | import os 3 | import time 4 | import logging 5 | import pytest 6 | import click 7 | from conftest import REPORT_DIR 8 | from config import RunConfig 9 | 10 | logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s') 11 | logger = logging.getLogger(__name__) 12 | 13 | ''' 14 | 说明: 15 | 1、用例创建原则,测试文件名必须以“test”开头,测试函数必须以“test”开头。 16 | 2、运行方式: 17 | > python run_tests.py (回归模式,生成HTML报告) 18 | > python run_tests.py -m debug (调试模式) 19 | ''' 20 | 21 | 22 | def init_env(new_report): 23 | """ 24 | 初始化测试报告目录 25 | """ 26 | os.mkdir(new_report) 27 | os.mkdir(new_report + "/image") 28 | 29 | 30 | @click.command() 31 | @click.option('-m', default=None, help='输入运行模式:run 或 debug.') 32 | def run(m): 33 | if m is None or m == "run": 34 | logger.info("回归模式,开始执行✈✈!") 35 | now_time = time.strftime("%Y_%m_%d_%H_%M_%S") 36 | RunConfig.NEW_REPORT = os.path.join(REPORT_DIR, now_time) 37 | init_env(RunConfig.NEW_REPORT) 38 | html_report = os.path.join(RunConfig.NEW_REPORT, "report.html") 39 | xml_report = os.path.join(RunConfig.NEW_REPORT, "junit-xml.xml") 40 | pytest.main(["-s", "-v", RunConfig.cases_path, 41 | "--html=" + html_report, 42 | "--junit-xml=" + xml_report, 43 | "--self-contained-html", 44 | "--maxfail", RunConfig.max_fail, 45 | "--reruns", RunConfig.rerun]) 46 | logger.info("运行结束,生成测试报告♥❤!") 47 | elif m == "debug": 48 | print("debug模式,开始执行!") 49 | pytest.main(["-v", "-s", RunConfig.cases_path]) 50 | print("运行结束!!") 51 | 52 | 53 | if __name__ == '__main__': 54 | run() 55 | -------------------------------------------------------------------------------- /test_dir/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/defnngj/pyautoTest/e4d4a52665d63f42f6941c53a413e8f14ddbf174/test_dir/__init__.py -------------------------------------------------------------------------------- /test_dir/data/data_file.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "id": 1, 4 | "search_key": "Selenium" 5 | }, 6 | { 7 | "id": 2, 8 | "search_key": "poium" 9 | } 10 | ] -------------------------------------------------------------------------------- /test_dir/test_baidu.py: -------------------------------------------------------------------------------- 1 | """ 2 | @author: 虫师 3 | @data: 2019-10-17 4 | @function python 基本用法 5 | """ 6 | import sys 7 | from time import sleep 8 | import pytest 9 | from os.path import dirname, abspath 10 | 11 | sys.path.insert(0, dirname(dirname(abspath(__file__)))) 12 | from page.baidu_page import BaiduPage 13 | 14 | 15 | class TestSearch: 16 | """百度搜索""" 17 | 18 | def test_baidu_search_case(self, browser, base_url): 19 | """ 20 | 名称:百度搜索"pytest" 21 | 步骤: 22 | 1、打开浏览器 23 | 2、输入"pytest"关键字 24 | 3、点击搜索按钮 25 | 检查点: 26 | * 检查页面标题是否包含关键字。 27 | """ 28 | page = BaiduPage(browser) 29 | page.open(base_url) 30 | page.search_input = "pytest" 31 | page.search_button.click() 32 | sleep(2) 33 | assert browser.title == "pytest_百度搜索" 34 | 35 | 36 | class TestSearchSettings: 37 | """百度搜索设置""" 38 | 39 | def test_baidu_search_setting(self, browser, base_url): 40 | """ 41 | 名称:百度搜索设置 42 | 步骤: 43 | 1、打开百度浏览器 44 | 2、点击设置链接 45 | 3、在下拉框中"选择搜索" 46 | 4、点击"保存设置" 47 | 5、对弹出警告框保存 48 | 检查点: 49 | * 检查是否弹出提示框 50 | """ 51 | page = BaiduPage(browser) 52 | page.open(base_url) 53 | page.settings.click() 54 | page.search_setting.click() 55 | sleep(2) 56 | page.save_setting.click() 57 | alert_text = page.get_alert_text 58 | page.accept_alert() 59 | assert alert_text == "已经记录下您的使用偏好" 60 | 61 | 62 | if __name__ == '__main__': 63 | pytest.main(["-v", "-s", "test_baidu.py"]) 64 | # pytest.main(["-v", "-s", "test_baidu.py::TestSearch::test_baidu_search_case"]) 65 | # pytest.main(["-v", "-s", "test_baidu.py::TestSearch"]) 66 | # pytest.main(["-v", "-s", "test_baidu.py::TestSearchSettings"]) 67 | -------------------------------------------------------------------------------- /test_dir/test_parametrize.py: -------------------------------------------------------------------------------- 1 | """ 2 | @author: 虫师 3 | @data: 2019-10-17 4 | @function pytest 参数使用 5 | """ 6 | import sys 7 | import json 8 | from time import sleep 9 | import pytest 10 | from os.path import dirname, abspath 11 | 12 | base_path = dirname(dirname(abspath(__file__))) 13 | sys.path.insert(0, base_path) 14 | from page.baidu_page import BaiduPage 15 | 16 | 17 | @pytest.mark.parametrize( 18 | "name, search_key", 19 | [("1", "Selenium"), 20 | ("2", "pytest文档"), 21 | ("3", "pytest-html"), 22 | ], 23 | ids=["case1", "case2", "case3"] 24 | ) 25 | def test_baidu_search(name, search_key, browser, base_url): 26 | """百度搜索参数化""" 27 | page = BaiduPage(browser) 28 | page.open(base_url) 29 | page.search_input = search_key 30 | page.search_button.click() 31 | sleep(2) 32 | assert browser.title == search_key + "_百度搜索" 33 | 34 | 35 | def get_data(file_path): 36 | """ 37 | 读取参数化文件 38 | :param file_path: 39 | :return: 40 | """ 41 | data = [] 42 | with(open(file_path, "r")) as f: 43 | dict_data = json.loads(f.read()) 44 | for i in dict_data: 45 | data.append(tuple(i.values())) 46 | return data 47 | 48 | 49 | @pytest.mark.parametrize( 50 | "name, search_key", 51 | get_data(base_path + "/test_dir/data/data_file.json") 52 | ) 53 | def test_baidu_search(name, search_key, browser, base_url): 54 | page = BaiduPage(browser) 55 | page.open(base_url) 56 | page.search_input = search_key 57 | page.search_button.click() 58 | sleep(2) 59 | assert browser.title == search_key + "_百度搜索" 60 | -------------------------------------------------------------------------------- /test_report/2020_07_19_23_01_06/image/test_bd_search.py_test_search.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/defnngj/pyautoTest/e4d4a52665d63f42f6941c53a413e8f14ddbf174/test_report/2020_07_19_23_01_06/image/test_bd_search.py_test_search.png -------------------------------------------------------------------------------- /test_report/2020_07_19_23_01_06/junit-xml.xml: -------------------------------------------------------------------------------- 1 |Report generated on 19-Jul-2020 at 23:01:24 by pytest-html v2.1.1
424 |JAVA_HOME | 428 |C:\Program Files\Java\jdk1.8.0_251 |
Packages | 431 |{"pluggy": "0.13.1", "py": "1.9.0", "pytest": "5.4.3"} |
Platform | 434 |Windows-10-10.0.18362-SP0 |
Plugins | 437 |{"allure-pytest": "2.8.16", "html": "2.1.1", "metadata": "1.10.0", "rerunfailures": "9.0"} |
Python | 440 |3.7.7 |
1 tests ran in 17.83 seconds.
443 |(Un)check the boxes to filter the results.
0 passed, 0 skipped, 1 failed, 0 errors, 0 expected failures, 0 unexpected passes, 1 rerun 444 |Result | 449 |Test | 450 |Description | 451 |Duration |
---|---|---|---|
No results found. Try to check the filters | |||
Failed | 457 |test_dir/test_bd_search.py::test_search | 458 |
459 |
460 |
461 |
462 |
463 | 搜索 pytest 关键字 464 |1. 打开百度首页 465 |2. 输入关键字“pytest” 466 |3. 点击搜索按钮 467 |
|
468 | 0.83 |
471 | ![]() browser = <selenium.webdriver.chrome.webdriver.WebDriver (session="e13773595aaaca74488d45366ce33b66")> base_url = 'https://www.baidu.com' def test_search(browser, base_url): """ 搜索 pytest 关键字 1. 打开百度首页 2. 输入关键字“pytest” 3. 点击搜索按钮 """ browser.get(base_url) browser.find_element_by_id("kw").send_keys("pytest") > browser.find_element_by_id("susss").click() test_dir\test_bd_search.py:13: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ C:\Python37\lib\site-packages\selenium\webdriver\remote\webdriver.py:360: in find_element_by_id return self.find_element(by=By.ID, value=id_) C:\Python37\lib\site-packages\selenium\webdriver\remote\webdriver.py:978: in find_element 'value': value})['value'] C:\Python37\lib\site-packages\selenium\webdriver\remote\webdriver.py:321: in execute self.error_handler.check_response(response) _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = <selenium.webdriver.remote.errorhandler.ErrorHandler object at 0x000002749E2209C8> response = {'status': 404, 'value': '{"value":{"error":"no such element","message":"no such element: Unable to locate element: {\...\n\\tRtlGetAppContainerNamedObjectPath [0x77687C24+228]\\n\\tRtlGetAppContainerNamedObjectPath [0x77687BF4+180]\\n"}}'} def check_response(self, response): """ Checks that a JSON response from the WebDriver does not have an error. :Args: - response - The JSON response from the WebDriver server as a dictionary object. :Raises: If the response contains an error message. """ status = response.get('status', None) if status is None or status == ErrorCode.SUCCESS: return value = None message = response.get("message", "") screen = response.get("screen", "") stacktrace = None if isinstance(status, int): value_json = response.get('value', None) if value_json and isinstance(value_json, basestring): import json try: value = json.loads(value_json) if len(value.keys()) == 1: value = value['value'] status = value.get('error', None) if status is None: status = value["status"] message = value["value"] if not isinstance(message, basestring): value = message message = message.get('message') else: message = value.get('message', None) except ValueError: pass exception_class = ErrorInResponseException if status in ErrorCode.NO_SUCH_ELEMENT: exception_class = NoSuchElementException elif status in ErrorCode.NO_SUCH_FRAME: exception_class = NoSuchFrameException elif status in ErrorCode.NO_SUCH_WINDOW: exception_class = NoSuchWindowException elif status in ErrorCode.STALE_ELEMENT_REFERENCE: exception_class = StaleElementReferenceException elif status in ErrorCode.ELEMENT_NOT_VISIBLE: exception_class = ElementNotVisibleException elif status in ErrorCode.INVALID_ELEMENT_STATE: exception_class = InvalidElementStateException elif status in ErrorCode.INVALID_SELECTOR \ or status in ErrorCode.INVALID_XPATH_SELECTOR \ or status in ErrorCode.INVALID_XPATH_SELECTOR_RETURN_TYPER: exception_class = InvalidSelectorException elif status in ErrorCode.ELEMENT_IS_NOT_SELECTABLE: exception_class = ElementNotSelectableException elif status in ErrorCode.ELEMENT_NOT_INTERACTABLE: exception_class = ElementNotInteractableException elif status in ErrorCode.INVALID_COOKIE_DOMAIN: exception_class = InvalidCookieDomainException elif status in ErrorCode.UNABLE_TO_SET_COOKIE: exception_class = UnableToSetCookieException elif status in ErrorCode.TIMEOUT: exception_class = TimeoutException elif status in ErrorCode.SCRIPT_TIMEOUT: exception_class = TimeoutException elif status in ErrorCode.UNKNOWN_ERROR: exception_class = WebDriverException elif status in ErrorCode.UNEXPECTED_ALERT_OPEN: exception_class = UnexpectedAlertPresentException elif status in ErrorCode.NO_ALERT_OPEN: exception_class = NoAlertPresentException elif status in ErrorCode.IME_NOT_AVAILABLE: exception_class = ImeNotAvailableException elif status in ErrorCode.IME_ENGINE_ACTIVATION_FAILED: exception_class = ImeActivationFailedException elif status in ErrorCode.MOVE_TARGET_OUT_OF_BOUNDS: exception_class = MoveTargetOutOfBoundsException elif status in ErrorCode.JAVASCRIPT_ERROR: exception_class = JavascriptException elif status in ErrorCode.SESSION_NOT_CREATED: exception_class = SessionNotCreatedException elif status in ErrorCode.INVALID_ARGUMENT: exception_class = InvalidArgumentException elif status in ErrorCode.NO_SUCH_COOKIE: exception_class = NoSuchCookieException elif status in ErrorCode.UNABLE_TO_CAPTURE_SCREEN: exception_class = ScreenshotException elif status in ErrorCode.ELEMENT_CLICK_INTERCEPTED: exception_class = ElementClickInterceptedException elif status in ErrorCode.INSECURE_CERTIFICATE: exception_class = InsecureCertificateException elif status in ErrorCode.INVALID_COORDINATES: exception_class = InvalidCoordinatesException elif status in ErrorCode.INVALID_SESSION_ID: exception_class = InvalidSessionIdException elif status in ErrorCode.UNKNOWN_METHOD: exception_class = UnknownMethodException else: exception_class = WebDriverException if value == '' or value is None: value = response['value'] if isinstance(value, basestring): if exception_class == ErrorInResponseException: raise exception_class(response, value) raise exception_class(value) if message == "" and 'message' in value: message = value['message'] screen = None if 'screen' in value: screen = value['screen'] stacktrace = None if 'stackTrace' in value and value['stackTrace']: stacktrace = [] try: for frame in value['stackTrace']: line = self._value_or_default(frame, 'lineNumber', '') file = self._value_or_default(frame, 'fileName', '<anonymous>') if line: file = "%s:%s" % (file, line) meth = self._value_or_default(frame, 'methodName', '<anonymous>') if 'className' in frame: meth = "%s.%s" % (frame['className'], meth) msg = " at %s (%s)" msg = msg % (meth, file) stacktrace.append(msg) except TypeError: pass if exception_class == ErrorInResponseException: raise exception_class(response, message) elif exception_class == UnexpectedAlertPresentException: alert_text = None if 'data' in value: alert_text = value['data'].get('text') elif 'alert' in value: alert_text = value['alert'].get('text') raise exception_class(message, screen, stacktrace, alert_text) > raise exception_class(message, screen, stacktrace) E selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"css selector","selector":"[id="susss"]"} E (Session info: chrome=84.0.4147.89) C:\Python37\lib\site-packages\selenium\webdriver\remote\errorhandler.py:242: NoSuchElementException | |||
Rerun | 476 |test_dir/test_bd_search.py::test_search | 477 |
478 |
479 |
480 |
481 |
482 | 搜索 pytest 关键字 483 |1. 打开百度首页 484 |2. 输入关键字“pytest” 485 |3. 点击搜索按钮 486 |
|
487 | 1.10 |
490 | ![]() browser = <selenium.webdriver.chrome.webdriver.WebDriver (session="8ab137205f23c019f6ffcc6c0ad1dc46")> base_url = 'https://www.baidu.com' def test_search(browser, base_url): """ 搜索 pytest 关键字 1. 打开百度首页 2. 输入关键字“pytest” 3. 点击搜索按钮 """ browser.get(base_url) browser.find_element_by_id("kw").send_keys("pytest") > browser.find_element_by_id("susss").click() test_dir\test_bd_search.py:13: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ C:\Python37\lib\site-packages\selenium\webdriver\remote\webdriver.py:360: in find_element_by_id return self.find_element(by=By.ID, value=id_) C:\Python37\lib\site-packages\selenium\webdriver\remote\webdriver.py:978: in find_element 'value': value})['value'] C:\Python37\lib\site-packages\selenium\webdriver\remote\webdriver.py:321: in execute self.error_handler.check_response(response) _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = <selenium.webdriver.remote.errorhandler.ErrorHandler object at 0x000002749E1E7CC8> response = {'status': 404, 'value': '{"value":{"error":"no such element","message":"no such element: Unable to locate element: {\...\n\\tRtlGetAppContainerNamedObjectPath [0x77687C24+228]\\n\\tRtlGetAppContainerNamedObjectPath [0x77687BF4+180]\\n"}}'} def check_response(self, response): """ Checks that a JSON response from the WebDriver does not have an error. :Args: - response - The JSON response from the WebDriver server as a dictionary object. :Raises: If the response contains an error message. """ status = response.get('status', None) if status is None or status == ErrorCode.SUCCESS: return value = None message = response.get("message", "") screen = response.get("screen", "") stacktrace = None if isinstance(status, int): value_json = response.get('value', None) if value_json and isinstance(value_json, basestring): import json try: value = json.loads(value_json) if len(value.keys()) == 1: value = value['value'] status = value.get('error', None) if status is None: status = value["status"] message = value["value"] if not isinstance(message, basestring): value = message message = message.get('message') else: message = value.get('message', None) except ValueError: pass exception_class = ErrorInResponseException if status in ErrorCode.NO_SUCH_ELEMENT: exception_class = NoSuchElementException elif status in ErrorCode.NO_SUCH_FRAME: exception_class = NoSuchFrameException elif status in ErrorCode.NO_SUCH_WINDOW: exception_class = NoSuchWindowException elif status in ErrorCode.STALE_ELEMENT_REFERENCE: exception_class = StaleElementReferenceException elif status in ErrorCode.ELEMENT_NOT_VISIBLE: exception_class = ElementNotVisibleException elif status in ErrorCode.INVALID_ELEMENT_STATE: exception_class = InvalidElementStateException elif status in ErrorCode.INVALID_SELECTOR \ or status in ErrorCode.INVALID_XPATH_SELECTOR \ or status in ErrorCode.INVALID_XPATH_SELECTOR_RETURN_TYPER: exception_class = InvalidSelectorException elif status in ErrorCode.ELEMENT_IS_NOT_SELECTABLE: exception_class = ElementNotSelectableException elif status in ErrorCode.ELEMENT_NOT_INTERACTABLE: exception_class = ElementNotInteractableException elif status in ErrorCode.INVALID_COOKIE_DOMAIN: exception_class = InvalidCookieDomainException elif status in ErrorCode.UNABLE_TO_SET_COOKIE: exception_class = UnableToSetCookieException elif status in ErrorCode.TIMEOUT: exception_class = TimeoutException elif status in ErrorCode.SCRIPT_TIMEOUT: exception_class = TimeoutException elif status in ErrorCode.UNKNOWN_ERROR: exception_class = WebDriverException elif status in ErrorCode.UNEXPECTED_ALERT_OPEN: exception_class = UnexpectedAlertPresentException elif status in ErrorCode.NO_ALERT_OPEN: exception_class = NoAlertPresentException elif status in ErrorCode.IME_NOT_AVAILABLE: exception_class = ImeNotAvailableException elif status in ErrorCode.IME_ENGINE_ACTIVATION_FAILED: exception_class = ImeActivationFailedException elif status in ErrorCode.MOVE_TARGET_OUT_OF_BOUNDS: exception_class = MoveTargetOutOfBoundsException elif status in ErrorCode.JAVASCRIPT_ERROR: exception_class = JavascriptException elif status in ErrorCode.SESSION_NOT_CREATED: exception_class = SessionNotCreatedException elif status in ErrorCode.INVALID_ARGUMENT: exception_class = InvalidArgumentException elif status in ErrorCode.NO_SUCH_COOKIE: exception_class = NoSuchCookieException elif status in ErrorCode.UNABLE_TO_CAPTURE_SCREEN: exception_class = ScreenshotException elif status in ErrorCode.ELEMENT_CLICK_INTERCEPTED: exception_class = ElementClickInterceptedException elif status in ErrorCode.INSECURE_CERTIFICATE: exception_class = InsecureCertificateException elif status in ErrorCode.INVALID_COORDINATES: exception_class = InvalidCoordinatesException elif status in ErrorCode.INVALID_SESSION_ID: exception_class = InvalidSessionIdException elif status in ErrorCode.UNKNOWN_METHOD: exception_class = UnknownMethodException else: exception_class = WebDriverException if value == '' or value is None: value = response['value'] if isinstance(value, basestring): if exception_class == ErrorInResponseException: raise exception_class(response, value) raise exception_class(value) if message == "" and 'message' in value: message = value['message'] screen = None if 'screen' in value: screen = value['screen'] stacktrace = None if 'stackTrace' in value and value['stackTrace']: stacktrace = [] try: for frame in value['stackTrace']: line = self._value_or_default(frame, 'lineNumber', '') file = self._value_or_default(frame, 'fileName', '<anonymous>') if line: file = "%s:%s" % (file, line) meth = self._value_or_default(frame, 'methodName', '<anonymous>') if 'className' in frame: meth = "%s.%s" % (frame['className'], meth) msg = " at %s (%s)" msg = msg % (meth, file) stacktrace.append(msg) except TypeError: pass if exception_class == ErrorInResponseException: raise exception_class(response, message) elif exception_class == UnexpectedAlertPresentException: alert_text = None if 'data' in value: alert_text = value['data'].get('text') elif 'alert' in value: alert_text = value['alert'].get('text') raise exception_class(message, screen, stacktrace, alert_text) > raise exception_class(message, screen, stacktrace) E selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"css selector","selector":"[id="susss"]"} E (Session info: chrome=84.0.4147.89) C:\Python37\lib\site-packages\selenium\webdriver\remote\errorhandler.py:242: NoSuchElementException |