From 6bf0a5cb5034a7e684dcc3500e841785237ce2dd Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 19:32:43 +0200 Subject: Adding upstream version 1:115.7.0. Signed-off-by: Daniel Baumann --- testing/marionette/client/MANIFEST.in | 2 + testing/marionette/client/docs/Makefile | 153 ++ .../marionette/client/docs/advanced/actions.rst | 21 + testing/marionette/client/docs/advanced/debug.rst | 35 + .../client/docs/advanced/findelement.rst | 87 + .../marionette/client/docs/advanced/landing.rst | 13 + testing/marionette/client/docs/advanced/stale.rst | 76 + testing/marionette/client/docs/basics.rst | 185 ++ testing/marionette/client/docs/conf.py | 274 +++ testing/marionette/client/docs/index.rst | 16 + testing/marionette/client/docs/interactive.rst | 52 + testing/marionette/client/docs/make.bat | 190 ++ testing/marionette/client/docs/reference.rst | 66 + .../client/marionette_driver/__init__.py | 22 + .../marionette/client/marionette_driver/addons.py | 76 + testing/marionette/client/marionette_driver/by.py | 25 + .../client/marionette_driver/date_time_value.py | 49 + .../client/marionette_driver/decorators.py | 79 + .../marionette/client/marionette_driver/errors.py | 206 ++ .../client/marionette_driver/expected.py | 315 +++ .../client/marionette_driver/geckoinstance.py | 673 +++++++ .../marionette/client/marionette_driver/keys.py | 88 + .../client/marionette_driver/localization.py | 54 + .../client/marionette_driver/marionette.py | 2104 ++++++++++++++++++++ .../marionette/client/marionette_driver/timeout.py | 103 + .../client/marionette_driver/transport.py | 409 ++++ .../marionette/client/marionette_driver/wait.py | 175 ++ testing/marionette/client/requirements.txt | 3 + testing/marionette/client/setup.py | 54 + testing/marionette/harness/MANIFEST.in | 4 + testing/marionette/harness/README.rst | 30 + .../harness/marionette_harness/__init__.py | 32 + .../marionette_harness/certificates/test.cert | 86 + .../marionette_harness/certificates/test.key | 28 + .../marionette_harness/marionette_test/__init__.py | 24 + .../marionette_test/decorators.py | 194 ++ .../marionette_test/testcases.py | 422 ++++ .../harness/marionette_harness/runner/__init__.py | 16 + .../harness/marionette_harness/runner/base.py | 1268 ++++++++++++ .../harness/marionette_harness/runner/httpd.py | 243 +++ .../marionette_harness/runner/mixins/__init__.py | 5 + .../runner/mixins/window_manager.py | 210 ++ .../harness/marionette_harness/runner/serve.py | 239 +++ .../harness/marionette_harness/runtests.py | 115 ++ .../tests/harness_unit/conftest.py | 99 + .../tests/harness_unit/python.ini | 9 + .../tests/harness_unit/test_httpd.py | 92 + .../harness_unit/test_marionette_arguments.py | 80 + .../tests/harness_unit/test_marionette_harness.py | 110 + .../tests/harness_unit/test_marionette_runner.py | 541 +++++ .../harness_unit/test_marionette_test_result.py | 55 + .../tests/harness_unit/test_serve.py | 69 + .../marionette_harness/tests/unit-tests.ini | 30 + .../marionette_harness/tests/unit/data/test.html | 13 + .../tests/unit/test_accessibility.py | 271 +++ .../marionette_harness/tests/unit/test_addons.py | 140 ++ .../tests/unit/test_capabilities.py | 273 +++ .../marionette_harness/tests/unit/test_checkbox.py | 17 + .../tests/unit/test_checkbox_chrome.py | 33 + .../marionette_harness/tests/unit/test_chrome.py | 31 + .../tests/unit/test_chrome_action.py | 61 + .../tests/unit/test_chrome_element_css.py | 31 + .../tests/unit/test_cli_arguments.py | 98 + .../marionette_harness/tests/unit/test_click.py | 594 ++++++ .../tests/unit/test_click_chrome.py | 33 + .../tests/unit/test_click_scrolling.py | 167 ++ .../marionette_harness/tests/unit/test_context.py | 82 + .../marionette_harness/tests/unit/test_cookies.py | 115 ++ .../marionette_harness/tests/unit/test_crash.py | 212 ++ .../tests/unit/test_data_driven.py | 72 + .../tests/unit/test_date_time_value.py | 33 + .../tests/unit/test_element_id.py | 55 + .../tests/unit/test_element_id_chrome.py | 88 + .../tests/unit/test_element_rect.py | 22 + .../tests/unit/test_element_rect_chrome.py | 30 + .../tests/unit/test_element_state.py | 175 ++ .../tests/unit/test_element_state_chrome.py | 56 + .../marionette_harness/tests/unit/test_errors.py | 105 + .../tests/unit/test_execute_async_script.py | 240 +++ .../tests/unit/test_execute_isolate.py | 46 + .../tests/unit/test_execute_sandboxes.py | 86 + .../tests/unit/test_execute_script.py | 569 ++++++ .../marionette_harness/tests/unit/test_expected.py | 233 +++ .../tests/unit/test_expectedfail.py | 11 + .../tests/unit/test_file_upload.py | 169 ++ .../tests/unit/test_findelement.py | 479 +++++ .../tests/unit/test_findelement_chrome.py | 169 ++ .../tests/unit/test_geckoinstance.py | 25 + .../tests/unit/test_get_computed_label.py | 26 + .../tests/unit/test_get_computed_role.py | 26 + .../tests/unit/test_get_current_url_chrome.py | 39 + .../tests/unit/test_get_shadow_root.py | 66 + .../tests/unit/test_implicit_waits.py | 26 + .../tests/unit/test_key_actions.py | 71 + .../tests/unit/test_localization.py | 71 + .../tests/unit/test_marionette.py | 138 ++ .../tests/unit/test_modal_dialogs.py | 161 ++ .../tests/unit/test_mouse_action.py | 200 ++ .../tests/unit/test_navigation.py | 949 +++++++++ .../tests/unit/test_pagesource.py | 52 + .../tests/unit/test_pagesource_chrome.py | 26 + .../marionette_harness/tests/unit/test_position.py | 46 + .../marionette_harness/tests/unit/test_prefs.py | 217 ++ .../tests/unit/test_prefs_enforce.py | 54 + .../tests/unit/test_profile_management.py | 267 +++ .../marionette_harness/tests/unit/test_proxy.py | 159 ++ .../tests/unit/test_quit_restart.py | 550 +++++ .../marionette_harness/tests/unit/test_reftest.py | 105 + .../tests/unit/test_rendered_element.py | 31 + .../marionette_harness/tests/unit/test_report.py | 27 + .../tests/unit/test_run_js_test.py | 10 + .../tests/unit/test_screen_orientation.py | 75 + .../tests/unit/test_screenshot.py | 393 ++++ .../marionette_harness/tests/unit/test_select.py | 218 ++ .../tests/unit/test_sendkeys_menupopup_chrome.py | 106 + .../marionette_harness/tests/unit/test_session.py | 49 + .../tests/unit/test_shadowroot_findelement.py | 113 ++ .../tests/unit/test_skip_setup.py | 35 + .../tests/unit/test_switch_frame.py | 96 + .../tests/unit/test_switch_frame_chrome.py | 57 + .../tests/unit/test_switch_window_chrome.py | 113 ++ .../tests/unit/test_switch_window_content.py | 258 +++ .../tests/unit/test_teardown_context_preserved.py | 21 + .../marionette_harness/tests/unit/test_text.py | 26 + .../tests/unit/test_text_chrome.py | 35 + .../marionette_harness/tests/unit/test_timeouts.py | 113 ++ .../marionette_harness/tests/unit/test_title.py | 17 + .../tests/unit/test_title_chrome.py | 37 + .../tests/unit/test_transport.py | 110 + .../marionette_harness/tests/unit/test_typing.py | 374 ++++ .../tests/unit/test_unhandled_prompt_behavior.py | 126 ++ .../tests/unit/test_visibility.py | 175 ++ .../marionette_harness/tests/unit/test_wait.py | 347 ++++ .../tests/unit/test_window_close_chrome.py | 73 + .../tests/unit/test_window_close_content.py | 129 ++ .../tests/unit/test_window_handles_chrome.py | 253 +++ .../tests/unit/test_window_handles_content.py | 156 ++ .../tests/unit/test_window_management.py | 141 ++ .../tests/unit/test_window_maximize.py | 36 + .../tests/unit/test_window_rect.py | 315 +++ .../tests/unit/test_window_status_chrome.py | 23 + .../tests/unit/test_window_status_content.py | 94 + .../tests/unit/test_window_type_chrome.py | 26 + .../tests/unit/test_windowless.py | 56 + .../marionette_harness/tests/unit/unit-tests.ini | 103 + .../tests/unit/webextension-invalid.xpi | Bin 0 -> 295 bytes .../tests/unit/webextension-signed.xpi | Bin 0 -> 4221 bytes .../tests/unit/webextension-unsigned.xpi | Bin 0 -> 310 bytes .../www/addons/webextension-signed.xpi | Bin 0 -> 4221 bytes .../www/addons/webextension-unsigned.xpi | Bin 0 -> 310 bytes .../harness/marionette_harness/www/black.png | Bin 0 -> 150 bytes .../harness/marionette_harness/www/bug814037.html | 56 + .../www/click_out_of_bounds_overflow.html | 90 + .../harness/marionette_harness/www/clicks.html | 57 + .../marionette_harness/www/dom/cacheUsage.html | 28 + .../www/dom/indexedDB/basicIDB_PBM.html | 40 + .../www/element_outside_viewport.html | 41 + .../harness/marionette_harness/www/empty.html | 12 + .../harness/marionette_harness/www/formPage.html | 114 ++ .../harness/marionette_harness/www/frameset.html | 13 + .../marionette_harness/www/framesetPage2.html | 7 + .../harness/marionette_harness/www/html5/blue.jpg | Bin 0 -> 92 bytes .../www/html5/boolean_attributes.html | 2 + .../marionette_harness/www/html5/geolocation.js | 29 + .../harness/marionette_harness/www/html5/green.jpg | Bin 0 -> 92 bytes .../marionette_harness/www/html5/offline.html | 1 + .../harness/marionette_harness/www/html5/red.jpg | Bin 0 -> 92 bytes .../marionette_harness/www/html5/status.html | 1 + .../marionette_harness/www/html5/test.appcache | 11 + .../www/html5/test_html_inputs.html | 2 + .../marionette_harness/www/html5/yellow.jpg | Bin 0 -> 92 bytes .../harness/marionette_harness/www/html5Page.html | 46 + .../harness/marionette_harness/www/keyboard.html | 99 + .../www/layout/test_carets_columns.html | 31 + .../www/layout/test_carets_cursor.html | 31 + .../www/layout/test_carets_display_none.html | 10 + .../www/layout/test_carets_iframe.html | 15 + .../www/layout/test_carets_iframe_scroll.html | 11 + .../layout/test_carets_iframe_scroll_inner.html | 24 + .../www/layout/test_carets_longtext.html | 9 + .../www/layout/test_carets_multipleline.html | 18 + .../www/layout/test_carets_multiplerange.html | 19 + .../www/layout/test_carets_selection.html | 43 + .../www/layout/test_carets_svg_shapes.html | 12 + .../www/navigation_pushstate.html | 20 + .../www/navigation_pushstate_target.html | 13 + .../marionette_harness/www/nestedElements.html | 9 + .../www/reftest/mostly-teal-700x700.html | 21 + .../www/reftest/teal-700x700.html | 21 + .../harness/marionette_harness/www/resultPage.html | 16 + .../www/serviceworker/install_serviceworker.html | 11 + .../www/serviceworker/serviceworker.js | 0 .../harness/marionette_harness/www/shim.js | 297 +++ .../marionette_harness/www/slow_resource.html | 13 + .../harness/marionette_harness/www/test.html | 43 + .../harness/marionette_harness/www/testAction.html | 96 + .../marionette_harness/www/test_accessibility.html | 57 + .../marionette_harness/www/test_clearing.html | 24 + .../marionette_harness/www/test_dynamic.html | 38 + .../marionette_harness/www/test_iframe.html | 16 + .../marionette_harness/www/test_inner_iframe.html | 13 + .../marionette_harness/www/test_nested_iframe.html | 13 + .../harness/marionette_harness/www/test_oop_1.html | 14 + .../harness/marionette_harness/www/test_oop_2.html | 14 + .../marionette_harness/www/test_windows.html | 13 + .../marionette_harness/www/update/complete.mar | Bin 0 -> 86612 bytes .../www/update/complete.mar.headers | 1 + .../harness/marionette_harness/www/visibility.html | 51 + .../harness/marionette_harness/www/white.png | Bin 0 -> 150 bytes .../marionette_harness/www/windowHandles.html | 16 + .../harness/marionette_harness/www/xhtmlTest.html | 79 + testing/marionette/harness/requirements.txt | 15 + testing/marionette/harness/setup.py | 58 + testing/marionette/mach_commands.py | 113 ++ testing/marionette/mach_test_package_commands.py | 66 + testing/marionette/moz.build | 13 + 216 files changed, 24102 insertions(+) create mode 100644 testing/marionette/client/MANIFEST.in create mode 100644 testing/marionette/client/docs/Makefile create mode 100644 testing/marionette/client/docs/advanced/actions.rst create mode 100644 testing/marionette/client/docs/advanced/debug.rst create mode 100644 testing/marionette/client/docs/advanced/findelement.rst create mode 100644 testing/marionette/client/docs/advanced/landing.rst create mode 100644 testing/marionette/client/docs/advanced/stale.rst create mode 100644 testing/marionette/client/docs/basics.rst create mode 100644 testing/marionette/client/docs/conf.py create mode 100644 testing/marionette/client/docs/index.rst create mode 100644 testing/marionette/client/docs/interactive.rst create mode 100644 testing/marionette/client/docs/make.bat create mode 100644 testing/marionette/client/docs/reference.rst create mode 100644 testing/marionette/client/marionette_driver/__init__.py create mode 100644 testing/marionette/client/marionette_driver/addons.py create mode 100644 testing/marionette/client/marionette_driver/by.py create mode 100644 testing/marionette/client/marionette_driver/date_time_value.py create mode 100644 testing/marionette/client/marionette_driver/decorators.py create mode 100644 testing/marionette/client/marionette_driver/errors.py create mode 100644 testing/marionette/client/marionette_driver/expected.py create mode 100644 testing/marionette/client/marionette_driver/geckoinstance.py create mode 100644 testing/marionette/client/marionette_driver/keys.py create mode 100644 testing/marionette/client/marionette_driver/localization.py create mode 100644 testing/marionette/client/marionette_driver/marionette.py create mode 100644 testing/marionette/client/marionette_driver/timeout.py create mode 100644 testing/marionette/client/marionette_driver/transport.py create mode 100644 testing/marionette/client/marionette_driver/wait.py create mode 100644 testing/marionette/client/requirements.txt create mode 100644 testing/marionette/client/setup.py create mode 100644 testing/marionette/harness/MANIFEST.in create mode 100644 testing/marionette/harness/README.rst create mode 100644 testing/marionette/harness/marionette_harness/__init__.py create mode 100644 testing/marionette/harness/marionette_harness/certificates/test.cert create mode 100644 testing/marionette/harness/marionette_harness/certificates/test.key create mode 100644 testing/marionette/harness/marionette_harness/marionette_test/__init__.py create mode 100644 testing/marionette/harness/marionette_harness/marionette_test/decorators.py create mode 100644 testing/marionette/harness/marionette_harness/marionette_test/testcases.py create mode 100644 testing/marionette/harness/marionette_harness/runner/__init__.py create mode 100644 testing/marionette/harness/marionette_harness/runner/base.py create mode 100755 testing/marionette/harness/marionette_harness/runner/httpd.py create mode 100644 testing/marionette/harness/marionette_harness/runner/mixins/__init__.py create mode 100644 testing/marionette/harness/marionette_harness/runner/mixins/window_manager.py create mode 100755 testing/marionette/harness/marionette_harness/runner/serve.py create mode 100644 testing/marionette/harness/marionette_harness/runtests.py create mode 100644 testing/marionette/harness/marionette_harness/tests/harness_unit/conftest.py create mode 100644 testing/marionette/harness/marionette_harness/tests/harness_unit/python.ini create mode 100644 testing/marionette/harness/marionette_harness/tests/harness_unit/test_httpd.py create mode 100644 testing/marionette/harness/marionette_harness/tests/harness_unit/test_marionette_arguments.py create mode 100644 testing/marionette/harness/marionette_harness/tests/harness_unit/test_marionette_harness.py create mode 100644 testing/marionette/harness/marionette_harness/tests/harness_unit/test_marionette_runner.py create mode 100644 testing/marionette/harness/marionette_harness/tests/harness_unit/test_marionette_test_result.py create mode 100644 testing/marionette/harness/marionette_harness/tests/harness_unit/test_serve.py create mode 100644 testing/marionette/harness/marionette_harness/tests/unit-tests.ini create mode 100644 testing/marionette/harness/marionette_harness/tests/unit/data/test.html create mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_accessibility.py create mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_addons.py create mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_capabilities.py create mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_checkbox.py create mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_checkbox_chrome.py create mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_chrome.py create mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_chrome_action.py create mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_chrome_element_css.py create mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_cli_arguments.py create mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_click.py create mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_click_chrome.py create mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_click_scrolling.py create mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_context.py create mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_cookies.py create mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_crash.py create mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_data_driven.py create mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_date_time_value.py create mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_element_id.py create mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_element_id_chrome.py create mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_element_rect.py create mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_element_rect_chrome.py create mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_element_state.py create mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_element_state_chrome.py create mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_errors.py create mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_execute_async_script.py create mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_execute_isolate.py create mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_execute_sandboxes.py create mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_execute_script.py create mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_expected.py create mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_expectedfail.py create mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_file_upload.py create mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_findelement.py create mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_findelement_chrome.py create mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_geckoinstance.py create mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_get_computed_label.py create mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_get_computed_role.py create mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_get_current_url_chrome.py create mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_get_shadow_root.py create mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_implicit_waits.py create mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_key_actions.py create mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_localization.py create mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_marionette.py create mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_modal_dialogs.py create mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_mouse_action.py create mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_navigation.py create mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_pagesource.py create mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_pagesource_chrome.py create mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_position.py create mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_prefs.py create mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_prefs_enforce.py create mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_profile_management.py create mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_proxy.py create mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_quit_restart.py create mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_reftest.py create mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_rendered_element.py create mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_report.py create mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_run_js_test.py create mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_screen_orientation.py create mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_screenshot.py create mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_select.py create mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_sendkeys_menupopup_chrome.py create mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_session.py create mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_shadowroot_findelement.py create mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_skip_setup.py create mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_switch_frame.py create mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_switch_frame_chrome.py create mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_switch_window_chrome.py create mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_switch_window_content.py create mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_teardown_context_preserved.py create mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_text.py create mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_text_chrome.py create mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_timeouts.py create mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_title.py create mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_title_chrome.py create mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_transport.py create mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_typing.py create mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_unhandled_prompt_behavior.py create mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_visibility.py create mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_wait.py create mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_window_close_chrome.py create mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_window_close_content.py create mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_window_handles_chrome.py create mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_window_handles_content.py create mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_window_management.py create mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_window_maximize.py create mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_window_rect.py create mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_window_status_chrome.py create mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_window_status_content.py create mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_window_type_chrome.py create mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_windowless.py create mode 100644 testing/marionette/harness/marionette_harness/tests/unit/unit-tests.ini create mode 100644 testing/marionette/harness/marionette_harness/tests/unit/webextension-invalid.xpi create mode 100644 testing/marionette/harness/marionette_harness/tests/unit/webextension-signed.xpi create mode 100644 testing/marionette/harness/marionette_harness/tests/unit/webextension-unsigned.xpi create mode 100644 testing/marionette/harness/marionette_harness/www/addons/webextension-signed.xpi create mode 100644 testing/marionette/harness/marionette_harness/www/addons/webextension-unsigned.xpi create mode 100644 testing/marionette/harness/marionette_harness/www/black.png create mode 100644 testing/marionette/harness/marionette_harness/www/bug814037.html create mode 100644 testing/marionette/harness/marionette_harness/www/click_out_of_bounds_overflow.html create mode 100644 testing/marionette/harness/marionette_harness/www/clicks.html create mode 100644 testing/marionette/harness/marionette_harness/www/dom/cacheUsage.html create mode 100644 testing/marionette/harness/marionette_harness/www/dom/indexedDB/basicIDB_PBM.html create mode 100644 testing/marionette/harness/marionette_harness/www/element_outside_viewport.html create mode 100644 testing/marionette/harness/marionette_harness/www/empty.html create mode 100644 testing/marionette/harness/marionette_harness/www/formPage.html create mode 100644 testing/marionette/harness/marionette_harness/www/frameset.html create mode 100644 testing/marionette/harness/marionette_harness/www/framesetPage2.html create mode 100644 testing/marionette/harness/marionette_harness/www/html5/blue.jpg create mode 100644 testing/marionette/harness/marionette_harness/www/html5/boolean_attributes.html create mode 100644 testing/marionette/harness/marionette_harness/www/html5/geolocation.js create mode 100644 testing/marionette/harness/marionette_harness/www/html5/green.jpg create mode 100644 testing/marionette/harness/marionette_harness/www/html5/offline.html create mode 100644 testing/marionette/harness/marionette_harness/www/html5/red.jpg create mode 100644 testing/marionette/harness/marionette_harness/www/html5/status.html create mode 100644 testing/marionette/harness/marionette_harness/www/html5/test.appcache create mode 100644 testing/marionette/harness/marionette_harness/www/html5/test_html_inputs.html create mode 100644 testing/marionette/harness/marionette_harness/www/html5/yellow.jpg create mode 100644 testing/marionette/harness/marionette_harness/www/html5Page.html create mode 100644 testing/marionette/harness/marionette_harness/www/keyboard.html create mode 100644 testing/marionette/harness/marionette_harness/www/layout/test_carets_columns.html create mode 100644 testing/marionette/harness/marionette_harness/www/layout/test_carets_cursor.html create mode 100644 testing/marionette/harness/marionette_harness/www/layout/test_carets_display_none.html create mode 100644 testing/marionette/harness/marionette_harness/www/layout/test_carets_iframe.html create mode 100644 testing/marionette/harness/marionette_harness/www/layout/test_carets_iframe_scroll.html create mode 100644 testing/marionette/harness/marionette_harness/www/layout/test_carets_iframe_scroll_inner.html create mode 100644 testing/marionette/harness/marionette_harness/www/layout/test_carets_longtext.html create mode 100644 testing/marionette/harness/marionette_harness/www/layout/test_carets_multipleline.html create mode 100644 testing/marionette/harness/marionette_harness/www/layout/test_carets_multiplerange.html create mode 100644 testing/marionette/harness/marionette_harness/www/layout/test_carets_selection.html create mode 100644 testing/marionette/harness/marionette_harness/www/layout/test_carets_svg_shapes.html create mode 100644 testing/marionette/harness/marionette_harness/www/navigation_pushstate.html create mode 100644 testing/marionette/harness/marionette_harness/www/navigation_pushstate_target.html create mode 100644 testing/marionette/harness/marionette_harness/www/nestedElements.html create mode 100644 testing/marionette/harness/marionette_harness/www/reftest/mostly-teal-700x700.html create mode 100644 testing/marionette/harness/marionette_harness/www/reftest/teal-700x700.html create mode 100644 testing/marionette/harness/marionette_harness/www/resultPage.html create mode 100644 testing/marionette/harness/marionette_harness/www/serviceworker/install_serviceworker.html create mode 100644 testing/marionette/harness/marionette_harness/www/serviceworker/serviceworker.js create mode 100644 testing/marionette/harness/marionette_harness/www/shim.js create mode 100644 testing/marionette/harness/marionette_harness/www/slow_resource.html create mode 100644 testing/marionette/harness/marionette_harness/www/test.html create mode 100644 testing/marionette/harness/marionette_harness/www/testAction.html create mode 100644 testing/marionette/harness/marionette_harness/www/test_accessibility.html create mode 100644 testing/marionette/harness/marionette_harness/www/test_clearing.html create mode 100644 testing/marionette/harness/marionette_harness/www/test_dynamic.html create mode 100644 testing/marionette/harness/marionette_harness/www/test_iframe.html create mode 100644 testing/marionette/harness/marionette_harness/www/test_inner_iframe.html create mode 100644 testing/marionette/harness/marionette_harness/www/test_nested_iframe.html create mode 100644 testing/marionette/harness/marionette_harness/www/test_oop_1.html create mode 100644 testing/marionette/harness/marionette_harness/www/test_oop_2.html create mode 100644 testing/marionette/harness/marionette_harness/www/test_windows.html create mode 100644 testing/marionette/harness/marionette_harness/www/update/complete.mar create mode 100644 testing/marionette/harness/marionette_harness/www/update/complete.mar.headers create mode 100644 testing/marionette/harness/marionette_harness/www/visibility.html create mode 100644 testing/marionette/harness/marionette_harness/www/white.png create mode 100644 testing/marionette/harness/marionette_harness/www/windowHandles.html create mode 100644 testing/marionette/harness/marionette_harness/www/xhtmlTest.html create mode 100644 testing/marionette/harness/requirements.txt create mode 100644 testing/marionette/harness/setup.py create mode 100644 testing/marionette/mach_commands.py create mode 100644 testing/marionette/mach_test_package_commands.py create mode 100644 testing/marionette/moz.build (limited to 'testing/marionette') diff --git a/testing/marionette/client/MANIFEST.in b/testing/marionette/client/MANIFEST.in new file mode 100644 index 0000000000..cf628b039c --- /dev/null +++ b/testing/marionette/client/MANIFEST.in @@ -0,0 +1,2 @@ +exclude MANIFEST.in +include requirements.txt diff --git a/testing/marionette/client/docs/Makefile b/testing/marionette/client/docs/Makefile new file mode 100644 index 0000000000..f3d89d6d47 --- /dev/null +++ b/testing/marionette/client/docs/Makefile @@ -0,0 +1,153 @@ +# Makefile for Sphinx documentation +# + +# You can set these variables from the command line. +SPHINXOPTS = +SPHINXBUILD = sphinx-build +PAPER = +BUILDDIR = _build + +# Internal variables. +PAPEROPT_a4 = -D latex_paper_size=a4 +PAPEROPT_letter = -D latex_paper_size=letter +ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . +# the i18n builder cannot share the environment and doctrees with the others +I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . + +.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext + +help: + @echo "Please use \`make ' where is one of" + @echo " html to make standalone HTML files" + @echo " dirhtml to make HTML files named index.html in directories" + @echo " singlehtml to make a single large HTML file" + @echo " pickle to make pickle files" + @echo " json to make JSON files" + @echo " htmlhelp to make HTML files and a HTML help project" + @echo " qthelp to make HTML files and a qthelp project" + @echo " devhelp to make HTML files and a Devhelp project" + @echo " epub to make an epub" + @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" + @echo " latexpdf to make LaTeX files and run them through pdflatex" + @echo " text to make text files" + @echo " man to make manual pages" + @echo " texinfo to make Texinfo files" + @echo " info to make Texinfo files and run them through makeinfo" + @echo " gettext to make PO message catalogs" + @echo " changes to make an overview of all changed/added/deprecated items" + @echo " linkcheck to check all external links for integrity" + @echo " doctest to run all doctests embedded in the documentation (if enabled)" + +clean: + -rm -rf $(BUILDDIR)/* + +html: + $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html + @echo + @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." + +dirhtml: + $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml + @echo + @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." + +singlehtml: + $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml + @echo + @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." + +pickle: + $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle + @echo + @echo "Build finished; now you can process the pickle files." + +json: + $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json + @echo + @echo "Build finished; now you can process the JSON files." + +htmlhelp: + $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp + @echo + @echo "Build finished; now you can run HTML Help Workshop with the" \ + ".hhp project file in $(BUILDDIR)/htmlhelp." + +qthelp: + $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp + @echo + @echo "Build finished; now you can run "qcollectiongenerator" with the" \ + ".qhcp project file in $(BUILDDIR)/qthelp, like this:" + @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/MarionettePythonClient.qhcp" + @echo "To view the help file:" + @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/MarionettePythonClient.qhc" + +devhelp: + $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp + @echo + @echo "Build finished." + @echo "To view the help file:" + @echo "# mkdir -p $$HOME/.local/share/devhelp/MarionettePythonClient" + @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/MarionettePythonClient" + @echo "# devhelp" + +epub: + $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub + @echo + @echo "Build finished. The epub file is in $(BUILDDIR)/epub." + +latex: + $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex + @echo + @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." + @echo "Run \`make' in that directory to run these through (pdf)latex" \ + "(use \`make latexpdf' here to do that automatically)." + +latexpdf: + $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex + @echo "Running LaTeX files through pdflatex..." + $(MAKE) -C $(BUILDDIR)/latex all-pdf + @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." + +text: + $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text + @echo + @echo "Build finished. The text files are in $(BUILDDIR)/text." + +man: + $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man + @echo + @echo "Build finished. The manual pages are in $(BUILDDIR)/man." + +texinfo: + $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo + @echo + @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo." + @echo "Run \`make' in that directory to run these through makeinfo" \ + "(use \`make info' here to do that automatically)." + +info: + $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo + @echo "Running Texinfo files through makeinfo..." + make -C $(BUILDDIR)/texinfo info + @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo." + +gettext: + $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale + @echo + @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale." + +changes: + $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes + @echo + @echo "The overview file is in $(BUILDDIR)/changes." + +linkcheck: + $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck + @echo + @echo "Link check complete; look for any errors in the above output " \ + "or in $(BUILDDIR)/linkcheck/output.txt." + +doctest: + $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest + @echo "Testing of doctests in the sources finished, look at the " \ + "results in $(BUILDDIR)/doctest/output.txt." diff --git a/testing/marionette/client/docs/advanced/actions.rst b/testing/marionette/client/docs/advanced/actions.rst new file mode 100644 index 0000000000..c767bdecdc --- /dev/null +++ b/testing/marionette/client/docs/advanced/actions.rst @@ -0,0 +1,21 @@ +Actions +======= + +.. py:currentmodule:: marionette_driver.marionette + +Action Sequences +---------------- + +:class:`Actions` are designed as a way to simulate user input like a keyboard +or a pointer device as closely as possible. For multiple interactions an +action sequence can be used:: + + element = marionette.find_element("id", "input") + element.click() + + key_chain = self.marionette.actions.sequence("key", "keyboard1") + key_chain.send_keys("fooba").pause(100).key_down("r").perform() + +This will simulate entering "fooba" into the input field, waiting for 100ms, +and pressing the key "r". The pause is optional in this case, but can be useful +for simulating delays typical to a users behaviour. diff --git a/testing/marionette/client/docs/advanced/debug.rst b/testing/marionette/client/docs/advanced/debug.rst new file mode 100644 index 0000000000..895009ef7f --- /dev/null +++ b/testing/marionette/client/docs/advanced/debug.rst @@ -0,0 +1,35 @@ +Debugging +========= + +.. py:currentmodule:: marionette_driver.marionette + +Sometimes when working with Marionette you'll run into unexpected behaviour and +need to do some debugging. This page outlines some of the Marionette methods +that can be useful to you. + +Please note that the best tools for debugging are the `ones that ship with +Gecko`_. This page doesn't describe how to use those with Marionette. Also see +a related topic about `using the debugger with Marionette`_ on MDN. + +.. _ones that ship with Gecko: https://developer.mozilla.org/en-US/docs/Tools +.. _using the debugger with Marionette: https://developer.mozilla.org/en-US/docs/Marionette/Debugging + +Seeing What's on the Page +~~~~~~~~~~~~~~~~~~~~~~~~~ + +Sometimes it's difficult to tell what is actually on the page that is being +manipulated. Either because it happens too fast, the window isn't big enough or +you are manipulating a remote server! There are two methods that can help you +out. The first is :func:`~Marionette.screenshot`:: + + marionette.screenshot() # takes screenshot of entire frame + elem = marionette.find_element(By.ID, 'some-div') + marionette.screenshot(elem) # takes a screenshot of only the given element + +Sometimes you just want to see the DOM layout. You can do this with the +:attr:`~Marionette.page_source` property. Note that the page source depends on +the context you are in:: + + print(marionette.page_source) + marionette.set_context('chrome') + print(marionette.page_source) diff --git a/testing/marionette/client/docs/advanced/findelement.rst b/testing/marionette/client/docs/advanced/findelement.rst new file mode 100644 index 0000000000..6f61fa5e25 --- /dev/null +++ b/testing/marionette/client/docs/advanced/findelement.rst @@ -0,0 +1,87 @@ +Finding Elements +================ +.. py:currentmodule:: marionette_driver.marionette + +One of the most common and yet often most difficult tasks in Marionette is +finding a DOM element on a webpage or in the chrome UI. Marionette provides +several different search strategies to use when finding elements. All search +strategies work with both :func:`~Marionette.find_element` and +:func:`~Marionette.find_elements`, though some strategies are not implemented +in chrome scope. + +In the event that more than one element is matched by the query, +:func:`~Marionette.find_element` will only return the first element found. In +the event that no elements are matched by the query, +:func:`~Marionette.find_element` will raise `NoSuchElementException` while +:func:`~Marionette.find_elements` will return an empty list. + +Search Strategies +----------------- + +Search strategies are defined in the :class:`By` class:: + + from marionette_driver import By + print(By.ID) + +The strategies are: + +* `id` - The easiest way to find an element is to refer to its id directly:: + + container = client.find_element(By.ID, 'container') + +* `class name` - To find elements belonging to a certain class, use `class name`:: + + buttons = client.find_elements(By.CLASS_NAME, 'button') + +* `css selector` - It's also possible to find elements using a `css selector`_:: + + container_buttons = client.find_elements(By.CSS_SELECTOR, '#container .buttons') + +* `name` - Find elements by their name attribute (not implemented in chrome + scope):: + + form = client.find_element(By.NAME, 'signup') + +* `tag name` - To find all the elements with a given tag, use `tag name`:: + + paragraphs = client.find_elements(By.TAG_NAME, 'p') + +* `link text` - A convenience strategy for finding link elements by their + innerHTML (not implemented in chrome scope):: + + link = client.find_element(By.LINK_TEXT, 'Click me!') + +* `partial link text` - Same as `link text` except substrings of the innerHTML + are matched (not implemented in chrome scope):: + + link = client.find_element(By.PARTIAL_LINK_TEXT, 'Clic') + +* `xpath` - Find elements using an xpath_ query:: + + elem = client.find_element(By.XPATH, './/*[@id="foobar"') + +.. _css selector: https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Getting_Started/Selectors +.. _xpath: https://developer.mozilla.org/en-US/docs/Web/XPath + + + +Chaining Searches +----------------- + +In addition to the methods on the Marionette object, HTMLElement objects also +provide :func:`~HTMLElement.find_element` and :func:`~HTMLElement.find_elements` +methods. The difference is that only child nodes of the element will be searched. +Consider the following html snippet:: + +
+ +
+ + +Doing the following will work:: + + client.find_element(By.ID, 'container').find_element(By.ID, 'main') + +But this will raise a `NoSuchElementException`:: + + client.find_element(By.ID, 'container').find_element(By.ID, 'footer') diff --git a/testing/marionette/client/docs/advanced/landing.rst b/testing/marionette/client/docs/advanced/landing.rst new file mode 100644 index 0000000000..0a44de63d7 --- /dev/null +++ b/testing/marionette/client/docs/advanced/landing.rst @@ -0,0 +1,13 @@ +Advanced Topics +=============== + +Here are a collection of articles explaining some of the more complicated +aspects of Marionette. + +.. toctree:: + :maxdepth: 1 + + findelement + stale + actions + debug diff --git a/testing/marionette/client/docs/advanced/stale.rst b/testing/marionette/client/docs/advanced/stale.rst new file mode 100644 index 0000000000..885083993c --- /dev/null +++ b/testing/marionette/client/docs/advanced/stale.rst @@ -0,0 +1,76 @@ +Dealing with Stale Elements +=========================== +.. py:currentmodule:: marionette_driver.marionette + +Marionette does not keep a live representation of the DOM saved. All it can do +is send commands to the Marionette server which queries the DOM on the client's +behalf. References to elements are also not passed from server to client. A +unique id is generated for each element that gets referenced and a mapping of +id to element object is stored on the server. When commands such as +:func:`~HTMLElement.click` are run, the client sends the element's id along +with the command. The server looks up the proper DOM element in its reference +table and executes the command on it. + +In practice this means that the DOM can change state and Marionette will never +know until it sends another query. For example, look at the following HTML:: + + + + + + +
+
+ + + +Care needs to be taken as the DOM is being modified after the page has loaded. +The following code has a race condition:: + + button = client.find_element('id', 'button') + button.click() + assert len(client.find_elements('css selector', '#container div')) > 0 + + +Explicit Waiting and Expected Conditions +---------------------------------------- +.. py:currentmodule:: marionette_driver + +To avoid the above scenario, manual synchronisation is needed. Waits are used +to pause program execution until a given condition is true. This is a useful +technique to employ when documents load new content or change after +``Document.readyState``'s value changes to "complete". + +The :class:`Wait` helper class provided by Marionette avoids some of the +caveats of ``time.sleep(n)``. It will return immediately once the provided +condition evaluates to true. + +To avoid the race condition in the above example, one could do:: + + from marionette_driver import Wait + + button = client.find_element('id', 'button') + button.click() + + def find_divs(): + return client.find_elements('css selector', '#container div') + + divs = Wait(client).until(find_divs) + assert len(divs) > 0 + +This avoids the race condition. Because finding elements is a common condition +to wait for, it is built in to Marionette. Instead of the above, you could +write:: + + from marionette_driver import Wait + + button = client.find_element('id', 'button') + button.click() + assert len(Wait(client).until(expected.elements_present('css selector', '#container div'))) > 0 + +For a full list of built-in conditions, see :mod:`~marionette_driver.expected`. diff --git a/testing/marionette/client/docs/basics.rst b/testing/marionette/client/docs/basics.rst new file mode 100644 index 0000000000..57f10cd69a --- /dev/null +++ b/testing/marionette/client/docs/basics.rst @@ -0,0 +1,185 @@ +.. py:currentmodule:: marionette_driver.marionette + +Marionette Python Client +======================== + +The Marionette Python client library allows you to remotely control a +Gecko-based browser or device which is running a Marionette_ +server. This includes Firefox Desktop and Firefox for Android. + +The Marionette server is built directly into Gecko and can be started by +passing in a command line option to Gecko, or by using a Marionette-enabled +build. The server listens for connections from various clients. Clients can +then control Gecko by sending commands to the server. + +This is the official Python client for Marionette. There also exists a +`NodeJS client`_ maintained by the Firefox OS automation team. + +.. _Marionette: https://developer.mozilla.org/en-US/docs/Marionette +.. _NodeJS client: https://github.com/mozilla-b2g/gaia/tree/master/tests/jsmarionette + +Getting the Client +------------------ + +The Python client is officially supported. To install it, first make sure you +have `pip installed`_ then run: + +.. parsed-literal:: + pip install marionette_driver + +It's highly recommended to use virtualenv_ when installing Marionette to avoid +package conflicts and other general nastiness. + +You should now be ready to start using Marionette. The best way to learn is to +play around with it. Start a `Marionette-enabled instance of Firefox`_, fire up +a python shell and follow along with the +:doc:`interactive tutorial `! + +.. _pip installed: https://pip.pypa.io/en/latest/installing.html +.. _virtualenv: http://virtualenv.readthedocs.org/en/latest/ +.. _Marionette-enabled instance of Firefox: https://developer.mozilla.org/en-US/docs/Mozilla/QA/Marionette/Builds + +Using the Client for Testing +---------------------------- + +Please visit the `Marionette Tests`_ section on MDN for information regarding +testing with Marionette. + +.. _Marionette Tests: https://developer.mozilla.org/en/Marionette/Tests + +Session Management +------------------ +A session is a single instance of a Marionette client connected to a Marionette +server. Before you can start executing commands, you need to start a session +with :func:`start_session() `: + +.. parsed-literal:: + from marionette_driver.marionette import Marionette + + client = Marionette('127.0.0.1', port=2828) + client.start_session() + +This returns a session id and an object listing the capabilities of the +Marionette server. For example, a server running on Firefox Desktop will +have some features which a server running from Firefox Android won't. +It's also possible to access the capabilities using the +:attr:`~Marionette.session_capabilities` attribute. After finishing with a +session, you can delete it with :func:`~Marionette.delete_session()`. Note that +this will also happen automatically when the Marionette object is garbage +collected. + +Context Management +------------------ +Commands can only be executed in a single window, frame and scope at a time. In +order to run commands elsewhere, it's necessary to explicitly switch to the +appropriate context. + +Use :func:`~Marionette.switch_to_window` to execute commands in the context of a +new window: + +.. parsed-literal:: + original_window = client.current_window_handle + for handle in client.window_handles: + if handle != original_window: + client.switch_to_window(handle) + print("Switched to window with '{}' loaded.".format(client.get_url())) + client.switch_to_window(original_window) + +Similarly, use :func:`~Marionette.switch_to_frame` to execute commands in the +context of a new frame (e.g an + + + diff --git a/testing/marionette/harness/marionette_harness/www/layout/test_carets_iframe_scroll.html b/testing/marionette/harness/marionette_harness/www/layout/test_carets_iframe_scroll.html new file mode 100644 index 0000000000..5f4b00e5bd --- /dev/null +++ b/testing/marionette/harness/marionette_harness/www/layout/test_carets_iframe_scroll.html @@ -0,0 +1,11 @@ + + + Bug 1657256: Test select word, scroll up, and drag AccessibleCaret. + + + + diff --git a/testing/marionette/harness/marionette_harness/www/layout/test_carets_iframe_scroll_inner.html b/testing/marionette/harness/marionette_harness/www/layout/test_carets_iframe_scroll_inner.html new file mode 100644 index 0000000000..1087227007 --- /dev/null +++ b/testing/marionette/harness/marionette_harness/www/layout/test_carets_iframe_scroll_inner.html @@ -0,0 +1,24 @@ + + + + + + AAAAAA + BBBBBB + CCCCCC + DDDDDD + EEEEEE + FFFFFF + GGGGGG + HHHHHH + IIIIII + JJJJJJ + KKKKKK + LLLLLL + MMMMMM + + diff --git a/testing/marionette/harness/marionette_harness/www/layout/test_carets_longtext.html b/testing/marionette/harness/marionette_harness/www/layout/test_carets_longtext.html new file mode 100644 index 0000000000..7e2495509b --- /dev/null +++ b/testing/marionette/harness/marionette_harness/www/layout/test_carets_longtext.html @@ -0,0 +1,9 @@ + + + Bug 1094072: Orientation change test for AccessibleCaret positions + + +

long long text for orientation change test long long text for orientation change test long long text for orientation change test long long text for orientation change test

+
bottom text
+ + diff --git a/testing/marionette/harness/marionette_harness/www/layout/test_carets_multipleline.html b/testing/marionette/harness/marionette_harness/www/layout/test_carets_multipleline.html new file mode 100644 index 0000000000..fbbefbebcb --- /dev/null +++ b/testing/marionette/harness/marionette_harness/www/layout/test_carets_multipleline.html @@ -0,0 +1,18 @@ + + + + + + + Bug 1019441: Marionette tests for AccessibleCaret (multiple lines) + + +
+
+
First Line

Second Line

Third Line
+
+
First Line

Second Line

Third Line
+ + diff --git a/testing/marionette/harness/marionette_harness/www/layout/test_carets_multiplerange.html b/testing/marionette/harness/marionette_harness/www/layout/test_carets_multiplerange.html new file mode 100644 index 0000000000..9b9bbe9e9f --- /dev/null +++ b/testing/marionette/harness/marionette_harness/www/layout/test_carets_multiplerange.html @@ -0,0 +1,19 @@ + + + +

user can select this 1

+

user can select this 2

+

user can select this 3

+

user cannot select this 1

+

user cannot select this 2

+

user can select this 4

+

user can select this 5

+

user cannot select this 3

+

user can select this 6

+

user can select this 7

+ + diff --git a/testing/marionette/harness/marionette_harness/www/layout/test_carets_selection.html b/testing/marionette/harness/marionette_harness/www/layout/test_carets_selection.html new file mode 100644 index 0000000000..f992ee1ba3 --- /dev/null +++ b/testing/marionette/harness/marionette_harness/www/layout/test_carets_selection.html @@ -0,0 +1,43 @@ + + + + + + + Marionette tests for AccessibleCaret in selection mode + + + +
+ + + + + +
+
+
+ + + +
+
+
+
+
ABC DEF GHI
+
+
ABC DEF GHI
+
+
Non-selectable
+ + diff --git a/testing/marionette/harness/marionette_harness/www/layout/test_carets_svg_shapes.html b/testing/marionette/harness/marionette_harness/www/layout/test_carets_svg_shapes.html new file mode 100644 index 0000000000..ea3ad4ecf6 --- /dev/null +++ b/testing/marionette/harness/marionette_harness/www/layout/test_carets_svg_shapes.html @@ -0,0 +1,12 @@ + + + + + + + + +

ABC DEF GHI

+ + diff --git a/testing/marionette/harness/marionette_harness/www/navigation_pushstate.html b/testing/marionette/harness/marionette_harness/www/navigation_pushstate.html new file mode 100644 index 0000000000..fbde792d8c --- /dev/null +++ b/testing/marionette/harness/marionette_harness/www/navigation_pushstate.html @@ -0,0 +1,20 @@ + + + + + + Navigation by manipulating the browser history + + + + +

Navigate forward

+ + diff --git a/testing/marionette/harness/marionette_harness/www/navigation_pushstate_target.html b/testing/marionette/harness/marionette_harness/www/navigation_pushstate_target.html new file mode 100644 index 0000000000..153d0a657f --- /dev/null +++ b/testing/marionette/harness/marionette_harness/www/navigation_pushstate_target.html @@ -0,0 +1,13 @@ + + + + + + + + +

Pushstate target

+ + diff --git a/testing/marionette/harness/marionette_harness/www/nestedElements.html b/testing/marionette/harness/marionette_harness/www/nestedElements.html new file mode 100644 index 0000000000..618bf3231b --- /dev/null +++ b/testing/marionette/harness/marionette_harness/www/nestedElements.html @@ -0,0 +1,9 @@ + +hello world +hello worldhello world + + +hello worldhello worldhello world diff --git a/testing/marionette/harness/marionette_harness/www/reftest/mostly-teal-700x700.html b/testing/marionette/harness/marionette_harness/www/reftest/mostly-teal-700x700.html new file mode 100644 index 0000000000..a5aa12d0d2 --- /dev/null +++ b/testing/marionette/harness/marionette_harness/www/reftest/mostly-teal-700x700.html @@ -0,0 +1,21 @@ + + +
diff --git a/testing/marionette/harness/marionette_harness/www/reftest/teal-700x700.html b/testing/marionette/harness/marionette_harness/www/reftest/teal-700x700.html new file mode 100644 index 0000000000..e441e88e6d --- /dev/null +++ b/testing/marionette/harness/marionette_harness/www/reftest/teal-700x700.html @@ -0,0 +1,21 @@ + + +
diff --git a/testing/marionette/harness/marionette_harness/www/resultPage.html b/testing/marionette/harness/marionette_harness/www/resultPage.html new file mode 100644 index 0000000000..6e2fea9a14 --- /dev/null +++ b/testing/marionette/harness/marionette_harness/www/resultPage.html @@ -0,0 +1,16 @@ + + + + + We Arrive Here + + + + +
+ +
+ + diff --git a/testing/marionette/harness/marionette_harness/www/serviceworker/install_serviceworker.html b/testing/marionette/harness/marionette_harness/www/serviceworker/install_serviceworker.html new file mode 100644 index 0000000000..572a05c2bc --- /dev/null +++ b/testing/marionette/harness/marionette_harness/www/serviceworker/install_serviceworker.html @@ -0,0 +1,11 @@ + + + + Install Service Worker + + + + + diff --git a/testing/marionette/harness/marionette_harness/www/serviceworker/serviceworker.js b/testing/marionette/harness/marionette_harness/www/serviceworker/serviceworker.js new file mode 100644 index 0000000000..e69de29bb2 diff --git a/testing/marionette/harness/marionette_harness/www/shim.js b/testing/marionette/harness/marionette_harness/www/shim.js new file mode 100644 index 0000000000..9a8e09d6b6 --- /dev/null +++ b/testing/marionette/harness/marionette_harness/www/shim.js @@ -0,0 +1,297 @@ +/** + * mouse_event_shim.js: generate mouse events from touch events. + * + * This library listens for touch events and generates mousedown, mousemove + * mouseup, and click events to match them. It captures and dicards any + * real mouse events (non-synthetic events with isTrusted true) that are + * send by gecko so that there are not duplicates. + * + * This library does emit mouseover/mouseout and mouseenter/mouseleave + * events. You can turn them off by setting MouseEventShim.trackMouseMoves to + * false. This means that mousemove events will always have the same target + * as the mousedown even that began the series. You can also call + * MouseEventShim.setCapture() from a mousedown event handler to prevent + * mouse tracking until the next mouseup event. + * + * This library does not support multi-touch but should be sufficient + * to do drags based on mousedown/mousemove/mouseup events. + * + * This library does not emit dblclick events or contextmenu events + */ + +"use strict"; + +(function () { + // Make sure we don't run more than once + if (MouseEventShim) { + return; + } + + // Bail if we're not on running on a platform that sends touch + // events. We don't need the shim code for mouse events. + try { + document.createEvent("TouchEvent"); + } catch (e) { + return; + } + + let starttouch; // The Touch object that we started with + let target; // The element the touch is currently over + let emitclick; // Will we be sending a click event after mouseup? + + // Use capturing listeners to discard all mouse events from gecko + window.addEventListener("mousedown", discardEvent, true); + window.addEventListener("mouseup", discardEvent, true); + window.addEventListener("mousemove", discardEvent, true); + window.addEventListener("click", discardEvent, true); + + function discardEvent(e) { + if (e.isTrusted) { + e.stopImmediatePropagation(); // so it goes no further + if (e.type === "click") { + e.preventDefault(); + } // so it doesn't trigger a change event + } + } + + // Listen for touch events that bubble up to the window. + // If other code has called stopPropagation on the touch events + // then we'll never see them. Also, we'll honor the defaultPrevented + // state of the event and will not generate synthetic mouse events + window.addEventListener("touchstart", handleTouchStart); + window.addEventListener("touchmove", handleTouchMove); + window.addEventListener("touchend", handleTouchEnd); + window.addEventListener("touchcancel", handleTouchEnd); // Same as touchend + + function handleTouchStart(e) { + // If we're already handling a touch, ignore this one + if (starttouch) { + return; + } + + // Ignore any event that has already been prevented + if (e.defaultPrevented) { + return; + } + + // Sometimes an unknown gecko bug causes us to get a touchstart event + // for an iframe target that we can't use because it is cross origin. + // Don't start handling a touch in that case + try { + e.changedTouches[0].target.ownerDocument; + } catch (e) { + // Ignore the event if we can't see the properties of the target + return; + } + + // If there is more than one simultaneous touch, ignore all but the first + starttouch = e.changedTouches[0]; + target = starttouch.target; + emitclick = true; + + // Move to the position of the touch + emitEvent("mousemove", target, starttouch); + + // Now send a synthetic mousedown + let result = emitEvent("mousedown", target, starttouch); + + // If the mousedown was prevented, pass that on to the touch event. + // And remember not to send a click event + if (!result) { + e.preventDefault(); + emitclick = false; + } + } + + function handleTouchEnd(e) { + if (!starttouch) { + return; + } + + // End a MouseEventShim.setCapture() call + if (MouseEventShim.capturing) { + MouseEventShim.capturing = false; + MouseEventShim.captureTarget = null; + } + + for (let i = 0; i < e.changedTouches.length; i++) { + let touch = e.changedTouches[i]; + // If the ended touch does not have the same id, skip it + if (touch.identifier !== starttouch.identifier) { + continue; + } + + emitEvent("mouseup", target, touch); + + // If target is still the same element we started and the touch did not + // move more than the threshold and if the user did not prevent + // the mousedown, then send a click event, too. + if (emitclick) { + emitEvent("click", starttouch.target, touch); + } + + starttouch = null; + return; + } + } + + function handleTouchMove(e) { + if (!starttouch) { + return; + } + + for (let i = 0; i < e.changedTouches.length; i++) { + let touch = e.changedTouches[i]; + // If the ended touch does not have the same id, skip it + if (touch.identifier !== starttouch.identifier) { + continue; + } + + // Don't send a mousemove if the touchmove was prevented + if (e.defaultPrevented) { + return; + } + + // See if we've moved too much to emit a click event + let dx = Math.abs(touch.screenX - starttouch.screenX); + let dy = Math.abs(touch.screenY - starttouch.screenY); + if ( + dx > MouseEventShim.dragThresholdX || + dy > MouseEventShim.dragThresholdY + ) { + emitclick = false; + } + + let tracking = + MouseEventShim.trackMouseMoves && !MouseEventShim.capturing; + + let oldtarget; + let newtarget; + if (tracking) { + // If the touch point moves, then the element it is over + // may have changed as well. Note that calling elementFromPoint() + // forces a layout if one is needed. + // XXX: how expensive is it to do this on each touchmove? + // Can we listen for (non-standard) touchleave events instead? + oldtarget = target; + newtarget = document.elementFromPoint(touch.clientX, touch.clientY); + if (newtarget === null) { + // this can happen as the touch is moving off of the screen, e.g. + newtarget = oldtarget; + } + if (newtarget !== oldtarget) { + leave(oldtarget, newtarget, touch); // mouseout, mouseleave + target = newtarget; + } + } else if (MouseEventShim.captureTarget) { + target = MouseEventShim.captureTarget; + } + + emitEvent("mousemove", target, touch); + + if (tracking && newtarget !== oldtarget) { + enter(newtarget, oldtarget, touch); // mouseover, mouseenter + } + } + } + + // Return true if element a contains element b + function contains(a, b) { + return (a.compareDocumentPosition(b) & 16) !== 0; + } + + // A touch has left oldtarget and entered newtarget + // Send out all the events that are required + function leave(oldtarget, newtarget, touch) { + emitEvent("mouseout", oldtarget, touch, newtarget); + + // If the touch has actually left oldtarget (and has not just moved + // into a child of oldtarget) send a mouseleave event. mouseleave + // events don't bubble, so we have to repeat this up the hierarchy. + for (let e = oldtarget; !contains(e, newtarget); e = e.parentNode) { + emitEvent("mouseleave", e, touch, newtarget); + } + } + + // A touch has entered newtarget from oldtarget + // Send out all the events that are required. + function enter(newtarget, oldtarget, touch) { + emitEvent("mouseover", newtarget, touch, oldtarget); + + // Emit non-bubbling mouseenter events if the touch actually entered + // newtarget and wasn't already in some child of it + for (let e = newtarget; !contains(e, oldtarget); e = e.parentNode) { + emitEvent("mouseenter", e, touch, oldtarget); + } + } + + function emitEvent(type, target, touch, relatedTarget) { + let synthetic = document.createEvent("MouseEvents"); + let bubbles = type !== "mouseenter" && type !== "mouseleave"; + let count = + type === "mousedown" || type === "mouseup" || type === "click" ? 1 : 0; + + synthetic.initMouseEvent( + type, + bubbles, // canBubble + true, // cancelable + window, + count, // detail: click count + touch.screenX, + touch.screenY, + touch.clientX, + touch.clientY, + false, // ctrlKey: we don't have one + false, // altKey: we don't have one + false, // shiftKey: we don't have one + false, // metaKey: we don't have one + 0, // we're simulating the left button + relatedTarget || null + ); + + try { + return target.dispatchEvent(synthetic); + } catch (e) { + console.warn("Exception calling dispatchEvent", type, e); + return true; + } + } +})(); + +const MouseEventShim = { + // It is a known gecko bug that synthetic events have timestamps measured + // in microseconds while regular events have timestamps measured in + // milliseconds. This utility function returns a the timestamp converted + // to milliseconds, if necessary. + getEventTimestamp(e) { + if (e.isTrusted) { + // XXX: Are real events always trusted? + return e.timeStamp; + } + return e.timeStamp / 1000; + }, + + // Set this to false if you don't care about mouseover/out events + // and don't want the target of mousemove events to follow the touch + trackMouseMoves: true, + + // Call this function from a mousedown event handler if you want to guarantee + // that the mousemove and mouseup events will go to the same element + // as the mousedown even if they leave the bounds of the element. This is + // like setting trackMouseMoves to false for just one drag. It is a + // substitute for event.target.setCapture(true) + setCapture(target) { + this.capturing = true; // Will be set back to false on mouseup + if (target) { + this.captureTarget = target; + } + }, + + capturing: false, + + // Keep these in sync with ui.dragThresholdX and ui.dragThresholdY prefs. + // If a touch ever moves more than this many pixels from its starting point + // then we will not synthesize a click event when the touch ends. + dragThresholdX: 25, + dragThresholdY: 25, +}; diff --git a/testing/marionette/harness/marionette_harness/www/slow_resource.html b/testing/marionette/harness/marionette_harness/www/slow_resource.html new file mode 100644 index 0000000000..b87d9f4b86 --- /dev/null +++ b/testing/marionette/harness/marionette_harness/www/slow_resource.html @@ -0,0 +1,13 @@ + + + + + +Slow loading resource + + + + + diff --git a/testing/marionette/harness/marionette_harness/www/test.html b/testing/marionette/harness/marionette_harness/www/test.html new file mode 100644 index 0000000000..20689a6d59 --- /dev/null +++ b/testing/marionette/harness/marionette_harness/www/test.html @@ -0,0 +1,43 @@ + + + + + +Marionette Test + + + +

Test Page

+ + Click me! + + + + + + diff --git a/testing/marionette/harness/marionette_harness/www/testAction.html b/testing/marionette/harness/marionette_harness/www/testAction.html new file mode 100644 index 0000000000..404ce9809a --- /dev/null +++ b/testing/marionette/harness/marionette_harness/www/testAction.html @@ -0,0 +1,96 @@ + + + + + + + +Marionette Test + + +

Test Page

+ + + + + + + + + + diff --git a/testing/marionette/harness/marionette_harness/www/test_accessibility.html b/testing/marionette/harness/marionette_harness/www/test_accessibility.html new file mode 100644 index 0000000000..8cc9fd6493 --- /dev/null +++ b/testing/marionette/harness/marionette_harness/www/test_accessibility.html @@ -0,0 +1,57 @@ + + + + + + + +Marionette Test + + + + + I am a bad button with no accessible +

I am a bad button that is actually a header

+

+ I am a bad button that is actually an actionable header with a listener +

+ + + + + + I have no accessible object + + + I have no accessible object + Span button + Unexplorable Span button + +
+ +
+
+ +
+ + + + + diff --git a/testing/marionette/harness/marionette_harness/www/test_clearing.html b/testing/marionette/harness/marionette_harness/www/test_clearing.html new file mode 100644 index 0000000000..2aa3c6a21f --- /dev/null +++ b/testing/marionette/harness/marionette_harness/www/test_clearing.html @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + +
This is a contentEditable area
+ + diff --git a/testing/marionette/harness/marionette_harness/www/test_dynamic.html b/testing/marionette/harness/marionette_harness/www/test_dynamic.html new file mode 100644 index 0000000000..504e7e74ba --- /dev/null +++ b/testing/marionette/harness/marionette_harness/www/test_dynamic.html @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + diff --git a/testing/marionette/harness/marionette_harness/www/test_iframe.html b/testing/marionette/harness/marionette_harness/www/test_iframe.html new file mode 100644 index 0000000000..b323ace679 --- /dev/null +++ b/testing/marionette/harness/marionette_harness/www/test_iframe.html @@ -0,0 +1,16 @@ + + + + + +Marionette IFrame Test + + +

This is the heading

+ + + + + diff --git a/testing/marionette/harness/marionette_harness/www/test_inner_iframe.html b/testing/marionette/harness/marionette_harness/www/test_inner_iframe.html new file mode 100644 index 0000000000..8c9810d0bb --- /dev/null +++ b/testing/marionette/harness/marionette_harness/www/test_inner_iframe.html @@ -0,0 +1,13 @@ + + + + + +Inner Iframe + + + + + diff --git a/testing/marionette/harness/marionette_harness/www/test_nested_iframe.html b/testing/marionette/harness/marionette_harness/www/test_nested_iframe.html new file mode 100644 index 0000000000..49ac1b0ba5 --- /dev/null +++ b/testing/marionette/harness/marionette_harness/www/test_nested_iframe.html @@ -0,0 +1,13 @@ + + + + + +Marionette IFrame Test + + + + + diff --git a/testing/marionette/harness/marionette_harness/www/test_oop_1.html b/testing/marionette/harness/marionette_harness/www/test_oop_1.html new file mode 100644 index 0000000000..29add714cd --- /dev/null +++ b/testing/marionette/harness/marionette_harness/www/test_oop_1.html @@ -0,0 +1,14 @@ + + + + + +OOP Test Frame 1 + + +

OOP Test Frame 1

+ Hello! + + diff --git a/testing/marionette/harness/marionette_harness/www/test_oop_2.html b/testing/marionette/harness/marionette_harness/www/test_oop_2.html new file mode 100644 index 0000000000..6e5a4962fb --- /dev/null +++ b/testing/marionette/harness/marionette_harness/www/test_oop_2.html @@ -0,0 +1,14 @@ + + + + + +OOP Test Frame 2 + + +

OOP Test Frame 2

+ Hello! + + diff --git a/testing/marionette/harness/marionette_harness/www/test_windows.html b/testing/marionette/harness/marionette_harness/www/test_windows.html new file mode 100644 index 0000000000..f3759990c0 --- /dev/null +++ b/testing/marionette/harness/marionette_harness/www/test_windows.html @@ -0,0 +1,13 @@ + + + + + + XHTML Test Page + + +

Open new window

+ + diff --git a/testing/marionette/harness/marionette_harness/www/update/complete.mar b/testing/marionette/harness/marionette_harness/www/update/complete.mar new file mode 100644 index 0000000000..375fd7bd08 Binary files /dev/null and b/testing/marionette/harness/marionette_harness/www/update/complete.mar differ diff --git a/testing/marionette/harness/marionette_harness/www/update/complete.mar.headers b/testing/marionette/harness/marionette_harness/www/update/complete.mar.headers new file mode 100644 index 0000000000..bcf051e2c7 --- /dev/null +++ b/testing/marionette/harness/marionette_harness/www/update/complete.mar.headers @@ -0,0 +1 @@ +Content-Length: 86612 diff --git a/testing/marionette/harness/marionette_harness/www/visibility.html b/testing/marionette/harness/marionette_harness/www/visibility.html new file mode 100644 index 0000000000..2296f3cd46 --- /dev/null +++ b/testing/marionette/harness/marionette_harness/www/visibility.html @@ -0,0 +1,51 @@ + + + + + Testing Visibility + + + + +
+ Click to hide me. +
+ +
+
+ +
+
+ + + +
+

Displayed

+ +
+ + + + + + + +
+ + + Check box you can't see + +
+ + +
+ + + + diff --git a/testing/marionette/harness/marionette_harness/www/white.png b/testing/marionette/harness/marionette_harness/www/white.png new file mode 100644 index 0000000000..8a68c11548 Binary files /dev/null and b/testing/marionette/harness/marionette_harness/www/white.png differ diff --git a/testing/marionette/harness/marionette_harness/www/windowHandles.html b/testing/marionette/harness/marionette_harness/www/windowHandles.html new file mode 100644 index 0000000000..bcd0b08dc3 --- /dev/null +++ b/testing/marionette/harness/marionette_harness/www/windowHandles.html @@ -0,0 +1,16 @@ + + + + + +Marionette New Tab Link + + + New Tab + New blank Tab + + New Window + + diff --git a/testing/marionette/harness/marionette_harness/www/xhtmlTest.html b/testing/marionette/harness/marionette_harness/www/xhtmlTest.html new file mode 100644 index 0000000000..30940c709e --- /dev/null +++ b/testing/marionette/harness/marionette_harness/www/xhtmlTest.html @@ -0,0 +1,79 @@ + + + + + XHTML Test Page + + + + + + +
+

XHTML Might Be The Future

+ +

If you'd like to go elsewhere then click me.

+ +

Alternatively, this goes to the same place.

+ +
+ +
+ + This link has the same text as another link: click me. +
+ +
Another div starts here.

+

An H2 title

+

Some more text

+
+ +
+ Foo +
    + +
+ +
+
+
+ + +
+
+
+ + I have width +
+
+
+
+ + +

+

+
Link=equalssign + +

Spaced out

+ + +
first_div
+
second_div
+ first_span + second_span +
+ +
I'm a parent +
I'm a child
+
+ +
Woo woo
+ + diff --git a/testing/marionette/harness/requirements.txt b/testing/marionette/harness/requirements.txt new file mode 100644 index 0000000000..aa307b196d --- /dev/null +++ b/testing/marionette/harness/requirements.txt @@ -0,0 +1,15 @@ +browsermob-proxy >= 0.8.0 +manifestparser >= 1.1 +marionette-driver >= 3.0.0 +mozcrash >= 2.0 +mozdevice >= 4.0.0,<5 +mozinfo >= 1.0.0 +mozlog >= 6.0 +moznetwork >= 0.27 +mozprocess >= 1.0.0 +mozprofile >= 2.2.0 +mozrunner >= 7.4.0 +moztest >= 0.8 +mozversion >= 2.1.0 +six +wptserve >= 2.0.0 diff --git a/testing/marionette/harness/setup.py b/testing/marionette/harness/setup.py new file mode 100644 index 0000000000..fd43cdb969 --- /dev/null +++ b/testing/marionette/harness/setup.py @@ -0,0 +1,58 @@ +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +import os +import re + +from setuptools import find_packages, setup + +THIS_DIR = os.path.dirname(os.path.realpath(__name__)) + + +def read(*parts): + with open(os.path.join(THIS_DIR, *parts)) as f: + return f.read() + + +def get_version(): + return re.findall( + '__version__ = "([\d\.]+)"', read("marionette_harness", "__init__.py"), re.M + )[0] + + +setup( + name="marionette-harness", + version=get_version(), + description="Marionette test automation harness", + long_description=open("README.rst").read(), + # Get strings from http://pypi.python.org/pypi?%3Aaction=list_classifiers + classifiers=[ + "Development Status :: 5 - Production/Stable", + "Intended Audience :: Developers", + "License :: OSI Approved :: Mozilla Public License 2.0 (MPL 2.0)", + "Operating System :: MacOS :: MacOS X", + "Operating System :: Microsoft :: Windows", + "Operating System :: POSIX", + "Topic :: Software Development :: Quality Assurance", + "Topic :: Software Development :: Testing", + "Topic :: Utilities", + "Programming Language :: Python", + "Programming Language :: Python :: 2.7", + ], + keywords="mozilla", + author="Auto-tools", + author_email="dev-webdriver@mozilla.org", + url="https://wiki.mozilla.org/Auto-tools/Projects/Marionette", + license="Mozilla Public License 2.0 (MPL 2.0)", + packages=find_packages(), + # Needed to include package data as specified in MANIFEST.in + include_package_data=True, + install_requires=read("requirements.txt").splitlines(), + zip_safe=False, + entry_points=""" + # -*- Entry points: -*- + [console_scripts] + marionette = marionette_harness.runtests:cli + """, +) diff --git a/testing/marionette/mach_commands.py b/testing/marionette/mach_commands.py new file mode 100644 index 0000000000..36ff952689 --- /dev/null +++ b/testing/marionette/mach_commands.py @@ -0,0 +1,113 @@ +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +import argparse +import functools +import logging +import os +import sys + +from six import iteritems + +from mach.decorators import ( + Command, +) + +from mozbuild.base import ( + MachCommandConditions as conditions, + BinaryNotFoundException, +) + +SUPPORTED_APPS = ["firefox", "android", "thunderbird"] + + +def create_parser_tests(): + from marionette_harness.runtests import MarionetteArguments + from mozlog.structured import commandline + + parser = MarionetteArguments() + commandline.add_logging_group(parser) + return parser + + +def run_marionette(tests, binary=None, topsrcdir=None, **kwargs): + from mozlog.structured import commandline + + from marionette_harness.runtests import MarionetteTestRunner, MarionetteHarness + + parser = create_parser_tests() + + args = argparse.Namespace(tests=tests) + + args.binary = binary + args.logger = kwargs.pop("log", None) + + for k, v in iteritems(kwargs): + setattr(args, k, v) + + parser.verify_usage(args) + + # Causes Firefox to crash when using non-local connections. + os.environ["MOZ_DISABLE_NONLOCAL_CONNECTIONS"] = "1" + + if not args.logger: + args.logger = commandline.setup_logging( + "Marionette Unit Tests", args, {"mach": sys.stdout} + ) + failed = MarionetteHarness(MarionetteTestRunner, args=vars(args)).run() + if failed > 0: + return 1 + else: + return 0 + + +@Command( + "marionette-test", + category="testing", + description="Remote control protocol to Gecko, used for browser automation.", + conditions=[functools.partial(conditions.is_buildapp_in, apps=SUPPORTED_APPS)], + parser=create_parser_tests, +) +def marionette_test(command_context, tests, **kwargs): + if "test_objects" in kwargs: + tests = [] + for obj in kwargs["test_objects"]: + tests.append(obj["file_relpath"]) + del kwargs["test_objects"] + + if not tests: + if conditions.is_thunderbird(command_context): + tests = [ + os.path.join( + command_context.topsrcdir, + "comm/testing/marionette/unit-tests.ini", + ) + ] + else: + tests = [ + os.path.join( + command_context.topsrcdir, + "testing/marionette/harness/marionette_harness/tests/unit-tests.ini", + ) + ] + + if not kwargs.get("binary") and ( + conditions.is_firefox(command_context) + or conditions.is_thunderbird(command_context) + ): + try: + kwargs["binary"] = command_context.get_binary_path("app") + except BinaryNotFoundException as e: + command_context.log( + logging.ERROR, + "marionette-test", + {"error": str(e)}, + "ERROR: {error}", + ) + command_context.log( + logging.INFO, "marionette-test", {"help": e.help()}, "{help}" + ) + return 1 + + return run_marionette(tests, topsrcdir=command_context.topsrcdir, **kwargs) diff --git a/testing/marionette/mach_test_package_commands.py b/testing/marionette/mach_test_package_commands.py new file mode 100644 index 0000000000..22c298a88a --- /dev/null +++ b/testing/marionette/mach_test_package_commands.py @@ -0,0 +1,66 @@ +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +import argparse +import os +import sys +from functools import partial + +from mach.decorators import Command + +parser = None + + +def run_marionette(context, **kwargs): + from marionette.runtests import MarionetteHarness, MarionetteTestRunner + from mozlog.structured import commandline + + args = argparse.Namespace(**kwargs) + args.binary = args.binary or context.firefox_bin + + test_root = os.path.join(context.package_root, "marionette", "tests") + if not args.tests: + args.tests = [ + os.path.join( + test_root, + "testing", + "marionette", + "harness", + "marionette_harness", + "tests", + "unit-tests.ini", + ) + ] + + normalize = partial(context.normalize_test_path, test_root) + args.tests = list(map(normalize, args.tests)) + + commandline.add_logging_group(parser) + parser.verify_usage(args) + + args.logger = commandline.setup_logging( + "Marionette Unit Tests", args, {"mach": sys.stdout} + ) + status = MarionetteHarness(MarionetteTestRunner, args=vars(args)).run() + return 1 if status else 0 + + +def setup_marionette_argument_parser(): + from marionette.runner.base import BaseMarionetteArguments + + global parser + parser = BaseMarionetteArguments() + return parser + + +@Command( + "marionette-test", + category="testing", + description="Run a Marionette test (Check UI or the internal JavaScript " + "using marionette).", + parser=setup_marionette_argument_parser, +) +def run_marionette_test(command_context, **kwargs): + command_context.context.activate_mozharness_venv() + return run_marionette(command_context.context, **kwargs) diff --git a/testing/marionette/moz.build b/testing/marionette/moz.build new file mode 100644 index 0000000000..0cf40bb049 --- /dev/null +++ b/testing/marionette/moz.build @@ -0,0 +1,13 @@ +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +MARIONETTE_UNIT_MANIFESTS += ["harness/marionette_harness/tests/unit/unit-tests.ini"] + +with Files("**"): + BUG_COMPONENT = ("Testing", "Marionette Client and Harness") + +with Files("harness/**"): + SCHEDULES.exclusive = ["marionette", "firefox-ui"] + +SPHINX_PYTHON_PACKAGE_DIRS += ["client/marionette_driver"] -- cgit v1.2.3