├── .github └── workflows │ └── static.yml ├── .gitignore ├── Readme.md ├── atest ├── acceptance │ ├── 1-plugin │ │ ├── FailPlugin.py │ │ ├── ModulePlugin.py │ │ ├── MyPlugin.py │ │ ├── OpenBrowserExample.py │ │ ├── PluginWithAllArgs.py │ │ ├── PluginWithArgs.py │ │ ├── PluginWithKwArgs.py │ │ ├── PluginWithVarArgs.py │ │ ├── __init__.robot │ │ ├── adding_plugin.robot │ │ ├── adding_plugin_with_args.robot │ │ ├── failure_in_plugin.robot │ │ ├── plugin_does_not_exist.robot │ │ ├── plugin_from_module_fails.robot │ │ ├── plugin_open_browser.robot │ │ ├── plugin_with_all_args.robot │ │ ├── plugin_with_kw_args.robot │ │ └── plugin_with_var_args.robot │ ├── 2-event_firing_webdriver │ │ ├── __init__.robot │ │ ├── event_firing_webdriver.robot │ │ └── resource_event_firing_webdriver.robot │ ├── __init__.robot │ ├── big_list_of_naught_strings.robot │ ├── create_webdriver.robot │ ├── extending.robot │ ├── keywords │ │ ├── __init__.robot │ │ ├── alerts.robot │ │ ├── async_javascript.robot │ │ ├── checkbox_and_radio_buttons.robot │ │ ├── choose_file.robot │ │ ├── click_element.robot │ │ ├── click_element_at_coordinates.robot │ │ ├── click_element_modifier.robot │ │ ├── content_assertions.robot │ │ ├── cookies.robot │ │ ├── counting_elements.robot │ │ ├── element_focus.robot │ │ ├── element_should_be_enabled_and_disabled.robot │ │ ├── element_visibility.robot │ │ ├── elements.robot │ │ ├── executed_by_execute_javascript.js │ │ ├── forms_and_buttons.robot │ │ ├── frames.robot │ │ ├── implicit_wait.robot │ │ ├── javascript.robot │ │ ├── javascript_alert.js │ │ ├── lists.robot │ │ ├── location.robot │ │ ├── mouse.robot │ │ ├── navigation.robot │ │ ├── page_load_timeout.robot │ │ ├── press_keys.robot │ │ ├── run_on_failure.robot │ │ ├── screenshot_element.robot │ │ ├── screenshots.robot │ │ ├── screenshots_embed.robot │ │ ├── scroll_into_view.robot │ │ ├── set_selenium_speed.robot │ │ ├── tables │ │ │ ├── __init__.robot │ │ │ ├── col_should_contain.robot │ │ │ ├── finding_tables.robot │ │ │ ├── footer_should_contain.robot │ │ │ ├── get_table_cell.robot │ │ │ ├── header_should_contain.robot │ │ │ ├── negative_indexes.robot │ │ │ ├── row_should_contain.robot │ │ │ ├── table_resource.robot │ │ │ └── table_should_contain.robot │ │ ├── textfields.robot │ │ ├── textfields_html5.robot │ │ ├── timeout_with_alert.robot │ │ └── waiting.robot │ ├── locators │ │ ├── __init__.robot │ │ ├── custom.robot │ │ ├── locator_parsing.robot │ │ └── sizzle.robot │ ├── multiple_browsers.robot │ ├── multiple_browsers_executable_path.robot │ ├── multiple_browsers_multiple_windows.robot │ ├── multiple_browsers_options.robot │ ├── multiple_browsers_service_log_path.robot │ ├── multiple_browsers_with_alias.robot │ ├── open_and_close.robot │ ├── public_api.robot │ ├── remote_browsers.robot.TRIAGE │ ├── resource.robot │ └── windows.robot └── resources │ ├── html │ ├── broken.html │ ├── cookies.html │ ├── forms │ │ ├── buttons.html │ │ ├── email_form.html │ │ ├── enabled_disabled_fields_form.html │ │ ├── file_upload_form.html │ │ ├── form_with_image_submit.html │ │ ├── form_with_special_characters_in_field_names.html │ │ ├── form_without_name.html │ │ ├── html5_input_types.html │ │ ├── input_special_keys.html │ │ ├── login.html │ │ ├── named_email_form.html │ │ ├── named_submit_buttons.html │ │ ├── prefilled_email_form.html │ │ ├── robot.bmp │ │ └── submit.html │ ├── frames │ │ ├── bar.html │ │ ├── foo.html │ │ ├── frameset.html │ │ ├── iframes.html │ │ ├── left.html │ │ ├── poorlynamedframe.html │ │ ├── right.html │ │ └── search_results.html │ ├── image.jpg │ ├── index.html │ ├── javascript │ │ ├── alert.html │ │ ├── alert_prompt.html │ │ ├── click.html │ │ ├── click_at_coordinates.html │ │ ├── click_at_coordinates.png │ │ ├── click_modifier.html │ │ ├── context_menu.html │ │ ├── delayed_events.html │ │ ├── drag_and_drop.html │ │ ├── dynamic_content.html │ │ ├── dynamiclinks.html │ │ ├── functions.js │ │ ├── jquery-ui.css │ │ ├── jquery-ui.min.js │ │ ├── jquery.contextMenu.css │ │ ├── jquery.contextMenu.js │ │ ├── jquery.js │ │ ├── mouse_events.html │ │ ├── popupwindow.html │ │ ├── script_block_contains_html_tags.html │ │ ├── security_alert.html │ │ ├── self_closing_popup.html │ │ └── wait_location.html │ ├── jquery.html │ ├── links.html │ ├── mouse │ │ └── index.html │ ├── nested_divs.html │ ├── non_ascii.html │ ├── robot.png │ ├── scroll │ │ └── index.html │ ├── sub │ │ └── index.html │ ├── tables │ │ └── tables.html │ └── visibility.html │ ├── testlibs │ ├── BigListOfNaughtyStrings.py │ ├── ChooseFileLib.py │ ├── CustomSeleniumKeywords.py │ ├── ExtSL.py │ ├── MyListener.py │ ├── blns.json │ ├── cache_error.py │ ├── ctrl_or_command.py │ ├── custom_locator.py │ └── get_selenium_options.py │ └── testserver │ └── testserver.py ├── createPip_whl_tar.sh ├── doc └── index.html ├── pyproject.toml ├── setup.py └── src ├── SeleniumLibraryToBrowser ├── __init__.py ├── errors.py └── keys.py └── SeleniumStats ├── __init__.py └── __main__.py /.github/workflows/static.yml: -------------------------------------------------------------------------------- 1 | # Simple workflow for deploying static content to GitHub Pages 2 | name: Deploy static content to Pages 3 | 4 | on: 5 | # Runs on pushes targeting the default branch 6 | push: 7 | branches: ["master"] 8 | 9 | # Allows you to run this workflow manually from the Actions tab 10 | workflow_dispatch: 11 | 12 | # Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages 13 | permissions: 14 | contents: read 15 | pages: write 16 | id-token: write 17 | 18 | # Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued. 19 | # However, do NOT cancel in-progress runs as we want to allow these production deployments to complete. 20 | concurrency: 21 | group: "pages" 22 | cancel-in-progress: false 23 | 24 | jobs: 25 | # Single deploy job since we're just deploying 26 | deploy: 27 | environment: 28 | name: github-pages 29 | url: ${{ steps.deployment.outputs.page_url }} 30 | runs-on: ubuntu-latest 31 | steps: 32 | - name: Checkout 33 | uses: actions/checkout@v4 34 | - name: Setup Pages 35 | uses: actions/configure-pages@v4 36 | - name: Upload artifact 37 | uses: actions/upload-pages-artifact@v3 38 | with: 39 | # Upload entire repository 40 | path: './doc' 41 | - name: Deploy to GitHub Pages 42 | id: deployment 43 | uses: actions/deploy-pages@v4 44 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | # Created by https://www.toptal.com/developers/gitignore/api/python 3 | # Edit at https://www.toptal.com/developers/gitignore?templates=python 4 | 5 | ### Python ### 6 | # Byte-compiled / optimized / DLL files 7 | __pycache__/ 8 | *.py[cod] 9 | *$py.class 10 | 11 | # C extensions 12 | *.so 13 | 14 | # Distribution / packaging 15 | .Python 16 | build/ 17 | develop-eggs/ 18 | dist/ 19 | downloads/ 20 | eggs/ 21 | .eggs/ 22 | lib/ 23 | lib64/ 24 | parts/ 25 | sdist/ 26 | var/ 27 | wheels/ 28 | pip-wheel-metadata/ 29 | share/python-wheels/ 30 | *.egg-info/ 31 | .installed.cfg 32 | *.egg 33 | MANIFEST 34 | 35 | # PyInstaller 36 | # Usually these files are written by a python script from a template 37 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 38 | *.manifest 39 | *.spec 40 | 41 | # Installer logs 42 | pip-log.txt 43 | pip-delete-this-directory.txt 44 | 45 | # Unit test / coverage reports 46 | htmlcov/ 47 | .tox/ 48 | .nox/ 49 | .coverage 50 | .coverage.* 51 | .cache 52 | nosetests.xml 53 | coverage.xml 54 | *.cover 55 | *.py,cover 56 | .hypothesis/ 57 | .pytest_cache/ 58 | pytestdebug.log 59 | 60 | # Translations 61 | *.mo 62 | *.pot 63 | 64 | # Django stuff: 65 | *.log 66 | local_settings.py 67 | db.sqlite3 68 | db.sqlite3-journal 69 | 70 | # Flask stuff: 71 | instance/ 72 | .webassets-cache 73 | 74 | # Scrapy stuff: 75 | .scrapy 76 | 77 | # Sphinx documentation 78 | docs/_build/ 79 | doc/_build/ 80 | 81 | # PyBuilder 82 | target/ 83 | 84 | # Jupyter Notebook 85 | .ipynb_checkpoints 86 | 87 | # IPython 88 | profile_default/ 89 | ipython_config.py 90 | 91 | # pyenv 92 | .python-version 93 | 94 | # pipenv 95 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 96 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 97 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 98 | # install all needed dependencies. 99 | #Pipfile.lock 100 | 101 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow 102 | __pypackages__/ 103 | 104 | # Celery stuff 105 | celerybeat-schedule 106 | celerybeat.pid 107 | 108 | # SageMath parsed files 109 | *.sage.py 110 | 111 | # Environments 112 | .env 113 | .venv 114 | env/ 115 | venv/ 116 | ENV/ 117 | env.bak/ 118 | venv.bak/ 119 | 120 | # Spyder project settings 121 | .spyderproject 122 | .spyproject 123 | 124 | # Rope project settings 125 | .ropeproject 126 | 127 | # mkdocs documentation 128 | /site 129 | 130 | # mypy 131 | .mypy_cache/ 132 | .dmypy.json 133 | dmypy.json 134 | 135 | # Pyre type checker 136 | .pyre/ 137 | 138 | # pytype static type analyzer 139 | .pytype/ 140 | 141 | # End of https://www.toptal.com/developers/gitignore/api/python 142 | .idea 143 | keyword_stats.json 144 | .vscode/ 145 | 146 | results/ 147 | -------------------------------------------------------------------------------- /atest/acceptance/1-plugin/FailPlugin.py: -------------------------------------------------------------------------------- 1 | from SeleniumLibrary.base import LibraryComponent, keyword 2 | 3 | 4 | class FailPlugin(LibraryComponent): 5 | def __init__(self, ctx): 6 | LibraryComponent.__init__(self, ctx) 7 | raise ValueError("Error in import") 8 | 9 | @keyword 10 | def keyword(self): 11 | pass 12 | -------------------------------------------------------------------------------- /atest/acceptance/1-plugin/ModulePlugin.py: -------------------------------------------------------------------------------- 1 | from SeleniumLibrary.base import keyword 2 | 3 | 4 | @keyword 5 | def keyword(): 6 | pass 7 | -------------------------------------------------------------------------------- /atest/acceptance/1-plugin/MyPlugin.py: -------------------------------------------------------------------------------- 1 | from robot.api import logger 2 | from SeleniumLibrary.base import LibraryComponent, keyword 3 | from SeleniumLibrary.locators import ElementFinder 4 | 5 | 6 | class DummyFinder: 7 | def __init__(self, ctx): 8 | self.ctx = ctx 9 | 10 | def find(self, *args): 11 | logger.info('DummyFinder args "%s"' % str(args)) 12 | logger.info("Original finder %s" % self.ctx._original_element_finder) 13 | return "Dummy find" 14 | 15 | 16 | class MyPlugin(LibraryComponent): 17 | def __init__(self, ctx): 18 | LibraryComponent.__init__(self, ctx) 19 | ctx._original_element_finder = ElementFinder(ctx) 20 | self.element_finder = DummyFinder(ctx) 21 | 22 | @keyword 23 | def new_keyword(self): 24 | """Adding new keyword.""" 25 | self.info("New Keyword") 26 | return "New Keyword" 27 | 28 | @keyword() 29 | def open_browser(self, location): 30 | """Overwrite existing keyword.""" 31 | self.info(location) 32 | return location 33 | -------------------------------------------------------------------------------- /atest/acceptance/1-plugin/OpenBrowserExample.py: -------------------------------------------------------------------------------- 1 | from robot.api import logger 2 | from selenium import webdriver 3 | from SeleniumLibrary.base import LibraryComponent, keyword 4 | from SeleniumLibrary.keywords import BrowserManagementKeywords 5 | from SeleniumLibrary.keywords.webdrivertools import WebDriverCreator 6 | 7 | 8 | class OpenBrowserExample(LibraryComponent): 9 | def __init__(self, ctx): 10 | LibraryComponent.__init__(self, ctx) 11 | self._new_creator = NewWebDriverCreator(self.log_dir) 12 | 13 | @keyword 14 | def open_browser( 15 | self, 16 | url, 17 | browser="firefox", 18 | alias=None, 19 | remote_url=False, 20 | desired_capabilities=None, 21 | ff_profile_dir=None, 22 | options=None, 23 | service_log_path=None, 24 | extra_dictionary=None, 25 | executable_path=None, 26 | ): 27 | self._new_creator.extra_dictionary = extra_dictionary 28 | browser_manager = BrowserManagementKeywords(self.ctx) 29 | browser_manager._make_driver = self._make_driver 30 | browser_manager.open_browser( 31 | url, 32 | browser=browser, 33 | alias=alias, 34 | remote_url=remote_url, 35 | desired_capabilities=desired_capabilities, 36 | ff_profile_dir=ff_profile_dir, 37 | options=options, 38 | service_log_path=service_log_path, 39 | executable_path=None, 40 | ) 41 | 42 | def _make_driver( 43 | self, 44 | browser, 45 | desired_capabilities=None, 46 | profile_dir=None, 47 | remote=None, 48 | options=None, 49 | service_log_path=None, 50 | executable_path=None, 51 | ): 52 | driver = self._new_creator.create_driver( 53 | browser=browser, 54 | desired_capabilities=desired_capabilities, 55 | remote_url=remote, 56 | profile_dir=profile_dir, 57 | options=options, 58 | service_log_path=service_log_path, 59 | executable_path=executable_path, 60 | ) 61 | driver.set_script_timeout(self.ctx.timeout) 62 | driver.implicitly_wait(self.ctx.implicit_wait) 63 | if self.ctx.speed: 64 | self._monkey_patch_speed(driver) 65 | return driver 66 | 67 | 68 | class NewWebDriverCreator(WebDriverCreator): 69 | def create_driver( 70 | self, 71 | browser, 72 | desired_capabilities, 73 | remote_url, 74 | profile_dir=None, 75 | options=None, 76 | service_log_path=None, 77 | executable_path=None, 78 | ): 79 | self.browser_names["seleniumwire"] = "seleniumwire" 80 | browser = self._normalise_browser_name(browser) 81 | creation_method = self._get_creator_method(browser) 82 | desired_capabilities = self._parse_capabilities(desired_capabilities, browser) 83 | service_log_path = self._get_log_path(service_log_path) 84 | options = self.selenium_options.create(self.browser_names.get(browser), options) 85 | if service_log_path: 86 | logger.info("Browser driver log file created to: %s" % service_log_path) 87 | self._create_directory(service_log_path) 88 | if ( 89 | creation_method == self.create_firefox 90 | or creation_method == self.create_headless_firefox 91 | ): 92 | return creation_method( 93 | desired_capabilities, 94 | remote_url, 95 | profile_dir, 96 | options=options, 97 | service_log_path=service_log_path, 98 | ) 99 | if creation_method == self.create_seleniumwire: 100 | return creation_method( 101 | desired_capabilities, 102 | remote_url, 103 | options=options, 104 | service_log_path=service_log_path, 105 | ) 106 | return creation_method( 107 | desired_capabilities, 108 | remote_url, 109 | options=options, 110 | service_log_path=service_log_path, 111 | ) 112 | 113 | def create_seleniumwire( 114 | self, desired_capabilities, remote_url, options=None, service_log_path=None 115 | ): 116 | logger.info(self.extra_dictionary) 117 | return webdriver.Chrome() 118 | -------------------------------------------------------------------------------- /atest/acceptance/1-plugin/PluginWithAllArgs.py: -------------------------------------------------------------------------------- 1 | from collections import OrderedDict 2 | 3 | from SeleniumLibrary.base import LibraryComponent, keyword 4 | 5 | 6 | class PluginWithAllArgs(LibraryComponent): 7 | def __init__(self, ctx, arg, *varargs, **kwargs): 8 | LibraryComponent.__init__(self, ctx) 9 | self.arg = arg 10 | self.varargs = varargs 11 | self.kwargs = kwargs 12 | 13 | @keyword 14 | def return_all_args_as_string(self): 15 | joined_str = "start: arg=%s," % self.arg 16 | for arg in self.varargs: 17 | joined_str = f"{joined_str} {arg}," 18 | kwargs = OrderedDict(sorted(self.kwargs.items())) 19 | for key in kwargs: 20 | joined_str = f"{joined_str} {key}={kwargs[key]}," 21 | return joined_str[:-1] 22 | -------------------------------------------------------------------------------- /atest/acceptance/1-plugin/PluginWithArgs.py: -------------------------------------------------------------------------------- 1 | from SeleniumLibrary.base import LibraryComponent, keyword 2 | 3 | 4 | class PluginWithArgs(LibraryComponent): 5 | def __init__(self, ctx, arg1, arg2): 6 | LibraryComponent.__init__(self, ctx) 7 | self.arg1 = arg1 8 | self.arg2 = arg2 9 | 10 | @keyword 11 | def return_arg1_arg2_as_string(self): 12 | return f"{self.arg1} {self.arg2}" 13 | -------------------------------------------------------------------------------- /atest/acceptance/1-plugin/PluginWithKwArgs.py: -------------------------------------------------------------------------------- 1 | from collections import OrderedDict 2 | 3 | from SeleniumLibrary.base import LibraryComponent, keyword 4 | 5 | 6 | class PluginWithKwArgs(LibraryComponent): 7 | def __init__(self, ctx, **kwargs): 8 | LibraryComponent.__init__(self, ctx) 9 | self.kwargs = kwargs 10 | 11 | @keyword 12 | def return_kw_args_as_string(self): 13 | kwargs = OrderedDict(sorted(self.kwargs.items())) 14 | joined_str = "start:" 15 | for key in kwargs: 16 | joined_str = f"{joined_str} {key}={kwargs[key]}," 17 | return joined_str[:-1] 18 | -------------------------------------------------------------------------------- /atest/acceptance/1-plugin/PluginWithVarArgs.py: -------------------------------------------------------------------------------- 1 | from SeleniumLibrary.base import LibraryComponent, keyword 2 | 3 | 4 | class PluginWithVarArgs(LibraryComponent): 5 | def __init__(self, ctx, *args): 6 | LibraryComponent.__init__(self, ctx) 7 | self.args = args 8 | 9 | @keyword 10 | def return_var_args_as_string(self): 11 | joined_str = "start:" 12 | for arg in self.args: 13 | joined_str = f"{joined_str} {arg}," 14 | return joined_str[:-1] 15 | -------------------------------------------------------------------------------- /atest/acceptance/1-plugin/__init__.robot: -------------------------------------------------------------------------------- 1 | *** Settings *** 2 | Test Tags robot:skip 3 | -------------------------------------------------------------------------------- /atest/acceptance/1-plugin/adding_plugin.robot: -------------------------------------------------------------------------------- 1 | *** Settings *** 2 | Library SeleniumLibraryToBrowser plugins=${CURDIR}/MyPlugin.py 3 | 4 | 5 | *** Test Cases *** 6 | Adding New Keyword From Class 7 | ${text} = New Keyword 8 | Should Be Equal ${text} New Keyword 9 | 10 | Overwriting Exsisting Keyword 11 | ${text} = Open Browser text is returned 12 | Should Be Equal ${text} text is returned 13 | 14 | Oerwriting ElementFinder 15 | ${element} = Get WebElement //div 16 | Should Be Equal ${element} Dummy find 17 | -------------------------------------------------------------------------------- /atest/acceptance/1-plugin/adding_plugin_with_args.robot: -------------------------------------------------------------------------------- 1 | *** Settings *** 2 | Library SeleniumLibraryToBrowser plugins=${CURDIR}/PluginWithArgs.py;${ARG1};${ARG2},${CURDIR}/MyPlugin.py 3 | 4 | 5 | *** Variables *** 6 | ${ARG1} Text1 7 | ${ARG2} Text2 8 | 9 | 10 | *** Test Cases *** 11 | Testing Plugin With Arguments 12 | ${text1} = Return Arg1 Arg2 As String 13 | Should Be Equal As Strings ${text1} Text1 Text2 14 | ${text2} = New Keyword 15 | Should Be Equal As Strings ${text2} New Keyword 16 | -------------------------------------------------------------------------------- /atest/acceptance/1-plugin/failure_in_plugin.robot: -------------------------------------------------------------------------------- 1 | *** Test Cases *** 2 | Importing SeleniumLibrary Should Fail If Plugin Is Not Found 3 | [Documentation] When importing plugin fails, the SeleniumLibrary import fails and 4 | ... therefore Open Browser keyword is not found. 5 | ... FAIL REGEXP: (Initializing test library 'SeleniumLibrary'|Initializing library 'SeleniumLibrary' with arguments).* 6 | Import Library 7 | ... SeleniumLibraryToBrowser 8 | ... plugins=${CURDIR}/FailPlugin.py 9 | 10 | SeleniumLibrary Open Browser Keyword Should Not Be Found 11 | [Documentation] FAIL No keyword with name 'Open Browser' found. 12 | Open Browser 13 | ... foobar 14 | ... Not Here 15 | -------------------------------------------------------------------------------- /atest/acceptance/1-plugin/plugin_does_not_exist.robot: -------------------------------------------------------------------------------- 1 | *** Variables *** 2 | ${SERVER}= localhost:7000 3 | ${BROWSER}= chrome 4 | ${REMOTE_URL}= ${NONE} 5 | ${ROOT}= http://${SERVER}/html 6 | ${FRONT_PAGE}= ${ROOT}/ 7 | 8 | 9 | *** Test Cases *** 10 | Importing SeleniumLibrary Should Fail If Plugin Is Not Found 11 | [Documentation] When finding plugin fails, the SeleniumLibrary import fails and 12 | ... therefore Open Browser keyword is not found. 13 | ... FAIL REGEXP: (Initializing test library 'SeleniumLibrary'|Initializing library 'SeleniumLibrary' with arguments).* 14 | Import Library 15 | ... SeleniumLibraryToBrowser 16 | ... plugins=${CURDIR}/NotHere.py 17 | 18 | SeleniumLibrary Open Browser Keyword Should Not Be Found 19 | [Documentation] FAIL No keyword with name 'Open Browser' found. 20 | Open Browser 21 | ... ${FRONT PAGE} 22 | ... ${BROWSER} 23 | ... remote_url=${REMOTE_URL} 24 | -------------------------------------------------------------------------------- /atest/acceptance/1-plugin/plugin_from_module_fails.robot: -------------------------------------------------------------------------------- 1 | *** Test Cases *** 2 | Importing SeleniumLibrary Should Fail If Plugin Is Not Found 3 | [Documentation] When importing plugin from module, the SeleniumLibrary import fails and 4 | ... therefore Open Browser keyword is not found. 5 | ... FAIL REGEXP: (Initializing test library 'SeleniumLibrary'|Initializing library 'SeleniumLibrary' with arguments).* 6 | Import Library 7 | ... SeleniumLibraryToBrowser 8 | ... plugins=${CURDIR}/ModulePlugin.py 9 | 10 | SeleniumLibrary Open Browser Keyword Should Not Be Found 11 | [Documentation] FAIL No keyword with name 'Open Browser' found. 12 | Open Browser 13 | ... foobar 14 | ... Not Here 15 | -------------------------------------------------------------------------------- /atest/acceptance/1-plugin/plugin_open_browser.robot: -------------------------------------------------------------------------------- 1 | *** Settings *** 2 | Library SeleniumLibraryToBrowser plugins=${CURDIR}/OpenBrowserExample.py 3 | 4 | 5 | *** Variables *** 6 | ${SERVER}= localhost:7000 7 | ${ROOT}= http://${SERVER}/html 8 | &{EXTRA DICTIONARY} extra=dictionary key=value 9 | 10 | 11 | *** Test Cases *** 12 | Open Browser Coplex Example 13 | [Documentation] 14 | ... LOG 1:2 INFO GLOB: *'key': *'value'* 15 | ... LOG 1:2 INFO GLOB: *'extra': *'dictionary'* 16 | Open Browser ${ROOT}/forms/prefilled_email_form.html seleniumwire extra_dictionary=${EXTRA DICTIONARY} 17 | [Teardown] Close All Browsers 18 | -------------------------------------------------------------------------------- /atest/acceptance/1-plugin/plugin_with_all_args.robot: -------------------------------------------------------------------------------- 1 | *** Settings *** 2 | Library SeleniumLibraryToBrowser plugins=${CURDIR}/PluginWithAllArgs.py;argument1;varg1;varg2;kw1=kwarg1;kw2=kwarg2 3 | 4 | 5 | *** Test Cases *** 6 | Testing Plugin With Many Arguments Types 7 | ${text} = Return All Args As String 8 | Should Be Equal As Strings ${text} start: arg=argument1, varg1, varg2, kw1=kwarg1, kw2=kwarg2 9 | -------------------------------------------------------------------------------- /atest/acceptance/1-plugin/plugin_with_kw_args.robot: -------------------------------------------------------------------------------- 1 | *** Settings *** 2 | Library SeleniumLibraryToBrowser plugins=${CURDIR}/PluginWithKwArgs.py;kw1=Text1;kw2=Text2 3 | 4 | 5 | *** Test Cases *** 6 | Testing Plugin With Keyword Arguments 7 | ${text} = Return Kw Args As String 8 | Should Be Equal As Strings ${text} start: kw1=Text1, kw2=Text2 9 | -------------------------------------------------------------------------------- /atest/acceptance/1-plugin/plugin_with_var_args.robot: -------------------------------------------------------------------------------- 1 | *** Settings *** 2 | Library SeleniumLibraryToBrowser plugins=${CURDIR}/PluginWithVarArgs.py;Text1;Text2;Text3 3 | 4 | 5 | *** Test Cases *** 6 | Testing Plugin With Variable Number Of Arguments 7 | ${text} = Return Var Args As String 8 | Should Be Equal As Strings ${text} start: Text1, Text2, Text3 9 | -------------------------------------------------------------------------------- /atest/acceptance/2-event_firing_webdriver/__init__.robot: -------------------------------------------------------------------------------- 1 | *** Settings *** 2 | Test Tags robot:skip 3 | -------------------------------------------------------------------------------- /atest/acceptance/2-event_firing_webdriver/event_firing_webdriver.robot: -------------------------------------------------------------------------------- 1 | *** Settings *** 2 | Library SeleniumLibraryToBrowser event_firing_webdriver=${CURDIR}/../../resources/testlibs/MyListener.py 3 | Resource resource_event_firing_webdriver.robot 4 | 5 | Suite Setup Open Browser ${FRONT PAGE} ${BROWSER} alias=event_firing_webdriver 6 | ... remote_url=${REMOTE_URL} executable_path=%{WEBDRIVERPATH} 7 | Suite Teardown Close All Browsers 8 | 9 | 10 | *** Variables *** 11 | ${event_firing_or_none} ${NONE} 12 | 13 | 14 | *** Test Cases *** 15 | Open Browser To Start Page 16 | [Documentation] 17 | ... LOG 1:20 DEBUG Wrapping driver to event_firing_webdriver. 18 | ... LOG 1:22 INFO Got driver also from SeleniumLibrary. 19 | [Tags] nogrid 20 | Open Browser ${FRONT PAGE} ${BROWSER} remote_url=${REMOTE_URL} 21 | ... executable_path=%{WEBDRIVERPATH} 22 | 23 | Event Firing Webdriver Go To (WebDriver) 24 | [Documentation] 25 | ... LOG 1:2 INFO STARTS: Before navigate to 26 | ... LOG 1:3 INFO Got driver also from SeleniumLibrary. 27 | ... LOG 1:8 INFO STARTS: After navigate to 28 | [Tags] nogrid 29 | Go To ${ROOT}/forms/named_submit_buttons.html 30 | 31 | Event Firing Webdriver Input Text (WebElement) 32 | [Documentation] 33 | ... LOG 1:6 INFO Before clear and send_keys 34 | ... LOG 1:11 INFO After clear and send_keys 35 | ... LOG 1:12 INFO Before clear and send_keys 36 | ... LOG 1:17 INFO After clear and send_keys 37 | [Tags] nogrid 38 | Input Text //input[@name="textfield"] FooBar 39 | 40 | Event Firing Webdriver With Get WebElement (WebElement) 41 | [Tags] nogrid 42 | Go To ${ROOT}/nested_divs.html 43 | ${link}= Get WebElement //a[@id="needleC"] 44 | Wait Until Element Contains ${link} top/c/needle 45 | -------------------------------------------------------------------------------- /atest/acceptance/2-event_firing_webdriver/resource_event_firing_webdriver.robot: -------------------------------------------------------------------------------- 1 | *** Variables *** 2 | ${SERVER}= localhost:7000 3 | ${BROWSER}= Chrome 4 | ${REMOTE_URL}= ${NONE} 5 | ${DESIRED_CAPABILITIES}= ${NONE} 6 | ${ROOT}= http://${SERVER}/html 7 | ${FRONT_PAGE}= ${ROOT}/ 8 | 9 | 10 | *** Keywords *** 11 | Go To Page "${relative url}" 12 | [Documentation] Goes to page 13 | Go To ${ROOT}/${relative url} 14 | -------------------------------------------------------------------------------- /atest/acceptance/__init__.robot: -------------------------------------------------------------------------------- 1 | *** Settings *** 2 | Resource resource.robot 3 | 4 | Test Tags regression 5 | 6 | 7 | *** Variables *** 8 | ${FF PROFILE DIR}= ${CURDIR}${/}..${/}resources${/}firefoxprofile 9 | -------------------------------------------------------------------------------- /atest/acceptance/big_list_of_naught_strings.robot: -------------------------------------------------------------------------------- 1 | *** Settings *** 2 | Resource resource.robot 3 | Library BigListOfNaughtyStrings.BigListOfNaughtyStrings WITH NAME blns 4 | 5 | 6 | *** Test Cases *** 7 | Big List Of Naughty Strings 8 | [Documentation] The Big List of Naughty Strings is originally copied from: 9 | ... https://github.com/minimaxir/big-list-of-naughty-strings 10 | Open Browser To Start Page 11 | ${blns} = blns.Get Blns 12 | FOR ${string} IN @{blns} 13 | Check Blns Error Check ${string} 14 | END 15 | 16 | 17 | *** Keywords *** 18 | Check Blns Error Check 19 | [Arguments] ${string} 20 | Run Keyword And Expect Error 21 | ... Page should have contained element* 22 | ... Page Should Contain Element ${string} 23 | -------------------------------------------------------------------------------- /atest/acceptance/create_webdriver.robot: -------------------------------------------------------------------------------- 1 | *** Settings *** 2 | Documentation Tests Webdriver 3 | 4 | Resource resource.robot 5 | Library Collections 6 | 7 | Test Tags robot:skip 8 | 9 | 10 | *** Test Cases *** 11 | Create Webdriver Creates Functioning WebDriver 12 | [Documentation] 13 | ... LOG 1:1 INFO REGEXP: Creating an instance of the \\w+ WebDriver. 14 | ... LOG 1:19 DEBUG REGEXP: Created \\w+ WebDriver instance with session id (\\w|-)+. 15 | [Tags] known issue internet explorer known issue safari 16 | [Setup] Set Driver Variables 17 | Create Webdriver ${DRIVER_NAME} kwargs=${KWARGS} 18 | Go To ${FRONT_PAGE} 19 | Wait Until Page Contains needle 5s 20 | [Teardown] Close Browser 21 | 22 | Create Webdriver With Bad Driver Name 23 | [Documentation] Invalid browser name 24 | Run Keyword And Expect Error 'Fireox' is not a valid WebDriver name. 25 | ... Create Webdriver Fireox 26 | 27 | Create Webdriver With Duplicate Arguments 28 | [Documentation] Invalid values in arguments 29 | ${kwargs}= Create Dictionary arg=1 30 | Run Keyword And Expect Error Got multiple values for argument 'arg'. 31 | ... Create Webdriver Firefox kwargs=${kwargs} arg=2 32 | 33 | Create Webdriver With Bad Keyword Argument Dictionary 34 | [Documentation] Invalid arguments types 35 | ${status} ${error}= Run Keyword And Ignore Error Create Webdriver Firefox kwargs={'spam': 'eggs'} 36 | Should Be Equal ${status} FAIL 37 | Should Match Regexp 38 | ... ${error} 39 | ... (TypeError: (?:WebDriver.)?__init__\\(\\) got an unexpected keyword argument 'spam'|kwargs must be a dictionary\.) 40 | 41 | 42 | *** Keywords *** 43 | Set Driver Variables 44 | [Documentation] Selects proper driver 45 | ${drivers}= Create Dictionary ff=Firefox firefox=Firefox ie=Ie 46 | ... internetexplorer=Ie googlechrome=Chrome gc=Chrome chrome=Chrome 47 | ... safari=Safari headlesschrome=Chrome headlessfirefox=Firefox 48 | ${name}= Evaluate "Remote" if "${REMOTE_URL}"!="None" else $drivers["${BROWSER}"] 49 | Set Test Variable ${DRIVER_NAME} ${name} 50 | ${dc names}= Create Dictionary ff=FIREFOX firefox=FIREFOX ie=INTERNETEXPLORER 51 | ... internetexplorer=INTERNETEXPLORER googlechrome=CHROME gc=CHROME 52 | ... chrome=CHROME safari=SAFARI headlessfirefox=FIREFOX headlesschrome=CHROME 53 | ${dc name}= Get From Dictionary ${dc names} ${BROWSER.lower().replace(' ', '')} 54 | ${caps}= Evaluate selenium.webdriver.DesiredCapabilities.${dc name} 55 | ... modules=selenium, selenium.webdriver 56 | ${kwargs}= Create Dictionary 57 | IF "${name}"=="Remote" 58 | Set To Dictionary ${kwargs} command_executor ${REMOTE_URL} desired_capabilities ${caps} 59 | END 60 | Set Test Variable ${KWARGS} ${kwargs} 61 | -------------------------------------------------------------------------------- /atest/acceptance/extending.robot: -------------------------------------------------------------------------------- 1 | *** Settings *** 2 | Resource resource.robot 3 | Library ExtSL.ExtSL WITH NAME ExtSeLib 4 | 5 | Suite Setup Extending Suite Setup 6 | Suite Teardown ExtSeLib.Close All Browsers 7 | 8 | Test Tags robot:skip 9 | 10 | 11 | *** Test Cases *** 12 | When Extending SeleniumLibrary Keywords With Decorated Name Can Be Used For Extending 13 | ${elements} = ExtSeLib.Ext Web Element //tr 14 | Should Not Be Empty ${elements} 15 | 16 | When Extending SeleniumLibrary Keywords With Method Name Can Be Used For Extending 17 | ExtSeLib.Ext Page Should Contain Email: 18 | 19 | 20 | *** Keywords *** 21 | Extending Suite Setup 22 | ExtSeLib.Open Browser ${ROOT}/forms/prefilled_email_form.html ${BROWSER} 23 | -------------------------------------------------------------------------------- /atest/acceptance/keywords/__init__.robot: -------------------------------------------------------------------------------- 1 | *** Settings *** 2 | Resource ../resource.robot 3 | 4 | Suite Setup Open Browser To Start Page keywords 5 | Suite Teardown Close All Browsers 6 | -------------------------------------------------------------------------------- /atest/acceptance/keywords/alerts.robot: -------------------------------------------------------------------------------- 1 | *** Settings *** 2 | Resource ../resource.robot 3 | 4 | Suite Setup Set Global Timeout 1 second 5 | Suite Teardown Restore Global Timeout 6 | Test Setup Go To Page "javascript/alert.html" 7 | 8 | Test Tags known issue safari 9 | 10 | 11 | *** Test Cases *** 12 | Handle Alert accepts by default 13 | [Setup] Go To Page "javascript/dynamic_content.html" 14 | Click Button Change the title 15 | Handle Alert 16 | Alert Should Not Be Present 17 | Wait For Title Change Original Changed! 18 | 19 | Handle Alert can dismiss 20 | [Setup] Go To Page "javascript/dynamic_content.html" 21 | Click Button Change the title 22 | Handle Alert action=DISMISS 23 | Alert Should Not Be Present 24 | Wait For Title Change Original 25 | 26 | Handle Alert can leave open 27 | Click Link Click Me! 28 | Handle Alert Leave 29 | Alert Should Be Present 30 | 31 | Handle Alert with invalid action 32 | Click Link Click Me! 33 | Run Keyword And Expect Error 34 | ... ValueError: Invalid alert action 'INVALID'. 35 | ... Handle Alert INVALID 36 | Alert Should Be Present 37 | 38 | Handle Alert returns message 39 | Click Link Click Me! 40 | ${message} = Handle Alert 41 | Should Be Equal ${message} ALERT! 42 | Click Link Click Me Too! 43 | ${message} = Handle Alert action=LEAVE 44 | Should Be Equal ${message} MULTILINE ALERT! 45 | Alert Should Be Present 46 | 47 | Handle Alert with custom timeout 48 | Click Button Slow alert 49 | Handle Alert timeout=1s 50 | Click Button Slow alert 51 | Run Keyword And Expect Error 52 | ... Alert not found in 1 millisecond. 53 | ... Handle Alert ACCEPT 1 ms 54 | Handle Alert timeout=3.14 seconds 55 | 56 | Alert Should Not Be Present 57 | Alert Should Not Be Present 58 | Click Link Click Me! 59 | Run Keyword And Expect Error 60 | ... Alert with message 'ALERT!' present. 61 | ... Alert Should Not Be Present 62 | 63 | Alert Should Not Be Present with custom actions 64 | [Setup] Go To Page "javascript/dynamic_content.html" 65 | Click Button Change the title 66 | Run Keyword And Expect Error 67 | ... Alert with message 'Really change the title?' present. 68 | ... Alert Should Not Be Present action=LEAVE 69 | Run Keyword And Expect Error 70 | ... Alert with message 'Really change the title?' present. 71 | ... Alert Should Not Be Present action=DISmiss 72 | Wait For Title Change Original 73 | 74 | Alert Should Not Be Present with custom timeout 75 | Alert Should Not Be Present timeout=0.1s 76 | Click Button Slow alert 77 | Alert Should Not Be Present DISMISS ${0.001} 78 | Run Keyword And Expect Error 79 | ... Alert with message 'Alert after 500ms!' present. 80 | ... Alert Should Not Be Present timeout=0.99999 81 | 82 | Alert Should Be Present 83 | Run Keyword And Expect Error 84 | ... Alert not found in 1 second. 85 | ... Alert Should Be Present 86 | Click Link Click Me! 87 | Alert Should Be Present 88 | 89 | Alert Should Be Present with message validation 90 | Click Link Click Me! 91 | Alert Should Be Present ALERT! 92 | Click Link Click Me Too! 93 | Alert Should Be Present MULTILINE ALERT! 94 | Click Link Click Me! 95 | Run Keyword And Expect Error 96 | ... Alert message should have been 'foo bar' but it was 'ALERT!'. 97 | ... Alert Should Be Present foo bar 98 | 99 | Alert Should Be Present accepts by default 100 | [Setup] Go To Page "javascript/dynamic_content.html" 101 | Click Button Change the title 102 | Alert Should Be Present Really change the title? 103 | Wait For Title Change Original Changed! 104 | Alert Should Not Be Present 105 | 106 | Alert Should Be Present can dismiss 107 | [Setup] Go To Page "javascript/dynamic_content.html" 108 | Click Button Change the title 109 | Alert Should Be Present Really change the title? action=DISMISS 110 | Wait For Title Change Original 111 | Alert Should Not Be Present 112 | 113 | Alert Should Be Present can leave alert open 114 | [Setup] Go To Page "javascript/dynamic_content.html" 115 | Click Button Change the title 116 | Alert Should Be Present action=LEAVE 117 | Alert Should Be Present 118 | 119 | Alert Should Be Present with custom timeout 120 | Click Button Slow alert 121 | Run Keyword And Expect Error 122 | ... Alert not found in 1 millisecond. 123 | ... Alert Should Be Present timeout=1ms 124 | Alert Should Be Present Alert after 500ms! ACCEPT 3s 125 | 126 | Handle Alert when popup window closes 127 | [Documentation] Popup window is closed by javascript while 128 | ... 'Handle Alert' keyword is waiting for alert 129 | ... FAIL GLOB: An exception occurred waiting for alert* 130 | [Tags] triage 131 | [Setup] Go To Page "javascript/self_closing_popup.html" 132 | Click Button Self Closing 133 | ${handle} = Switch Window NEW 134 | Handle Alert timeout=10s 135 | [Teardown] Switch Window ${handle} 136 | 137 | 138 | *** Keywords *** 139 | Wait For Title Change 140 | [Arguments] ${expected} 141 | Wait For Condition return document.title == '${expected}' 142 | -------------------------------------------------------------------------------- /atest/acceptance/keywords/async_javascript.robot: -------------------------------------------------------------------------------- 1 | *** Settings *** 2 | Documentation Tests asynchronous javascript 3 | 4 | Resource ../resource.robot 5 | 6 | Suite Teardown Set Selenium Timeout 5 seconds 7 | Test Setup Go To Page "javascript/dynamic_content.html" 8 | 9 | 10 | *** Test Cases *** 11 | Should Not Timeout If Callback Invoked Immediately 12 | ${result} = Execute Async Javascript 13 | ... JAVASCRIPT 14 | ... arguments[arguments.length - 1](123); 15 | Should Be Equal ${result} ${123} 16 | 17 | Execute Async Javascript With ARGUMENTS and JAVASCRIPT Marker 18 | Execute Async Javascript 19 | ... ARGUMENTS 20 | ... 123 21 | ... JAVASCRIPT 22 | ... alert(arguments[0]); 23 | Alert Should Be Present 123 timeout=10 s 24 | 25 | Execute Javascript with dictionary object 26 | &{ARGS} = Create Dictionary key=value number=${1} boolean=${TRUE} 27 | ${returned} = Execute Async Javascript arguments[1](arguments[0]); ARGUMENTS ${ARGS} 28 | Should Be True type($returned) == dict 29 | Should Be Equal ${returned}[key] value 30 | Should Be Equal ${returned}[number] ${1} 31 | Should Be Equal ${returned}[boolean] ${TRUE} 32 | 33 | Should Be Able To Return Javascript Primitives From Async Scripts Neither None Nor Undefined 34 | ${result} = Execute Async Javascript arguments[arguments.length - 1](123); 35 | Should Be Equal ${result} ${123} 36 | ${result} = Execute Async Javascript arguments[arguments.length - 1]('abc'); 37 | Should Be Equal ${result} abc 38 | ${result} = Execute Async Javascript arguments[arguments.length - 1](false); 39 | Should Be Equal ${result} ${false} 40 | ${result} = Execute Async Javascript arguments[arguments.length - 1](true); 41 | Should Be Equal ${result} ${true} 42 | 43 | Should Be Able To Return Javascript Primitives From Async Scripts Null And Undefined 44 | ${result} = Execute Async Javascript arguments[arguments.length - 1](null); 45 | Should Be Equal ${result} ${None} 46 | ${result} = Execute Async Javascript arguments[arguments.length - 1](); 47 | Should Be Equal ${result} ${None} 48 | 49 | Should Be Able To Return An Array Literal From An Async Script 50 | ${result} = Execute Async Javascript arguments[arguments.length - 1]([]); 51 | Should Not Be Equal ${result} ${None} 52 | Length Should Be ${result} 0 53 | 54 | Should Be Able To Return An Array Object From An Async Script 55 | ${result} = Execute Async Javascript arguments[arguments.length - 1](new Array()); 56 | Should Not Be Equal ${result} ${None} 57 | Length Should Be ${result} 0 58 | 59 | Should Be Able To Return Arrays Of Primitives From Async Scripts 60 | ${result} = Execute Async Javascript 61 | ... arguments[arguments.length - 1]([null, 123, 'abc', true, false]); 62 | Should Not Be Equal ${result} ${None} 63 | Length Should Be ${result} 5 64 | ${value} = Remove From List ${result} -1 65 | Should Be Equal ${value} ${false} 66 | ${value} = Remove From List ${result} -1 67 | Should Be Equal ${value} ${true} 68 | ${value} = Remove From List ${result} -1 69 | Should Be Equal ${value} abc 70 | ${value} = Remove From List ${result} -1 71 | Should Be Equal ${value} ${123} 72 | ${value} = Remove From List ${result} -1 73 | Should Be Equal ${value} ${None} 74 | Length Should Be ${result} 0 75 | 76 | Should Timeout If Script Does Not Invoke Callback 77 | Run Keyword And Expect Error TimeoutException:* Execute Async Javascript return 1 + 2; 78 | 79 | Should Timeout If Script Does Not Invoke Callback With A Zero Timeout 80 | Run Keyword And Expect Error TimeoutException:* Execute Async Javascript 81 | ... window.setTimeout(function() {}, 0); 82 | 83 | Should Not Timeout If Script Callsback Inside A Zero Timeout 84 | ${result} = Execute Async Javascript 85 | ... var callback = arguments[arguments.length - 1]; 86 | ... window.setTimeout(function() { callback(123); }, 0) 87 | 88 | Should Timeout If Script Does Not Invoke Callback With Long Timeout 89 | Set Selenium Timeout 0.5 seconds 90 | Run Keyword And Expect Error TimeoutException:* Execute Async Javascript 91 | ... var callback = arguments[arguments.length - 1]; window.setTimeout(callback, 1500); 92 | 93 | Should Detect Page Loads While Waiting On An Async Script And Return An Error 94 | Set Selenium Timeout 0.5 seconds 95 | ${status} ${error} = Run Keyword And Ignore Error Execute Async Javascript 96 | ... window.location = 'javascript/dynamic'; 97 | Should Match Regexp ${error} (WebDriverException\:|JavascriptException\:) 98 | 99 | Should Catch Errors When Executing Initial Script 100 | ${status} ${error} = Run Keyword And Ignore Error Execute Async Javascript 101 | ... throw Error('you should catch this!'); 102 | Should Match Regexp ${error} (WebDriverException\:|JavascriptException\:) 103 | -------------------------------------------------------------------------------- /atest/acceptance/keywords/checkbox_and_radio_buttons.robot: -------------------------------------------------------------------------------- 1 | *** Settings *** 2 | Documentation Test checkboxes and radio buttons 3 | 4 | Resource ../resource.robot 5 | 6 | Test Setup Go To Page "forms/prefilled_email_form.html" 7 | 8 | 9 | *** Test Cases *** 10 | Checkbox Should Be Selected 11 | [Documentation] LOG 1 Verifying checkbox 'can_send_email' is selected. 12 | Checkbox Should Be Selected can_send_email 13 | Run Keyword And Expect Error 14 | ... Checkbox 'can_send_sms' should have been selected but was not. 15 | ... Checkbox Should Be Selected can_send_sms 16 | 17 | Checkbox Should Not Be Selected 18 | [Documentation] LOG 1 Verifying checkbox 'can_send_sms' is not selected. 19 | Checkbox Should Not Be Selected can_send_sms 20 | Run Keyword And Expect Error 21 | ... Checkbox 'can_send_email' should not have been selected. 22 | ... Checkbox Should Not Be Selected can_send_email 23 | 24 | Select Checkbox 25 | [Documentation] LOG 1 Selecting checkbox 'can_send_sms'. 26 | Select Checkbox can_send_sms 27 | Checkbox Should Be Selected can_send_sms 28 | Select Checkbox can_send_sms 29 | Checkbox Should Be Selected can_send_sms 30 | 31 | UnSelect Checkbox 32 | [Documentation] LOG 1 Unselecting checkbox 'can_send_email'. 33 | Unselect Checkbox can_send_email 34 | Checkbox Should Not Be Selected can_send_email 35 | Unselect Checkbox can_send_email 36 | Checkbox Should Not Be Selected can_send_email 37 | 38 | Checkbox keywords don't work with radio buttons 39 | Run Keyword And Expect Error 40 | ... Page should have contained checkbox 'referrer' but did not. 41 | ... Page Should Contain Checkbox referrer 42 | Page Should Not Contain Checkbox referrer 43 | Run Keyword And Expect Error 44 | ... Checkbox with locator 'referrer' not found. 45 | ... Checkbox Should Be Selected referrer 46 | Run Keyword And Expect Error 47 | ... Checkbox with locator 'referrer' not found. 48 | ... Checkbox Should Not Be Selected referrer 49 | Run Keyword And Expect Error 50 | ... Checkbox with locator 'referrer' not found. 51 | ... Select Checkbox referrer 52 | Run Keyword And Expect Error 53 | ... Checkbox with locator 'referrer' not found. 54 | ... Unselect Checkbox referrer 55 | 56 | Radio Button Should Be Set To 57 | [Documentation] LOG 1 Verifying radio button 'sex' has selection 'female'. 58 | Radio Button Should Be Set To sex female 59 | Run Keyword And Expect Error 60 | ... Selection of radio button 'sex' should have been 'male' but was 'female'. 61 | ... Radio Button Should Be Set To sex male 62 | 63 | Select Radio Button 64 | [Documentation] LOG 1 Selecting 'male' from radio button 'sex'. 65 | Select Radio Button sex male 66 | Radio Button Should Be Set To sex male 67 | Select Radio Button sex female 68 | Radio Button Should Be Set To sex female 69 | 70 | Radio Button Should Not Be Selected 71 | [Documentation] LOG 1 Verifying radio button 'referrer' has no selection. 72 | Radio Button Should Not Be Selected referrer 73 | Run Keyword And Expect Error 74 | ... Radio button group 'sex' should not have had selection, but 'female' was selected. 75 | ... Radio Button Should Not Be Selected sex 76 | 77 | Clicking Radio Button Should Trigger Onclick Event 78 | [Setup] Go To Page "javascript/dynamic_content.html" 79 | Select Radio Button group title 80 | Title Should Be Changed by Button 81 | 82 | Radio button not found 83 | Run Keyword And Expect Error 84 | ... No radio button with name 'nonex' and value 'whatever' found. 85 | ... Select Radio Button nonex whatever 86 | Run Keyword And Expect Error 87 | ... No radio button with name 'nonex' found. 88 | ... Radio button should be set to nonex whatever 89 | 90 | Radio button keywords don't work with checkboxes 91 | Run Keyword And Expect Error 92 | ... No radio button with name 'can_send_email' and value 'whatever' found. 93 | ... Select Radio Button can_send_email whatever 94 | Run Keyword And Expect Error 95 | ... No radio button with name 'can_send_email' found. 96 | ... Radio button should be set to can_send_email whatever 97 | -------------------------------------------------------------------------------- /atest/acceptance/keywords/choose_file.robot: -------------------------------------------------------------------------------- 1 | *** Settings *** 2 | Resource ../resource.robot 3 | 4 | Test Setup Go To Page "forms/named_submit_buttons.html" 5 | 6 | 7 | *** Test Cases *** 8 | Choose File 9 | [Setup] Navigate To File Upload Form And Create Temp File To Upload 10 | Choose File file_to_upload ${CURDIR}${/}temp.txt 11 | # Not sure do you get "C:\fakepath\" prefix with all browsers but at least 12 | # Chrome and Firefox use it regardless the OS. 13 | Textfield Value Should Be file_to_upload C:\\fakepath\\temp.txt 14 | [Teardown] Remove File ${CURDIR}${/}temp.txt 15 | 16 | Choose File And File Does Not Exist 17 | [Setup] Go To Page "forms/file_upload_form.html" 18 | Run Keyword And Expect Error 19 | ... InvalidArgumentException: Message:* 20 | ... Choose File file_to_upload ${CURDIR}${/}NotHere.txt 21 | 22 | Choose File And Folder 23 | [Tags] known issue firefox 24 | [Setup] Go To Page "forms/file_upload_form.html" 25 | Choose File file_to_upload ${CURDIR} 26 | Textfield Value Should Be file_to_upload C:\\fakepath\\keywords 27 | 28 | Choose File With Grid 29 | [Documentation] 30 | ... LOG 1:6 DEBUG GLOB: POST*/session/*/file*"file": "* 31 | [Tags] onlygrid 32 | [Setup] Touch ${CURDIR}${/}temp2.txt 33 | Choose File file_to_upload ${CURDIR}${/}temp2.txt 34 | Textfield Value Should Be file_to_upload C:\\fakepath\\temp2.txt 35 | [Teardown] Remove File ${CURDIR}${/}temp2.txt 36 | 37 | Choose File With Grid From Library Using SL choose_file method 38 | [Documentation] 39 | ... LOG 3:6 DEBUG GLOB: POST*/session/*/file*"file": "* 40 | [Tags] onlygrid 41 | [Setup] Go To Page "forms/file_upload_form.html" 42 | Touch ${CURDIR}${/}temp42.txt 43 | Import Library ${CURDIR}/../../resources/testlibs/ChooseFileLib.py 44 | ChooseFileLib.my_choose_file css=[name="file_to_upload"] ${CURDIR}${/}temp42.txt 45 | Textfield Value Should Be file_to_upload C:\\fakepath\\temp42.txt 46 | [Teardown] Remove File ${CURDIR}${/}temp42.txt 47 | 48 | Input Text Should Work Same Way When Not Using Grid 49 | [Documentation] 50 | ... LOG 1:6 DEBUG GLOB: POST*/session/*/clear {* 51 | ... LOG 1:9 DEBUG Finished Request 52 | ... LOG 1:10 DEBUG GLOB: POST*/session/*/value*"text": "* 53 | ... LOG 1:13 DEBUG Finished Request 54 | ... LOG 1:14 DEBUG NONE 55 | [Tags] nogrid 56 | [Setup] Touch ${CURDIR}${/}temp.txt 57 | Input Text file_to_upload ${CURDIR}${/}temp.txt 58 | Textfield Value Should Be file_to_upload C:\\fakepath\\temp.txt 59 | [Teardown] Remove File ${CURDIR}${/}temp.txt 60 | 61 | Input Text Should Work Same Way When Using Grid 62 | [Tags] onlygrid 63 | [Setup] Touch ${CURDIR}${/}temp3.txt 64 | Input Text file_to_upload ${CURDIR}${/}temp3.txt 65 | Textfield Value Should Be file_to_upload C:\\fakepath\\temp3.txt 66 | [Teardown] Remove File ${CURDIR}${/}temp3.txt 67 | 68 | 69 | *** Keywords *** 70 | Navigate To File Upload Form And Create Temp File To Upload 71 | Cannot Be Executed in IE 72 | Go To Page "forms/file_upload_form.html" 73 | Touch ${CURDIR}${/}temp.txt 74 | -------------------------------------------------------------------------------- /atest/acceptance/keywords/click_element.robot: -------------------------------------------------------------------------------- 1 | *** Settings *** 2 | Documentation Tests clicking element 3 | 4 | Resource ../resource.robot 5 | 6 | Suite Setup Go To Page "javascript/click.html" 7 | Test Setup Initialize Page 8 | 9 | 10 | *** Test Cases *** 11 | Click Element 12 | [Documentation] LOG 1 Clicking element 'singleClickButton'. 13 | Click Element singleClickButton 14 | Element Text Should Be output single clicked 15 | 16 | Double Click Element 17 | [Documentation] LOG 1 Double clicking element 'doubleClickButton'. 18 | [Tags] known issue safari 19 | Double Click Element doubleClickButton 20 | Element Text Should Be output double clicked 21 | 22 | Click Element Error 23 | [Setup] Go To Page "javascript/click.html" 24 | 25 | Run Keyword And Expect Error Element with locator 'id:äääääää' not found. Click Element id:äääääää 26 | 27 | Click Element Error 2 28 | [Setup] Go To Page "javascript/click.html" 29 | Run Keyword And Expect Error Element with locator 'id:鱼鱼鱼鱼' not found. Click Element id:鱼鱼鱼鱼 30 | 31 | Click Element Error 3 32 | [Setup] Go To Page "javascript/click.html" 33 | Run Keyword And Expect Error Element with locator '鱼在天空中飞翔' not found. Click Element 鱼在天空中飞翔 34 | 35 | Double Click Element Error 36 | [Setup] Go To Page "javascript/click.html" 37 | Run Keyword And Expect Error Element with locator 'id:öööö' not found. Double Click Element id:öööö 38 | 39 | Click Element Action Chain 40 | [Documentation] 41 | ... LOB 1:1 INFO Clicking 'singleClickButton' using an action chain. 42 | [Tags] nogrid 43 | Click Element singleClickButton action_chain=True 44 | Element Text Should Be output single clicked 45 | 46 | 47 | *** Keywords *** 48 | Initialize Page 49 | [Documentation] Initialize Page 50 | Reload Page 51 | Set Selenium Timeout 1 seconds 52 | Element Text Should Be output initial output 53 | -------------------------------------------------------------------------------- /atest/acceptance/keywords/click_element_at_coordinates.robot: -------------------------------------------------------------------------------- 1 | *** Settings *** 2 | Documentation Clicks element at coordinates 3 | 4 | Resource ../resource.robot 5 | 6 | Suite Setup Go To Page "javascript/click_at_coordinates.html" 7 | Test Setup Initialize Page 8 | 9 | 10 | *** Test Cases *** 11 | Click Element At Coordinates 12 | [Documentation] LOG 1 Clicking element 'Clickable' at coordinates x=10, y=20. 13 | [Tags] known issue internet explorer known issue safari 14 | Click Element At Coordinates Clickable ${10} ${20} 15 | Element Text Should Be outputX 110 16 | Element Text Should Be outputY 120 17 | 18 | 19 | *** Keywords *** 20 | Initialize page 21 | [Documentation] Initialize page 22 | Reload Page 23 | Element Text Should Be outputX initial outputX 24 | Element Text Should Be outputY initial outputY 25 | -------------------------------------------------------------------------------- /atest/acceptance/keywords/click_element_modifier.robot: -------------------------------------------------------------------------------- 1 | *** Settings *** 2 | Resource ../resource.robot 3 | 4 | Suite Setup Go To Page "javascript/click_modifier.html" 5 | Test Setup Initialize Page 6 | 7 | 8 | *** Test Cases *** 9 | Click Element Modifier CTRL 10 | Click Element Button modifier=ALT 11 | Element Text Should Be output ALT click 12 | 13 | Click Link Modifier CTRL 14 | Click Link link text modifier=ALT 15 | Element Text Should Be output ALT click 16 | [Teardown] Close Popup Window 17 | 18 | Click Button Modifier CTRL 19 | Click Button Click me! modifier=CTRL 20 | Element Text Should Be output CTRL click 21 | 22 | Click Image Modifier CTRL 23 | Click Image robot modifier=CTRL 24 | Element Text Should Be output CTRL click 25 | 26 | Click Element Modifier ALT 27 | Click Element Button alt 28 | Element Text Should Be output ALT click 29 | 30 | Click Element Modifier Shift 31 | Click Element Button Shift 32 | Element Text Should Be output Shift click 33 | 34 | Click Element Modifier CTRL+Shift 35 | Click Element Button modifier=CTRL+Shift 36 | Element Text Should Be output CTRL and Shift click 37 | 38 | Click Element No Modifier 39 | Click Element Button modifier=False 40 | Element Text Should Be output Normal click 41 | 42 | Click Element Wrong Modifier 43 | Run Keyword And Expect Error 44 | ... ValueError: 'FOOBAR' modifier does not match to Selenium Keys 45 | ... Click Element Button Foobar 46 | 47 | Click Element Action Chain and modifier 48 | [Documentation] LOG 1:1 INFO Clicking element 'Button' with CTRL. 49 | Click Element Button modifier=ALT action_chain=True 50 | Element Text Should Be output ALT click 51 | 52 | 53 | *** Keywords *** 54 | Initialize Page 55 | Reload Page 56 | Element Text Should Be output initial output 57 | 58 | Close Popup Window 59 | Switch Window myName timeout=5s 60 | Close Window 61 | Switch Window MAIN timeout=5s 62 | -------------------------------------------------------------------------------- /atest/acceptance/keywords/counting_elements.robot: -------------------------------------------------------------------------------- 1 | *** Settings *** 2 | Resource ../resource.robot 3 | Library String 4 | 5 | Test Setup Go To Front Page 6 | 7 | Default Tags element count 8 | 9 | 10 | *** Test Cases *** 11 | Get Element Count With Xpath Locator 12 | [Setup] Go To Page "links.html" 13 | ${count} = Get Element Count xpath://*[@name="div_name"] 14 | Should Be Equal ${count} ${2} 15 | ${count} = Get Element Count //*[@name="div_name"] 16 | Should Be Equal ${count} ${2} 17 | 18 | Get Element Count With Default Locator 19 | [Setup] Go To Page "links.html" 20 | ${count} = Get Element Count div_name 21 | Should Be Equal ${count} ${2} 22 | 23 | Get Element Count With Name Locator 24 | [Setup] Go To Page "links.html" 25 | ${count} = Get Element Count name:div_name 26 | Should Be Equal ${count} ${2} 27 | 28 | Get Element Count Should Not Fail When Zero Elements Is Found 29 | [Setup] Go To Page "links.html" 30 | ${count} = Get Element Count name:not_exist 31 | Should Be Equal ${count} ${0} 32 | 33 | Page Should Contain Element When Limit Is None 34 | [Setup] Go To Page "links.html" 35 | Page Should Contain Element name: div_name 36 | Page Should Contain Element name: div_name limit=None 37 | Page Should Contain Element name: div_name limit=${None} 38 | 39 | Page Should Contain Element When Limit Is Number 40 | [Documentation] LOG 1:5 INFO Current page contains 2 element(s). 41 | [Tags] nogrid 42 | [Setup] Go To Page "links.html" 43 | Page Should Contain Element name: div_name limit=2 44 | 45 | Page Should Contain Element Log Level Does Not Affect When Keyword Passes 46 | [Documentation] LOG 1:5 INFO Current page contains 2 element(s). 47 | [Tags] nogrid 48 | [Setup] Go To Page "links.html" 49 | Page Should Contain Element name: div_name loglevel=debug limit=2 50 | 51 | Page Should Contain Element When Limit Is Number And Error 52 | [Setup] Go To Page "links.html" 53 | Run Keyword And Expect Error 54 | ... Page should have contained "99" element(s), but it did contain "2" element(s). 55 | ... Page Should Contain Element name: div_name limit=99 56 | Run Keyword And Expect Error 57 | ... Custom error message. 58 | ... Page Should Contain Element name: div_name message=Custom error message. limit=${99} 59 | 60 | Page Should Contain Element When Limit Is Not Number 61 | [Setup] Go To Page "links.html" 62 | Run Keyword And Expect Error 63 | ... ValueError: *Argument 'limit' got value 'AA'* 64 | ... Page Should Contain Element name: div_name limit=AA 65 | 66 | Page Should Contain Element When Error With Limit And Different Loglevels 67 | [Documentation] Only at DEBUG loglevel is the html placed in the log. 68 | [Tags] nogrid 69 | [Setup] Go To Page "links.html" 70 | Run Keyword And Ignore Error 71 | ... Page Should Contain Element name: div_name limit=99 72 | Run Keyword And Expect Error Page should have contained "99" element(s), but it did contain "2" element(s). 73 | ... Page Should Contain Element name: div_name loglevel=debug limit=99 74 | -------------------------------------------------------------------------------- /atest/acceptance/keywords/element_focus.robot: -------------------------------------------------------------------------------- 1 | *** Settings *** 2 | Documentation Tests Focus Verification and Wait for Focus 3 | 4 | Resource ../resource.robot 5 | 6 | Suite Setup Open Browser To Start Page 7 | 8 | 9 | *** Test Cases *** 10 | Should Be Focused 11 | [Setup] Go To Page "mouse/index.html" 12 | Click Element el_for_focus 13 | Element Should Be Focused el_for_focus 14 | 15 | Should Not Be Focused 16 | [Setup] Go To Page "mouse/index.html" 17 | Click Element el_for_focus 18 | Run Keyword And Expect Error 19 | ... Element 'el_for_blur' does not have focus. 20 | ... Element Should Be Focused el_for_blur 21 | Element Should Be Focused el_for_focus 22 | 23 | Unexistent Element Not Focused 24 | [Setup] Go To Page "mouse/index.html" 25 | Click Element el_for_focus 26 | Run Keyword And Expect Error 27 | ... Element with locator 'Unexistent_element' not found. 28 | ... Element Should Be Focused Unexistent_element 29 | 30 | Span Element Not Focused 31 | [Documentation] Focus on not Focusable Span 32 | [Setup] Go To Page "/" 33 | Click Element some_id 34 | Run Keyword And Expect Error 35 | ... Element 'some_id' does not have focus. 36 | ... Element Should Be Focused some_id 37 | 38 | Table Element Not Focused 39 | [Documentation] Focus on not Focusable Table 40 | [Setup] Go To Page "tables/tables.html" 41 | Click Element simpleTable 42 | Run Keyword And Expect Error 43 | ... Element 'simpleTable' does not have focus. 44 | ... Element Should Be Focused simpleTable 45 | 46 | Radio Button Should Be Focused 47 | [Setup] Go To Page "forms/prefilled_email_form.html" 48 | Click Element xpath=//input[@name='sex' and @value='male'] 49 | Element Should Be Focused xpath=//input[@name='sex' and @value='male'] 50 | Run Keyword And Expect Error 51 | ... Element 'xpath=//input?@name=\'sex\' and @value=\'female\'?' does not have focus. 52 | ... Element Should Be Focused xpath=//input[@name='sex' and @value='female'] 53 | 54 | Checkbox Should Be Focused 55 | [Setup] Go To Page "forms/prefilled_email_form.html" 56 | Click Element xpath=//input[@name='can_send_sms'] 57 | Element Should Be Focused xpath=//input[@name='can_send_sms'] 58 | Run Keyword And Expect Error 59 | ... Element 'xpath=//input?@name=\'can_send_email\'?' does not have focus. 60 | ... Element Should Be Focused xpath=//input[@name='can_send_email'] 61 | 62 | Select Button Should Be Focused 63 | [Setup] Go To Page "forms/prefilled_email_form.html" 64 | Mouse Down xpath=//select[@name='preferred_channel'] 65 | Element Should Be Focused xpath=//select[@name='preferred_channel'] 66 | Run Keyword And Expect Error 67 | ... Element 'xpath=//select?@name=\'preferred_channel\'?/option?@value=\'phone\'?' does not have focus. 68 | ... Element Should Be Focused xpath=//select[@name='preferred_channel']/option[@value='phone'] 69 | Click Element xpath=//option[@value='email'] 70 | Run Keyword And Expect Error 71 | ... Element 'xpath=//option?@value=\'email\'?' does not have focus. 72 | ... Element Should Be Focused xpath=//option[@value='email'] 73 | 74 | Submit Button Should Be Focused 75 | [Setup] Go To Page "forms/prefilled_email_form.html" 76 | Mouse Up preferred_channel 77 | Mouse Down submit 78 | Sleep 1 second 79 | Element Should Be Focused submit 80 | Mouse Up submit 81 | [Teardown] Wait Until Location Is http://localhost:7000/html/forms/submit.html 82 | 83 | Set Focus To Element 84 | [Setup] Go To Page "mouse/index.html" 85 | Set Focus To Element id:el_for_focus 86 | Textfield Value Should Be el_for_focus focus el_for_focus 87 | Element Should Be Focused el_for_focus 88 | -------------------------------------------------------------------------------- /atest/acceptance/keywords/element_should_be_enabled_and_disabled.robot: -------------------------------------------------------------------------------- 1 | *** Settings *** 2 | Documentation Tests disabled and readonly elements 3 | 4 | Resource ../resource.robot 5 | 6 | Test Setup Go To Page "forms/enabled_disabled_fields_form.html" 7 | 8 | 9 | *** Test Cases *** 10 | Input Text 11 | Should Be Enabled Not Disabled enabled_input 12 | Should Be Disabled Not Enabled readonly_input 13 | Should Be Disabled Not Enabled disabled_input 14 | 15 | Input Password 16 | Should Be Enabled Not Disabled enabled_password 17 | Should Be Disabled Not Enabled readonly_password 18 | Should Be Disabled Not Enabled disabled_password 19 | 20 | Input Button 21 | Should Be Enabled Not Disabled enabled_input_button 22 | Should Be Disabled Not Enabled disabled_input_button 23 | 24 | Textarea 25 | Should Be Enabled Not Disabled enabled_textarea 26 | Should Be Disabled Not Enabled readonly_textarea 27 | Should Be Disabled Not Enabled disabled_textarea 28 | 29 | Button 30 | Should Be Enabled Not Disabled enabled_button 31 | Should Be Disabled Not Enabled disabled_button 32 | 33 | Option 34 | Should Be Enabled Not Disabled enabled_option 35 | Should Be Disabled Not Enabled disabled_option 36 | 37 | Disabled with different syntaxes 38 | Should Be Disabled Not Enabled disabled_only 39 | Should Be Disabled Not Enabled disabled_with_equals_only 40 | Should Be Disabled Not Enabled disabled_empty 41 | Should Be Disabled Not Enabled disabled_invalid_value 42 | 43 | Readonly with different syntaxes 44 | Should Be Disabled Not Enabled readonly_only 45 | Should Be Disabled Not Enabled readonly_with_equals_only 46 | Should Be Disabled Not Enabled readonly_empty 47 | Should Be Disabled Not Enabled readonly_invalid_value 48 | 49 | Not Input nor Editable Element 50 | Should Be Enabled Not Disabled table1 51 | 52 | 53 | *** Keywords *** 54 | Should Be Enabled Not Disabled 55 | [Documentation] Should Be Enabled Not Disabled 56 | [Arguments] ${locator} 57 | Element Should Be Enabled ${locator} 58 | Run Keyword And Expect Error Element '${locator}' is enabled. 59 | ... Element Should Be Disabled ${locator} 60 | 61 | Should Be Disabled Not Enabled 62 | [Documentation] Should Be Disabled Not Enabled 63 | [Arguments] ${locator} 64 | Element Should Be Disabled ${locator} 65 | Run Keyword And Expect Error Element '${locator}' is disabled. 66 | ... Element Should Be Enabled ${locator} 67 | -------------------------------------------------------------------------------- /atest/acceptance/keywords/element_visibility.robot: -------------------------------------------------------------------------------- 1 | *** Settings *** 2 | Resource ../resource.robot 3 | 4 | 5 | *** Test Cases *** 6 | Wait Until Element Is Visible 7 | [Tags] known issue internet explorer 8 | [Setup] Go To Page "javascript/delayed_events.html" 9 | Run Keyword And Expect Error 10 | ... Element 'hidden' not visible after 10 milliseconds. 11 | ... Wait Until Element Is Visible hidden 0.01 12 | Run Keyword And Expect Error 13 | ... User error message 14 | ... Wait Until Element Is Visible hidden 0.01 User error message 15 | Wait Until Element Is Visible hidden 2 s 16 | Run Keyword And Expect Error 17 | ... Element 'invalid' not visible after 100 milliseconds. 18 | ... Wait Until Element Is Visible invalid 0.1 19 | 20 | Wait Until Element Is Visible with locator and error arguments 21 | [Tags] known issue internet explorer 22 | [Setup] Go To Page "javascript/delayed_events.html" 23 | Wait Until Element Is Visible hidden error=My error message 24 | 25 | Wait Until Element Is Visible with locator only 26 | [Tags] known issue internet explorer 27 | [Setup] Go To Page "javascript/delayed_events.html" 28 | Wait Until Element Is Visible hidden 29 | 30 | Wait Until Element Is Not Visible 31 | [Setup] Go To Page "javascript/delayed_events.html" 32 | Wait Until Element Is Not Visible id:hide_delay 33 | Wait Until Element Is Not Visible id:not_present timeout=3 34 | 35 | Element Should Be Visible 36 | [Setup] Go To Page "visibility.html" 37 | Element Should Be Visible i_am_visible 38 | Run Keyword And Expect Error 39 | ... The element 'i_am_hidden' should be visible, but it is not. 40 | ... Element Should Be Visible i_am_hidden 41 | 42 | Element Should Not Be Visible 43 | [Setup] Go To Page "visibility.html" 44 | Element Should Not Be Visible i_am_hidden 45 | Element Should Not Be Visible not_here 46 | Run Keyword And Expect Error 47 | ... The element 'i_am_visible' should not be visible, but it is. 48 | ... Element Should Not Be Visible i_am_visible 49 | -------------------------------------------------------------------------------- /atest/acceptance/keywords/executed_by_execute_javascript.js: -------------------------------------------------------------------------------- 1 | window.add_content('button_target', 'Inserted via file') 2 | -------------------------------------------------------------------------------- /atest/acceptance/keywords/forms_and_buttons.robot: -------------------------------------------------------------------------------- 1 | *** Settings *** 2 | Resource ../resource.robot 3 | 4 | Test Setup Go To Page "forms/named_submit_buttons.html" 5 | 6 | 7 | *** Variables *** 8 | ${FORM SUBMITTED} forms/submit.html 9 | 10 | 11 | *** Test Cases *** 12 | Submit Form 13 | [Documentation] LOG 1 Submitting form 'form_name'. 14 | Submit Form form_name 15 | Verify Location Is "${FORM SUBMITTED}" 16 | 17 | Submit Form Without Args 18 | [Setup] Go To Page "forms/form_without_name.html" 19 | Submit Form 20 | Verify Location Is "target/first.html" 21 | 22 | Click Ok Button By Name 23 | [Documentation] LOG 1 Clicking button 'ok_button'. 24 | Click Button ok_button 25 | Verify Location Is "${FORM SUBMITTED}" 26 | 27 | Click Cancel Button By Name 28 | Click Button cancel_button 29 | Value Should Be Cancel 30 | 31 | Click Ok Button By Value 32 | Click Button Ok 33 | Verify Location Is "${FORM SUBMITTED}" 34 | 35 | Click Cancel Button By Value 36 | Click Button Cancel 37 | Value Should Be Cancel 38 | 39 | Click button created with 8 | 9 |
10 | 11 |
12 |
13 | 14 |
15 |
16 | 17 |
18 | 19 | 20 | -------------------------------------------------------------------------------- /atest/resources/html/forms/email_form.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | (root)/forms/email_form.html 4 | 5 | 6 |
7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 |
Name:
Email:
Website:
Comment:
28 |
29 | 30 | -------------------------------------------------------------------------------- /atest/resources/html/forms/enabled_disabled_fields_form.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | (root)/forms/enabled_disabled_fields_form.html 4 | 5 | 6 |
7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 43 | 44 |
Enabled input:
Readonly input:
Disabled input:
Enabled password:
Readonly password:
Disabled password:
45 |
46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 |
Enabled textarea:
Readonly textarea:
Disabled textarea:
Enabled button:
Disabled button:
disabled
disabled=
disabled=""
disabled="kekkonen"readonly
readonly=
readonly=""
readonly="kekkonen"
98 | 99 | 100 | -------------------------------------------------------------------------------- /atest/resources/html/forms/file_upload_form.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | (root)/forms/file_upload_form.html 4 | 5 | 6 |
7 | 8 | 9 |
10 | 11 | -------------------------------------------------------------------------------- /atest/resources/html/forms/form_with_image_submit.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | (root)/forms/email_form.html 4 | 5 | 6 |
7 |

Example

8 | 9 | 13 | 15 |
A List 10 |
Example...


16 |

Clicking the image below submits this form

17 |
18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /atest/resources/html/forms/form_with_special_characters_in_field_names.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |
5 | 6 |

Tracing Options

7 | 8 | 9 | 10 | 11 | 12 | 13 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 44 | 45 | 46 | 47 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 |
Write trace information to System ConsoleLowest level:   14 |
Write trace information to temporary fileLowest level: nbsp; 33 |
nbsp;Write to temporary file: 48 |
Show trace for selected classes onlynbsp;
59 |

60 | 61 | 62 |

63 | 64 | 65 | -------------------------------------------------------------------------------- /atest/resources/html/forms/form_without_name.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | (root)/forms/form_without_name.html 4 | 5 | 6 |
7 | 8 | 9 |
10 |
11 | 12 | 13 |
14 | 15 | -------------------------------------------------------------------------------- /atest/resources/html/forms/html5_input_types.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | HTML 5 input types 6 | 7 | 8 |

Testing HMTL 5 different input types

9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 |
Type color
Type date
Type datetime-local
Type email
Type month
Type number
Type range
Type search
Type tel
Type time
Type url
Type week
59 | 60 | 61 | -------------------------------------------------------------------------------- /atest/resources/html/forms/input_special_keys.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |

Please input text and click the button. Text will appear in the page.


5 |

6 |
7 |
8 | 9 | 19 | 20 | -------------------------------------------------------------------------------- /atest/resources/html/forms/login.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | (root)/forms/login.html 4 | 5 | 6 |

Login Page

7 |

Please input your user name and password and click the login button.

8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 |
User Name:
Password:
 
23 |
24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /atest/resources/html/forms/named_email_form.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | (root)/forms/named_email_form.html 4 | 5 | 6 |
7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 |
Name:
Email:
Comment:
24 |
25 | 26 | -------------------------------------------------------------------------------- /atest/resources/html/forms/named_submit_buttons.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | (root)/forms/named_submit_buttons.html 4 | 5 | 6 |
7 | 8 | 9 | 10 |
11 | 12 | -------------------------------------------------------------------------------- /atest/resources/html/forms/prefilled_email_form.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | (root)/forms/prefilled_email_form.html 4 | 5 | 6 |
7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 31 | 32 | 33 | 34 | 38 | 39 | 40 | 41 | 46 | 47 | 48 | 49 | 56 | 57 | 58 | 59 | 66 | 67 | 68 | 69 | 76 | 77 | 78 | 79 | 80 |
Name:
Email:
Website:
Comment:
Opt-in settings: 28 | Can send email?
29 | Can send SMS? 30 |
Which sex are you: 35 | Female
36 | Male 37 |
Where did you hear of us: 42 | From the Internet
43 | At the water cooler
44 | From your mother 45 |
Select the preferred media for contacting you: 50 | 55 |
Select the media we can use for contacting you if the preferred media is unavailable: 60 | 65 |
Select your interests: 70 | 75 |
81 |
82 | 83 | -------------------------------------------------------------------------------- /atest/resources/html/forms/robot.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Snooz82/robotframework-browser-migration/7aa142a60e84e4676e8a40aa41ba1ce81328f53b/atest/resources/html/forms/robot.bmp -------------------------------------------------------------------------------- /atest/resources/html/forms/submit.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | (root)/forms/submit.html 4 | 5 | 6 | The form was submitted. 7 | 8 | -------------------------------------------------------------------------------- /atest/resources/html/frames/bar.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |

You're looking at bar.

4 | 5 | -------------------------------------------------------------------------------- /atest/resources/html/frames/foo.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |

You're looking at foo.

4 | 5 | -------------------------------------------------------------------------------- /atest/resources/html/frames/frameset.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /atest/resources/html/frames/iframes.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /atest/resources/html/frames/left.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |

This is LEFT side. Links:

4 | 10 |

Form:

11 |
12 | 13 | 14 |
15 | 16 | 17 | -------------------------------------------------------------------------------- /atest/resources/html/frames/poorlynamedframe.html: -------------------------------------------------------------------------------- 1 | 2 | Relative
3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /atest/resources/html/frames/right.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |

This is RIGHT side.

4 |

You're looking at right.

5 | 6 | 7 | -------------------------------------------------------------------------------- /atest/resources/html/frames/search_results.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |

You're looking at search results.

4 | 5 | -------------------------------------------------------------------------------- /atest/resources/html/image.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Snooz82/robotframework-browser-migration/7aa142a60e84e4676e8a40aa41ba1ce81328f53b/atest/resources/html/image.jpg -------------------------------------------------------------------------------- /atest/resources/html/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | (root)/index.html 4 | 5 | 6 |

This is the haystack and somewhere on this page is a needle.

7 | 8 |

This is more text

9 | This text is inside an identified element 10 | 1 11 | 12 | 13 | -------------------------------------------------------------------------------- /atest/resources/html/javascript/alert.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Click link to show an alert 4 | 5 | 6 |

Click Me!

7 |

Click Me Too!

8 |

9 | 10 | 11 | -------------------------------------------------------------------------------- /atest/resources/html/javascript/alert_prompt.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 |

Click the button to demonstrate the prompt box.

6 | 7 | 8 | 9 |

10 | 11 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /atest/resources/html/javascript/click.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 11 | 12 | 13 | 14 |

Clicking

15 |

Watch the output below

16 |

initial output

17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /atest/resources/html/javascript/click_at_coordinates.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 31 | 39 | 40 | 41 |
42 | Click on image 45 |
46 |

Clicking at coordinates

47 |

Watch the output below

48 |

initial outputX

49 |

initial outputY

50 | 51 | 52 | -------------------------------------------------------------------------------- /atest/resources/html/javascript/click_at_coordinates.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Snooz82/robotframework-browser-migration/7aa142a60e84e4676e8a40aa41ba1ce81328f53b/atest/resources/html/javascript/click_at_coordinates.png -------------------------------------------------------------------------------- /atest/resources/html/javascript/click_modifier.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Clicking with modifier 6 | 31 | 32 | 33 |

Clicking with modifier

34 |

Watch the output below

35 |

initial output

36 |
37 | link text
38 |
39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /atest/resources/html/javascript/context_menu.html: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 17 | 18 | 19 | 20 | 37 | 38 | 39 |
Right click for context menu
40 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /atest/resources/html/javascript/delayed_events.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Original 4 | 52 | 53 | 54 | 55 |
This is content
56 |
57 |
Element that should disappear
58 |
Element that should set display:none
59 | 60 | 61 | 62 | 63 | 64 | -------------------------------------------------------------------------------- /atest/resources/html/javascript/drag_and_drop.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 12 | 25 | 26 | 27 |
28 |
29 |

Drag me to my target

30 |
31 |
32 |

Drop here

33 |
34 |
35 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /atest/resources/html/javascript/dynamic_content.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Original 6 | 14 | 15 | 16 | change title
17 | add content
18 | title to ääää
19 |

20 | Change Title
22 | Add Content
24 |

25 |
26 |
27 |
28 |
29 |
30 | 33 |
34 |

35 |

36 | 37 | 38 | 39 | 40 | 42 | 43 |
44 |

45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /atest/resources/html/javascript/dynamiclinks.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | (root)/javascript/dynamiclinks.html 4 | 21 | 22 | 23 | my popup

24 | 25 | 26 | -------------------------------------------------------------------------------- /atest/resources/html/javascript/script_block_contains_html_tags.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Original 4 | 9 | 10 | 11 | 16 | 17 | 22 | 23 | 29 | 30 | 37 | 38 | 52 | 53 |

Page rendered correctly

54 | 55 | -------------------------------------------------------------------------------- /atest/resources/html/javascript/security_alert.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 8 | 9 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /atest/resources/html/javascript/self_closing_popup.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Self Closing Popup 4 | 12 | 13 | 14 |

When you click this button, another window / tab will open and automatically close 0.5s later

15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /atest/resources/html/javascript/wait_location.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 11 | 12 | 13 | Title 14 | 15 | 16 |

Test

17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /atest/resources/html/links.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | (root)/links.html 4 | 5 | 6 | 7 |
8 | Relative with text after
9 | Relative to sub-directory
10 | Absolute external link
11 | Link with id
12 |
13 |
14 | tooltip
15 | Text and image
16 | Link with double " quote
17 | Link with < & > \
18 | Link with asterisk * and another *
19 | Link with Unicode äöüÄÖÜß 20 |
21 |
22 | 23 | Link with whitespace 24 |
25 | 26 | Link with 27 | whitespace within 28 |
29 | Link with bolded text 30 |
31 |
32 | Image 33 | Link 34 |
35 |
36 | Image 37 | Link 38 |
39 |
40 | Target opens in new window 41 |
42 | 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /atest/resources/html/mouse/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Mouse Keyword Testbed 4 | 5 | 6 |
7 |
8 |
9 |
10 |
11 |
12 | 19 | 20 | -------------------------------------------------------------------------------- /atest/resources/html/nested_divs.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | (root)/nested_divs.html 4 | 5 | 6 |
7 |
A
8 |
B
9 |
10 | top/c/needle 11 |
12 |
13 |
D1
14 |
15 | top/d/d2/needle 16 |
17 | top/d/needle 18 |
19 |
20 | 21 | -------------------------------------------------------------------------------- /atest/resources/html/non_ascii.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Nön–Äßćîï ðåþä 6 | 7 | 8 |

This page contains some non-ASCII test data.

9 |

Different ways to represent umlauts:

10 | 16 |

good day in some languages:

17 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /atest/resources/html/robot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Snooz82/robotframework-browser-migration/7aa142a60e84e4676e8a40aa41ba1ce81328f53b/atest/resources/html/robot.png -------------------------------------------------------------------------------- /atest/resources/html/scroll/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Scroll Keyword Testbed 4 | 5 | 16 | 17 |
18 |
Div 1
19 |
Div 2
20 |
Div 3
21 |
Div 4
22 |
Div 5
23 |
Div 6
24 |
Div 7
25 |
Div 8
26 |
27 |
28 | 29 |
30 | 36 | 37 | -------------------------------------------------------------------------------- /atest/resources/html/sub/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | (root)/sub/index.html 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /atest/resources/html/visibility.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Visibility Keyword Testbed 4 | 5 | 6 |
nothing special
7 | 8 | 9 | -------------------------------------------------------------------------------- /atest/resources/testlibs/BigListOfNaughtyStrings.py: -------------------------------------------------------------------------------- 1 | import json 2 | import os 3 | import platform 4 | 5 | from robot.api import logger 6 | 7 | 8 | class BigListOfNaughtyStrings: 9 | """The Big List of Naughty Strings is originally copied from here: 10 | https://github.com/minimaxir/big-list-of-naughty-strings 11 | """ 12 | 13 | def get_blns(self): 14 | if platform.system() == "Windows": 15 | logger.warn("Rading Big List of Naughty Strings does not work in Windows OS") 16 | return [] 17 | cur_dir = os.path.dirname(os.path.abspath(__file__)) 18 | with open(os.path.join(cur_dir, "blns.json")) as blns: 19 | return json.load(blns) 20 | -------------------------------------------------------------------------------- /atest/resources/testlibs/ChooseFileLib.py: -------------------------------------------------------------------------------- 1 | from robot.libraries.BuiltIn import BuiltIn 2 | 3 | 4 | def my_choose_file(locator, path): 5 | sl = BuiltIn().get_library_instance("SeleniumLibraryToBrowser") 6 | sl.choose_file(locator, path) 7 | -------------------------------------------------------------------------------- /atest/resources/testlibs/CustomSeleniumKeywords.py: -------------------------------------------------------------------------------- 1 | from robot.libraries.BuiltIn import BuiltIn 2 | from SeleniumLibraryToBrowser import SeleniumLibraryToBrowser, keyword 3 | 4 | 5 | class CustomSeleniumKeywords(SeleniumLibraryToBrowser): 6 | def __init__(self, *args, **kwargs): 7 | """Share `SeleniumLibrary`'s cache of browsers, so that 8 | we don't have to open a separate browser instance for the 9 | `Run On Failure Keyword Only Called Once` test.""" 10 | super().__init__(*args, **kwargs) 11 | sl = BuiltIn().get_library_instance("SeleniumLibraryToBrowser") 12 | 13 | @keyword 14 | def custom_selenium_keyword(self): 15 | self.custom_selenium_keyword_inner() 16 | 17 | @keyword 18 | def custom_selenium_keyword_inner(self): 19 | raise AssertionError 20 | 21 | @keyword 22 | def use_find_element(self, locator, parent=None): 23 | return self.find_element(locator, parent) 24 | 25 | @keyword 26 | def use_find_elements(self, locator, parent=None): 27 | return self.find_elements(locator, parent) 28 | -------------------------------------------------------------------------------- /atest/resources/testlibs/ExtSL.py: -------------------------------------------------------------------------------- 1 | from SeleniumLibrary import SeleniumLibrary 2 | from SeleniumLibrary.base import keyword 3 | 4 | 5 | class ExtSL(SeleniumLibrary): 6 | @keyword 7 | def ext_web_element(self, locator): 8 | return self.get_webelements(locator) 9 | 10 | @keyword 11 | def ext_page_should_contain(self, text): 12 | self.page_should_contain(text) 13 | -------------------------------------------------------------------------------- /atest/resources/testlibs/MyListener.py: -------------------------------------------------------------------------------- 1 | from robot.api import logger 2 | from robot.libraries.BuiltIn import BuiltIn 3 | from selenium.webdriver.support.events import AbstractEventListener 4 | 5 | 6 | class MyListener(AbstractEventListener): 7 | def before_navigate_to(self, url, driver): 8 | logger.info("Before navigate to %s" % url) 9 | sl = BuiltIn().get_library_instance("SeleniumLibrary") 10 | if sl.driver: 11 | logger.info("Got driver also from SeleniumLibrary.") 12 | 13 | def after_navigate_to(self, url, driver): 14 | logger.info("After navigate to %s" % url) 15 | 16 | def before_click(self, element, driver): 17 | logger.info("Before click") 18 | 19 | def after_click(self, element, driver): 20 | logger.info("After click") 21 | 22 | def before_change_value_of(self, element, driver): 23 | logger.info("Before clear and send_keys") 24 | 25 | def after_change_value_of(self, element, driver): 26 | logger.info("After clear and send_keys") 27 | -------------------------------------------------------------------------------- /atest/resources/testlibs/blns.json: -------------------------------------------------------------------------------- 1 | [ 2 | "\\\\", 3 | "$1.00", 4 | "-1E+02", 5 | "-9223372036854775808/-1", 6 | "--1", 7 | "-", 8 | "999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999", 9 | "-1#IND", 10 | "0xabad1dea", 11 | "2.2250738585072011e-308", 12 | ",./;'[]\\-=", 13 | "<>?:\"{}|_+", 14 | "!@#$%^&*()`~", 15 | "\u0001\u0002\u0003\u0004\u0005\u0006\u0007\b\u000e\u000f\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017\u0018\u0019\u001a\u001b\u001c\u001d\u001e\u001f", 16 | "€‚ƒ„†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ", 17 | "\t\u000b\f …             ​

   ", 18 | "­؀؁؂؃؄؅؜۝܏᠎​‌‍‎‏‪‫‬‭‮⁠⁡⁢⁣⁤⁦⁧⁨⁩𑂽𛲠𛲡𛲢𛲣𝅳𝅴𝅵𝅶𝅷𝅸𝅹𝅺󠀁󠀠󠀡󠀢󠀣󠀤󠀥󠀦󠀧󠀨󠀩󠀪󠀫󠀬󠀭󠀮󠀯󠀰󠀱󠀲󠀳󠀴󠀵󠀶󠀷󠀸󠀹󠀺󠀻󠀼󠀽󠀾󠀿󠁀󠁁󠁂󠁃󠁄󠁅󠁆󠁇󠁈󠁉󠁊󠁋󠁌󠁍󠁎󠁏󠁐󠁑󠁒󠁓󠁔󠁕󠁖󠁗󠁘󠁙󠁚󠁛󠁜󠁝󠁞󠁟󠁠󠁡󠁢󠁣󠁤󠁥󠁦󠁧󠁨󠁩󠁪󠁫󠁬󠁭󠁮󠁯󠁰󠁱󠁲󠁳󠁴󠁵󠁶󠁷󠁸󠁹󠁺󠁻󠁼󠁽󠁾󠁿", 19 | "ЁЂЃЄЅІЇЈЉЊЋЌЍЎЏАБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыьэюя", 20 | "٠١٢٣٤٥٦٧٨٩", 21 | "⁰⁴⁵", 22 | "ด้้้้้็็็็็้้้้้็็็็็้้้้้้้้็็็็็้้้้้็็็็็้้้้้้้้็็็็็้้้้้็็็็็้้้้้้้้็็็็็้้้้้็็็็ ด้้้้้็็็็็้้้้้็็็็็้้้้้้้้็็็็็้้้้้็็็็็้้้้้้้้็็็็็้้้้้็็็็็้้้้้้้้็็็็็้้้้้็็็็ ด้้้้้็็็็็้้้้้็็็็็้้้้้้้้็็็็็้้้้้็็็็็้้้้้้้้็็็็็้้้้้็็็็็้้้้้้้้็็็็็้้้้้็็็็", 23 | "\"'\"'\"''''\"", 24 | "田中さんにあげて下さい", 25 | "𠜎𠜱𠝹𠱓𠱸𠲖𠳏", 26 | "Ⱥ", 27 | "(。◕ ∀ ◕。)", 28 | "🚾 🆒 🆓 🆕 🆖 🆗 🆙 🏧", 29 | "0️⃣ 1️⃣ 2️⃣ 3️⃣ 4️⃣ 5️⃣ 6️⃣ 7️⃣ 8️⃣ 9️⃣ 🔟", 30 | "🇺🇸🇷🇺🇸 🇦🇫🇦🇲🇸", 31 | "בְּרֵאשִׁית, בָּרָא אֱלֹהִים, אֵת הַשָּׁמַיִם, וְאֵת הָאָרֶץ", 32 | "﷽", 33 | "مُنَاقَشَةُ سُبُلِ اِسْتِخْدَامِ اللُّغَةِ فِي النُّظُمِ الْقَائِمَةِ وَفِيم يَخُصَّ التَّطْبِيقَاتُ الْحاسُوبِيَّةُ، ", 34 | "⁦test⁧", 35 | "̦H̬̤̗̤͝e͜ ̜̥̝̻͍̟́w̕h̖̯͓o̝͙̖͎̱̮ ҉̺̙̞̟͈W̷̼̭a̺̪͍į͈͕̭͙̯̜t̶̼̮s̘͙͖̕ ̠̫̠B̻͍͙͉̳ͅe̵h̵̬͇̫͙i̹͓̳̳̮͎̫̕n͟d̴̪̜̖ ̰͉̩͇͙̲͞ͅT͖̼͓̪͢h͏͓̮̻e̬̝̟ͅ ̤̹̝W͙̞̝͔͇͝ͅa͏͓͔̹̼̣l̴͔̰̤̟͔ḽ̫.͕", 36 | "Z̮̞̠͙͔ͅḀ̗̞͈̻̗Ḷ͙͎̯̹̞͓G̻O̭̗̮", 37 | "˙ɐnbᴉlɐ ɐuƃɐɯ ǝɹolop ʇǝ ǝɹoqɐl ʇn ʇunpᴉpᴉɔuᴉ ɹodɯǝʇ poɯsnᴉǝ op pǝs 'ʇᴉlǝ ƃuᴉɔsᴉdᴉpɐ ɹnʇǝʇɔǝsuoɔ 'ʇǝɯɐ ʇᴉs ɹolop ɯnsdᴉ ɯǝɹo˥", 38 | "00˙Ɩ$-", 39 | "⒯⒣⒠ ⒬⒰⒤⒞⒦ ⒝⒭⒪⒲⒩ ⒡⒪⒳ ⒥⒰⒨⒫⒮ ⒪⒱⒠⒭ ⒯⒣⒠ ⒧⒜⒵⒴ ⒟⒪⒢", 40 | "<script>alert(123)</script>", 41 | "http://a/%%30%30", 42 | "", 43 | " ", 44 | "%", 45 | "_", 46 | "$(touch /tmp/blns.fail)", 47 | "%s%s%s%s%s", 48 | "{0}", 49 | "%*.*s", 50 | "%n", 51 | "File:///", 52 | "../../../../../../../../../../../etc/hosts", 53 | "() { 0; }; touch /tmp/blns.shellshock1.fail;", 54 | "() { _; } >_[$($())] { touch /tmp/blns.shellshock2.fail; }", 55 | "<<< %s(un='%s') = %u", 56 | "+++ATH0", 57 | "http://www.cum.qc.ca/", 58 | "Roses are \u001b[0;31mred\u001b[0m, violets are \u001b[0;34mblue. Hope you enjoy terminal hue", 59 | "Powerلُلُصّبُلُلصّبُررً ॣ ॣh ॣ ॣ冗", 60 | "జ్ఞ‌ా" 61 | ] -------------------------------------------------------------------------------- /atest/resources/testlibs/cache_error.py: -------------------------------------------------------------------------------- 1 | from robot.libraries.BuiltIn import BuiltIn 2 | 3 | 4 | def invalidate_driver(): 5 | sl = BuiltIn().get_library_instance("SeleniumLibrary") 6 | sl.register_driver(None, "tidii") 7 | sl.register_driver(None, "foobar") 8 | -------------------------------------------------------------------------------- /atest/resources/testlibs/ctrl_or_command.py: -------------------------------------------------------------------------------- 1 | import platform 2 | 3 | 4 | def ctrl_or_command_key(): 5 | if platform.system() == "Darwin": 6 | return "COMMAND" 7 | return "CONTROL" 8 | -------------------------------------------------------------------------------- /atest/resources/testlibs/custom_locator.py: -------------------------------------------------------------------------------- 1 | from robot.libraries.BuiltIn import BuiltIn 2 | from selenium.webdriver.common.by import By 3 | from SeleniumLibrary import ElementFinder 4 | 5 | 6 | def custom_library_locator(parent, criteria, tag, constraints): 7 | sl = BuiltIn().get_library_instance("SeleniumLibrary") 8 | el = ElementFinder(sl) 9 | elements = parent.find_elements(By.XPATH, "//%s" % criteria) 10 | return el._filter_elements(elements, tag, constraints) 11 | -------------------------------------------------------------------------------- /atest/resources/testlibs/get_selenium_options.py: -------------------------------------------------------------------------------- 1 | from selenium import webdriver 2 | 3 | 4 | def get_chrome_options(): 5 | options = webdriver.ChromeOptions() 6 | options.add_argument("--disable-dev-shm-usage") 7 | return options 8 | -------------------------------------------------------------------------------- /atest/resources/testserver/testserver.py: -------------------------------------------------------------------------------- 1 | # Initially based on: 2 | # http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/336012 3 | 4 | import os 5 | import sys 6 | from http.client import HTTPConnection 7 | from http.server import HTTPServer, SimpleHTTPRequestHandler 8 | from socketserver import ThreadingMixIn 9 | 10 | 11 | class StoppableHttpRequestHandler(SimpleHTTPRequestHandler): 12 | """http request handler with QUIT stopping the server""" 13 | 14 | def do_QUIT(self): 15 | self.send_response(200) 16 | self.end_headers() 17 | self.server.shutdown() 18 | self.server.server_close() 19 | 20 | def do_POST(self): 21 | self.do_GET() 22 | 23 | 24 | class ThreadingHttpServer(ThreadingMixIn, HTTPServer): 25 | pass 26 | 27 | 28 | def stop_server(port=7000): 29 | """send QUIT request to http server running on localhost:""" 30 | conn = HTTPConnection("localhost:%d" % port) 31 | conn.request("QUIT", "/") 32 | conn.getresponse() 33 | 34 | 35 | def start_server(path, port=7000): 36 | os.chdir(path) 37 | server = ThreadingHttpServer(("", port), StoppableHttpRequestHandler) 38 | server.serve_forever() 39 | 40 | 41 | if __name__ == "__main__": 42 | if len(sys.argv) != 2 or sys.argv[1] not in ["start", "stop"]: 43 | print("usage: %s start|stop" % sys.argv[0]) 44 | sys.exit(1) 45 | if sys.argv[1] == "start": 46 | path = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) 47 | start_server(path) 48 | else: 49 | stop_server() 50 | -------------------------------------------------------------------------------- /createPip_whl_tar.sh: -------------------------------------------------------------------------------- 1 | #!/bin/zsh 2 | libdoc SeleniumLibraryToBrowser doc/index.html 3 | surge doc robotframework-browser-migration.surge.sh 4 | check-manifest --update 5 | rm -f dist/*.* 6 | python setup.py bdist_wheel sdist 7 | twine check dist/* 8 | echo "Next step - uploading to pypi!" 9 | read -n 1 10 | twine upload dist/* 11 | -------------------------------------------------------------------------------- /pyproject.toml: -------------------------------------------------------------------------------- 1 | [tool.pylint] 2 | max-line-length = 100 3 | disable = "missing-function-docstring,too-many-lines,missing-module-docstring,missing-class-docstring,invalid-name,too-many-arguments,too-many-instance-attributes,redefined-builtin,redefined-outer-name,too-many-public-methods,broad-exception-caught,keyword-arg-before-vararg" 4 | 5 | [tool.black] 6 | target-version = ['py38'] 7 | line-length = 100 8 | 9 | [tool.ruff] 10 | unfixable = [] 11 | exclude = [ 12 | "__pycache__", 13 | "dist", 14 | ".venv" 15 | ] 16 | ignore = [ 17 | "B008", # do not perform function calls in argument defaults 18 | "B904", # TODO only temporary. should be fixed. 19 | "E501", # line too long 20 | "N815", # mixedCase variable in class scope 21 | "N803", # argument name should be lowercase 22 | "N806", # variable in function should be lowercase 23 | "N812", # lowercase imported as non lowercase 24 | "N999", # Invalid module name: 'Browser' 25 | "PLR0913", # too many arguments 26 | ] 27 | target-version = "py38" 28 | select = [ 29 | "E", 30 | "F", 31 | "W", 32 | "C90", 33 | "I", 34 | "N", 35 | "B", 36 | "PYI", 37 | "PL", 38 | "PTH", 39 | "UP", 40 | "A", 41 | "C4", 42 | "DTZ", 43 | "ISC", 44 | "ICN", 45 | "INP", 46 | "PIE", 47 | "T20", 48 | "PYI", 49 | "PT", 50 | "RSE", 51 | "RET", 52 | "SIM", 53 | "RUF" 54 | ] -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | import re 2 | from os.path import abspath, dirname, join 3 | 4 | from setuptools import find_packages, setup 5 | 6 | CURDIR = dirname(abspath(__file__)) 7 | 8 | with open("README.rst", encoding="utf-8") as fh: 9 | long_description = fh.read() 10 | 11 | with open(join(CURDIR, "src", "SeleniumLibraryToBrowser", "__init__.py"), encoding="utf-8") as f: 12 | VERSION = re.search('__version__ = "(.*)"', f.read()).group(1) 13 | 14 | setup( 15 | name="robotframework-browser-migration", 16 | version=VERSION, 17 | author="René Rohner(Snooz82)", 18 | author_email="snooz@posteo.de", 19 | description="Some small helpers for migration of SeleniumLibrary to Browser", 20 | long_description_content_type="text/x-rst", 21 | long_description=long_description, 22 | url="https://github.com/Snooz82/robotframework-browser-migration", 23 | package_dir={"": "src"}, 24 | packages=find_packages("src"), 25 | classifiers=[ 26 | "Programming Language :: Python :: 3", 27 | "Programming Language :: Python :: 3.6", 28 | "Programming Language :: Python :: 3.7", 29 | "Programming Language :: Python :: 3.8", 30 | "License :: OSI Approved :: Apache Software License", 31 | "Operating System :: OS Independent", 32 | "Topic :: Software Development :: Testing", 33 | "Topic :: Software Development :: Testing :: Acceptance", 34 | "Framework :: Robot Framework", 35 | ], 36 | python_requires=">=3.6", 37 | install_requires=["robotframework >= 5.0"], 38 | entry_points={"console_scripts": ["SeleniumStats = SeleniumStats.__main__:main"]}, 39 | ) 40 | -------------------------------------------------------------------------------- /src/SeleniumLibraryToBrowser/errors.py: -------------------------------------------------------------------------------- 1 | # Copyright 2008-2011 Nokia Networks 2 | # Copyright 2011-2016 Ryan Tomac, Ed Manlove and contributors 3 | # Copyright 2016- Robot Framework Foundation 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | 18 | class SeleniumLibraryException(Exception): 19 | ROBOT_SUPPRESS_NAME = True 20 | 21 | 22 | class ElementNotFound(SeleniumLibraryException): 23 | pass 24 | 25 | 26 | class NoSuchElementException(Exception): 27 | pass 28 | 29 | 30 | class NoSuchFrameException(Exception): 31 | pass 32 | 33 | 34 | class InvalidArgumentException(Exception): 35 | pass 36 | 37 | 38 | class WindowNotFound(SeleniumLibraryException): 39 | pass 40 | 41 | 42 | class CookieNotFound(SeleniumLibraryException): 43 | pass 44 | 45 | 46 | class NoOpenBrowser(SeleniumLibraryException): 47 | pass 48 | 49 | 50 | class PluginError(SeleniumLibraryException): 51 | pass 52 | -------------------------------------------------------------------------------- /src/SeleniumLibraryToBrowser/keys.py: -------------------------------------------------------------------------------- 1 | from enum import Enum 2 | 3 | 4 | class Keys(Enum): 5 | """Set of special keys codes.""" 6 | 7 | NULL = "" 8 | CANCEL = "Cancel" # ^break 9 | HELP = "Help" 10 | BACKSPACE = "Backspace" 11 | BACK_SPACE = BACKSPACE 12 | TAB = "Tab" 13 | CLEAR = "Clear" 14 | RETURN = "Enter" 15 | ENTER = RETURN 16 | SHIFT = "Shift" 17 | LEFT_SHIFT = SHIFT 18 | CONTROL = "Control" 19 | CTRL = CONTROL 20 | LEFT_CONTROL = CTRL 21 | ALT = "Alt" 22 | LEFT_ALT = ALT 23 | PAUSE = "Pause" 24 | ESCAPE = "Escape" 25 | ESC = ESCAPE 26 | SPACE = " " 27 | PAGE_UP = "PageUp" 28 | PAGE_DOWN = "PageDown" 29 | END = "End" 30 | HOME = "Home" 31 | LEFT = "ArrowLeft" 32 | ARROW_LEFT = LEFT 33 | UP = "ArrowUp" 34 | ARROW_UP = UP 35 | RIGHT = "ArrowRight" 36 | ARROW_RIGHT = RIGHT 37 | DOWN = "ArrowDown" 38 | ARROW_DOWN = DOWN 39 | INSERT = "Insert" 40 | DELETE = "Delete" 41 | SEMICOLON = ";" 42 | EQUALS = "=" 43 | NUMPAD0 = "0" 44 | NUMPAD1 = "1" 45 | NUMPAD2 = "2" 46 | NUMPAD3 = "3" 47 | NUMPAD4 = "4" 48 | NUMPAD5 = "5" 49 | NUMPAD6 = "6" 50 | NUMPAD7 = "7" 51 | NUMPAD8 = "8" 52 | NUMPAD9 = "9" 53 | MULTIPLY = "Multiply" 54 | ADD = "Add" 55 | SEPARATOR = "Separator" 56 | SUBTRACT = "Subtract" 57 | DECIMAL = "Decimal" 58 | DIVIDE = "Divide" 59 | F1 = "F1" 60 | F2 = "F2" 61 | F3 = "F3" 62 | F4 = "F4" 63 | F5 = "F5" 64 | F6 = "F6" 65 | F7 = "F7" 66 | F8 = "F8" 67 | F9 = "F9" 68 | F10 = "F10" 69 | F11 = "F11" 70 | F12 = "F12" 71 | META = "Meta" 72 | COMMAND = META 73 | ZENKAKU_HANKAKU = "ZenkakuHanaku" 74 | -------------------------------------------------------------------------------- /src/SeleniumStats/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Snooz82/robotframework-browser-migration/7aa142a60e84e4676e8a40aa41ba1ce81328f53b/src/SeleniumStats/__init__.py --------------------------------------------------------------------------------