From 26a029d407be480d791972afb5975cf62c9360a6 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Fri, 19 Apr 2024 02:47:55 +0200 Subject: Adding upstream version 124.0.1. 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 | 195 ++ 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 | 663 ++++++ .../marionette/client/marionette_driver/keys.py | 87 + .../client/marionette_driver/localization.py | 54 + .../client/marionette_driver/marionette.py | 2183 ++++++++++++++++++++ .../marionette/client/marionette_driver/timeout.py | 103 + .../client/marionette_driver/transport.py | 409 ++++ .../marionette/client/marionette_driver/wait.py | 175 ++ .../client/marionette_driver/webauthn.py | 63 + 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 | 420 ++++ .../harness/marionette_harness/runner/__init__.py | 16 + .../harness/marionette_harness/runner/base.py | 1265 ++++++++++++ .../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.toml | 14 + .../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.toml | 43 + .../marionette_harness/tests/unit/data/test.html | 13 + .../tests/unit/test_accessibility.py | 241 +++ .../tests/unit/test_actions_key.py | 71 + .../tests/unit/test_actions_pointer.py | 134 ++ .../tests/unit/test_actions_wheel.py | 68 + .../marionette_harness/tests/unit/test_addons.py | 140 ++ .../tests/unit/test_capabilities.py | 322 +++ .../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 | 571 +++++ .../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 | 211 ++ .../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_localization.py | 71 + .../tests/unit/test_marionette.py | 138 ++ .../tests/unit/test_modal_dialogs.py | 161 ++ .../tests/unit/test_navigation.py | 901 ++++++++ .../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 | 213 ++ .../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 | 33 + .../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 | 109 + .../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 | 60 + .../marionette_harness/tests/unit/unit-tests.toml | 193 ++ .../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 .../marionette_harness/www/actions_scroll.html | 139 ++ .../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 + .../www/dom/cache/basicCacheAPI_PBM.html | 21 + .../www/dom/cache/cacheUsage.html | 28 + .../www/dom/indexedDB/basicIDB_PBM.html | 49 + .../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_key_scroll.html | 18 + .../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 | 49 + .../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 + .../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 + 220 files changed, 24370 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/marionette_driver/webauthn.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.toml 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.toml 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_actions_key.py create mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_actions_pointer.py create mode 100644 testing/marionette/harness/marionette_harness/tests/unit/test_actions_wheel.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_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_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.toml 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/actions_scroll.html 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/cache/basicCacheAPI_PBM.html create mode 100644 testing/marionette/harness/marionette_harness/www/dom/cache/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_key_scroll.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/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..9d4a34b052 --- /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, WebElement objects also +provide :func:`~WebElement.find_element` and :func:`~WebElement.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..f90ab63579 --- /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:`~WebElement.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..76ae71015b --- /dev/null +++ b/testing/marionette/client/docs/basics.rst @@ -0,0 +1,195 @@ +.. 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: + +.. code-block:: bash + + $ 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() `: + +.. code-block:: python + + 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: + +.. code-block:: python + + 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 + + +
+
+

Events

+
+
+ + diff --git a/testing/marionette/harness/marionette_harness/www/addons/webextension-signed.xpi b/testing/marionette/harness/marionette_harness/www/addons/webextension-signed.xpi new file mode 100644 index 0000000000..5363911af1 Binary files /dev/null and b/testing/marionette/harness/marionette_harness/www/addons/webextension-signed.xpi differ diff --git a/testing/marionette/harness/marionette_harness/www/addons/webextension-unsigned.xpi b/testing/marionette/harness/marionette_harness/www/addons/webextension-unsigned.xpi new file mode 100644 index 0000000000..cf0fad63b5 Binary files /dev/null and b/testing/marionette/harness/marionette_harness/www/addons/webextension-unsigned.xpi differ diff --git a/testing/marionette/harness/marionette_harness/www/black.png b/testing/marionette/harness/marionette_harness/www/black.png new file mode 100644 index 0000000000..b62a3a7bc8 Binary files /dev/null and b/testing/marionette/harness/marionette_harness/www/black.png differ diff --git a/testing/marionette/harness/marionette_harness/www/bug814037.html b/testing/marionette/harness/marionette_harness/www/bug814037.html new file mode 100644 index 0000000000..47c2968163 --- /dev/null +++ b/testing/marionette/harness/marionette_harness/www/bug814037.html @@ -0,0 +1,56 @@ + + + + + + + +
+
+

Section 1

+
+ +
+ +
+
+

Section 2

+
+ +
+
out in left field!
+ + diff --git a/testing/marionette/harness/marionette_harness/www/click_out_of_bounds_overflow.html b/testing/marionette/harness/marionette_harness/www/click_out_of_bounds_overflow.html new file mode 100644 index 0000000000..f0bee9b469 --- /dev/null +++ b/testing/marionette/harness/marionette_harness/www/click_out_of_bounds_overflow.html @@ -0,0 +1,90 @@ + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
data
click me
+
+ + diff --git a/testing/marionette/harness/marionette_harness/www/clicks.html b/testing/marionette/harness/marionette_harness/www/clicks.html new file mode 100644 index 0000000000..96e9f55171 --- /dev/null +++ b/testing/marionette/harness/marionette_harness/www/clicks.html @@ -0,0 +1,57 @@ + + + + Testing Clicks + + + + + +

Testing Clicks

+ + + +
+ + +
+ +
+

Special:

+ + +

+ looooooooooong short looooooooooong +

+
+ + + diff --git a/testing/marionette/harness/marionette_harness/www/dom/cache/basicCacheAPI_PBM.html b/testing/marionette/harness/marionette_harness/www/dom/cache/basicCacheAPI_PBM.html new file mode 100644 index 0000000000..8a23acf437 --- /dev/null +++ b/testing/marionette/harness/marionette_harness/www/dom/cache/basicCacheAPI_PBM.html @@ -0,0 +1,21 @@ + + + + + diff --git a/testing/marionette/harness/marionette_harness/www/dom/cache/cacheUsage.html b/testing/marionette/harness/marionette_harness/www/dom/cache/cacheUsage.html new file mode 100644 index 0000000000..8bb7da8f71 --- /dev/null +++ b/testing/marionette/harness/marionette_harness/www/dom/cache/cacheUsage.html @@ -0,0 +1,28 @@ + + + + + diff --git a/testing/marionette/harness/marionette_harness/www/dom/indexedDB/basicIDB_PBM.html b/testing/marionette/harness/marionette_harness/www/dom/indexedDB/basicIDB_PBM.html new file mode 100644 index 0000000000..90472d64d2 --- /dev/null +++ b/testing/marionette/harness/marionette_harness/www/dom/indexedDB/basicIDB_PBM.html @@ -0,0 +1,49 @@ + + + + + diff --git a/testing/marionette/harness/marionette_harness/www/element_outside_viewport.html b/testing/marionette/harness/marionette_harness/www/element_outside_viewport.html new file mode 100644 index 0000000000..69b66b8759 --- /dev/null +++ b/testing/marionette/harness/marionette_harness/www/element_outside_viewport.html @@ -0,0 +1,41 @@ + + + +
+
+
+
+
+
+
+
+
+
+
+
+ diff --git a/testing/marionette/harness/marionette_harness/www/empty.html b/testing/marionette/harness/marionette_harness/www/empty.html new file mode 100644 index 0000000000..646edf9a72 --- /dev/null +++ b/testing/marionette/harness/marionette_harness/www/empty.html @@ -0,0 +1,12 @@ + + + + + +Marionette Test + + + + diff --git a/testing/marionette/harness/marionette_harness/www/formPage.html b/testing/marionette/harness/marionette_harness/www/formPage.html new file mode 100644 index 0000000000..43fde32431 --- /dev/null +++ b/testing/marionette/harness/marionette_harness/www/formPage.html @@ -0,0 +1,114 @@ + + + We Leave From Here + + + + +There should be a form here: + +
+ + +
+ +
+ Here's a checkbox: + + + + +
+ + + + + + + + + + + + + + + + + + + + +
+ + Cheese
+ Peas
+ Cheese and peas
+ Not a sausage
+ Not another sausage + + + +

I like cheese

+ + + Cumberland sausage +
+ +
+

+ +

+
+ + + diff --git a/testing/marionette/harness/marionette_harness/www/frameset.html b/testing/marionette/harness/marionette_harness/www/frameset.html new file mode 100644 index 0000000000..e91472c952 --- /dev/null +++ b/testing/marionette/harness/marionette_harness/www/frameset.html @@ -0,0 +1,13 @@ + + + Unique title + + + + + + + + + + diff --git a/testing/marionette/harness/marionette_harness/www/framesetPage2.html b/testing/marionette/harness/marionette_harness/www/framesetPage2.html new file mode 100644 index 0000000000..5190ceb6ce --- /dev/null +++ b/testing/marionette/harness/marionette_harness/www/framesetPage2.html @@ -0,0 +1,7 @@ + + + + + + + diff --git a/testing/marionette/harness/marionette_harness/www/html5/blue.jpg b/testing/marionette/harness/marionette_harness/www/html5/blue.jpg new file mode 100644 index 0000000000..8ea27c42fa Binary files /dev/null and b/testing/marionette/harness/marionette_harness/www/html5/blue.jpg differ diff --git a/testing/marionette/harness/marionette_harness/www/html5/boolean_attributes.html b/testing/marionette/harness/marionette_harness/www/html5/boolean_attributes.html new file mode 100644 index 0000000000..431e575aef --- /dev/null +++ b/testing/marionette/harness/marionette_harness/www/html5/boolean_attributes.html @@ -0,0 +1,2 @@ + + diff --git a/testing/marionette/harness/marionette_harness/www/html5/geolocation.js b/testing/marionette/harness/marionette_harness/www/html5/geolocation.js new file mode 100644 index 0000000000..4fb4a4747b --- /dev/null +++ b/testing/marionette/harness/marionette_harness/www/html5/geolocation.js @@ -0,0 +1,29 @@ +/* eslint-disable no-unsanitized/property */ + +function success(position) { + let message = document.getElementById("status"); + message.innerHTML = + ""; + message.innerHTML += "

Longitude: " + position.coords.longitude + "

"; + message.innerHTML += "

Latitude: " + position.coords.latitude + "

"; + message.innerHTML += "

Altitude: " + position.coords.altitude + "

"; +} + +function error(msg) { + let message = document.getElementById("status"); + message.innerHTML = "Failed to get geolocation."; +} + +if (navigator.geolocation) { + navigator.geolocation.getCurrentPosition(success, error); +} else { + error("Geolocation is not supported."); +} diff --git a/testing/marionette/harness/marionette_harness/www/html5/green.jpg b/testing/marionette/harness/marionette_harness/www/html5/green.jpg new file mode 100644 index 0000000000..6a0d3bea47 Binary files /dev/null and b/testing/marionette/harness/marionette_harness/www/html5/green.jpg differ diff --git a/testing/marionette/harness/marionette_harness/www/html5/offline.html b/testing/marionette/harness/marionette_harness/www/html5/offline.html new file mode 100644 index 0000000000..c24178b5f5 --- /dev/null +++ b/testing/marionette/harness/marionette_harness/www/html5/offline.html @@ -0,0 +1 @@ +Offline diff --git a/testing/marionette/harness/marionette_harness/www/html5/red.jpg b/testing/marionette/harness/marionette_harness/www/html5/red.jpg new file mode 100644 index 0000000000..f296e27195 Binary files /dev/null and b/testing/marionette/harness/marionette_harness/www/html5/red.jpg differ diff --git a/testing/marionette/harness/marionette_harness/www/html5/status.html b/testing/marionette/harness/marionette_harness/www/html5/status.html new file mode 100644 index 0000000000..394116a522 --- /dev/null +++ b/testing/marionette/harness/marionette_harness/www/html5/status.html @@ -0,0 +1 @@ +Online diff --git a/testing/marionette/harness/marionette_harness/www/html5/test.appcache b/testing/marionette/harness/marionette_harness/www/html5/test.appcache new file mode 100644 index 0000000000..3bc4e00257 --- /dev/null +++ b/testing/marionette/harness/marionette_harness/www/html5/test.appcache @@ -0,0 +1,11 @@ +CACHE MANIFEST + +CACHE: +# Additional items to cache. +yellow.jpg +red.jpg +blue.jpg +green.jpg + +FALLBACK: +status.html offline.html diff --git a/testing/marionette/harness/marionette_harness/www/html5/test_html_inputs.html b/testing/marionette/harness/marionette_harness/www/html5/test_html_inputs.html new file mode 100644 index 0000000000..a170ced1ab --- /dev/null +++ b/testing/marionette/harness/marionette_harness/www/html5/test_html_inputs.html @@ -0,0 +1,2 @@ + + diff --git a/testing/marionette/harness/marionette_harness/www/html5/yellow.jpg b/testing/marionette/harness/marionette_harness/www/html5/yellow.jpg new file mode 100644 index 0000000000..7c609b3712 Binary files /dev/null and b/testing/marionette/harness/marionette_harness/www/html5/yellow.jpg differ diff --git a/testing/marionette/harness/marionette_harness/www/html5Page.html b/testing/marionette/harness/marionette_harness/www/html5Page.html new file mode 100644 index 0000000000..fbd943d792 --- /dev/null +++ b/testing/marionette/harness/marionette_harness/www/html5Page.html @@ -0,0 +1,46 @@ + + + + + +HTML5 + + + +

Geolocation Test

+
Location unknown
+ + +

Application Cache Test

+
+

Current network status:

+ + + + + +
+ + + diff --git a/testing/marionette/harness/marionette_harness/www/keyboard.html b/testing/marionette/harness/marionette_harness/www/keyboard.html new file mode 100644 index 0000000000..e711b31e05 --- /dev/null +++ b/testing/marionette/harness/marionette_harness/www/keyboard.html @@ -0,0 +1,99 @@ + + + + + + Testing Javascript + + + + + +

Type Stuff

+ +
+ Result:

+
+ +
+
+

+ + + + +

+

+ +

+

+ + + +

+

+ +

+
+
+ +
+
+ Key Up:
+ Key Down:
+ Key Press:
+ Change:
+ + + + + + + + + +
+
+ +
+
+ + +
+
+ + + diff --git a/testing/marionette/harness/marionette_harness/www/layout/test_carets_columns.html b/testing/marionette/harness/marionette_harness/www/layout/test_carets_columns.html new file mode 100644 index 0000000000..bc414cfc45 --- /dev/null +++ b/testing/marionette/harness/marionette_harness/www/layout/test_carets_columns.html @@ -0,0 +1,31 @@ + + + + + + + + + +
+
+

Before image 1

+

+

After image 1

+

Before image 2

+

+

After image 2

+
+
+ + diff --git a/testing/marionette/harness/marionette_harness/www/layout/test_carets_cursor.html b/testing/marionette/harness/marionette_harness/www/layout/test_carets_cursor.html new file mode 100644 index 0000000000..fdbd6fe7a8 --- /dev/null +++ b/testing/marionette/harness/marionette_harness/www/layout/test_carets_cursor.html @@ -0,0 +1,31 @@ + + + + + + Marionette tests for AccessibleCaret in cursor mode + + + +
+ + +
+
+
+ + +
+
+
ABCDEFGHI
+ + diff --git a/testing/marionette/harness/marionette_harness/www/layout/test_carets_display_none.html b/testing/marionette/harness/marionette_harness/www/layout/test_carets_display_none.html new file mode 100644 index 0000000000..766f320011 --- /dev/null +++ b/testing/marionette/harness/marionette_harness/www/layout/test_carets_display_none.html @@ -0,0 +1,10 @@ + + + + + +
ABC DEF GHI
+ + diff --git a/testing/marionette/harness/marionette_harness/www/layout/test_carets_iframe.html b/testing/marionette/harness/marionette_harness/www/layout/test_carets_iframe.html new file mode 100644 index 0000000000..175d3c3d5c --- /dev/null +++ b/testing/marionette/harness/marionette_harness/www/layout/test_carets_iframe.html @@ -0,0 +1,15 @@ + + + + + + + Marionette tests for AccessibleCaret in selection mode (iframe) + + + + + + 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_key_scroll.html b/testing/marionette/harness/marionette_harness/www/layout/test_carets_key_scroll.html new file mode 100644 index 0000000000..a42a342285 --- /dev/null +++ b/testing/marionette/harness/marionette_harness/www/layout/test_carets_key_scroll.html @@ -0,0 +1,18 @@ + + + + +
+ AAAAA
+ BBBBB +
+ 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..9098ed447c --- /dev/null +++ b/testing/marionette/harness/marionette_harness/www/layout/test_carets_selection.html @@ -0,0 +1,49 @@ + + + + + + + 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/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..7736806d1e --- /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.toml", + ) + ] + + 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..0bb3df8b89 --- /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.toml", + ) + ] + + 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..1986d20904 --- /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_MANIFESTS += ["harness/marionette_harness/tests/unit/unit-tests.toml"] + +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